Commit 7a5e2f3c authored by Christian Dullweber's avatar Christian Dullweber Committed by Commit Bot

Add CookiesPreference in PageInfo

Add preference for a cookies view in page info.

Screenshot: https://crbug.com/1077766#c16
Bug: 1077766
Change-Id: I197782a86b9cb5bd608e4ce036bed99ac463706f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2274623Reviewed-by: default avatarTed Choc <tedchoc@chromium.org>
Reviewed-by: default avatarEhimare Okoyomon <eokoyomon@chromium.org>
Reviewed-by: default avatarNatalie Chouinard <chouinard@chromium.org>
Reviewed-by: default avatarPeter Conn <peconn@chromium.org>
Commit-Queue: Christian Dullweber <dullweber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#787682}
parent 42f9f0bb
......@@ -13,6 +13,7 @@ import static org.junit.Assert.assertNotNull;
import static org.chromium.components.content_settings.PrefNames.BLOCK_THIRD_PARTY_COOKIES;
import android.os.Build;
import android.view.View;
import androidx.test.filters.MediumTest;
......@@ -237,5 +238,20 @@ public class PageInfoViewTest {
mRenderTestRule.render(getPageInfoView(), "PageInfo_SecureWebsiteV2");
}
/**
* Tests the new PageInfo UI on a secure website.
*/
@Test
@MediumTest
@Feature({"RenderTest"})
@Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
public void testShowCookiesSubpage() throws IOException {
setThirdPartyCookieBlocking(true);
loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath));
View dialog = (View) getPageInfoView().getParent();
onView(withId(R.id.page_info_cookies_row)).perform(click());
mRenderTestRule.render(dialog, "PageInfo_CookiesSubpage");
}
// TODO(1071762): Add tests for preview pages, offline pages, offline state and other states.
}
......@@ -456,6 +456,20 @@
<message name="IDS_PAGE_INFO_FAST_SITE_SUMMARY" desc="A short summary phrase in the Page Info bubble (which shows when you click the lock icon) that indicates that pages on the current website should load quickly.">
Site is fast
</message>
<message name="IDS_PAGE_INFO_COOKIES_CLEAR" desc="Text on the button to clear cookies for a site.">
Clear cookies
</message>
<message name="IDS_PAGE_INFO_COOKIES_DESCRIPTION" desc="Description in the Page Info UI explaining cookies.">
Cookies and other site data are used to remember you, for example to sign you in or to personalize ads. To manage cookies for all sites, see <ph name="BEGIN_LINK">&lt;link&gt;</ph>Settings<ph name="END_LINK">&lt;/link&gt;</ph>.
</message>
<message name="IDS_PAGE_INFO_COOKIES_BLOCK" desc="Label for a toggle to allow or block third-party cookies for a site.">
Block third-party cookies
</message>
<message name="IDS_PAGE_INFO_COOKIES_IN_USE" desc="Label showing the amount of cookies being used by a site.">
{NUM_SELECTED, plural,
=1 {1 cookie in use}
other {# cookies in use}}
</message>
<message name="IDS_PAGE_INFO_FAST_SITE_MESSAGE" desc="A short paragraph that explains what is meant by labeling the current website as fast.">
This site opens and responds quickly for most people
</message>
......
0cb81b39f83707f165dbd91808566d46dbb0e2d8
\ No newline at end of file
0cb81b39f83707f165dbd91808566d46dbb0e2d8
\ No newline at end of file
0cb81b39f83707f165dbd91808566d46dbb0e2d8
\ No newline at end of file
......@@ -93,6 +93,7 @@ android_resources("java_resources") {
"java/res/drawable-xxxhdpi/plus.png",
"java/res/drawable-xxxhdpi/settings_all_sites.png",
"java/res/drawable-xxxhdpi/top_round.9.png",
"java/res/drawable/ic_eye_crossed.xml",
"java/res/drawable/ic_help_and_feedback.xml",
"java/res/drawable/ic_offline_pin_24dp_on_light_bg.xml",
"java/res/drawable/ic_security_grey.xml",
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M11.86,9.5l2.64,2.63L14.5,12A2.5,2.5 0,0 0,12 9.5h-0.14zM8.27,10.17l1.3,1.29a2.5,2.5 0,0 0,2.97 2.97l1.3,1.3a4.13,4.13 0,0 1,-5.57 -5.56zM3.67,5.56l1.9,1.9 0.37,0.37A9.86,9.86 0,0 0,2.84 12a9.86,9.86 0,0 0,12.81 5.55l0.36,0.35 2.43,2.43 1.06,-1.05L4.72,4.5 3.67,5.56zM12,7.83a4.17,4.17 0,0 1,3.87 5.69l2.44,2.44A9.87,9.87 0,0 0,21.17 12a9.86,9.86 0,0 0,-12.5 -5.67l1.8,1.8c0.48,-0.19 0.99,-0.3 1.53,-0.3z"
android:fillColor="@color/default_icon_color"/>
</vector>
......@@ -60,6 +60,7 @@ android_resources("java_resources") {
"java/res/values/dimens.xml",
"java/res/values/ids.xml",
"java/res/values/styles.xml",
"java/res/xml/page_info_cookie_preference.xml",
]
custom_package = "org.chromium.components.page_info"
deps = [
......@@ -80,6 +81,7 @@ android_library("java") {
"java/src/org/chromium/components/page_info/PageInfoController.java",
"java/src/org/chromium/components/page_info/PageInfoControllerDelegate.java",
"java/src/org/chromium/components/page_info/PageInfoCookiesController.java",
"java/src/org/chromium/components/page_info/PageInfoCookiesPreference.java",
"java/src/org/chromium/components/page_info/PageInfoDialog.java",
"java/src/org/chromium/components/page_info/PageInfoFeatureList.java",
"java/src/org/chromium/components/page_info/PageInfoMainPageController.java",
......@@ -100,6 +102,7 @@ android_library("java") {
":page_info_action_enum_java",
"//base:base_java",
"//base:jni_java",
"//components/browser_ui/settings/android:java",
"//components/browser_ui/site_settings/android:java",
"//components/content_settings/android:content_settings_enums_java",
"//components/content_settings/android:java",
......@@ -118,6 +121,7 @@ android_library("java") {
"//services/device/public/java:device_feature_list_java",
"//third_party/android_deps:android_support_v7_appcompat_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
"//third_party/android_deps:androidx_preference_preference_java",
"//ui/android:ui_java",
"//url:gurl_java",
]
......
include_rules = [
"+components/browser_ui/settings/android/java",
"+components/browser_ui/settings/android/widget/java",
"+components/browser_ui/site_settings/android/java",
"+components/content_settings/android/java",
"+components/dom_distiller/core/android/java",
......
......@@ -36,9 +36,10 @@
android:id="@+id/subpage_back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"
android:layout_marginStart="-12dp"
android:layout_marginEnd="4dp"
android:minHeight="@dimen/min_touch_target_size"
android:minWidth="@dimen/min_touch_target_size"
android:layout_marginEnd="20dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_arrow_back_white_24dp"
app:tint="@color/default_icon_color" />
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- TODO(crbug.com/1077766): Add link. -->
<org.chromium.components.browser_ui.settings.TextMessagePreference
android:key="cookie_summary"
app:iconSpaceReserved="false"/>
<org.chromium.components.browser_ui.settings.ChromeSwitchPreference
android:key="cookie_switch"
android:persistent="false"
android:title="@string/page_info_cookies_block" />
<org.chromium.components.browser_ui.settings.ChromeBasePreference
android:key="cookie_in_use" />
<org.chromium.components.browser_ui.settings.ButtonPreference
android:key="clear_button"
android:title="@string/page_info_cookies_clear"/>
</PreferenceScreen>
......@@ -293,7 +293,9 @@ public class PageInfoController
new PermissionParamsListBuilder(mContext, mWindowAndroid, mFullUrl, showTitle, this,
mView::setPermissions, mPermissionParamsListBuilderDelegate);
mNativePageInfoController = PageInfoControllerJni.get().init(this, mWebContents);
mCookieBridge = mDelegate.createCookieControlsBridge(this);
mCookieBridge =
mDelegate.createCookieControlsBridge(mIsV2Enabled ? mCookiesController : this);
if (mCookiesController != null) mCookiesController.setCookieControlsBridge(mCookieBridge);
mWebContentsObserver = new WebContentsObserver(webContents) {
@Override
......@@ -492,6 +494,8 @@ public class PageInfoController
@VisibleForTesting
public PageInfoView getPageInfoViewForTesting() {
// Check that this view is active.
assert mView.getParent() != null;
return mView;
}
......@@ -540,19 +544,15 @@ public class PageInfoController
@Override
public void onCookieBlockingStatusChanged(
@CookieControlsStatus int status, @CookieControlsEnforcement int enforcement) {
if (!mIsV2Enabled) {
mView.getCookieControlsView().setCookieBlockingStatus(
status, enforcement != CookieControlsEnforcement.NO_ENFORCEMENT);
}
assert !mIsV2Enabled;
mView.getCookieControlsView().setCookieBlockingStatus(
status, enforcement != CookieControlsEnforcement.NO_ENFORCEMENT);
}
@Override
public void onCookiesCountChanged(int allowedCookies, int blockedCookies) {
if (mIsV2Enabled) {
mCookiesController.onBlockedCookiesCountChanged(blockedCookies);
} else {
mView.getCookieControlsView().setBlockedCookiesCount(blockedCookies);
}
assert !mIsV2Enabled;
mView.getCookieControlsView().setBlockedCookiesCount(blockedCookies);
}
@NativeMethods
......@@ -610,10 +610,8 @@ public class PageInfoController
parent.addView(newView, index);
}
/**
* Switches back to the main page info view.
*/
private void exitSubpage() {
@Override
public void exitSubpage() {
replaceView(mSubpage, mView);
mSubpageController.onSubpageRemoved();
mSubpageController = null;
......
......@@ -7,14 +7,32 @@ package org.chromium.components.page_info;
import android.view.View;
import android.view.ViewGroup;
import androidx.appcompat.app.AppCompatActivity;
import org.chromium.components.browser_ui.site_settings.SiteDataCleaner;
import org.chromium.components.browser_ui.site_settings.Website;
import org.chromium.components.browser_ui.site_settings.WebsiteAddress;
import org.chromium.components.content_settings.CookieControlsBridge;
import org.chromium.components.content_settings.CookieControlsEnforcement;
import org.chromium.components.content_settings.CookieControlsObserver;
import org.chromium.components.embedder_support.util.Origin;
/**
* Class for controlling the page info cookies section.
*/
public class PageInfoCookiesController implements PageInfoSubpageController {
public class PageInfoCookiesController
implements PageInfoSubpageController, CookieControlsObserver {
private PageInfoMainPageController mMainController;
private PageInfoRowView mRowView;
private CookieControlsBridge mBridge;
private String mFullUrl;
private String mTitle;
private PageInfoCookiesPreference mSubPage;
private int mAllowedCookies;
private int mBlockedCookies;
private int mStatus;
private boolean mIsEnforced;
public PageInfoCookiesController(PageInfoMainPageController mainController,
PageInfoRowView rowView, boolean isVisible, String fullUrl) {
......@@ -41,19 +59,69 @@ public class PageInfoCookiesController implements PageInfoSubpageController {
@Override
public View createViewForSubpage(ViewGroup parent) {
// TODO(crbug.com/1077766): Create and set the cookie specific view.
return null;
assert mSubPage == null;
mSubPage = new PageInfoCookiesPreference();
AppCompatActivity host = (AppCompatActivity) mRowView.getContext();
host.getSupportFragmentManager().beginTransaction().add(mSubPage, "FOO").commitNow();
return mSubPage.requireView();
}
@Override
public void onSubPageAttached() {}
public void onSubPageAttached() {
PageInfoCookiesPreference.PageInfoCookiesViewParams params =
new PageInfoCookiesPreference.PageInfoCookiesViewParams();
params.onCheckedChangedCallback = this::onCheckedChangedCallback;
params.onClearCallback = this::clearData;
mSubPage.setParams(params);
// TODO(crbug.com/1077766): Get storage size.
mSubPage.setCookiesCount(mAllowedCookies, mBlockedCookies);
mSubPage.setCookieBlockingStatus(mStatus, mIsEnforced);
}
private void onCheckedChangedCallback(boolean state) {
mBridge.setThirdPartyCookieBlockingEnabledForSite(state);
}
private void clearData() {
String origin = Origin.createOrThrow(mFullUrl).toString();
WebsiteAddress address = WebsiteAddress.create(origin);
new SiteDataCleaner().clearData(mMainController.getBrowserContext(),
new Website(address, address), mMainController::exitSubpage);
}
@Override
public void onSubpageRemoved() {}
public void onSubpageRemoved() {
AppCompatActivity host = (AppCompatActivity) mRowView.getContext();
host.getSupportFragmentManager().beginTransaction().remove(mSubPage).commitNow();
mSubPage = null;
}
public void onBlockedCookiesCountChanged(int blockedCookies) {
String subtitle = mRowView.getContext().getResources().getQuantityString(
R.plurals.cookie_controls_blocked_cookies, blockedCookies, blockedCookies);
@Override
public void onCookiesCountChanged(int allowedCookies, int blockedCookies) {
mAllowedCookies = allowedCookies;
mBlockedCookies = blockedCookies;
String subtitle = blockedCookies > 0
? mRowView.getContext().getResources().getQuantityString(
R.plurals.cookie_controls_blocked_cookies, blockedCookies, blockedCookies)
: mRowView.getContext().getResources().getQuantityString(
R.plurals.page_info_cookies_in_use, allowedCookies, allowedCookies);
mRowView.updateSubtitle(subtitle);
if (mSubPage != null) {
mSubPage.setCookiesCount(allowedCookies, blockedCookies);
}
}
@Override
public void onCookieBlockingStatusChanged(int status, int enforcement) {
mStatus = status;
mIsEnforced = enforcement != CookieControlsEnforcement.NO_ENFORCEMENT;
if (mSubPage != null) {
mSubPage.setCookieBlockingStatus(mStatus, mIsEnforced);
}
}
public void setCookieControlsBridge(CookieControlsBridge cookieBridge) {
mBridge = cookieBridge;
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.components.page_info;
import android.os.Bundle;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import org.chromium.base.Callback;
import org.chromium.components.browser_ui.settings.ButtonPreference;
import org.chromium.components.browser_ui.settings.ChromeBasePreference;
import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
import org.chromium.components.browser_ui.settings.SettingsUtils;
import org.chromium.components.content_settings.CookieControlsStatus;
import org.chromium.ui.text.NoUnderlineClickableSpan;
import org.chromium.ui.text.SpanApplier;
/**
* View showing a toggle and a description for third-party cookie blocking for a site.
*/
public class PageInfoCookiesPreference extends PreferenceFragmentCompat {
private static final String COOKIE_SUMMARY_PREFERENCE = "cookie_summary";
private static final String COOKIE_SWITCH_PREFERENCE = "cookie_switch";
private static final String COOKIE_IN_USE_PREFERENCE = "cookie_in_use";
private static final String CLEAR_BUTTON_PREFERENCE = "clear_button";
private PageInfoCookiesViewParams mParams;
private ChromeSwitchPreference mCookieSwitch;
private ChromeBasePreference mCookieInUse;
/** Parameters to configure the cookie controls view. */
public static class PageInfoCookiesViewParams {
// Called when the toggle controlling third-party cookie blocking changes.
public Callback<Boolean> onCheckedChangedCallback;
public Runnable onClearCallback;
}
@Override
public void onCreatePreferences(Bundle bundle, String s) {
SettingsUtils.addPreferencesFromResource(this, R.xml.page_info_cookie_preference);
Preference cookieSummary = findPreference(COOKIE_SUMMARY_PREFERENCE);
// TODO(crbug.com/1077766): Show cookie settings.
NoUnderlineClickableSpan linkSpan =
new NoUnderlineClickableSpan(getResources(), view -> {});
cookieSummary.setSummary(
SpanApplier.applySpans(getString(R.string.page_info_cookies_description),
new SpanApplier.SpanInfo("<link>", "</link>", linkSpan)));
// TODO(crbug.com/1077766): Set a ManagedPreferenceDelegate?
mCookieSwitch = findPreference(COOKIE_SWITCH_PREFERENCE);
mCookieSwitch.setOnPreferenceChangeListener((preference, newValue) -> {
mParams.onCheckedChangedCallback.onResult((Boolean) newValue);
return true;
});
mCookieInUse = findPreference(COOKIE_IN_USE_PREFERENCE);
mCookieInUse.setIcon(
SettingsUtils.getTintedIcon(getContext(), R.drawable.permission_cookie));
ButtonPreference clearButton = findPreference(CLEAR_BUTTON_PREFERENCE);
clearButton.setOnPreferenceClickListener(preference -> {
mParams.onClearCallback.run();
return true;
});
}
public void setParams(PageInfoCookiesViewParams params) {
mParams = params;
}
public void setCookieBlockingStatus(@CookieControlsStatus int status, boolean isEnforced) {
boolean visible = status != CookieControlsStatus.DISABLED;
boolean enabled = status == CookieControlsStatus.ENABLED;
mCookieSwitch.setVisible(visible);
if (visible) {
mCookieSwitch.setIcon(
SettingsUtils.getTintedIcon(getContext(), R.drawable.ic_eye_crossed));
mCookieSwitch.setChecked(enabled);
mCookieSwitch.setEnabled(!isEnforced);
}
}
public void setCookiesCount(int allowedCookies, int blockedCookies) {
mCookieSwitch.setSummary(getContext().getResources().getQuantityString(
R.plurals.cookie_controls_blocked_cookies, blockedCookies, blockedCookies));
mCookieInUse.setTitle(getContext().getResources().getQuantityString(
R.plurals.page_info_cookies_in_use, allowedCookies, allowedCookies));
}
}
......@@ -16,6 +16,11 @@ public interface PageInfoMainPageController {
*/
void launchSubpage(PageInfoSubpageController controller);
/**
* Switches back to the main page info view.
*/
void exitSubpage();
/**
* @return A BrowserContext for this dialog.
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment