1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
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/. */
7 #include "StorageAccessPermissionRequest.h"
8 #include "nsGlobalWindowInner.h"
9 #include "mozilla/StaticPrefs_dom.h"
12 namespace mozilla::dom
{
14 NS_IMPL_CYCLE_COLLECTION_INHERITED(StorageAccessPermissionRequest
,
15 ContentPermissionRequestBase
)
17 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(StorageAccessPermissionRequest
,
18 ContentPermissionRequestBase
)
20 StorageAccessPermissionRequest::StorageAccessPermissionRequest(
21 nsPIDOMWindowInner
* aWindow
, nsIPrincipal
* aNodePrincipal
,
22 AllowCallback
&& aAllowCallback
, CancelCallback
&& aCancelCallback
)
23 : ContentPermissionRequestBase(aNodePrincipal
, aWindow
,
24 "dom.storage_access"_ns
,
26 mAllowCallback(std::move(aAllowCallback
)),
27 mCancelCallback(std::move(aCancelCallback
)),
28 mCallbackCalled(false) {
29 mPermissionRequests
.AppendElement(
30 PermissionRequest(mType
, nsTArray
<nsString
>()));
34 StorageAccessPermissionRequest::Cancel() {
35 if (!mCallbackCalled
) {
36 mCallbackCalled
= true;
43 StorageAccessPermissionRequest::Allow(JS::HandleValue aChoices
) {
44 nsTArray
<PermissionChoice
> choices
;
45 nsresult rv
= TranslateChoices(aChoices
, mPermissionRequests
, choices
);
50 // There is no support to allow grants automatically from the prompting code
53 if (!mCallbackCalled
) {
54 mCallbackCalled
= true;
55 if (choices
.Length() == 1 && choices
[0].choice().EqualsLiteral("allow")) {
62 RefPtr
<StorageAccessPermissionRequest::AutoGrantDelayPromise
>
63 StorageAccessPermissionRequest::MaybeDelayAutomaticGrants() {
64 RefPtr
<AutoGrantDelayPromise::Private
> p
=
65 new AutoGrantDelayPromise::Private(__func__
);
67 unsigned simulatedDelay
= CalculateSimulatedDelay();
69 nsCOMPtr
<nsITimer
> timer
;
70 RefPtr
<AutoGrantDelayPromise::Private
> promise
= p
;
71 nsresult rv
= NS_NewTimerWithFuncCallback(
72 getter_AddRefs(timer
),
73 [](nsITimer
* aTimer
, void* aClosure
) -> void {
75 static_cast<AutoGrantDelayPromise::Private
*>(aClosure
);
76 promise
->Resolve(true, __func__
);
80 promise
, simulatedDelay
, nsITimer::TYPE_ONE_SHOT
,
81 "DelayedAllowAutoGrantCallback");
82 if (NS_WARN_IF(NS_FAILED(rv
))) {
83 p
->Reject(false, __func__
);
85 // Leak the references here! We'll release them inside the callback.
86 Unused
<< timer
.forget();
87 Unused
<< promise
.forget();
90 p
->Resolve(false, __func__
);
95 already_AddRefed
<StorageAccessPermissionRequest
>
96 StorageAccessPermissionRequest::Create(nsPIDOMWindowInner
* aWindow
,
97 AllowCallback
&& aAllowCallback
,
98 CancelCallback
&& aCancelCallback
) {
102 nsGlobalWindowInner
* win
= nsGlobalWindowInner::Cast(aWindow
);
104 return Create(aWindow
, win
->GetPrincipal(), std::move(aAllowCallback
),
105 std::move(aCancelCallback
));
108 already_AddRefed
<StorageAccessPermissionRequest
>
109 StorageAccessPermissionRequest::Create(nsPIDOMWindowInner
* aWindow
,
110 nsIPrincipal
* aPrincipal
,
111 AllowCallback
&& aAllowCallback
,
112 CancelCallback
&& aCancelCallback
) {
121 RefPtr
<StorageAccessPermissionRequest
> request
=
122 new StorageAccessPermissionRequest(aWindow
, aPrincipal
,
123 std::move(aAllowCallback
),
124 std::move(aCancelCallback
));
125 return request
.forget();
128 unsigned StorageAccessPermissionRequest::CalculateSimulatedDelay() {
129 if (!StaticPrefs::dom_storage_access_auto_grants_delayed()) {
133 // Generate a random time value that is at least 0 and and most 3 seconds.
134 std::srand(static_cast<unsigned>(PR_Now()));
136 const unsigned kMin
= 0;
137 const unsigned kMax
= 3000;
138 const unsigned random
= std::abs(std::rand());
140 return kMin
+ random
% (kMax
- kMin
);
143 } // namespace mozilla::dom