NS_IMETHODIMP nsFilePickerProxy::Init(mozIDOMWindowProxy* aParent, const nsAString& aTitle, int16_t aMode) { TabChild* tabChild = TabChild::GetFrom(aParent); if (!tabChild) { return NS_ERROR_FAILURE; } mParent = nsPIDOMWindowOuter::From(aParent); mMode = aMode; NS_ADDREF_THIS(); tabChild->SendPFilePickerConstructor(this, nsString(aTitle), aMode); return NS_OK; }
/* static */ nsresult nsContentPermissionUtils::AskPermission(nsIContentPermissionRequest* aRequest, nsPIDOMWindow* aWindow) { MOZ_ASSERT(!aWindow || aWindow->IsInnerWindow()); NS_ENSURE_STATE(aWindow && aWindow->IsCurrentInnerWindow()); // for content process if (XRE_GetProcessType() == GeckoProcessType_Content) { nsRefPtr<RemotePermissionRequest> req = new RemotePermissionRequest(aRequest, aWindow); MOZ_ASSERT(NS_IsMainThread()); // IPC can only be execute on main thread. TabChild* child = TabChild::GetFrom(aWindow->GetDocShell()); NS_ENSURE_TRUE(child, NS_ERROR_FAILURE); nsCOMPtr<nsIArray> typeArray; nsresult rv = aRequest->GetTypes(getter_AddRefs(typeArray)); NS_ENSURE_SUCCESS(rv, rv); nsTArray<PermissionRequest> permArray; ConvertArrayToPermissionRequest(typeArray, permArray); nsCOMPtr<nsIPrincipal> principal; rv = aRequest->GetPrincipal(getter_AddRefs(principal)); NS_ENSURE_SUCCESS(rv, rv); req->IPDLAddRef(); child->SendPContentPermissionRequestConstructor(req, permArray, IPC::Principal(principal)); req->Sendprompt(); return NS_OK; } // for chrome process nsCOMPtr<nsIContentPermissionPrompt> prompt = do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID); if (prompt) { prompt->Prompt(aRequest); } return NS_OK; }
NS_IMETHODIMP nsFilePickerProxy::Init(nsIDOMWindow* aParent, const nsAString& aTitle, int16_t aMode) { TabChild* tabChild = TabChild::GetFrom(aParent); if (!tabChild) { return NS_ERROR_FAILURE; } mParent = do_QueryInterface(aParent); if (!mParent->IsInnerWindow()) { mParent = mParent->GetCurrentInnerWindow(); } mMode = aMode; NS_ADDREF_THIS(); tabChild->SendPFilePickerConstructor(this, nsString(aTitle), aMode); return NS_OK; }
NS_IMETHODIMP nsScreenManagerProxy::ScreenForNativeWidget(void* aWidget, nsIScreen** outScreen) { // Because ScreenForNativeWidget can be called numerous times // indirectly from content via the DOM Screen API, we cache the // results for this tick of the event loop. TabChild* tabChild = static_cast<TabChild*>(aWidget); // Enumerate the cached screen array, looking for one that has // the TabChild that we're looking for... for (uint32_t i = 0; i < mScreenCache.Length(); ++i) { ScreenCacheEntry& curr = mScreenCache[i]; if (curr.mTabChild == aWidget) { NS_ADDREF(*outScreen = static_cast<nsIScreen*>(curr.mScreenProxy)); return NS_OK; } } // Never cached this screen, so we have to ask the parent process // for it. bool success = false; ScreenDetails details; Unused << SendScreenForBrowser(tabChild->GetTabId(), &details, &success); if (!success) { return NS_ERROR_FAILURE; } ScreenCacheEntry newEntry; RefPtr<ScreenProxy> screen = new ScreenProxy(this, details); newEntry.mScreenProxy = screen; newEntry.mTabChild = tabChild; mScreenCache.AppendElement(newEntry); NS_ADDREF(*outScreen = screen); InvalidateCacheOnNextTick(); return NS_OK; }
bool CompositorChild::RecvRemotePaintIsReady() { // Used on the content thread, this bounces the message to the // TabParent (via the TabChild) if the notification was previously requested. // XPCOM gives a soup of compiler errors when trying to do_QueryReference // so I'm using static_cast<> MOZ_LAYERS_LOG(("[RemoteGfx] CompositorChild received RemotePaintIsReady")); nsRefPtr<nsISupports> iTabChildBase(do_QueryReferent(mWeakTabChild)); if (!iTabChildBase) { MOZ_LAYERS_LOG(("[RemoteGfx] Note: TabChild was released before RemotePaintIsReady. " "MozAfterRemotePaint will not be sent to listener.")); return true; } TabChildBase* tabChildBase = static_cast<TabChildBase*>(iTabChildBase.get()); TabChild* tabChild = static_cast<TabChild*>(tabChildBase); MOZ_ASSERT(tabChild); unused << tabChild->SendRemotePaintIsReady(); mWeakTabChild = nullptr; return true; }
already_AddRefed<nsIEventTarget> CompositorManagerChild::GetSpecificMessageEventTarget(const Message& aMsg) { if (aMsg.type() == PCompositorBridge::Msg_DidComposite__ID) { LayersId layersId; PickleIterator iter(aMsg); if (!IPC::ReadParam(&aMsg, &iter, &layersId)) { return nullptr; } TabChild* tabChild = TabChild::GetFrom(layersId); if (!tabChild) { return nullptr; } return do_AddRef(tabChild->TabGroup()->EventTargetFor(TaskCategory::Other)); } if (aMsg.type() == PCompositorBridge::Msg_ParentAsyncMessages__ID) { return do_AddRef(SystemGroup::EventTargetFor(TaskCategory::Other)); } return nullptr; }
void ClientLayerManager::ForwardTransaction(bool aScheduleComposite) { TimeStamp start = TimeStamp::Now(); if (mForwarder->GetSyncObject()) { mForwarder->GetSyncObject()->FinalizeFrame(); } mPhase = PHASE_FORWARD; mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(); TimeStamp transactionStart; if (!mTransactionIdAllocator->GetTransactionStart().IsNull()) { transactionStart = mTransactionIdAllocator->GetTransactionStart(); } else { transactionStart = mTransactionStart; } // forward this transaction's changeset to our LayerManagerComposite bool sent; AutoInfallibleTArray<EditReply, 10> replies; if (mForwarder->EndTransaction(&replies, mRegionToClear, mLatestTransactionId, aScheduleComposite, mPaintSequenceNumber, mIsRepeatTransaction, transactionStart, &sent)) { for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) { const EditReply& reply = replies[i]; switch (reply.type()) { case EditReply::TOpContentBufferSwap: { MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap")); const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap(); CompositableClient* compositable = CompositableClient::FromIPDLActor(obs.compositableChild()); ContentClientRemote* contentClient = static_cast<ContentClientRemote*>(compositable); MOZ_ASSERT(contentClient); contentClient->SwapBuffers(obs.frontUpdatedRegion()); break; } default: NS_RUNTIMEABORT("not reached"); } } if (sent) { mNeedsComposite = false; } } else if (HasShadowManager()) { NS_WARNING("failed to forward Layers transaction"); } if (!sent) { // Clear the transaction id so that it doesn't get returned // unless we forwarded to somewhere that doesn't actually // have a compositor. mTransactionIdAllocator->RevokeTransactionId(mLatestTransactionId); } mForwarder->RemoveTexturesIfNecessary(); mForwarder->RemoveCompositablesIfNecessary(); mForwarder->SendPendingAsyncMessges(); mPhase = PHASE_NONE; // this may result in Layers being deleted, which results in // PLayer::Send__delete__() and DeallocShmem() mKeepAlive.Clear(); TabChild* window = mWidget->GetOwningTabChild(); if (window) { TimeStamp end = TimeStamp::Now(); window->DidRequestComposite(start, end); } }
bool IsImageExtractionAllowed(nsIDocument *aDocument, JSContext *aCx) { // Do the rest of the checks only if privacy.resistFingerprinting is on. if (!nsContentUtils::ShouldResistFingerprinting()) { return true; } // Don't proceed if we don't have a document or JavaScript context. if (!aDocument || !aCx) { return false; } // Documents with system principal can always extract canvas data. nsPIDOMWindowOuter *win = aDocument->GetWindow(); nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(win)); if (sop && nsContentUtils::IsSystemPrincipal(sop->GetPrincipal())) { return true; } // Always give permission to chrome scripts (e.g. Page Inspector). if (nsContentUtils::ThreadsafeIsCallerChrome()) { return true; } // Get the document URI and its spec. nsIURI *docURI = aDocument->GetDocumentURI(); nsCString docURISpec; docURI->GetSpec(docURISpec); // Allow local files to extract canvas data. bool isFileURL; (void) docURI->SchemeIs("file", &isFileURL); if (isFileURL) { return true; } // Get calling script file and line for logging. JS::AutoFilename scriptFile; unsigned scriptLine = 0; bool isScriptKnown = false; if (JS::DescribeScriptedCaller(aCx, &scriptFile, &scriptLine)) { isScriptKnown = true; // Don't show canvas prompt for PDF.js if (scriptFile.get() && strcmp(scriptFile.get(), "resource://pdf.js/build/pdf.js") == 0) { return true; } } nsIDocument* topLevelDocument = aDocument->GetTopLevelContentDocument(); nsIURI *topLevelDocURI = topLevelDocument ? topLevelDocument->GetDocumentURI() : nullptr; nsCString topLevelDocURISpec; if (topLevelDocURI) { topLevelDocURI->GetSpec(topLevelDocURISpec); } // Load Third Party Util service. nsresult rv; nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, false); // Block all third-party attempts to extract canvas. bool isThirdParty = true; rv = thirdPartyUtil->IsThirdPartyURI(topLevelDocURI, docURI, &isThirdParty); NS_ENSURE_SUCCESS(rv, false); if (isThirdParty) { nsAutoCString message; message.AppendPrintf("Blocked third party %s in page %s from extracting canvas data.", docURISpec.get(), topLevelDocURISpec.get()); if (isScriptKnown) { message.AppendPrintf(" %s:%u.", scriptFile.get(), scriptLine); } nsContentUtils::LogMessageToConsole(message.get()); return false; } // Load Permission Manager service. nsCOMPtr<nsIPermissionManager> permissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, false); // Check if the site has permission to extract canvas data. // Either permit or block extraction if a stored permission setting exists. uint32_t permission; rv = permissionManager->TestPermission(topLevelDocURI, PERMISSION_CANVAS_EXTRACT_DATA, &permission); NS_ENSURE_SUCCESS(rv, false); switch (permission) { case nsIPermissionManager::ALLOW_ACTION: return true; case nsIPermissionManager::DENY_ACTION: return false; default: break; } // At this point, permission is unknown (nsIPermissionManager::UNKNOWN_ACTION). nsAutoCString message; message.AppendPrintf("Blocked %s in page %s from extracting canvas data.", docURISpec.get(), topLevelDocURISpec.get()); if (isScriptKnown) { message.AppendPrintf(" %s:%u.", scriptFile.get(), scriptLine); } nsContentUtils::LogMessageToConsole(message.get()); // Prompt the user (asynchronous). if (XRE_IsContentProcess()) { TabChild* tabChild = TabChild::GetFrom(win); if (tabChild) { tabChild->SendShowCanvasPermissionPrompt(topLevelDocURISpec); } } else { nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); if (obs) { obs->NotifyObservers(win, TOPIC_CANVAS_PERMISSIONS_PROMPT, NS_ConvertUTF8toUTF16(topLevelDocURISpec).get()); } } // We don't extract the image for now -- user may override at prompt. return false; }
void ClientLayerManager::ForwardTransaction(bool aScheduleComposite) { AutoProfilerTracing tracing("Paint", "ForwardTransaction"); TimeStamp start = TimeStamp::Now(); // Skip the synchronization for buffer since we also skip the painting during // device-reset status. if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) { if (mForwarder->GetSyncObject() && mForwarder->GetSyncObject()->IsSyncObjectValid()) { mForwarder->GetSyncObject()->Synchronize(); } } mPhase = PHASE_FORWARD; mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(!mIsRepeatTransaction); TimeStamp transactionStart; if (!mTransactionIdAllocator->GetTransactionStart().IsNull()) { transactionStart = mTransactionIdAllocator->GetTransactionStart(); } else { transactionStart = mTransactionStart; } if (gfxPrefs::AlwaysPaint() && XRE_IsContentProcess()) { mForwarder->SendPaintTime(mLatestTransactionId, mLastPaintTime); } // forward this transaction's changeset to our LayerManagerComposite bool sent = false; bool ok = mForwarder->EndTransaction( mRegionToClear, mLatestTransactionId, aScheduleComposite, mPaintSequenceNumber, mIsRepeatTransaction, transactionStart, &sent); if (ok) { if (sent) { mNeedsComposite = false; } } else if (HasShadowManager()) { NS_WARNING("failed to forward Layers transaction"); } if (!sent) { // Clear the transaction id so that it doesn't get returned // unless we forwarded to somewhere that doesn't actually // have a compositor. mTransactionIdAllocator->RevokeTransactionId(mLatestTransactionId); } mPhase = PHASE_NONE; // this may result in Layers being deleted, which results in // PLayer::Send__delete__() and DeallocShmem() mKeepAlive.Clear(); TabChild* window = mWidget ? mWidget->GetOwningTabChild() : nullptr; if (window) { TimeStamp end = TimeStamp::Now(); window->DidRequestComposite(start, end); } }
NS_IMETHODIMP OfflineCacheUpdateChild::Schedule() { LOG(("OfflineCacheUpdateChild::Schedule [%p]", this)); NS_ASSERTION(mWindow, "Window must be provided to the offline cache update child"); nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(mWindow); mWindow = nullptr; nsIDocShell *docshell = piWindow->GetDocShell(); nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(docshell); if (!item) { NS_WARNING("doc shell tree item is null"); return NS_ERROR_FAILURE; } nsCOMPtr<nsIDocShellTreeOwner> owner; item->GetTreeOwner(getter_AddRefs(owner)); nsCOMPtr<nsITabChild> tabchild = do_GetInterface(owner); // because owner implements nsITabChild, we can assume that it is // the one and only TabChild. TabChild* child = tabchild ? static_cast<TabChild*>(tabchild.get()) : nullptr; if (MissingRequiredTabChild(child, "offlinecacheupdate")) { return NS_ERROR_FAILURE; } URIParams manifestURI, documentURI; SerializeURI(mManifestURI, manifestURI); SerializeURI(mDocumentURI, documentURI); nsresult rv = NS_OK; PrincipalInfo loadingPrincipalInfo; rv = PrincipalToPrincipalInfo(mLoadingPrincipal, &loadingPrincipalInfo); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService(); if (observerService) { LOG(("Calling offline-cache-update-added")); observerService->NotifyObservers(static_cast<nsIOfflineCacheUpdate*>(this), "offline-cache-update-added", nullptr); LOG(("Done offline-cache-update-added")); } // mDocument is non-null if both: // 1. this update was initiated by a document that referred a manifest // 2. the document has not already been loaded from the application cache // This tells the update to cache this document even in case the manifest // has not been changed since the last fetch. // See also nsOfflineCacheUpdate::ScheduleImplicit. bool stickDocument = mDocument != nullptr; // Need to addref ourself here, because the IPC stack doesn't hold // a reference to us. Will be released in RecvFinish() that identifies // the work has been done. ContentChild::GetSingleton()->SendPOfflineCacheUpdateConstructor( this, manifestURI, documentURI, loadingPrincipalInfo, stickDocument, child->GetTabId()); // ContentChild::DeallocPOfflineCacheUpdate will release this. NS_ADDREF_THIS(); return NS_OK; }
// static nsresult IDBFactory::Create(nsPIDOMWindow* aWindow, const nsACString& aASCIIOrigin, ContentParent* aContentParent, IDBFactory** aFactory) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(aASCIIOrigin.IsEmpty() || nsContentUtils::IsCallerChrome(), "Non-chrome may not supply their own origin!"); NS_ENSURE_TRUE(aWindow, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); if (aWindow->IsOuterWindow()) { aWindow = aWindow->GetCurrentInnerWindow(); NS_ENSURE_TRUE(aWindow, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); } // Make sure that the manager is up before we do anything here since lots of // decisions depend on which process we're running in. indexedDB::IndexedDatabaseManager* mgr = indexedDB::IndexedDatabaseManager::GetOrCreate(); NS_ENSURE_TRUE(mgr, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); nsresult rv; nsCString origin(aASCIIOrigin); if (origin.IsEmpty()) { rv = QuotaManager::GetASCIIOriginFromWindow(aWindow, origin); if (NS_FAILED(rv)) { // Not allowed. *aFactory = nullptr; return NS_OK; } } nsRefPtr<IDBFactory> factory = new IDBFactory(); factory->mASCIIOrigin = origin; factory->mWindow = aWindow; factory->mContentParent = aContentParent; if (!IndexedDatabaseManager::IsMainProcess()) { TabChild* tabChild = GetTabChildFrom(aWindow); NS_ENSURE_TRUE(tabChild, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); IndexedDBChild* actor = new IndexedDBChild(origin); bool allowed; tabChild->SendPIndexedDBConstructor(actor, origin, &allowed); if (!allowed) { actor->Send__delete__(actor); *aFactory = nullptr; return NS_OK; } actor->SetFactory(factory); } factory.forget(aFactory); return NS_OK; }
nsDOMDesktopNotification::nsDOMDesktopNotification(const nsAString & title, const nsAString & description, const nsAString & iconURL, nsPIDOMWindow *aWindow, nsIScriptContext* aScriptContext, nsIURI* uri) : mTitle(title) , mDescription(description) #ifdef ANDROID , mIconURL((PRUnichar*)L"drawable://desktop_notification") #else , mIconURL(iconURL) #endif , mURI(uri) , mAllow(PR_FALSE) , mShowHasBeenCalled(PR_FALSE) { mOwner = aWindow; mScriptContext = aScriptContext; if (nsContentUtils::GetBoolPref("notification.disabled", PR_FALSE)) return; // If we are in testing mode (running mochitests, for example) // and we are suppose to allow requests, then just post an allow event. if (nsContentUtils::GetBoolPref("notification.prompt.testing", PR_FALSE) && nsContentUtils::GetBoolPref("notification.prompt.testing.allow", PR_TRUE)) { mAllow = PR_TRUE; return; } nsRefPtr<nsDesktopNotificationRequest> request = new nsDesktopNotificationRequest(this); // if we are in the content process, then remote it to the parent. if (XRE_GetProcessType() == GeckoProcessType_Content) { // if for some reason mOwner is null, just silently // bail. The user will not see a notification, and that // is fine. if (!mOwner) return; // because owner implements nsITabChild, we can assume that it is // the one and only TabChild for this docshell. TabChild* child = GetTabChildFrom(mOwner->GetDocShell()); // Retain a reference so the object isn't deleted without IPDL's knowledge. // Corresponding release occurs in DeallocPContentPermissionRequest. request->AddRef(); nsCString type = NS_LITERAL_CSTRING("desktop-notification"); child->SendPContentPermissionRequestConstructor(request, type, IPC::URI(mURI)); request->Sendprompt(); return; } // otherwise, dispatch it NS_DispatchToMainThread(request); }