Add API allowing plugins to participate in private browsing. b=468877 r/sr=jst

This commit is contained in:
Josh Aas 2009-01-30 16:40:14 -05:00
Родитель f8adbaad93
Коммит 023787822c
11 изменённых файлов: 181 добавлений и 24 удалений

Просмотреть файл

@ -91,7 +91,7 @@
/*----------------------------------------------------------------------*/
#define NP_VERSION_MAJOR 0
#define NP_VERSION_MINOR 21
#define NP_VERSION_MINOR 22
/* The OS/2 version of Netscape uses RC_DATA to define the
@ -327,7 +327,10 @@ typedef enum {
/* Checks if the plugin is interested in receiving the http body of
* all http requests (including failed ones, http status != 200).
*/
NPPVpluginWantsAllNetworkStreams = 18
NPPVpluginWantsAllNetworkStreams = 18,
NPPVprivateModeBool = 19
#ifdef XP_MACOSX
/* Used for negotiating drawing models */
, NPPVpluginDrawingModel = 1000
@ -358,7 +361,9 @@ typedef enum {
/* Get the NPObject wrapper for the plugins DOM element. */
NPNVPluginElementNPObject = 16,
NPNVSupportsWindowless = 17
NPNVSupportsWindowless = 17,
NPNVprivateModeBool = 18
#ifdef XP_MACOSX
/* Used for negotiating drawing models */

Просмотреть файл

@ -61,10 +61,10 @@ typedef void (*NPP_URLNotifyProcPtr)(NPP instance, const char* url, NPRe
/* Any NPObjects returned to the browser via NPP_GetValue should be retained
by the plugin on the way out. The browser is responsible for releasing. */
typedef NPError (*NPP_GetValueProcPtr)(NPP instance, NPPVariable variable, void *ret_value);
typedef NPError (*NPP_SetValueProcPtr)(NPP instance, NPNVariable variable, void *ret_value);
typedef NPError (*NPP_SetValueProcPtr)(NPP instance, NPNVariable variable, void *value);
typedef NPError (*NPN_GetValueProcPtr)(NPP instance, NPNVariable variable, void *ret_value);
typedef NPError (*NPN_SetValueProcPtr)(NPP instance, NPPVariable variable, void *ret_value);
typedef NPError (*NPN_SetValueProcPtr)(NPP instance, NPPVariable variable, void *value);
typedef NPError (*NPN_GetURLNotifyProcPtr)(NPP instance, const char* url, const char* window, void* notifyData);
typedef NPError (*NPN_PostURLNotifyProcPtr)(NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file, void* notifyData);
typedef NPError (*NPN_GetURLProcPtr)(NPP instance, const char* url, const char* window);

Просмотреть файл

@ -45,6 +45,7 @@
#include "nsNPAPIPluginStreamListener.h"
#include "nsIServiceManager.h"
#include "nsThreadUtils.h"
#include "nsIPrivateBrowsingService.h"
#include "nsIPluginStreamListener.h"
#include "nsPluginsDir.h"
@ -2042,6 +2043,15 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
return NPERR_NO_ERROR;
}
case NPNVprivateModeBool: {
nsCOMPtr<nsIPrivateBrowsingService> pbs = do_GetService(NS_PRIVATE_BROWSING_SERVICE_CONTRACTID);
if (pbs) {
pbs->GetPrivateBrowsingEnabled((PRBool*)result);
return NPERR_NO_ERROR;
}
return NPERR_GENERIC_ERROR;
}
#ifdef XP_MACOSX
case NPNVpluginDrawingModel: {
if (npp) {

Просмотреть файл

@ -48,6 +48,7 @@
#include "nsPluginHostImpl.h"
#include "nsPluginSafety.h"
#include "nsPluginLogging.h"
#include "nsIPrivateBrowsingService.h"
#include "nsPIPluginInstancePeer.h"
#include "nsPIDOMWindow.h"
@ -1482,3 +1483,28 @@ nsNPAPIPluginInstance::GetPluginAPIVersion()
{
return fCallbacks->version;
}
nsresult nsNPAPIPluginInstance::PrivateModeStateChanged()
{
if (!mStarted)
return NS_OK;
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance informing plugin of private mode state change this=%p\n",this));
if (fCallbacks->setvalue) {
PluginDestructionGuard guard(this);
nsCOMPtr<nsIPrivateBrowsingService> pbs = do_GetService(NS_PRIVATE_BROWSING_SERVICE_CONTRACTID);
if (pbs) {
PRBool pme = PR_FALSE;
nsresult rv = pbs->GetPrivateBrowsingEnabled(&pme);
if (NS_FAILED(rv))
return rv;
NPError error;
NS_TRY_SAFE_CALL_RETURN(error, (*fCallbacks->setvalue)(&fNPP, NPNVprivateModeBool, &pme), fLibrary, this);
return (error == NPERR_NO_ERROR) ? NS_OK : NS_ERROR_FAILURE;
}
}
return NS_ERROR_FAILURE;
}

Просмотреть файл

@ -89,7 +89,6 @@ public:
// nsNPAPIPluginInstance-specific methods
// Return the 4.x-style interface object.
nsresult GetNPP(NPP * aNPP);
// Return the callbacks for the plugin instance.
@ -132,6 +131,7 @@ public:
already_AddRefed<nsPIDOMWindow> GetDOMWindow();
nsresult PrivateModeStateChanged();
protected:
nsresult InitializePlugin(nsIPluginInstancePeer* peer);

Просмотреть файл

@ -94,6 +94,7 @@
#include "nsPrintfCString.h"
#include "nsIBlocklistService.h"
#include "nsVersionComparator.h"
#include "nsIPrivateBrowsingService.h"
// Friggin' X11 has to "#define None". Lame!
#ifdef None
@ -1071,7 +1072,7 @@ nsresult PostPluginUnloadEvent(PRLibrary* aLibrary)
void nsPluginTag::TryUnloadPlugin(PRBool aForceShutdown)
{
PRBool isXPCOM = PR_FALSE;
if (!(mFlags & NS_PLUGIN_FLAG_OLDSCHOOL))
if (!(mFlags & NS_PLUGIN_FLAG_NPAPI))
isXPCOM = PR_TRUE;
if (isXPCOM && !aForceShutdown) return;
@ -2519,9 +2520,9 @@ nsPluginHostImpl::nsPluginHostImpl()
}
nsCOMPtr<nsIObserverService> obsService = do_GetService("@mozilla.org/observer-service;1");
if (obsService)
{
if (obsService) {
obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
obsService->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, PR_FALSE);
}
#ifdef PLUGIN_LOGGING
@ -2688,7 +2689,7 @@ nsresult nsPluginHostImpl::ReloadPlugins(PRBool reloadPages)
// if plugins are reloaded. This also fixes a crash on UNIX where the call
// to shutdown would break the ProxyJNI connection to the JRE after a reload.
// see bug 86591
if (!IsRunningPlugin(p) && (!p->mEntryPoint || p->HasFlag(NS_PLUGIN_FLAG_OLDSCHOOL))) {
if (!IsRunningPlugin(p) && (!p->mEntryPoint || p->HasFlag(NS_PLUGIN_FLAG_NPAPI))) {
if (p == mPlugins)
mPlugins = next;
else
@ -4529,11 +4530,11 @@ NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlugi
}
#endif
else {
// Now lets try to get the entry point from a 4.x plugin
// Now lets try to get the entry point from an NPAPI plugin
rv = CreateNPAPIPlugin(serviceManager, pluginTag, &plugin);
if (NS_SUCCEEDED(rv))
pluginTag->mEntryPoint = plugin;
pluginTag->Mark(NS_PLUGIN_FLAG_OLDSCHOOL);
pluginTag->Mark(NS_PLUGIN_FLAG_NPAPI);
// no need to initialize, already done by CreatePlugin()
}
}
@ -6142,6 +6143,16 @@ NS_IMETHODIMP nsPluginHostImpl::Observe(nsISupports *aSubject,
UnloadUnusedLibraries();
sInst->Release();
}
if (!nsCRT::strcmp(NS_PRIVATE_BROWSING_SWITCH_TOPIC, aTopic)) {
// inform all active NPAPI plugins of changed private mode state
for (nsActivePlugin* ap = mActivePluginList.mFirst; ap; ap = ap->mNext) {
nsPluginTag* pt = ap->mPluginTag;
if (pt->HasFlag(NS_PLUGIN_FLAG_NPAPI)) {
nsNPAPIPluginInstance* pi = static_cast<nsNPAPIPluginInstance*>(ap->mInstance);
pi->PrivateModeStateChanged();
}
}
}
if (!nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
NS_ASSERTION(someData &&
nsDependentString(someData).EqualsLiteral("security.enable_java"),
@ -6161,7 +6172,7 @@ NS_IMETHODIMP nsPluginHostImpl::Observe(nsISupports *aSubject,
for (nsPluginTag* cur = mPlugins; cur; cur = cur->mNext) {
if (cur->mIsJavaPlugin)
cur->SetDisabled(!mJavaEnabled);
}
}
}
}
return NS_OK;
@ -6297,7 +6308,6 @@ nsPluginHostImpl::ParsePostBufferToFixHeaders(
const char *pEoh = 0; // pointer to end of headers in inPostData
const char *pEod = inPostData + inPostDataLen; // pointer to end of inPostData
if (*inPostData == LF) {
// from 4.x spec http://developer.netscape.com/docs/manuals/communicator/plugin/pgfn2.htm#1007754
// If no custom headers are required, simply add a blank
// line ('\n') to the beginning of the file or buffer.
// so *inPostData == '\n' is valid
@ -6500,8 +6510,6 @@ nsPluginHostImpl::CreateTmpFileToPost(const char *postDataURL, char **pTmpFileNa
if (NS_FAILED(rv) || (PRInt32)br <= 0)
break;
if (firstRead) {
// according to the 4.x spec
// http://developer.netscape.com/docs/manuals/communicator/plugin/pgfn2.htm#1007707
//"For protocols in which the headers must be distinguished from the body,
// such as HTTP, the buffer or file should contain the headers, followed by
// a blank line, then the body. If no custom headers are required, simply

Просмотреть файл

@ -79,7 +79,7 @@ class nsIRegistry;
class nsPluginHostImpl;
#define NS_PLUGIN_FLAG_ENABLED 0x0001 // is this plugin enabled?
#define NS_PLUGIN_FLAG_OLDSCHOOL 0x0002 // is this a pre-xpcom plugin?
#define NS_PLUGIN_FLAG_NPAPI 0x0002 // is this an NPAPI plugin?
#define NS_PLUGIN_FLAG_FROMCACHE 0x0004 // this plugintag info was loaded from cache
#define NS_PLUGIN_FLAG_UNWANTED 0x0008 // this is an unwanted plugin
#define NS_PLUGIN_FLAG_BLOCKLISTED 0x0010 // this is a blocklisted plugin

Просмотреть файл

@ -45,6 +45,10 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES = test_npruntime.xul
_TEST_FILES = \
test_npruntime.xul \
test_privatemode.xul \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)

Просмотреть файл

@ -0,0 +1,69 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window title="NPAPI Private Mode Tests"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>NPAPI Private Mode Tests</title>
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<body xmlns="http://www.w3.org/1999/xhtml" onload="runTests()">
<embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
<embed id="plugin2" type="application/x-test" width="200" height="200"></embed>
</body>
<script class="testbody" type="application/javascript">
<![CDATA[
SimpleTest.waitForExplicitFinish();
function runTests() {
var pluginElement1 = document.getElementById("plugin1");
var pluginElement2 = document.getElementById("plugin2");
var state1 = false;
var state2 = false;
var exceptionThrown = false;
try {
state1 = pluginElement1.queryPrivateModeState();
state2 = pluginElement2.queryPrivateModeState();
} catch (e) {
exceptionThrown = true;
}
is(exceptionThrown, false, "Exception thrown getting private mode state.");
is(state1, false, "Browser returned incorrect private mode state.");
is(state2, false, "Browser returned incorrect private mode state.");
// change private mode pref
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
var privateBrowsing = Components.classes["@mozilla.org/privatebrowsing;1"].getService(Components.interfaces.nsIPrivateBrowsingService);
var keepCurrentSession;
try {
keepCurrentSession = prefs.getBoolPref("browser.privatebrowsing.keep_current_session");
} catch (e) {
keepCurrentSession = false
}
prefs.setBoolPref("browser.privatebrowsing.keep_current_session", true);
privateBrowsing.privateBrowsingEnabled = true;
try {
state1 = pluginElement1.lastReportedPrivateModeState();
state2 = pluginElement2.lastReportedPrivateModeState();
} catch (e) {
exceptionThrown = true;
}
is(exceptionThrown, false, "Exception thrown getting private mode state.");
is(state1, true, "Private mode state reported incorrectly.");
is(state2, true, "Private mode state reported incorrectly.");
// reset preference states
privateBrowsing.privateBrowsingEnabled = false;
prefs.setBoolPref("browser.privatebrowsing.keep_current_session", keepCurrentSession);
SimpleTest.finish();
}
]]>
</script>
</window>

Просмотреть файл

@ -55,12 +55,16 @@ static NPClass sNPClass;
// identifiers
//
#define IDENTIFIER_TO_STRING_TEST_METHOD 0
#define NUM_METHOD_IDENTIFIERS 1
#define IDENTIFIER_TO_STRING_TEST_METHOD 0
#define QUERY_PRIVATE_MODE_STATE_METHOD 1
#define LAST_REPORTED_PRIVATE_MODE_STATE_METHOD 2
#define NUM_METHOD_IDENTIFIERS 3
static NPIdentifier sPluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
static const NPUTF8 *sPluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
"identifierToStringTest",
"queryPrivateModeState",
"lastReportedPrivateModeState",
};
static bool sIdentifiersInitialized = false;
@ -83,7 +87,9 @@ static void clearIdentifiers()
// function signatures
//
bool identifierToStringTest(const NPVariant* args, uint32_t argCount, NPVariant* result);
bool identifierToStringTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
bool queryPrivateModeState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
bool lastReportedPrivateModeState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
NPObject* scriptableAllocate(NPP npp, NPClass* aClass);
void scriptableDeallocate(NPObject* npobj);
@ -249,6 +255,8 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char*
}
}
instanceData->lastReportedPrivateModeState = false;
// do platform-specific initialization
NPError err = pluginInstanceInit(instanceData);
if (err != NPERR_NO_ERROR)
@ -337,6 +345,11 @@ NPP_GetValue(NPP instance, NPPVariable variable, void* value)
NPError
NPP_SetValue(NPP instance, NPNVariable variable, void* value)
{
if (variable == NPNVprivateModeBool) {
InstanceData* instanceData = (InstanceData*)(instance->pdata);
instanceData->lastReportedPrivateModeState = *static_cast<NPBool*>(value);
return NPERR_NO_ERROR;
}
return NPERR_GENERIC_ERROR;
}
@ -473,7 +486,11 @@ bool
scriptableInvoke(NPObject* npobj, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
if (name == sPluginMethodIdentifiers[IDENTIFIER_TO_STRING_TEST_METHOD])
return identifierToStringTest(args, argCount, result);
return identifierToStringTest(npobj, args, argCount, result);
else if (name == sPluginMethodIdentifiers[QUERY_PRIVATE_MODE_STATE_METHOD])
return queryPrivateModeState(npobj, args, argCount, result);
else if (name == sPluginMethodIdentifiers[LAST_REPORTED_PRIVATE_MODE_STATE_METHOD])
return lastReportedPrivateModeState(npobj, args, argCount, result);
return false;
}
@ -524,7 +541,7 @@ scriptableConstruct(NPObject* npobj, const NPVariant* args, uint32_t argCount, N
//
bool
identifierToStringTest(const NPVariant* args, uint32_t argCount, NPVariant* result)
identifierToStringTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
if (argCount != 1)
return false;
@ -537,3 +554,21 @@ identifierToStringTest(const NPVariant* args, uint32_t argCount, NPVariant* resu
STRINGZ_TO_NPVARIANT(utf8String, *result);
return true;
}
bool
queryPrivateModeState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
NPBool pms = false;
NPN_GetValue(static_cast<TestNPObject*>(npobj)->npp, NPNVprivateModeBool, &pms);
BOOLEAN_TO_NPVARIANT(pms, *result);
return true;
}
bool
lastReportedPrivateModeState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
InstanceData* id = static_cast<InstanceData*>(static_cast<TestNPObject*>(npobj)->npp->pdata);
NPBool pms = id->lastReportedPrivateModeState;
BOOLEAN_TO_NPVARIANT(pms, *result);
return true;
}

Просмотреть файл

@ -49,14 +49,14 @@ typedef enum {
typedef struct TestNPObject : NPObject {
NPP npp;
DrawMode drawMode;
// 0xAARRGGBB
PRUint32 drawColor;
PRUint32 drawColor; // 0xAARRGGBB
} TestNPObject;
typedef struct InstanceData {
NPP npp;
NPWindow window;
TestNPObject* scriptableObject;
NPBool lastReportedPrivateModeState;
} InstanceData;
#endif // nptest_h_