LeOSium_webview/LeOS/patches/Add-lifetime-options-for-pe...

1652 lines
84 KiB
Diff
Raw Normal View History

2023-11-18 11:46:19 +01:00
From: uazo <uazo@users.noreply.github.com>
Date: Fri, 8 Apr 2022 11:04:04 +0000
Subject: Add lifetime options for permissions
Indicate the session mode for content-settings by using the constraint `content_settings::SessionModel` as
UserSession when setting the value, and also make use of an expiration time value.
This is used in Chromium for `ClientHints` but it is generally possible to use this functionality when a
specific value needs to be persisted by origin.
All content settings of this type are not saved on disk (except for the `Forever` option), allowing user to
reset the status each time application is restarted.
There are 4 main areas affected to introduce the functionality:
* components/content_settings
A new `content_settings::LifetimeMode` enum value is defined to specify the user's
choice (Always, OnlyThisTime, UntilOriginClosed, UntilBrowserClosed).
Enumeration is also generated for java by adding it in `content_settings_enums_javagen` (gn).
This is mainly used in `content_settings_utils.cc` to create a specialised `content_settings::ContentSettingConstraints`
that is then used in `SetContentSettingDefaultScope()` by `PermissionContextBase::UpdateContentSetting`.
Existing Chromium data structures do not provide a specific property to define a choice which is instead encoded through
the `ContentSettingConstraints`; this approach is already used in other parts of the Chromium codebase so it is not
novel here.
Therefore, `content_settings::GetConstraintSessionExpiration()` and `content_settings::IsConstraintSessionExpiration()`
manage the lifetime modes of the session content-settings.
The modificaiton also adds the session pattern to the ContentSettingPatternSource so that it is available for the UI.
* components/permissions
Lifetime support is added to the permissions; most of the changes are caused by the fact that it is necessary to report
the value selected by the user from the Java UI managed by `components/browser_ui` up to
`PermissionContextBase::UpdateContentSetting()`, without necessarily having to modify all requests that are not
related to geolocation/camera/microphone. The approach used is a new
`PermissionRequest::PermissionDecidedCallbackWithLifetime` used by an overload of
`PermissionContextBase::CreatePermissionRequest` so that options are present only for the specific content-settings
(see `PermissionDialogModel.java`).
For other permissions no behaviour is changed (see `PermissionDialogDelegate::Accept`); for geolocation it was
necessary to act directly in the specific context, because, unlike microphone/camera, the content-setting value is
inserted in its specific method (`FinishNotifyPermissionSet`, that calls the callback), even if the class always
derives from `PermissionContextBase`.
* components/page_info
Some changes needed to see in the summary of the `page_info` the text "(only this session)"
(aka `page_info_android_permission_session_permission`) through adding a new property "is_user_session" in
`PageInfoPermissionEntry` (Java).
* components/browser_ui
Changes to the Settings UI to show "(only this session)" in the specific content-setting.
The same view is used both in the settings and in the page_info.
For the management of `UntilOriginClosed` the logic used by flag `kOneTimeGeolocationPermission` was used; this flag
is active only in the desktop (files `last_tab_standing_tracker_*`). It is a class that manages a list of the active
origins and allows to perform operations when all the tabs relating to that origin have been closed, in this case
deleting the session content settings of `UntilOriginClosed`.
See also: https://github.com/bromite/bromite/issues/1549
Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html
---
.../permissions/last_tab_standing_tracker.cc | 32 ++++++++
.../one_time_permissions_tracker.cc | 33 +++++++-
.../one_time_permissions_tracker.h | 5 +-
.../one_time_permissions_tracker_factory.cc | 2 +-
.../embedded_permission_prompt_ask_view.cc | 2 +-
.../permission_prompt_bubble_base_view.cc | 2 +-
.../browser/content_autofill_driver.cc | 64 ++++++++-------
.../content/browser/content_autofill_driver.h | 2 +-
.../autofill/core/browser/autofill_driver.h | 2 +
.../site_settings/PermissionInfo.java | 14 +++-
.../site_settings/SingleWebsiteSettings.java | 10 +++
.../WebsitePreferenceBridge.java | 6 +-
.../android/website_preference_bridge.cc | 7 +-
.../strings/android/browser_ui_strings.grd | 5 ++
components/content_settings/android/BUILD.gn | 1 +
.../core/browser/content_settings_utils.cc | 36 +++++++++
.../core/browser/content_settings_utils.h | 6 ++
.../common/content_settings_constraints.h | 11 +++
.../page_info/PageInfoController.java | 4 +-
.../PermissionParamsListBuilder.java | 13 ++-
.../android/page_info_controller_android.cc | 10 ++-
components/page_info/page_info.cc | 2 +
components/page_info/page_info.h | 1 +
.../permissions/PermissionDialogDelegate.java | 13 +++
.../permissions/PermissionDialogModel.java | 81 ++++++++++++++++++-
.../permission_dialog_delegate.cc | 19 +++++
.../permission_dialog_delegate.h | 1 +
.../permission_prompt_android.cc | 8 ++
.../permission_prompt_android.h | 2 +
.../android/permissions_android_strings.grd | 17 ++++
.../geolocation_permission_context_android.cc | 35 ++++++--
.../geolocation_permission_context_android.h | 14 +++-
.../permissions/permission_context_base.cc | 51 ++++++++++--
.../permissions/permission_context_base.h | 23 +++++-
components/permissions/permission_prompt.h | 3 +-
components/permissions/permission_request.cc | 30 ++++++-
components/permissions/permission_request.h | 16 +++-
.../permissions/permission_request_manager.cc | 45 +++++++----
.../permissions/permission_request_manager.h | 11 ++-
39 files changed, 547 insertions(+), 92 deletions(-)
diff --git a/chrome/browser/permissions/last_tab_standing_tracker.cc b/chrome/browser/permissions/last_tab_standing_tracker.cc
--- a/chrome/browser/permissions/last_tab_standing_tracker.cc
+++ b/chrome/browser/permissions/last_tab_standing_tracker.cc
@@ -7,6 +7,32 @@
#include "base/observer_list.h"
#include "url/gurl.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/content_settings/core/common/content_settings_utils.h"
+#include "components/permissions/permissions_client.h"
+
+namespace {
+ // Remove all sessions content setting by origin and type
+ void RemoveSessionSettings(HostContentSettingsMap* content_settings,
+ const url::Origin& origin,
+ ContentSettingsType type) {
+ ContentSettingsForOneType session_settings =
+ content_settings->GetSettingsForOneType(
+ type, content_settings::SessionModel::UserSession);
+
+ GURL url = origin.GetURL();
+ for (ContentSettingPatternSource& entry : session_settings) {
+ if (content_settings::IsConstraintSessionExpiration(entry,
+ content_settings::LifetimeMode::UntilOriginClosed) &&
+ entry.primary_pattern.Matches(url)) {
+ content_settings->SetWebsiteSettingCustomScope(
+ entry.primary_pattern, entry.secondary_pattern,
+ type, base::Value());
+ }
+ }
+ }
+}
+
LastTabStandingTracker::LastTabStandingTracker(content::BrowserContext* context)
: context_(context) {}
@@ -56,4 +82,10 @@ void LastTabStandingTracker::WebContentsUnloadedOrigin(
for (auto& observer : observer_list_) {
observer.OnLastPageFromOriginClosed(origin);
}
+ HostContentSettingsMap* content_settings =
+ permissions::PermissionsClient::Get()->GetSettingsMap(context_);
+ RemoveSessionSettings(content_settings, origin, ContentSettingsType::GEOLOCATION);
+ RemoveSessionSettings(content_settings, origin, ContentSettingsType::MEDIASTREAM_MIC);
+ RemoveSessionSettings(content_settings, origin, ContentSettingsType::MEDIASTREAM_CAMERA);
+ }
}
diff --git a/chrome/browser/permissions/one_time_permissions_tracker.cc b/chrome/browser/permissions/one_time_permissions_tracker.cc
--- a/chrome/browser/permissions/one_time_permissions_tracker.cc
+++ b/chrome/browser/permissions/one_time_permissions_tracker.cc
@@ -19,8 +19,34 @@
#include "components/permissions/permission_context_base.h"
#include "content/public/browser/visibility.h"
#include "url/gurl.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/content_settings/core/common/content_settings_utils.h"
+#include "components/permissions/permissions_client.h"
+
+namespace {
+ // Remove all sessions content setting by origin and type
+ void RemoveSessionSettings(HostContentSettingsMap* content_settings,
+ const url::Origin& origin,
+ ContentSettingsType type) {
+ ContentSettingsForOneType session_settings =
+ content_settings->GetSettingsForOneType(
+ type, content_settings::SessionModel::UserSession);
+
+ GURL url = origin.GetURL();
+ for (ContentSettingPatternSource& entry : session_settings) {
+ if (content_settings::IsConstraintSessionExpiration(entry,
+ content_settings::LifetimeMode::UntilOriginClosed) &&
+ entry.primary_pattern.Matches(url)) {
+ content_settings->SetWebsiteSettingCustomScope(
+ entry.primary_pattern, entry.secondary_pattern,
+ type, base::Value());
+ }
+ }
+ }
+}
-OneTimePermissionsTracker::OneTimePermissionsTracker() = default;
+OneTimePermissionsTracker::OneTimePermissionsTracker(content::BrowserContext* context)
+ : context_(context) {}
OneTimePermissionsTracker::~OneTimePermissionsTracker() = default;
OneTimePermissionsTracker::OriginTrackEntry::OriginTrackEntry() = default;
@@ -108,6 +134,11 @@ void OneTimePermissionsTracker::WebContentsUnloadedOrigin(
observer.OnLastPageFromOriginClosed(origin);
}
}
+ HostContentSettingsMap* content_settings =
+ permissions::PermissionsClient::Get()->GetSettingsMap(context_);
+ RemoveSessionSettings(content_settings, origin, ContentSettingsType::GEOLOCATION);
+ RemoveSessionSettings(content_settings, origin, ContentSettingsType::MEDIASTREAM_MIC);
+ RemoveSessionSettings(content_settings, origin, ContentSettingsType::MEDIASTREAM_CAMERA);
}
}
diff --git a/chrome/browser/permissions/one_time_permissions_tracker.h b/chrome/browser/permissions/one_time_permissions_tracker.h
--- a/chrome/browser/permissions/one_time_permissions_tracker.h
+++ b/chrome/browser/permissions/one_time_permissions_tracker.h
@@ -12,6 +12,7 @@
#include "base/timer/timer.h"
#include "chrome/browser/permissions/one_time_permissions_tracker_observer.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
+#include "chrome/browser/profiles/profile.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/visibility.h"
@@ -24,7 +25,7 @@ class OneTimePermissionsTracker : public KeyedService {
void (OneTimePermissionsTracker::*)(const url::Origin&);
public:
- OneTimePermissionsTracker();
+ OneTimePermissionsTracker(content::BrowserContext* context);
~OneTimePermissionsTracker() override;
OneTimePermissionsTracker(const OneTimePermissionsTracker&) = delete;
@@ -136,7 +137,7 @@ class OneTimePermissionsTracker : public KeyedService {
base::ObserverList<OneTimePermissionsTrackerObserver> observer_list_;
std::map<url::Origin, OriginTrackEntry> origin_tracker_;
-
+ raw_ptr<content::BrowserContext> context_;
base::WeakPtrFactory<OneTimePermissionsTracker> weak_factory_{this};
};
diff --git a/chrome/browser/permissions/one_time_permissions_tracker_factory.cc b/chrome/browser/permissions/one_time_permissions_tracker_factory.cc
--- a/chrome/browser/permissions/one_time_permissions_tracker_factory.cc
+++ b/chrome/browser/permissions/one_time_permissions_tracker_factory.cc
@@ -41,5 +41,5 @@ bool OneTimePermissionsTrackerFactory::ServiceIsCreatedWithBrowserContext()
std::unique_ptr<KeyedService>
OneTimePermissionsTrackerFactory::BuildServiceInstanceForBrowserContext(
content::BrowserContext* context) const {
- return std::make_unique<OneTimePermissionsTracker>();
+ return std::make_unique<OneTimePermissionsTracker>(context);
}
diff --git a/chrome/browser/ui/views/permissions/embedded_permission_prompt_ask_view.cc b/chrome/browser/ui/views/permissions/embedded_permission_prompt_ask_view.cc
--- a/chrome/browser/ui/views/permissions/embedded_permission_prompt_ask_view.cc
+++ b/chrome/browser/ui/views/permissions/embedded_permission_prompt_ask_view.cc
@@ -34,7 +34,7 @@ void EmbeddedPermissionPromptAskView::RunButtonCallback(int button_id) {
if (delegate()) {
if (button == ButtonType::kAllowThisTime) {
- delegate()->AcceptThisTime();
+ delegate()->AcceptThisTime(content_settings::LifetimeMode::OnlyThisTime);
} else if (button == ButtonType::kAllow) {
delegate()->Accept();
}
diff --git a/chrome/browser/ui/views/permissions/permission_prompt_bubble_base_view.cc b/chrome/browser/ui/views/permissions/permission_prompt_bubble_base_view.cc
--- a/chrome/browser/ui/views/permissions/permission_prompt_bubble_base_view.cc
+++ b/chrome/browser/ui/views/permissions/permission_prompt_bubble_base_view.cc
@@ -263,7 +263,7 @@ void PermissionPromptBubbleBaseView::RunButtonCallback(int button_id) {
return;
case PermissionDialogButton::kAcceptOnce:
RecordDecision(permissions::PermissionAction::GRANTED_ONCE);
- delegate_->AcceptThisTime();
+ delegate_->AcceptThisTime(content_settings::LifetimeMode::OnlyThisTime);
return;
case PermissionDialogButton::kDeny:
RecordDecision(permissions::PermissionAction::DENIED);
diff --git a/components/autofill/content/browser/content_autofill_driver.cc b/components/autofill/content/browser/content_autofill_driver.cc
--- a/components/autofill/content/browser/content_autofill_driver.cc
+++ b/components/autofill/content/browser/content_autofill_driver.cc
@@ -412,8 +412,8 @@ void ContentAutofillDriver::FormsSeen(
const std::vector<FormGlobalId>& removed_forms) {
target->GetAutofillManager().OnFormsSeen(
WithNewVersion(updated_forms), removed_forms);
- if (target->secondary_autofill_manager_) {
- target->secondary_autofill_manager_->OnFormsSeen(
+ if (target->secondary_autofill_manager()) {
+ target->secondary_autofill_manager()->OnFormsSeen(
WithNewVersion(updated_forms), removed_forms);
}
});
@@ -443,8 +443,8 @@ void ContentAutofillDriver::FormSubmitted(
}
target->GetAutofillManager().OnFormSubmitted(
WithNewVersion(form), known_success, submission_source);
- if (target->secondary_autofill_manager_) {
- target->secondary_autofill_manager_->OnFormSubmitted(
+ if (target->secondary_autofill_manager()) {
+ target->secondary_autofill_manager()->OnFormSubmitted(
WithNewVersion(form), known_success, submission_source);
}
});
@@ -468,8 +468,8 @@ void ContentAutofillDriver::TextFieldDidChange(const FormData& raw_form,
base::TimeTicks timestamp) {
target->GetAutofillManager().OnTextFieldDidChange(
WithNewVersion(form), field, bounding_box, timestamp);
- if (target->secondary_autofill_manager_) {
- target->secondary_autofill_manager_->OnTextFieldDidChange(
+ if (target->secondary_autofill_manager()) {
+ target->secondary_autofill_manager()->OnTextFieldDidChange(
WithNewVersion(form), field, bounding_box, timestamp);
}
});
@@ -491,8 +491,8 @@ void ContentAutofillDriver::TextFieldDidScroll(const FormData& raw_form,
const FormFieldData& field, const gfx::RectF& bounding_box) {
target->GetAutofillManager().OnTextFieldDidScroll(WithNewVersion(form),
field, bounding_box);
- if (target->secondary_autofill_manager_) {
- target->secondary_autofill_manager_->OnTextFieldDidScroll(
+ if (target->secondary_autofill_manager()) {
+ target->secondary_autofill_manager()->OnTextFieldDidScroll(
WithNewVersion(form), field, bounding_box);
}
});
@@ -515,8 +515,8 @@ void ContentAutofillDriver::SelectControlDidChange(
const FormFieldData& field, const gfx::RectF& bounding_box) {
target->GetAutofillManager().OnSelectControlDidChange(
WithNewVersion(form), field, bounding_box);
- if (target->secondary_autofill_manager_) {
- target->secondary_autofill_manager_->OnSelectControlDidChange(
+ if (target->secondary_autofill_manager()) {
+ target->secondary_autofill_manager()->OnSelectControlDidChange(
WithNewVersion(form), field, bounding_box);
}
});
@@ -541,8 +541,8 @@ void ContentAutofillDriver::AskForValuesToFill(
AutofillSuggestionTriggerSource trigger_source) {
target->GetAutofillManager().OnAskForValuesToFill(
WithNewVersion(form), field, bounding_box, trigger_source);
- if (target->secondary_autofill_manager_) {
- target->secondary_autofill_manager_->OnAskForValuesToFill(
+ if (target->secondary_autofill_manager()) {
+ target->secondary_autofill_manager()->OnAskForValuesToFill(
WithNewVersion(form), field, bounding_box, trigger_source);
}
});
@@ -556,8 +556,8 @@ void ContentAutofillDriver::HidePopup() {
DCHECK(!target->IsPrerendering())
<< "We should never affect UI while prerendering";
target->GetAutofillManager().OnHidePopup();
- if (target->secondary_autofill_manager_)
- target->secondary_autofill_manager_->OnHidePopup();
+ if (target->secondary_autofill_manager())
+ target->secondary_autofill_manager()->OnHidePopup();
});
}
@@ -569,8 +569,8 @@ void ContentAutofillDriver::FocusNoLongerOnForm(bool had_interacted_form) {
this, had_interacted_form,
[](autofill::AutofillDriver* target, bool had_interacted_form) {
target->GetAutofillManager().OnFocusNoLongerOnForm(had_interacted_form);
- if (target->secondary_autofill_manager_)
- target->secondary_autofill_manager_->OnFocusNoLongerOnForm(had_interacted_form);
+ if (target->secondary_autofill_manager())
+ target->secondary_autofill_manager()->OnFocusNoLongerOnForm(had_interacted_form);
});
}
@@ -590,15 +590,15 @@ void ContentAutofillDriver::FocusOnFormField(const FormData& raw_form,
const FormFieldData& field, const gfx::RectF& bounding_box) {
target->GetAutofillManager().OnFocusOnFormField(WithNewVersion(form),
field, bounding_box);
- if (target->secondary_autofill_manager_) {
- target->secondary_autofill_manager_->OnFocusOnFormField(
+ if (target->secondary_autofill_manager()) {
+ target->secondary_autofill_manager()->OnFocusOnFormField(
WithNewVersion(form), field, bounding_box);
}
},
[](autofill::AutofillDriver* target) {
target->GetAutofillManager().OnFocusNoLongerOnForm(true);
- if (target->secondary_autofill_manager_) {
- target->secondary_autofill_manager_->OnFocusNoLongerOnForm(true);
+ if (target->secondary_autofill_manager()) {
+ target->secondary_autofill_manager()->OnFocusNoLongerOnForm(true);
}
});
}
@@ -614,8 +614,8 @@ void ContentAutofillDriver::DidFillAutofillFormData(const FormData& raw_form,
base::TimeTicks timestamp) {
target->GetAutofillManager().OnDidFillAutofillFormData(
WithNewVersion(form), timestamp);
- if (target->secondary_autofill_manager_) {
- target->secondary_autofill_manager_->OnDidFillAutofillFormData(
+ if (target->secondary_autofill_manager()) {
+ target->secondary_autofill_manager()->OnDidFillAutofillFormData(
WithNewVersion(form), timestamp);
}
});
@@ -627,8 +627,8 @@ void ContentAutofillDriver::DidEndTextFieldEditing() {
}
router().DidEndTextFieldEditing(this, [](autofill::AutofillDriver* target) {
target->GetAutofillManager().OnDidEndTextFieldEditing();
- if (target->secondary_autofill_manager_)
- target->secondary_autofill_manager_->OnDidEndTextFieldEditing();
+ if (target->secondary_autofill_manager())
+ target->secondary_autofill_manager()->OnDidEndTextFieldEditing();
});
}
@@ -643,8 +643,8 @@ void ContentAutofillDriver::SelectOrSelectListFieldOptionsDidChange(
cast(target)
->GetAutofillManager()
.OnSelectOrSelectListFieldOptionsDidChange(WithNewVersion(form));
- if (target->secondary_autofill_manager_) {
- target->secondary_autofill_manager_->OnSelectOrSelectMenuFieldOptionsDidChange(
+ if (target->secondary_autofill_manager()) {
+ target->secondary_autofill_manager()->OnSelectOrSelectListFieldOptionsDidChange(
WithNewVersion(form));
}
});
@@ -666,8 +666,8 @@ void ContentAutofillDriver::JavaScriptChangedAutofilledValue(
const FormFieldData& field, const std::u16string& old_value) {
target->GetAutofillManager().OnJavaScriptChangedAutofilledValue(
WithNewVersion(form), field, old_value);
- if (target->secondary_autofill_manager_) {
- target->secondary_autofill_manager_->OnJavaScriptChangedAutofilledValue(
+ if (target->secondary_autofill_manager()) {
+ target->secondary_autofill_manager()->OnJavaScriptChangedAutofilledValue(
WithNewVersion(form), field, old_value);
}
});
@@ -682,8 +682,8 @@ void ContentAutofillDriver::OnContextMenuShownInField(
const FieldGlobalId& field_global_id) {
target->GetAutofillManager().OnContextMenuShownInField(form_global_id,
field_global_id);
- if (target->secondary_autofill_manager_)
- target->secondary_autofill_manager_->OnContextMenuShownInField(form_global_id, field_global_id);
+ if (target->secondary_autofill_manager())
+ target->secondary_autofill_manager()->OnContextMenuShownInField(form_global_id, field_global_id);
});
}
@@ -708,6 +708,10 @@ ContentAutofillDriver::GetAutofillAgent() {
return autofill_agent_;
}
+raw_ptr<AutofillManager> ContentAutofillDriver::secondary_autofill_manager() {
+ return secondary_autofill_manager_.get();
+}
+
void ContentAutofillDriver::SetFrameAndFormMetaData(
FormData& form,
FormFieldData* optional_field) const {
diff --git a/components/autofill/content/browser/content_autofill_driver.h b/components/autofill/content/browser/content_autofill_driver.h
--- a/components/autofill/content/browser/content_autofill_driver.h
+++ b/components/autofill/content/browser/content_autofill_driver.h
@@ -132,7 +132,7 @@ class ContentAutofillDriver : public AutofillDriver,
autofill_manager_ = std::move(autofill_manager);
secondary_autofill_manager_ = std::move(secondary_autofill_manager);
}
- AutofillManager* secondary_autofill_manager() { return secondary_autofill_manager_.get(); }
+ raw_ptr<AutofillManager> secondary_autofill_manager() override;
content::RenderFrameHost* render_frame_host() { return &*render_frame_host_; }
const content::RenderFrameHost* render_frame_host() const {
diff --git a/components/autofill/core/browser/autofill_driver.h b/components/autofill/core/browser/autofill_driver.h
--- a/components/autofill/core/browser/autofill_driver.h
+++ b/components/autofill/core/browser/autofill_driver.h
@@ -69,6 +69,8 @@ class AutofillDriver {
// Returns the AutofillManager owned by the AutofillDriver.
virtual AutofillManager& GetAutofillManager() = 0;
+ virtual raw_ptr<AutofillManager> secondary_autofill_manager() = 0;
+
// Returns whether the AutofillDriver instance is associated with an active
// frame in the MPArch sense.
virtual bool IsInActiveFrame() const = 0;
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/PermissionInfo.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/PermissionInfo.java
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/PermissionInfo.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/PermissionInfo.java
@@ -9,6 +9,7 @@ import androidx.annotation.Nullable;
import org.chromium.components.content_settings.ContentSettingValues;
import org.chromium.components.content_settings.ContentSettingsType;
import org.chromium.content_public.browser.BrowserContextHandle;
+import org.chromium.components.content_settings.SessionModel;
import java.io.Serializable;
@@ -20,9 +21,15 @@ public class PermissionInfo implements Serializable {
private final String mEmbedder;
private final String mOrigin;
private final @ContentSettingsType int mContentSettingsType;
+ private final @SessionModel int mSessionModel;
+
+ public PermissionInfo(@ContentSettingsType int type, String origin, String embedder, boolean isEmbargoed) {
+ this(type, origin, embedder, isEmbargoed, 0);
+ }
public PermissionInfo(
- @ContentSettingsType int type, String origin, String embedder, boolean isEmbargoed) {
+ @ContentSettingsType int type, String origin, String embedder, boolean isEmbargoed,
+ @SessionModel int sessionModel) {
assert WebsitePermissionsFetcher.getPermissionsType(type)
== WebsitePermissionsFetcher.WebsitePermissionsType.PERMISSION_INFO
: "invalid type: "
@@ -31,6 +38,11 @@ public class PermissionInfo implements Serializable {
mEmbedder = embedder;
mContentSettingsType = type;
mIsEmbargoed = isEmbargoed;
+ mSessionModel = sessionModel;
+ }
+
+ public @SessionModel int getSessionModel() {
+ return mSessionModel;
}
public @ContentSettingsType int getContentSettingsType() {
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
@@ -38,6 +38,7 @@ import org.chromium.components.browser_ui.settings.TextMessagePreference;
import org.chromium.components.browsing_data.DeleteBrowsingDataAction;
import org.chromium.components.content_settings.ContentSettingValues;
import org.chromium.components.content_settings.ContentSettingsType;
+import org.chromium.components.content_settings.SessionModel;
import org.chromium.components.embedder_support.util.Origin;
import org.chromium.content_public.browser.BrowserContextHandle;
@@ -558,6 +559,11 @@ public class SingleWebsiteSettings extends BaseSiteSettingsFragment
}
}
+ private boolean isSessionPermission(@ContentSettingsType int type) {
+ return mSite.getPermissionInfo(type) != null &&
+ mSite.getPermissionInfo(type).getSessionModel() == SessionModel.USER_SESSION;
+ }
+
private void setUpClearDataPreference() {
ClearWebsiteStorage preference = findPreference(PREF_CLEAR_DATA);
long usage = mSite.getTotalUsage();
@@ -1024,6 +1030,10 @@ public class SingleWebsiteSettings extends BaseSiteSettingsFragment
if (contentType == mHighlightedPermission) {
switchPreference.setBackgroundColor(mHighlightColor);
}
+ if (isSessionPermission(contentType)) {
+ switchPreference.setSummary(switchPreference.getSummary() + " " +
+ getString(R.string.page_info_android_permission_session_permission));
+ }
}
/**
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
@@ -9,6 +9,7 @@ import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.components.content_settings.ContentSettingValues;
import org.chromium.components.content_settings.ContentSettingsType;
+import org.chromium.components.content_settings.SessionModel;
import org.chromium.components.location.LocationUtils;
import org.chromium.content_public.browser.BrowserContextHandle;
import org.chromium.url.GURL;
@@ -55,7 +56,8 @@ public class WebsitePreferenceBridge {
@CalledByNative
private static void insertPermissionInfoIntoList(@ContentSettingsType int type,
- ArrayList<PermissionInfo> list, String origin, String embedder, boolean isEmbargoed) {
+ ArrayList<PermissionInfo> list, String origin, String embedder, boolean isEmbargoed,
+ @SessionModel int sessionModel) {
if (type == ContentSettingsType.MEDIASTREAM_CAMERA
|| type == ContentSettingsType.MEDIASTREAM_MIC) {
for (PermissionInfo info : list) {
@@ -64,7 +66,7 @@ public class WebsitePreferenceBridge {
}
}
}
- list.add(new PermissionInfo(type, origin, embedder, isEmbargoed));
+ list.add(new PermissionInfo(type, origin, embedder, isEmbargoed, sessionModel));
}
@CalledByNative
diff --git a/components/browser_ui/site_settings/android/website_preference_bridge.cc b/components/browser_ui/site_settings/android/website_preference_bridge.cc
--- a/components/browser_ui/site_settings/android/website_preference_bridge.cc
+++ b/components/browser_ui/site_settings/android/website_preference_bridge.cc
@@ -131,7 +131,8 @@ typedef void (*InfoListInsertionFunction)(
const base::android::JavaRef<jobject>&,
const base::android::JavaRef<jstring>&,
const base::android::JavaRef<jstring>&,
- jboolean);
+ jboolean,
+ JniIntWrapper);
void GetOrigins(JNIEnv* env,
const JavaParamRef<jobject>& jbrowser_context_handle,
@@ -173,7 +174,7 @@ void GetOrigins(JNIEnv* env,
seen_origins.push_back(origin);
insertionFunc(env, static_cast<int>(content_type), list,
ConvertOriginToJavaString(env, origin), jembedder,
- /*is_embargoed=*/false);
+ /*is_embargoed=*/false, static_cast<int>(settings_it.metadata.session_model()));
}
// Add any origins which have a default content setting value (thus skipped
@@ -195,7 +196,7 @@ void GetOrigins(JNIEnv* env,
seen_origins.push_back(origin);
insertionFunc(env, static_cast<int>(content_type), list,
ConvertOriginToJavaString(env, origin), jembedder,
- /*is_embargoed=*/true);
+ /*is_embargoed=*/true, 0);
}
}
}
diff --git a/components/browser_ui/strings/android/browser_ui_strings.grd b/components/browser_ui/strings/android/browser_ui_strings.grd
--- a/components/browser_ui/strings/android/browser_ui_strings.grd
+++ b/components/browser_ui/strings/android/browser_ui_strings.grd
@@ -642,6 +642,11 @@
<message name="IDS_PAGE_INFO_URL_TRUNCATED" desc="Accessibility announcement when the URL in PageInfo switches from full to truncated display">
URL truncated
</message>
+ <message name="IDS_PAGE_INFO_ANDROID_PERMISSION_SESSION_PERMISSION"
+ desc="The label used in the About Page dialog to indicate a session permission">
+ (only this session)
+ </message>
+
<message name="IDS_PAGE_INFO_AD_PERSONALIZATION_TITLE" desc="The title of the 'Ad personalization' section in Page Info.">
Ad personalization
</message>
diff --git a/components/content_settings/android/BUILD.gn b/components/content_settings/android/BUILD.gn
--- a/components/content_settings/android/BUILD.gn
+++ b/components/content_settings/android/BUILD.gn
@@ -60,6 +60,7 @@ java_cpp_enum("content_settings_enums_javagen") {
"../core/common/cookie_controls_breakage_confidence_level.h",
"../core/common/cookie_controls_enforcement.h",
"../core/common/cookie_controls_status.h",
+ "../core/common/content_settings_constraints.h",
]
visibility = [ ":*" ] # Depend on through :content_settings_enums_java
}
diff --git a/components/content_settings/core/browser/content_settings_utils.cc b/components/content_settings/core/browser/content_settings_utils.cc
--- a/components/content_settings/core/browser/content_settings_utils.cc
+++ b/components/content_settings/core/browser/content_settings_utils.cc
@@ -174,6 +174,42 @@ bool IsConstraintPersistent(const ContentSettingConstraints& constraints) {
return constraints.session_model() == SessionModel::Durable;
}
+ContentSettingConstraints GetConstraintSessionExpiration(LifetimeMode lifetime_mode) {
+ int lifetime;
+ base::Time now;
+ if (lifetime_mode == LifetimeMode::OnlyThisTime) {
+ // note: this content settings will be discarded immediately
+ // 1h is used as a magic constant to identify the one-time lifetime mode
+ lifetime = 1;
+ } else if (lifetime_mode == LifetimeMode::UntilOriginClosed) {
+ now = base::Time::Now();
+ lifetime = 24;
+ } else {
+ lifetime = 0;
+ }
+ content_settings::ContentSettingConstraints c(now);
+ c.set_lifetime(base::Hours(lifetime));
+ c.set_session_model(content_settings::SessionModel::UserSession);
+ return c;
+}
+
+bool IsConstraintSessionExpiration(const ContentSettingPatternSource& source,
+ LifetimeMode lifetime_mode) {
+ if (source.metadata.session_model() != content_settings::SessionModel::UserSession)
+ return false;
+
+ LifetimeMode type;
+ if (source.metadata.lifetime() == base::Hours(24)) {
+ type = LifetimeMode::UntilOriginClosed;
+ } else if (source.metadata.expiration() == (base::Time() + base::Hours(1))) {
+ type = LifetimeMode::OnlyThisTime;
+ } else {
+ type = LifetimeMode::UntilBrowserClosed;
+ }
+
+ return lifetime_mode == type;
+}
+
bool CanTrackLastVisit(ContentSettingsType type) {
// Last visit is not tracked for notification permission as it shouldn't be
// auto-revoked.
diff --git a/components/content_settings/core/browser/content_settings_utils.h b/components/content_settings/core/browser/content_settings_utils.h
--- a/components/content_settings/core/browser/content_settings_utils.h
+++ b/components/content_settings/core/browser/content_settings_utils.h
@@ -73,6 +73,12 @@ bool IsConstraintPersistent(const ContentSettingConstraints& constraints);
// Returns whether the given type supports tracking last_visit timestamps.
bool CanTrackLastVisit(ContentSettingsType type);
+ContentSettingConstraints GetConstraintSessionExpiration(LifetimeMode lifetime_mode);
+
+bool IsConstraintSessionExpiration(
+ const ContentSettingPatternSource& source,
+ LifetimeMode lifetime_mode);
+
// Get a timestamp with week-precision.
base::Time GetCoarseVisitedTime(base::Time time);
diff --git a/components/content_settings/core/common/content_settings_constraints.h b/components/content_settings/core/common/content_settings_constraints.h
--- a/components/content_settings/core/common/content_settings_constraints.h
+++ b/components/content_settings/core/common/content_settings_constraints.h
@@ -23,6 +23,8 @@ namespace content_settings {
// a crash or update related restart.
// OneTime: Settings will persist for the current "tab session", meaning
// until the last tab from the origin is closed.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.content_settings
+// GENERATED_JAVA_CLASS_NAME_OVERRIDE: SessionModel
enum class SessionModel {
Durable = 0,
UserSession = 1,
@@ -31,6 +33,15 @@ enum class SessionModel {
kMaxValue = OneTime,
};
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.content_settings
+// GENERATED_JAVA_CLASS_NAME_OVERRIDE: LifetimeMode
+enum class LifetimeMode {
+ Always = 99,
+ OnlyThisTime = 1,
+ UntilOriginClosed = 2,
+ UntilBrowserClosed = 0,
+};
+
// Constraints to be applied when setting a content setting.
class ContentSettingConstraints {
public:
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java
--- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java
+++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java
@@ -336,9 +336,9 @@ public class PageInfoController implements PageInfoMainController, ModalDialogPr
*/
@CalledByNative
private void addPermissionSection(String name, String nameMidSentence, int type,
- @ContentSettingValues int currentSettingValue) {
+ @ContentSettingValues int currentSettingValue, boolean is_user_session) {
mPermissionParamsListBuilder.addPermissionEntry(
- name, nameMidSentence, type, currentSettingValue);
+ name, nameMidSentence, type, currentSettingValue, is_user_session);
}
/**
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java b/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java
--- a/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java
+++ b/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java
@@ -44,8 +44,9 @@ public class PermissionParamsListBuilder {
}
public void addPermissionEntry(
- String name, String nameMidSentence, int type, @ContentSettingValues int value) {
- mEntries.add(new PageInfoPermissionEntry(name, nameMidSentence, type, value));
+ String name, String nameMidSentence, int type, @ContentSettingValues int value,
+ boolean is_user_session) {
+ mEntries.add(new PageInfoPermissionEntry(name, nameMidSentence, type, value, is_user_session));
}
public void clearPermissionEntries() {
@@ -86,6 +87,10 @@ public class PermissionParamsListBuilder {
permissionParams.warningTextResource =
R.string.page_info_android_permission_blocked;
}
+ if (permission.is_user_session) {
+ permissionParams.warningTextResource =
+ R.string.page_info_android_permission_session_permission;
+ }
}
}
@@ -123,13 +128,15 @@ public class PermissionParamsListBuilder {
public final String nameMidSentence;
public final int type;
public final @ContentSettingValues int setting;
+ public final boolean is_user_session;
PageInfoPermissionEntry(
- String name, String nameMidSentence, int type, @ContentSettingValues int setting) {
+ String name, String nameMidSentence, int type, @ContentSettingValues int setting, boolean is_user_session) {
this.name = name;
this.nameMidSentence = nameMidSentence;
this.type = type;
this.setting = setting;
+ this.is_user_session = is_user_session;
}
@Override
diff --git a/components/page_info/android/page_info_controller_android.cc b/components/page_info/android/page_info_controller_android.cc
--- a/components/page_info/android/page_info_controller_android.cc
+++ b/components/page_info/android/page_info_controller_android.cc
@@ -154,6 +154,8 @@ void PageInfoControllerAndroid::SetPermissionInfo(
std::map<ContentSettingsType, ContentSetting>
user_specified_settings_to_display;
+ std::map<ContentSettingsType, bool>
+ user_specified_settings_is_user_session;
for (const auto& permission : permission_info_list) {
if (base::Contains(permissions_to_display, permission.type)) {
@@ -162,6 +164,8 @@ void PageInfoControllerAndroid::SetPermissionInfo(
if (setting_to_display) {
user_specified_settings_to_display[permission.type] =
*setting_to_display;
+ user_specified_settings_is_user_session[permission.type] =
+ permission.is_user_session;
}
}
}
@@ -178,7 +182,8 @@ void PageInfoControllerAndroid::SetPermissionInfo(
ConvertUTF16ToJavaString(env, setting_title),
ConvertUTF16ToJavaString(env, setting_title_mid_sentence),
static_cast<jint>(permission),
- static_cast<jint>(user_specified_settings_to_display[permission]));
+ static_cast<jint>(user_specified_settings_to_display[permission]),
+ user_specified_settings_is_user_session[permission]);
}
}
@@ -191,7 +196,8 @@ void PageInfoControllerAndroid::SetPermissionInfo(
env, controller_jobject_, ConvertUTF16ToJavaString(env, object_title),
ConvertUTF16ToJavaString(env, object_title),
static_cast<jint>(chosen_object->ui_info->content_settings_type),
- static_cast<jint>(CONTENT_SETTING_ALLOW));
+ static_cast<jint>(CONTENT_SETTING_ALLOW),
+ /* is_user_session */ false);
}
Java_PageInfoController_updatePermissionDisplay(env, controller_jobject_);
diff --git a/components/page_info/page_info.cc b/components/page_info/page_info.cc
--- a/components/page_info/page_info.cc
+++ b/components/page_info/page_info.cc
@@ -1184,6 +1184,8 @@ void PageInfo::PopulatePermissionInfo(PermissionInfo& permission_info,
permission_info.source = info.source;
permission_info.is_one_time = (info.metadata.session_model() ==
content_settings::SessionModel::OneTime);
+ permission_info.is_user_session =
+ (info.metadata.session_model() == content_settings::SessionModel::UserSession);
auto* page_specific_content_settings = GetPageSpecificContentSettings();
if (page_specific_content_settings && setting == CONTENT_SETTING_ALLOW) {
diff --git a/components/page_info/page_info.h b/components/page_info/page_info.h
--- a/components/page_info/page_info.h
+++ b/components/page_info/page_info.h
@@ -199,6 +199,7 @@ class PageInfo : private content_settings::CookieControlsObserver,
content_settings::SETTING_SOURCE_NONE;
// Whether the permission is a one-time grant.
bool is_one_time = false;
+ bool is_user_session = false;
// Only set for settings that can have multiple permissions for different
// embedded origins.
absl::optional<url::Origin> requesting_origin;
diff --git a/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogDelegate.java b/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogDelegate.java
--- a/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogDelegate.java
+++ b/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogDelegate.java
@@ -8,6 +8,7 @@ import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.ui.base.WindowAndroid;
+import org.chromium.components.content_settings.LifetimeMode;
/**
* Delegate class for modal permission dialogs. Contains all of the data displayed in a prompt,
@@ -46,6 +47,9 @@ public class PermissionDialogDelegate {
/** The {@link ContentSettingsType}s requested in this dialog. */
private int[] mContentSettingsTypes;
+ /** Lifetime option selected by the user. */
+ private int mSelectedLifetimeOption = LifetimeMode.ALWAYS;
+
public WindowAndroid getWindow() {
return mWindow;
}
@@ -79,6 +83,15 @@ public class PermissionDialogDelegate {
PermissionDialogDelegateJni.get().accept(mNativeDelegatePtr, PermissionDialogDelegate.this);
}
+ public void setSelectedLifetimeOption(int idx) {
+ mSelectedLifetimeOption = idx;
+ }
+
+ @CalledByNative
+ public int getSelectedLifetimeOption() {
+ return mSelectedLifetimeOption;
+ }
+
public void onCancel() {
assert mNativeDelegatePtr != 0;
PermissionDialogDelegateJni.get().cancel(mNativeDelegatePtr, PermissionDialogDelegate.this);
diff --git a/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogModel.java b/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogModel.java
--- a/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogModel.java
+++ b/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogModel.java
@@ -16,6 +16,17 @@ import org.chromium.ui.UiUtils;
import org.chromium.ui.modaldialog.ModalDialogProperties;
import org.chromium.ui.modelutil.PropertyModel;
+import java.util.Arrays;
+import java.util.List;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.LinearLayout;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.ui.base.ViewUtils;
+import org.chromium.components.content_settings.ContentSettingsType;
+import org.chromium.components.content_settings.LifetimeMode;
+
/**
* This class creates the model for permission dialog.
*/
@@ -41,7 +52,7 @@ class PermissionDialogModel {
secondaryTextView.setVisibility(View.VISIBLE);
}
- return new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS)
+ PropertyModel pm = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS)
.with(ModalDialogProperties.CONTROLLER, controller)
.with(ModalDialogProperties.FOCUS_DIALOG, true)
.with(ModalDialogProperties.CUSTOM_VIEW, customView)
@@ -53,6 +64,74 @@ class PermissionDialogModel {
.with(ModalDialogProperties.BUTTON_TAP_PROTECTION_PERIOD_MS,
UiUtils.PROMPT_INPUT_PROTECTION_SHORT_DELAY_MS)
.build();
+
+ int[] types = delegate.getContentSettingsTypes();
+ if (contains(types, ContentSettingsType.GEOLOCATION) ||
+ contains(types, ContentSettingsType.MEDIASTREAM_MIC) ||
+ contains(types, ContentSettingsType.MEDIASTREAM_CAMERA))
+ {
+ LinearLayout layout = (LinearLayout) customView;
+
+ // Create a text label before the lifetime selector.
+ TextView lifetimeOptionsText = new TextView(context);
+ lifetimeOptionsText.setText(context.getString(
+ org.chromium.components.permissions.R.string.session_permissions_title));
+ ApiCompatibilityUtils.setTextAppearance(
+ lifetimeOptionsText, R.style.TextAppearance_TextMedium_Primary);
+
+ LinearLayout.LayoutParams lifetimeOptionsTextLayoutParams =
+ new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ lifetimeOptionsTextLayoutParams.setMargins(0, 0, 0, ViewUtils.dpToPx(context, 8));
+ lifetimeOptionsText.setLayoutParams(lifetimeOptionsTextLayoutParams);
+ layout.addView(lifetimeOptionsText);
+
+ // Create radio buttons with lifetime options.
+ RadioGroup radioGroup = new RadioGroup(context);
+
+ RadioButton radioButon = new RadioButton(context);
+ radioButon.setText(context.getString(
+ org.chromium.components.permissions.R.string.session_permissions_only_this_this));
+ radioButon.setId(LifetimeMode.ONLY_THIS_TIME);
+ radioGroup.addView(radioButon);
+
+ radioButon = new RadioButton(context);
+ radioButon.setText(context.getString(
+ org.chromium.components.permissions.R.string.session_permissions_until_page_close));
+ radioButon.setId(LifetimeMode.UNTIL_ORIGIN_CLOSED);
+ radioGroup.addView(radioButon);
+
+ radioButon = new RadioButton(context);
+ radioButon.setText(context.getString(
+ org.chromium.components.permissions.R.string.session_permissions_until_browser_close));
+ radioButon.setId(LifetimeMode.UNTIL_BROWSER_CLOSED);
+ radioGroup.addView(radioButon);
+
+ radioButon = new RadioButton(context);
+ radioButon.setText(context.getString(
+ org.chromium.components.permissions.R.string.session_permissions_forever));
+ radioButon.setId(LifetimeMode.ALWAYS);
+ radioGroup.addView(radioButon);
+
+ radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(RadioGroup group, int checkedId) {
+ delegate.setSelectedLifetimeOption(checkedId);
+ }
+ });
+ radioGroup.check(1);
+ layout.addView(radioGroup);
+ }
+
+ return pm;
+ }
+
+ private static boolean contains(final int[] array, final int key) {
+ int length = array.length;
+ for(int i = 0; i < length; i++) {
+ if (array[i] == key)
+ return true;
+ }
+ return false;
}
private static View loadDialogView(Context context) {
diff --git a/components/permissions/android/permission_prompt/permission_dialog_delegate.cc b/components/permissions/android/permission_prompt/permission_dialog_delegate.cc
--- a/components/permissions/android/permission_prompt/permission_dialog_delegate.cc
+++ b/components/permissions/android/permission_prompt/permission_dialog_delegate.cc
@@ -68,6 +68,11 @@ void PermissionDialogJavaDelegate::DismissDialog() {
Java_PermissionDialogDelegate_dismissFromNative(env, j_delegate_);
}
+int PermissionDialogJavaDelegate::GetSelectedLifetimeOption() {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ return Java_PermissionDialogDelegate_getSelectedLifetimeOption(env, j_delegate_);
+}
+
// static
void PermissionDialogDelegate::Create(
content::WebContents* web_contents,
@@ -96,12 +101,26 @@ PermissionDialogDelegate* PermissionDialogDelegate::CreateForTesting(
void PermissionDialogDelegate::Accept(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
DCHECK(permission_prompt_);
+ content_settings::LifetimeMode lifetimeOption =
+ static_cast<content_settings::LifetimeMode>(
+ java_delegate_->GetSelectedLifetimeOption());
+ if (lifetimeOption != content_settings::LifetimeMode::Always) {
+ permission_prompt_->AcceptThisTime(lifetimeOption);
+ return;
+ }
permission_prompt_->Accept();
}
void PermissionDialogDelegate::Cancel(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
DCHECK(permission_prompt_);
+ content_settings::LifetimeMode lifetimeOption =
+ static_cast<content_settings::LifetimeMode>(
+ java_delegate_->GetSelectedLifetimeOption());
+ if (lifetimeOption != content_settings::LifetimeMode::Always) {
+ permission_prompt_->DenyThisTime(lifetimeOption);
+ return;
+ }
permission_prompt_->Deny();
}
diff --git a/components/permissions/android/permission_prompt/permission_dialog_delegate.h b/components/permissions/android/permission_prompt/permission_dialog_delegate.h
--- a/components/permissions/android/permission_prompt/permission_dialog_delegate.h
+++ b/components/permissions/android/permission_prompt/permission_dialog_delegate.h
@@ -35,6 +35,7 @@ class PermissionDialogJavaDelegate {
PermissionDialogDelegate* owner);
virtual void CreateDialog();
virtual void DismissDialog();
+ virtual int GetSelectedLifetimeOption();
private:
base::android::ScopedJavaGlobalRef<jobject> j_delegate_;
diff --git a/components/permissions/android/permission_prompt/permission_prompt_android.cc b/components/permissions/android/permission_prompt/permission_prompt_android.cc
--- a/components/permissions/android/permission_prompt/permission_prompt_android.cc
+++ b/components/permissions/android/permission_prompt/permission_prompt_android.cc
@@ -47,6 +47,14 @@ void PermissionPromptAndroid::Accept() {
delegate_->Accept();
}
+void PermissionPromptAndroid::AcceptThisTime(content_settings::LifetimeMode lifetimeOption) {
+ delegate_->AcceptThisTime(lifetimeOption);
+}
+
+void PermissionPromptAndroid::DenyThisTime(content_settings::LifetimeMode lifetimeOption) {
+ delegate_->DenyThisTime(lifetimeOption);
+}
+
void PermissionPromptAndroid::Deny() {
delegate_->Deny();
}
diff --git a/components/permissions/android/permission_prompt/permission_prompt_android.h b/components/permissions/android/permission_prompt/permission_prompt_android.h
--- a/components/permissions/android/permission_prompt/permission_prompt_android.h
+++ b/components/permissions/android/permission_prompt/permission_prompt_android.h
@@ -46,7 +46,9 @@ class PermissionPromptAndroid : public PermissionPrompt {
void Closing();
void Accept();
+ void AcceptThisTime(content_settings::LifetimeMode lifetimeOption);
void Deny();
+ void DenyThisTime(content_settings::LifetimeMode lifetimeOption);
void SetManageClicked();
void SetLearnMoreClicked();
bool ShouldCurrentRequestUseQuietUI();
diff --git a/components/permissions/android/permissions_android_strings.grd b/components/permissions/android/permissions_android_strings.grd
--- a/components/permissions/android/permissions_android_strings.grd
+++ b/components/permissions/android/permissions_android_strings.grd
@@ -264,6 +264,23 @@
Unknown or unsupported device (<ph name="DEVICE_ID">%1$s<ex>A1:B2:C3:D4:E5:F6</ex></ph>)
</message>
+ <!-- Session permissions -->
+ <message name="IDS_SESSION_PERMISSIONS_TITLE" desc="Title for the session section in the permission request">
+ Remeber my decision
+ </message>
+ <message name="IDS_SESSION_PERMISSIONS_ONLY_THIS_THIS" desc="Message indicating that the permission is only for this time">
+ Only this time
+ </message>
+ <message name="IDS_SESSION_PERMISSIONS_UNTIL_PAGE_CLOSE" desc="Message indicating that the permission is deleted after navigating away from the page">
+ Until all pages of this origin are closed
+ </message>
+ <message name="IDS_SESSION_PERMISSIONS_UNTIL_BROWSER_CLOSE" desc="Message indicating that the permission is for the session only">
+ Until Bromite is closed
+ </message>
+ <message name="IDS_SESSION_PERMISSIONS_FOREVER" desc="Message indicating that the permission is for all sessions">
+ Forever
+ </message>
+
<!-- Item Chooser UI strings -->
<message name="IDS_ITEM_CHOOSER_ITEM_NAME_WITH_ID" desc="To distinguish items with the same name, the item chooser shows the item name with id.">
<ph name="ITEM_NAME">%1$s<ex>item_name</ex></ph> (<ph name="ITEM_ID">%2$s<ex>item id</ex></ph>)
diff --git a/components/permissions/contexts/geolocation_permission_context_android.cc b/components/permissions/contexts/geolocation_permission_context_android.cc
--- a/components/permissions/contexts/geolocation_permission_context_android.cc
+++ b/components/permissions/contexts/geolocation_permission_context_android.cc
@@ -163,7 +163,20 @@ void GeolocationPermissionContextAndroid::NotifyPermissionSet(
bool is_final_decision) {
DCHECK(!is_one_time);
DCHECK(is_final_decision);
+ NotifyPermissionSetWithLifetime(id, requesting_origin, embedding_origin,
+ std::move(callback), persist, content_setting, is_one_time, is_final_decision,
+ content_settings::LifetimeMode::Always);
+}
+void GeolocationPermissionContextAndroid::NotifyPermissionSetWithLifetime(
+ const PermissionRequestID& id,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin,
+ BrowserPermissionCallback callback,
+ bool persist,
+ ContentSetting content_setting,
+ bool is_one_time, bool is_final_decision,
+ content_settings::LifetimeMode lifetime_option) {
bool is_default_search = IsRequestingOriginDSE(requesting_origin);
if (content_setting == CONTENT_SETTING_ALLOW &&
!location_settings_->IsSystemLocationSettingEnabled()) {
@@ -176,7 +189,8 @@ void GeolocationPermissionContextAndroid::NotifyPermissionSet(
if (IsInLocationSettingsBackOff(is_default_search)) {
FinishNotifyPermissionSet(id, requesting_origin, embedding_origin,
std::move(callback), false /* persist */,
- CONTENT_SETTING_BLOCK);
+ CONTENT_SETTING_BLOCK,
+ is_one_time, lifetime_option);
return;
}
@@ -194,7 +208,8 @@ void GeolocationPermissionContextAndroid::NotifyPermissionSet(
!location_settings_dialog_callback_.is_null()) {
FinishNotifyPermissionSet(id, requesting_origin, embedding_origin,
std::move(callback), false /* persist */,
- CONTENT_SETTING_BLOCK);
+ CONTENT_SETTING_BLOCK,
+ is_one_time, lifetime_option);
return;
}
@@ -206,12 +221,13 @@ void GeolocationPermissionContextAndroid::NotifyPermissionSet(
base::BindOnce(
&GeolocationPermissionContextAndroid::OnLocationSettingsDialogShown,
weak_factory_.GetWeakPtr(), requesting_origin, embedding_origin,
- persist, content_setting));
+ persist, content_setting, is_one_time, lifetime_option));
return;
}
FinishNotifyPermissionSet(id, requesting_origin, embedding_origin,
- std::move(callback), persist, content_setting);
+ std::move(callback), persist, content_setting,
+ is_one_time, lifetime_option);
}
content::PermissionResult
@@ -377,6 +393,7 @@ void GeolocationPermissionContextAndroid::OnLocationSettingsDialogShown(
const GURL& embedding_origin,
bool persist,
ContentSetting content_setting,
+ bool is_one_time, content_settings::LifetimeMode lifetime_option,
LocationSettingsDialogOutcome prompt_outcome) {
bool is_default_search = IsRequestingOriginDSE(requesting_origin);
if (prompt_outcome == GRANTED) {
@@ -394,7 +411,8 @@ void GeolocationPermissionContextAndroid::OnLocationSettingsDialogShown(
FinishNotifyPermissionSet(
location_settings_dialog_request_id_, requesting_origin, embedding_origin,
- std::move(location_settings_dialog_callback_), persist, content_setting);
+ std::move(location_settings_dialog_callback_), persist, content_setting,
+ is_one_time, lifetime_option);
location_settings_dialog_request_id_ =
PermissionRequestID(content::GlobalRenderFrameHostId(0, 0),
@@ -407,10 +425,11 @@ void GeolocationPermissionContextAndroid::FinishNotifyPermissionSet(
const GURL& embedding_origin,
BrowserPermissionCallback callback,
bool persist,
- ContentSetting content_setting) {
- GeolocationPermissionContext::NotifyPermissionSet(
+ ContentSetting content_setting,
+ bool is_one_time, content_settings::LifetimeMode lifetime_option) {
+ GeolocationPermissionContext::NotifyPermissionSetWithLifetime(
id, requesting_origin, embedding_origin, std::move(callback), persist,
- content_setting, /*is_one_time=*/false, /*is_final_decision=*/true);
+ content_setting, is_one_time, /*is_final_decision=*/true, lifetime_option);
}
void GeolocationPermissionContextAndroid::SetLocationSettingsForTesting(
diff --git a/components/permissions/contexts/geolocation_permission_context_android.h b/components/permissions/contexts/geolocation_permission_context_android.h
--- a/components/permissions/contexts/geolocation_permission_context_android.h
+++ b/components/permissions/contexts/geolocation_permission_context_android.h
@@ -89,6 +89,15 @@ class GeolocationPermissionContextAndroid
ContentSetting content_setting,
bool is_one_time,
bool is_final_decision) override;
+ void NotifyPermissionSetWithLifetime(const PermissionRequestID& id,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin,
+ BrowserPermissionCallback callback,
+ bool persist,
+ ContentSetting content_setting,
+ bool is_one_time,
+ bool is_final_decision,
+ content_settings::LifetimeMode lifetime_option) override;
content::PermissionResult UpdatePermissionStatusWithDeviceStatus(
content::PermissionResult result,
const GURL& requesting_origin,
@@ -131,6 +140,7 @@ class GeolocationPermissionContextAndroid
const GURL& embedding_origin,
bool persist,
ContentSetting content_setting,
+ bool is_one_time, content_settings::LifetimeMode lifetime_option,
LocationSettingsDialogOutcome prompt_outcome);
void FinishNotifyPermissionSet(const PermissionRequestID& id,
@@ -138,7 +148,9 @@ class GeolocationPermissionContextAndroid
const GURL& embedding_origin,
BrowserPermissionCallback callback,
bool persist,
- ContentSetting content_setting);
+ ContentSetting content_setting,
+ bool is_one_time,
+ content_settings::LifetimeMode lifetime_option);
std::unique_ptr<LocationSettings> location_settings_;
diff --git a/components/permissions/permission_context_base.cc b/components/permissions/permission_context_base.cc
--- a/components/permissions/permission_context_base.cc
+++ b/components/permissions/permission_context_base.cc
@@ -262,6 +262,16 @@ PermissionContextBase::CreatePermissionRequest(
std::move(delete_callback));
}
+std::unique_ptr<PermissionRequest> PermissionContextBase::CreatePermissionRequest(
+ content::WebContents* web_contents,
+ PermissionRequestData request_data,
+ PermissionRequest::PermissionDecidedCallbackWithLifetime permission_decided_callback,
+ base::OnceClosure delete_callback) const {
+ return std::make_unique<PermissionRequest>(
+ std::move(request_data), std::move(permission_decided_callback),
+ std::move(delete_callback));
+}
+
content::PermissionResult PermissionContextBase::GetPermissionStatus(
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
@@ -506,7 +516,8 @@ void PermissionContextBase::PermissionDecided(const PermissionRequestID& id,
const GURL& embedding_origin,
ContentSetting content_setting,
bool is_one_time,
- bool is_final_decision) {
+ bool is_final_decision,
+ content_settings::LifetimeMode lifetime_option) {
DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
content_setting == CONTENT_SETTING_BLOCK ||
content_setting == CONTENT_SETTING_DEFAULT);
@@ -521,13 +532,14 @@ void PermissionContextBase::PermissionDecided(const PermissionRequestID& id,
// missing if a permission prompt was preignored and we already notified an
// origin about it.
if (request->second.second) {
- NotifyPermissionSet(id, requesting_origin, embedding_origin,
+ NotifyPermissionSetWithLifetime(id, requesting_origin, embedding_origin,
std::move(request->second.second), persist,
- content_setting, is_one_time, is_final_decision);
+ content_setting, is_one_time, is_final_decision,
+ lifetime_option);
} else {
- NotifyPermissionSet(id, requesting_origin, embedding_origin,
+ NotifyPermissionSetWithLifetime(id, requesting_origin, embedding_origin,
base::DoNothing(), persist, content_setting,
- is_one_time, is_final_decision);
+ is_one_time, is_final_decision, lifetime_option);
}
}
@@ -573,11 +585,27 @@ void PermissionContextBase::NotifyPermissionSet(
ContentSetting content_setting,
bool is_one_time,
bool is_final_decision) {
+ DCHECK(is_one_time == false);
+ NotifyPermissionSetWithLifetime(id, requesting_origin, embedding_origin, std::move(callback),
+ persist, content_setting, is_one_time, is_final_decision,
+ content_settings::LifetimeMode::Always);
+}
+
+void PermissionContextBase::NotifyPermissionSetWithLifetime(
+ const PermissionRequestID& id,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin,
+ BrowserPermissionCallback callback,
+ bool persist,
+ ContentSetting content_setting,
+ bool is_one_time,
+ bool is_final_decision,
+ content_settings::LifetimeMode lifetime_option) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (persist) {
UpdateContentSetting(requesting_origin, embedding_origin, content_setting,
- is_one_time);
+ is_one_time, lifetime_option);
}
if (is_final_decision) {
@@ -607,6 +635,15 @@ void PermissionContextBase::UpdateContentSetting(const GURL& requesting_origin,
const GURL& embedding_origin,
ContentSetting content_setting,
bool is_one_time) {
+ UpdateContentSetting(requesting_origin, embedding_origin, content_setting,
+ is_one_time, content_settings::LifetimeMode::Always);
+}
+
+void PermissionContextBase::UpdateContentSetting(const GURL& requesting_origin,
+ const GURL& embedding_origin,
+ ContentSetting content_setting,
+ bool is_one_time,
+ content_settings::LifetimeMode lifetime_option) {
DCHECK_EQ(requesting_origin, requesting_origin.DeprecatedGetOriginAsURL());
DCHECK_EQ(embedding_origin, embedding_origin.DeprecatedGetOriginAsURL());
DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
@@ -616,6 +653,8 @@ void PermissionContextBase::UpdateContentSetting(const GURL& requesting_origin,
constraints.set_session_model(is_one_time
? content_settings::SessionModel::OneTime
: content_settings::SessionModel::Durable);
+ if (is_one_time)
+ constraints = content_settings::GetConstraintSessionExpiration(lifetime_option);
#if !BUILDFLAG(IS_ANDROID)
if (base::FeatureList::IsEnabled(
diff --git a/components/permissions/permission_context_base.h b/components/permissions/permission_context_base.h
--- a/components/permissions/permission_context_base.h
+++ b/components/permissions/permission_context_base.h
@@ -149,6 +149,15 @@ class PermissionContextBase : public content_settings::Observer {
// Updates stored content setting if persist is set, updates tab indicators
// and runs the callback to finish the request.
+ virtual void NotifyPermissionSetWithLifetime(const PermissionRequestID& id,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin,
+ BrowserPermissionCallback callback,
+ bool persist,
+ ContentSetting content_setting,
+ bool is_one_time,
+ bool is_final_decision,
+ content_settings::LifetimeMode lifetime_option);
virtual void NotifyPermissionSet(const PermissionRequestID& id,
const GURL& requesting_origin,
const GURL& embedding_origin,
@@ -170,6 +179,11 @@ class PermissionContextBase : public content_settings::Observer {
// Store the decided permission as a content setting.
// virtual since the permission might be stored with different restrictions
// (for example for desktop notifications).
+ void UpdateContentSetting(const GURL& requesting_origin,
+ const GURL& embedding_origin,
+ ContentSetting content_setting,
+ bool is_one_time,
+ content_settings::LifetimeMode lifetime_option);
virtual void UpdateContentSetting(const GURL& requesting_origin,
const GURL& embedding_origin,
ContentSetting content_setting,
@@ -200,6 +214,12 @@ class PermissionContextBase : public content_settings::Observer {
PermissionRequest::PermissionDecidedCallback permission_decided_callback,
base::OnceClosure delete_callback) const;
+ virtual std::unique_ptr<PermissionRequest> CreatePermissionRequest(
+ content::WebContents* web_contents,
+ PermissionRequestData request_data,
+ PermissionRequest::PermissionDecidedCallbackWithLifetime permission_decided_callback,
+ base::OnceClosure delete_callback) const;
+
base::ObserverList<permissions::Observer> permission_observers_;
// Set by subclasses to inform the base class that they will handle adding
@@ -222,7 +242,8 @@ class PermissionContextBase : public content_settings::Observer {
const GURL& embedding_origin,
ContentSetting content_setting,
bool is_one_time,
- bool is_final_decision);
+ bool is_final_decision,
+ content_settings::LifetimeMode lifetime_option);
void NotifyObservers(const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
diff --git a/components/permissions/permission_prompt.h b/components/permissions/permission_prompt.h
--- a/components/permissions/permission_prompt.h
+++ b/components/permissions/permission_prompt.h
@@ -65,8 +65,9 @@ class PermissionPrompt {
virtual GURL GetEmbeddingOrigin() const = 0;
virtual void Accept() = 0;
- virtual void AcceptThisTime() = 0;
+ virtual void AcceptThisTime(content_settings::LifetimeMode lifetime_option) = 0;
virtual void Deny() = 0;
+ virtual void DenyThisTime(content_settings::LifetimeMode lifetime_option) = 0;
virtual void Dismiss() = 0;
virtual void Ignore() = 0;
diff --git a/components/permissions/permission_request.cc b/components/permissions/permission_request.cc
--- a/components/permissions/permission_request.cc
+++ b/components/permissions/permission_request.cc
@@ -37,6 +37,14 @@ PermissionRequest::PermissionRequest(
permission_decided_callback_(std::move(permission_decided_callback)),
delete_callback_(std::move(delete_callback)) {}
+PermissionRequest::PermissionRequest(
+ PermissionRequestData request_data,
+ PermissionDecidedCallbackWithLifetime permission_decided_callback,
+ base::OnceClosure delete_callback)
+ : data_(std::move(request_data)),
+ permission_decided_callback_withlifetime_(std::move(permission_decided_callback)),
+ delete_callback_(std::move(delete_callback)) {}
+
PermissionRequest::~PermissionRequest() {
DCHECK(delete_callback_.is_null());
}
@@ -276,19 +284,37 @@ bool PermissionRequest::ShouldUseTwoOriginPrompt() const {
permissions::features::kPermissionStorageAccessAPI);
}
-void PermissionRequest::PermissionGranted(bool is_one_time) {
+void PermissionRequest::PermissionGranted(bool is_one_time,
+ content_settings::LifetimeMode lifetime_option) {
+ if (permission_decided_callback_withlifetime_) {
+ std::move(permission_decided_callback_withlifetime_)
+ .Run(CONTENT_SETTING_ALLOW, is_one_time, /*is_final_decision=*/true, lifetime_option);
+ return;
+ }
std::move(permission_decided_callback_)
.Run(CONTENT_SETTING_ALLOW, is_one_time,
/*is_final_decision=*/true);
}
-void PermissionRequest::PermissionDenied() {
+void PermissionRequest::PermissionDenied(bool is_one_time,
+ content_settings::LifetimeMode lifetime_option) {
+ if (permission_decided_callback_withlifetime_) {
+ std::move(permission_decided_callback_withlifetime_)
+ .Run(CONTENT_SETTING_BLOCK, is_one_time, /*is_final_decision=*/true, lifetime_option);
+ return;
+ }
std::move(permission_decided_callback_)
.Run(CONTENT_SETTING_BLOCK, /*is_one_time=*/false,
/*is_final_decision=*/true);
}
void PermissionRequest::Cancelled(bool is_final_decision) {
+ if (permission_decided_callback_withlifetime_) {
+ std::move(permission_decided_callback_withlifetime_)
+ .Run(CONTENT_SETTING_DEFAULT, false, is_final_decision,
+ content_settings::LifetimeMode::Always);
+ return;
+ }
permission_decided_callback_.Run(CONTENT_SETTING_DEFAULT,
/*is_one_time=*/false, is_final_decision);
}
diff --git a/components/permissions/permission_request.h b/components/permissions/permission_request.h
--- a/components/permissions/permission_request.h
+++ b/components/permissions/permission_request.h
@@ -44,6 +44,11 @@ class PermissionRequest {
bool /*is_one_time*/,
bool /*is_final_decision*/)>;
+ using PermissionDecidedCallbackWithLifetime =
+ base::OnceCallback<void(ContentSetting /*result*/, bool /*is_one_time*/,
+ bool /*is_final_decision*/,
+ content_settings::LifetimeMode /*lifetime_option*/)>;
+
// `permission_decided_callback` is called when the permission request is
// resolved by the user (see comment on PermissionDecidedCallback above).
// `delete_callback` is called when the permission request is no longer needed
@@ -63,6 +68,10 @@ class PermissionRequest {
PermissionDecidedCallback permission_decided_callback,
base::OnceClosure delete_callback);
+ PermissionRequest(PermissionRequestData request_data,
+ PermissionDecidedCallbackWithLifetime permission_decided_callback,
+ base::OnceClosure delete_callback);
+
PermissionRequest(const PermissionRequest&) = delete;
PermissionRequest& operator=(const PermissionRequest&) = delete;
@@ -128,10 +137,10 @@ class PermissionRequest {
// If |is_one_time| is true the permission will last until all tabs of
// |origin| are closed or navigated away from, and then the permission will
// automatically expire after 1 day.
- void PermissionGranted(bool is_one_time);
+ void PermissionGranted(bool is_one_time, content_settings::LifetimeMode lifetime_option);
// Called when the user has denied the requested permission.
- void PermissionDenied();
+ void PermissionDenied(bool is_one_time, content_settings::LifetimeMode lifetime_option);
// Called when the user has cancelled the permission request. This
// corresponds to a denial, but is segregated in case the context needs to
@@ -174,6 +183,9 @@ class PermissionRequest {
// Called once a decision is made about the permission.
PermissionDecidedCallback permission_decided_callback_;
+ // Called once a decision is made about the permission (with lifetime option).
+ PermissionDecidedCallbackWithLifetime permission_decided_callback_withlifetime_;
+
// Called when the request is no longer in use so it can be deleted by the
// caller.
base::OnceClosure delete_callback_;
diff --git a/components/permissions/permission_request_manager.cc b/components/permissions/permission_request_manager.cc
--- a/components/permissions/permission_request_manager.cc
+++ b/components/permissions/permission_request_manager.cc
@@ -155,7 +155,7 @@ void PermissionRequestManager::AddRequest(
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDenyPermissionPrompts)) {
- request->PermissionDenied();
+ request->PermissionDenied(/*is_one_time*/false, content_settings::LifetimeMode::Always);
request->RequestFinished();
return;
}
@@ -231,7 +231,7 @@ void PermissionRequestManager::AddRequest(
if (auto_approval_origin) {
if (url::Origin::Create(request->requesting_origin()) ==
auto_approval_origin.value()) {
- request->PermissionGranted(/*is_one_time=*/false);
+ request->PermissionGranted(/*is_one_time=*/false, content_settings::LifetimeMode::Always);
}
request->RequestFinished();
return;
@@ -568,7 +568,8 @@ void PermissionRequestManager::Accept() {
(*requests_iter)->request_type(),
PermissionAction::GRANTED);
PermissionGrantedIncludingDuplicates(*requests_iter,
- /*is_one_time=*/false);
+ /*is_one_time=*/false,
+ content_settings::LifetimeMode::Always);
#if !BUILDFLAG(IS_ANDROID)
absl::optional<ContentSettingsType> content_settings_type =
@@ -586,7 +587,7 @@ void PermissionRequestManager::Accept() {
FinalizeCurrentRequests(PermissionAction::GRANTED);
}
-void PermissionRequestManager::AcceptThisTime() {
+void PermissionRequestManager::AcceptThisTime(content_settings::LifetimeMode mode) {
if (ignore_callbacks_from_prompt_)
return;
DCHECK(view_);
@@ -597,7 +598,8 @@ void PermissionRequestManager::AcceptThisTime() {
(*requests_iter)->request_type(),
PermissionAction::GRANTED_ONCE);
PermissionGrantedIncludingDuplicates(*requests_iter,
- /*is_one_time=*/true);
+ /*is_one_time=*/true,
+ mode);
}
NotifyRequestDecided(PermissionAction::GRANTED_ONCE);
@@ -605,6 +607,15 @@ void PermissionRequestManager::AcceptThisTime() {
}
void PermissionRequestManager::Deny() {
+ Deny_(/*is_one_time*/ false, content_settings::LifetimeMode::Always);
+}
+
+void PermissionRequestManager::DenyThisTime(content_settings::LifetimeMode mode) {
+ Deny_(/*is_one_time*/ true, mode);
+}
+
+void PermissionRequestManager::Deny_(bool is_one_time,
+ content_settings::LifetimeMode lifetime_option) {
if (ignore_callbacks_from_prompt_)
return;
DCHECK(view_);
@@ -627,7 +638,7 @@ void PermissionRequestManager::Deny() {
StorePermissionActionForUMA((*requests_iter)->requesting_origin(),
(*requests_iter)->request_type(),
PermissionAction::DENIED);
- PermissionDeniedIncludingDuplicates(*requests_iter);
+ PermissionDeniedIncludingDuplicates(*requests_iter, is_one_time, lifetime_option);
}
NotifyRequestDecided(PermissionAction::DENIED);
@@ -1165,32 +1176,32 @@ PermissionRequestManager::VisitDuplicateRequests(
void PermissionRequestManager::PermissionGrantedIncludingDuplicates(
PermissionRequest* request,
- bool is_one_time) {
+ bool is_one_time, content_settings::LifetimeMode lifetime_option) {
DCHECK_EQ(1ul, base::ranges::count(requests_, request) +
pending_permission_requests_.Count(request))
<< "Only requests in [pending_permission_]requests_ can have duplicates";
- request->PermissionGranted(is_one_time);
+ request->PermissionGranted(is_one_time, lifetime_option);
VisitDuplicateRequests(
base::BindRepeating(
- [](bool is_one_time,
+ [](bool is_one_time, content_settings::LifetimeMode lifetime_option,
const base::WeakPtr<PermissionRequest>& weak_request) {
- weak_request->PermissionGranted(is_one_time);
+ weak_request->PermissionGranted(is_one_time, lifetime_option);
},
- is_one_time),
+ is_one_time, lifetime_option),
request);
}
void PermissionRequestManager::PermissionDeniedIncludingDuplicates(
- PermissionRequest* request) {
+ PermissionRequest* request, bool is_one_time, content_settings::LifetimeMode lifetime_option) {
DCHECK_EQ(1ul, base::ranges::count(requests_, request) +
pending_permission_requests_.Count(request))
<< "Only requests in [pending_permission_]requests_ can have duplicates";
- request->PermissionDenied();
+ request->PermissionDenied(is_one_time, lifetime_option);
VisitDuplicateRequests(
base::BindRepeating(
- [](const base::WeakPtr<PermissionRequest>& weak_request) {
- weak_request->PermissionDenied();
- }),
+ [](bool is_one_time, content_settings::LifetimeMode lifetime_option, const base::WeakPtr<PermissionRequest>& weak_request) {
+ weak_request->PermissionDenied(is_one_time, lifetime_option);
+ }, is_one_time, lifetime_option),
request);
}
@@ -1439,7 +1450,7 @@ void PermissionRequestManager::LogWarningToConsole(const char* message) {
void PermissionRequestManager::DoAutoResponseForTesting() {
switch (auto_response_for_test_) {
case ACCEPT_ONCE:
- AcceptThisTime();
+ AcceptThisTime(content_settings::LifetimeMode::OnlyThisTime);
break;
case ACCEPT_ALL:
Accept();
diff --git a/components/permissions/permission_request_manager.h b/components/permissions/permission_request_manager.h
--- a/components/permissions/permission_request_manager.h
+++ b/components/permissions/permission_request_manager.h
@@ -159,8 +159,10 @@ class PermissionRequestManager
GURL GetRequestingOrigin() const override;
GURL GetEmbeddingOrigin() const override;
void Accept() override;
- void AcceptThisTime() override;
+ void AcceptThisTime(content_settings::LifetimeMode lifetime_option) override;
void Deny() override;
+ void Deny_(bool is_one_time, content_settings::LifetimeMode lifetime_option);
+ void DenyThisTime(content_settings::LifetimeMode lifetime_option) override;
void Dismiss() override;
void Ignore() override;
void OpenHelpCenterLink(const ui::Event& event) override;
@@ -362,9 +364,12 @@ class PermissionRequestManager
// Calls PermissionGranted on a request and all its duplicates.
void PermissionGrantedIncludingDuplicates(PermissionRequest* request,
- bool is_one_time);
+ bool is_one_time,
+ content_settings::LifetimeMode lifetime_option);
// Calls PermissionDenied on a request and all its duplicates.
- void PermissionDeniedIncludingDuplicates(PermissionRequest* request);
+ void PermissionDeniedIncludingDuplicates(PermissionRequest* request,
+ bool is_one_time,
+ content_settings::LifetimeMode lifetime_option);
// Calls Cancelled on a request and all its duplicates.
void CancelledIncludingDuplicates(PermissionRequest* request,
bool is_final_decision = true);
--
2.25.1