tor-browser

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

Notification.h (6818B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_notification_h__
      8 #define mozilla_dom_notification_h__
      9 
     10 #include "mozilla/DOMEventTargetHelper.h"
     11 #include "mozilla/dom/DOMTypes.h"
     12 #include "mozilla/dom/NotificationBinding.h"
     13 #include "mozilla/dom/notification/NotificationChild.h"
     14 #include "nsCycleCollectionParticipant.h"
     15 #include "nsISupports.h"
     16 #include "nsString.h"
     17 
     18 class nsIPrincipal;
     19 class nsIVariant;
     20 
     21 namespace mozilla::dom {
     22 
     23 class NotificationRef;
     24 class WorkerNotificationObserver;
     25 class Promise;
     26 class StrongWorkerRef;
     27 
     28 namespace notification {
     29 enum class PermissionCheckPurpose : uint8_t;
     30 }
     31 
     32 /*
     33 * A Notification gets a corresponding IPC actor after successful construction.
     34 * The notification object and the actor do not own each other and their
     35 * lifetimes are controlled semi-independently.
     36 *
     37 * The Notification object can be cycle collected when either:
     38 * - no one is listening for the events, or
     39 * - the backend notification is closed.
     40 *
     41 * The actor goes away when either:
     42 * - the backend notification is closed, or
     43 * - the tab is closed or bfcached.
     44 *
     45 * (It cannot just go away on cycle collection because nsIAlertsService wants to
     46 * know whether the triggered page is still open to decide whether to open a new
     47 * tab or focus on the existing tab.)
     48 */
     49 class Notification : public DOMEventTargetHelper, public SupportsWeakPtr {
     50  friend class CloseNotificationRunnable;
     51  friend class NotificationTask;
     52  friend class NotificationPermissionRequest;
     53  friend class MainThreadNotificationObserver;
     54  friend class NotificationStorageCallback;
     55  friend class ServiceWorkerNotificationObserver;
     56  friend class WorkerGetRunnable;
     57  friend class WorkerNotificationObserver;
     58 
     59 public:
     60  IMPL_EVENT_HANDLER(click)
     61  IMPL_EVENT_HANDLER(show)
     62  IMPL_EVENT_HANDLER(error)
     63  IMPL_EVENT_HANDLER(close)
     64 
     65  NS_DECL_ISUPPORTS_INHERITED
     66  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(Notification,
     67                                                         DOMEventTargetHelper)
     68 
     69  static bool PrefEnabled(JSContext* aCx, JSObject* aObj);
     70 
     71  static already_AddRefed<Notification> Constructor(
     72      const GlobalObject& aGlobal, const nsAString& aTitle,
     73      const NotificationOptions& aOption, ErrorResult& aRv);
     74 
     75  /**
     76   * Used when retrieving notification objects from the parent process.
     77   */
     78  static Result<already_AddRefed<Notification>, nsresult> ConstructFromIPC(
     79      nsIGlobalObject* aGlobal, const IPCNotification& aIPCNotification,
     80      const nsAString& aServiceWorkerRegistrationScope);
     81 
     82  void GetID(nsAString& aRetval) { aRetval = mIPCNotification.id(); }
     83 
     84  void GetTitle(nsAString& aRetval) {
     85    aRetval = mIPCNotification.options().title();
     86  }
     87 
     88  NotificationDirection Dir() { return mIPCNotification.options().dir(); }
     89 
     90  void GetLang(nsAString& aRetval) {
     91    aRetval = mIPCNotification.options().lang();
     92  }
     93 
     94  void GetBody(nsAString& aRetval) {
     95    aRetval = mIPCNotification.options().body();
     96  }
     97 
     98  void GetTag(nsAString& aRetval) {
     99    aRetval = mIPCNotification.options().tag();
    100  }
    101 
    102  void GetIcon(nsACString& aRetval) {
    103    nsIURI* iconUri = mIPCNotification.options().icon();
    104    if (!iconUri) {
    105      aRetval.Truncate();
    106      return;
    107    }
    108    iconUri->GetSpec(aRetval);
    109  }
    110 
    111  void MaybeNotifyClose();
    112 
    113  static bool RequestPermissionEnabledForScope(JSContext* aCx,
    114                                               JSObject* /* unused */);
    115 
    116  static already_AddRefed<Promise> RequestPermission(
    117      const GlobalObject& aGlobal,
    118      const Optional<OwningNonNull<NotificationPermissionCallback>>& aCallback,
    119      ErrorResult& aRv);
    120 
    121  static NotificationPermission GetPermission(const GlobalObject& aGlobal,
    122                                              ErrorResult& aRv);
    123 
    124  static uint32_t MaxActions(const GlobalObject& aGlobal);
    125 
    126  // Notification implementation of
    127  // ServiceWorkerRegistration.showNotification.
    128  //
    129  //
    130  // Note that aCx may not be in the compartment of aGlobal, but aOptions will
    131  // have its JS things in the compartment of aCx.
    132  static already_AddRefed<Promise> ShowPersistentNotification(
    133      JSContext* aCx, nsIGlobalObject* aGlobal, const nsAString& aScope,
    134      const nsAString& aTitle, const NotificationOptions& aOptions,
    135      const ServiceWorkerRegistrationDescriptor& aDescriptor, ErrorResult& aRv);
    136 
    137  void Close();
    138 
    139  nsIGlobalObject* GetParentObject() const { return GetOwnerGlobal(); }
    140 
    141  JSObject* WrapObject(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
    142 
    143  bool RequireInteraction() const;
    144 
    145  bool Silent() const;
    146 
    147  void GetVibrate(nsTArray<uint32_t>& aRetval) const;
    148 
    149  void GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval);
    150 
    151  void GetActions(nsTArray<NotificationAction>& aRetVal);
    152 
    153  static NotificationPermission GetPermission(
    154      nsIGlobalObject* aGlobal, notification::PermissionCheckPurpose aPurpose,
    155      ErrorResult& aRv);
    156 
    157  bool DispatchClickEvent();
    158 
    159  nsresult DispatchToMainThread(already_AddRefed<nsIRunnable>&& aRunnable);
    160 
    161 protected:
    162  Notification(nsIGlobalObject* aGlobal,
    163               const IPCNotification& aIPCNotification,
    164               const nsAString& aScope);
    165 
    166  void Deactivate();
    167 
    168  static NotificationPermission GetPermissionInternal(
    169      nsPIDOMWindowInner* aWindow,
    170      notification::PermissionCheckPurpose aPurpose, ErrorResult& rv);
    171 
    172  WeakPtr<notification::NotificationChild> mActor;
    173 
    174  const IPCNotification mIPCNotification;
    175 
    176  // It's null until GetData is first called
    177  JS::Heap<JS::Value> mData;
    178 
    179  nsString mScope;
    180 
    181  bool mIsClosed = false;
    182 
    183 private:
    184  virtual ~Notification();
    185 
    186  // Creates a Notification and shows it. Returns a reference to the
    187  // Notification if result is NS_OK. The lifetime of this Notification is tied
    188  // to an underlying NotificationRef. Do not hold a non-stack raw pointer to
    189  // it. Be careful about thread safety if acquiring a strong reference.
    190  //
    191  // Note that aCx may not be in the compartment of aGlobal, but aOptions will
    192  // have its JS things in the compartment of aCx.
    193  static already_AddRefed<Notification> ValidateAndCreate(
    194      JSContext* aCx, nsIGlobalObject* aGlobal, const nsAString& aTitle,
    195      const NotificationOptions& aOptions, const nsAString& aScope,
    196      ErrorResult& aRv);
    197 
    198  bool CreateActor();
    199  bool SendShow(Promise* aPromise);
    200 
    201  static already_AddRefed<nsIURI> ResolveIconURL(nsIGlobalObject* aGlobal,
    202                                                 const nsACString& aIconUrl);
    203 };
    204 
    205 }  // namespace mozilla::dom
    206 
    207 #endif  // mozilla_dom_notification_h__