Esempio n. 1
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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);
  }
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
Esempio n. 11
0
// 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);

}