tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

BackgroundVideoDecodingPermissionObserver.cpp (5211B)


      1 /* vim:set ts=2 sw=2 sts=2 et cindent: */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "BackgroundVideoDecodingPermissionObserver.h"
      7 
      8 #include "MediaDecoder.h"
      9 #include "mozilla/AsyncEventDispatcher.h"
     10 #include "mozilla/Services.h"
     11 #include "mozilla/StaticPrefs_media.h"
     12 #include "mozilla/dom/BrowsingContext.h"
     13 #include "mozilla/dom/Document.h"
     14 #include "nsContentUtils.h"
     15 #include "nsIObserverService.h"
     16 
     17 namespace mozilla {
     18 
     19 BackgroundVideoDecodingPermissionObserver::
     20    BackgroundVideoDecodingPermissionObserver(MediaDecoder* aDecoder)
     21    : mDecoder(aDecoder), mIsRegisteredForEvent(false) {
     22  MOZ_ASSERT(mDecoder);
     23 }
     24 
     25 NS_IMETHODIMP
     26 BackgroundVideoDecodingPermissionObserver::Observe(nsISupports* aSubject,
     27                                                   const char* aTopic,
     28                                                   const char16_t* aData) {
     29  if (!StaticPrefs::media_resume_background_video_on_tabhover()) {
     30    return NS_OK;
     31  }
     32 
     33  if (!IsValidEventSender(aSubject)) {
     34    return NS_OK;
     35  }
     36 
     37  if (strcmp(aTopic, "unselected-tab-hover") == 0) {
     38    bool allowed = !NS_strcmp(aData, u"true");
     39    mDecoder->SetIsBackgroundVideoDecodingAllowed(allowed);
     40  }
     41  return NS_OK;
     42 }
     43 
     44 void BackgroundVideoDecodingPermissionObserver::RegisterEvent() {
     45  MOZ_ASSERT(!mIsRegisteredForEvent);
     46  nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
     47  if (observerService) {
     48    observerService->AddObserver(this, "unselected-tab-hover", false);
     49    mIsRegisteredForEvent = true;
     50    if (nsContentUtils::IsInStableOrMetaStableState()) {
     51      // Events shall not be fired synchronously to prevent anything visible
     52      // from the scripts while we are in stable state.
     53      if (nsCOMPtr<dom::Document> doc = GetOwnerDoc()) {
     54        doc->Dispatch(NewRunnableMethod(
     55            "BackgroundVideoDecodingPermissionObserver::EnableEvent", this,
     56            &BackgroundVideoDecodingPermissionObserver::EnableEvent));
     57      }
     58    } else {
     59      EnableEvent();
     60    }
     61  }
     62 }
     63 
     64 void BackgroundVideoDecodingPermissionObserver::UnregisterEvent() {
     65  MOZ_ASSERT(mIsRegisteredForEvent);
     66  nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
     67  if (observerService) {
     68    observerService->RemoveObserver(this, "unselected-tab-hover");
     69    mIsRegisteredForEvent = false;
     70    mDecoder->SetIsBackgroundVideoDecodingAllowed(false);
     71    if (nsContentUtils::IsInStableOrMetaStableState()) {
     72      // Events shall not be fired synchronously to prevent anything visible
     73      // from the scripts while we are in stable state.
     74      if (nsCOMPtr<dom::Document> doc = GetOwnerDoc()) {
     75        doc->Dispatch(NewRunnableMethod(
     76            "BackgroundVideoDecodingPermissionObserver::DisableEvent", this,
     77            &BackgroundVideoDecodingPermissionObserver::DisableEvent));
     78      }
     79    } else {
     80      DisableEvent();
     81    }
     82  }
     83 }
     84 
     85 BackgroundVideoDecodingPermissionObserver::
     86    ~BackgroundVideoDecodingPermissionObserver() {
     87  MOZ_ASSERT(!mIsRegisteredForEvent);
     88 }
     89 
     90 void BackgroundVideoDecodingPermissionObserver::EnableEvent() const {
     91  // If we can't get document or outer window, then you can't reach the chrome
     92  // <browser> either, so we don't need want to dispatch the event.
     93  dom::Document* doc = GetOwnerDoc();
     94  if (!doc || !doc->GetWindow()) {
     95    return;
     96  }
     97 
     98  RefPtr<AsyncEventDispatcher> asyncDispatcher =
     99      new AsyncEventDispatcher(doc, u"UnselectedTabHover:Enable"_ns,
    100                               CanBubble::eYes, ChromeOnlyDispatch::eYes);
    101  asyncDispatcher->PostDOMEvent();
    102 }
    103 
    104 void BackgroundVideoDecodingPermissionObserver::DisableEvent() const {
    105  // If we can't get document or outer window, then you can't reach the chrome
    106  // <browser> either, so we don't need want to dispatch the event.
    107  dom::Document* doc = GetOwnerDoc();
    108  if (!doc || !doc->GetWindow()) {
    109    return;
    110  }
    111 
    112  RefPtr<AsyncEventDispatcher> asyncDispatcher =
    113      new AsyncEventDispatcher(doc, u"UnselectedTabHover:Disable"_ns,
    114                               CanBubble::eYes, ChromeOnlyDispatch::eYes);
    115  asyncDispatcher->PostDOMEvent();
    116 }
    117 
    118 dom::BrowsingContext* BackgroundVideoDecodingPermissionObserver::GetOwnerBC()
    119    const {
    120  dom::Document* doc = GetOwnerDoc();
    121  return doc ? doc->GetBrowsingContext() : nullptr;
    122 }
    123 
    124 dom::Document* BackgroundVideoDecodingPermissionObserver::GetOwnerDoc() const {
    125  if (!mDecoder->GetOwner()) {
    126    return nullptr;
    127  }
    128 
    129  return mDecoder->GetOwner()->GetDocument();
    130 }
    131 
    132 bool BackgroundVideoDecodingPermissionObserver::IsValidEventSender(
    133    nsISupports* aSubject) const {
    134  nsCOMPtr<nsPIDOMWindowInner> senderInner(do_QueryInterface(aSubject));
    135  if (!senderInner) {
    136    return false;
    137  }
    138 
    139  RefPtr<dom::BrowsingContext> senderBC = senderInner->GetBrowsingContext();
    140  if (!senderBC) {
    141    return false;
    142  }
    143  // Valid sender should be in the same browsing context tree as where owner is.
    144  return GetOwnerBC() ? GetOwnerBC()->Top() == senderBC->Top() : false;
    145 }
    146 
    147 NS_IMPL_ISUPPORTS(BackgroundVideoDecodingPermissionObserver, nsIObserver)
    148 
    149 }  // namespace mozilla