diff --git a/modules/plugin/base/public/npapi.h b/modules/plugin/base/public/npapi.h index 80b1f24da4e..394bd40b9f7 100644 --- a/modules/plugin/base/public/npapi.h +++ b/modules/plugin/base/public/npapi.h @@ -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 */ diff --git a/modules/plugin/base/public/npfunctions.h b/modules/plugin/base/public/npfunctions.h index f3b5fdd3d5b..c6caaf0b509 100644 --- a/modules/plugin/base/public/npfunctions.h +++ b/modules/plugin/base/public/npfunctions.h @@ -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); diff --git a/modules/plugin/base/src/nsNPAPIPlugin.cpp b/modules/plugin/base/src/nsNPAPIPlugin.cpp index 5b15f8d9cf0..c313ccac87b 100644 --- a/modules/plugin/base/src/nsNPAPIPlugin.cpp +++ b/modules/plugin/base/src/nsNPAPIPlugin.cpp @@ -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 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) { diff --git a/modules/plugin/base/src/nsNPAPIPluginInstance.cpp b/modules/plugin/base/src/nsNPAPIPluginInstance.cpp index ab20a9ddbf6..b2fe9e75d6c 100644 --- a/modules/plugin/base/src/nsNPAPIPluginInstance.cpp +++ b/modules/plugin/base/src/nsNPAPIPluginInstance.cpp @@ -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 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; +} diff --git a/modules/plugin/base/src/nsNPAPIPluginInstance.h b/modules/plugin/base/src/nsNPAPIPluginInstance.h index 950006c93c3..45f7325dda0 100644 --- a/modules/plugin/base/src/nsNPAPIPluginInstance.h +++ b/modules/plugin/base/src/nsNPAPIPluginInstance.h @@ -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 GetDOMWindow(); + nsresult PrivateModeStateChanged(); protected: nsresult InitializePlugin(nsIPluginInstancePeer* peer); diff --git a/modules/plugin/base/src/nsPluginHostImpl.cpp b/modules/plugin/base/src/nsPluginHostImpl.cpp index 8857b626fc3..df675cfe61d 100644 --- a/modules/plugin/base/src/nsPluginHostImpl.cpp +++ b/modules/plugin/base/src/nsPluginHostImpl.cpp @@ -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 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(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 diff --git a/modules/plugin/base/src/nsPluginHostImpl.h b/modules/plugin/base/src/nsPluginHostImpl.h index e7686b34030..82ca9001f72 100644 --- a/modules/plugin/base/src/nsPluginHostImpl.h +++ b/modules/plugin/base/src/nsPluginHostImpl.h @@ -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 diff --git a/modules/plugin/test/mochitest/Makefile.in b/modules/plugin/test/mochitest/Makefile.in index 72ec45cc89f..b768e92144d 100644 --- a/modules/plugin/test/mochitest/Makefile.in +++ b/modules/plugin/test/mochitest/Makefile.in @@ -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) diff --git a/modules/plugin/test/mochitest/test_privatemode.xul b/modules/plugin/test/mochitest/test_privatemode.xul new file mode 100644 index 00000000000..31b6893f111 --- /dev/null +++ b/modules/plugin/test/mochitest/test_privatemode.xul @@ -0,0 +1,69 @@ + + + + + NPAPI Private Mode Tests + + + diff --git a/modules/plugin/test/testplugin/nptest.cpp b/modules/plugin/test/testplugin/nptest.cpp index 0cc914a4ab8..8a88298e794 100644 --- a/modules/plugin/test/testplugin/nptest.cpp +++ b/modules/plugin/test/testplugin/nptest.cpp @@ -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(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(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(static_cast(npobj)->npp->pdata); + NPBool pms = id->lastReportedPrivateModeState; + BOOLEAN_TO_NPVARIANT(pms, *result); + return true; +} diff --git a/modules/plugin/test/testplugin/nptest.h b/modules/plugin/test/testplugin/nptest.h index ced3a1267d4..32d075ceee9 100644 --- a/modules/plugin/test/testplugin/nptest.h +++ b/modules/plugin/test/testplugin/nptest.h @@ -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_