GVAutoplayPermissionRequest.h (3929B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef DOM_MEDIA_GVAUTOPLAYPERMISSIONREQUEST_H_ 6 #define DOM_MEDIA_GVAUTOPLAYPERMISSIONREQUEST_H_ 7 8 #include "GVAutoplayRequestUtils.h" 9 #include "nsContentPermissionHelper.h" 10 11 class nsGlobalWindowInner; 12 13 namespace mozilla::dom { 14 inline constexpr const char kGVAutoplayAllowedTopic[] = 15 "geckoview-autoplay-allowed"; 16 17 /** 18 * This class is used to provide an ability for GeckoView (GV) to allow its 19 * embedder (application) to decide whether the autoplay media should be allowed 20 * or denied on the page. We have two types of request, one for audible media, 21 * another one for inaudible media. Each page would at most have one request per 22 * type at a time, and the result of request would be effective on that page 23 * until the page gets reloaded or closed. 24 */ 25 class GVAutoplayPermissionRequest : public ContentPermissionRequestBase { 26 public: 27 NS_DECL_ISUPPORTS_INHERITED 28 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(GVAutoplayPermissionRequest, 29 ContentPermissionRequestBase) 30 31 // nsIContentPermissionRequest methods 32 NS_IMETHOD Cancel(void) override; 33 NS_IMETHOD Allow(JS::Handle<JS::Value> choices) override; 34 35 private: 36 // Only allow to create this request from the requestor. 37 friend class GVAutoplayPermissionRequestor; 38 static void CreateRequest(nsGlobalWindowInner* aWindow, 39 BrowsingContext* aContext, 40 GVAutoplayRequestType aType); 41 42 GVAutoplayPermissionRequest(nsGlobalWindowInner* aWindow, 43 BrowsingContext* aContext, 44 GVAutoplayRequestType aType); 45 ~GVAutoplayPermissionRequest(); 46 47 void SetRequestStatus(GVAutoplayRequestStatus aStatus); 48 49 GVAutoplayRequestType mType; 50 RefPtr<BrowsingContext> mContext; 51 }; 52 53 /** 54 * This class provides a method to request autoplay permission for a page, which 55 * would be used to be a factor to determine if media is allowed to autoplay or 56 * not on GeckoView. 57 * 58 * A page could only have at most one audible request and one inaudible request, 59 * and once a page has been closed or reloaded, those requests would be dropped. 60 * In order to achieve that all media existing in the same page can share the 61 * result of those requests, the request status would only be stored in the 62 * top-level browsing context, which allows them to be synchronized among 63 * different processes when Fission is enabled. 64 * 65 * The current way we choose is to request for a permission when creating media 66 * element, in order to get the response from the embedding app before media 67 * starts playing if the app can response the request quickly enough. However, 68 * the request might be pending if the app doesn't response to it, we might 69 * never get the response. As that is just one factor of determining the 70 * autoplay result, even if we don't get the response for the request, we still 71 * have a chance to play media. Check AutoplayPolicy to see more details about 72 * how we decide the final autoplay decision. 73 */ 74 class GVAutoplayPermissionRequestor final { 75 public: 76 // Creates async autoplay requests (eAUDIBLE and/or eINAUDIBLE) if needed. 77 static void AskForPermissionIfNeeded(nsPIDOMWindowInner* aWindow); 78 79 // Returns true if an audible and/or inaudible request is unknown or pending. 80 static bool HasUnresolvedRequest(nsPIDOMWindowInner* aWindow); 81 82 private: 83 static bool HasEverAskForRequest(BrowsingContext* aContext, 84 GVAutoplayRequestType aType); 85 static void CreateAsyncRequest(nsPIDOMWindowInner* aWindow, 86 BrowsingContext* aContext, 87 GVAutoplayRequestType aType); 88 }; 89 90 } // namespace mozilla::dom 91 92 #endif