diff --git a/DEPS b/DEPS index 170b0a3..940b8bf 100644 --- a/DEPS +++ b/DEPS
@@ -394,7 +394,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': 'd240b7de4d30af0769390eea62a27c1e648e8401', + 'devtools_frontend_revision': '646e7ba054335255c4186c6be09fee796b518b48', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -1609,7 +1609,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '722cdc7d46bd7c87d9b93b991d5ae1cc55205a0e', + '2f030b8b2858ba5b64842bf5a6268933929fddec', 'condition': 'checkout_android and checkout_src_internal', },
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileGroup.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileGroup.java index f61d02d..ff114ecb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileGroup.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileGroup.java
@@ -269,8 +269,6 @@ private final Observer mObserver; private final TileRenderer mTileRenderer; private final CustomTileModificationDelegate mCustomTileModificationDelegate; - // Used for TileInteractionDelegateImpl. - private final int mPrerenderDelay; /** * Tracks the tasks currently in flight. @@ -309,7 +307,6 @@ mTileGroupDelegate, mTileDragDelegate, mCustomTileModificationDelegate, - mPrerenderDelay, tile, view); } @@ -359,8 +356,6 @@ mOfflineModelObserver = new OfflineModelObserver(offlinePageBridge); mUiDelegate.addDestructionObserver(mOfflineModelObserver); mCustomTileModificationDelegate = new CustomTileModificationDelegateImpl(); - - mPrerenderDelay = 0; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileInteractionDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileInteractionDelegateImpl.java index f6e6082..270f97f1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileInteractionDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TileInteractionDelegateImpl.java
@@ -42,7 +42,6 @@ private final TileGroup.Delegate mTileGroupDelegate; private final TileDragDelegate mTileDragDelegate; private final TileGroup.CustomTileModificationDelegate mCustomTileModificationDelegate; - private final int mPrerenderDelay; private final Tile mTile; private final AndroidPrerenderManager mAndroidPrerenderManager; @@ -57,14 +56,12 @@ TileGroup.Delegate tileGroupDelegate, TileDragDelegate tileDragDelegate, TileGroup.CustomTileModificationDelegate customTileModificationDelegate, - int prerenderDelay, Tile tile, View view) { mContextMenuManager = contextMenuManager; mTileGroupDelegate = tileGroupDelegate; mTileDragDelegate = tileDragDelegate; mCustomTileModificationDelegate = customTileModificationDelegate; - mPrerenderDelay = prerenderDelay; mTile = tile; view.setOnClickListener(this); @@ -105,7 +102,7 @@ } mScheduldedPrerenderingUrl = null; }); - PostTask.postDelayedTask(TaskTraits.UI_DEFAULT, mPrerenderRunnable, mPrerenderDelay); + PostTask.postDelayedTask(TaskTraits.UI_DEFAULT, mPrerenderRunnable, 0); } // This function cancels scheduled prerendering or calls stopPrerendering to stop stale
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionUpdateMessageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionUpdateMessageTest.java index 46c1286..21753db9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionUpdateMessageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionUpdateMessageTest.java
@@ -29,12 +29,9 @@ import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.browser.LocationSettingsTestUtil; -import org.chromium.components.browser_ui.site_settings.GeolocationSetting; -import org.chromium.components.browser_ui.site_settings.PermissionInfo; import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridgeJni; 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.messages.MessageDispatcher; import org.chromium.components.messages.MessageDispatcherProvider; import org.chromium.components.messages.MessageIdentifier; @@ -355,19 +352,6 @@ final var windowAndroid = mActivityTestRule.getActivity().getWindowAndroid(); final String locationUrl = mTestServer.getURL(GEOLOCATION_PAGE); - final PermissionInfo geolocationSettings = - ThreadUtils.runOnUiThreadBlocking( - new Callable<>() { - @Override - public PermissionInfo call() { - return new PermissionInfo( - getGeolocationType(), - locationUrl, - null, - /* isEmbargoed= */ false, - SessionModel.DURABLE); - } - }); mActivityTestRule .getActivity() @@ -380,22 +364,7 @@ LocationSettingsTestUtil.setSystemLocationSettingEnabled(true); try { - ThreadUtils.runOnUiThreadBlocking( - () -> { - if (geolocationSettings.getContentSettingsType() - == ContentSettingsType.GEOLOCATION_WITH_OPTIONS) { - geolocationSettings.setGeolocationSetting( - ProfileManager.getLastUsedRegularProfile(), - new GeolocationSetting( - ContentSettingValues.ALLOW, - ContentSettingValues.ALLOW)); - - } else { - geolocationSettings.setContentSetting( - ProfileManager.getLastUsedRegularProfile(), - ContentSettingValues.ALLOW); - } - }); + setNativeContentSetting(getGeolocationType(), locationUrl, ContentSettingValues.ALLOW); mActivityTestRule.loadUrl(mTestServer.getURL(GEOLOCATION_PAGE)); CriteriaHelper.pollUiThread( () -> { @@ -435,11 +404,8 @@ Matchers.is(1)); }); } finally { - ThreadUtils.runOnUiThreadBlocking( - () -> - geolocationSettings.setContentSetting( - ProfileManager.getLastUsedRegularProfile(), - ContentSettingValues.DEFAULT)); + setNativeContentSetting( + getGeolocationType(), locationUrl, ContentSettingValues.DEFAULT); } } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SingleWebsiteSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SingleWebsiteSettingsTest.java index 35743022..f69724b5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SingleWebsiteSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SingleWebsiteSettingsTest.java
@@ -10,18 +10,23 @@ import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription; +import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; import static com.google.common.truth.Truth.assertThat; import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.mockito.Mockito.when; +import androidx.preference.Preference; import androidx.test.filters.SmallTest; -import org.junit.Assert; +import org.chromium.chrome.test.util.browser.LocationSettingsTestUtil; import org.junit.Assume; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,12 +47,15 @@ import org.chromium.chrome.browser.profiles.ProfileManager; import org.chromium.chrome.browser.settings.SettingsActivity; import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; +import org.chromium.chrome.test.R; import org.chromium.chrome.test.transit.AutoResetCtaTransitTestRule; import org.chromium.chrome.test.transit.ChromeTransitTestRules; import org.chromium.components.browser_ui.settings.ChromeSwitchPreference; import org.chromium.components.browser_ui.site_settings.ChosenObjectInfo; import org.chromium.components.browser_ui.site_settings.ContentSettingException; import org.chromium.components.browser_ui.site_settings.FileEditingInfo; +import org.chromium.components.browser_ui.site_settings.GeolocationSetting; +import org.chromium.components.browser_ui.site_settings.PermissionInfo; import org.chromium.components.browser_ui.site_settings.SingleWebsiteSettings; import org.chromium.components.browser_ui.site_settings.SiteSettingsDelegate; import org.chromium.components.browser_ui.site_settings.SiteSettingsUtil; @@ -57,6 +65,9 @@ import org.chromium.components.content_settings.ContentSettingValues; import org.chromium.components.content_settings.ContentSettingsType; import org.chromium.components.content_settings.ProviderType; +import org.chromium.components.content_settings.SessionModel; +import org.chromium.components.permissions.PermissionsAndroidFeatureList; +import org.chromium.components.permissions.PermissionsAndroidFeatureMap; import org.chromium.media.MediaFeatures; import org.chromium.url.GURL; @@ -81,17 +92,23 @@ @Mock private SiteSettingsDelegate mSiteSettingsDelegate; + @Before + public void setUp() { + LocationSettingsTestUtil.setSystemLocationSettingEnabled(true); + } + /** A provider supplying params for {@link #testExceptionToggleShowing}. */ public static class SingleWebsiteSettingsParams implements ParameterProvider { @Override public Iterable<ParameterSet> getParameters() { ArrayList<ParameterSet> testCases = new ArrayList<>(); for (@ContentSettingsType.EnumType - int contentSettings : SiteSettingsUtil.SETTINGS_ORDER) { - int enabled = SingleWebsiteSettings.getEnabledValue(contentSettings); - testCases.add(createParameterSet("Enabled_", contentSettings, enabled)); + int contentSettingsType : SiteSettingsUtil.SETTINGS_ORDER) { + int enabled = SingleWebsiteSettings.getEnabledValue(contentSettingsType); + testCases.add(createParameterSet("Enabled_", contentSettingsType, enabled)); testCases.add( - createParameterSet("Block_", contentSettings, ContentSettingValues.BLOCK)); + createParameterSet( + "Block_", contentSettingsType, ContentSettingValues.BLOCK)); } return testCases; } @@ -108,6 +125,17 @@ // SingleWebsiteSettings#setUpNotificationsPreference Assume.assumeFalse(contentSettingsType == ContentSettingsType.NOTIFICATIONS); + var approxGeoEnabled = + PermissionsAndroidFeatureMap.isEnabled( + PermissionsAndroidFeatureList.APPROXIMATE_GEOLOCATION_PERMISSION); + if (contentSettingsType == ContentSettingsType.GEOLOCATION && approxGeoEnabled) { + return; + } + if (contentSettingsType == ContentSettingsType.GEOLOCATION_WITH_OPTIONS + && !approxGeoEnabled) { + return; + } + new SingleExceptionTestCase(contentSettingsType, contentSettingValue).run(); } @@ -123,7 +151,7 @@ () -> { SingleWebsiteSettings websitePreferences = (SingleWebsiteSettings) settingsActivity.getMainFragment(); - Assert.assertNotNull( + assertNotNull( "Notification Preference not found.", websitePreferences.findPreference( SingleWebsiteSettings.getPreferenceKey( @@ -135,6 +163,101 @@ @Test @SmallTest + @EnableFeatures(PermissionsAndroidFeatureList.APPROXIMATE_GEOLOCATION_PERMISSION) + public void testGeolocationPermission() { + GeolocationSetting allowSetting = + new GeolocationSetting(ContentSettingValues.ALLOW, ContentSettingValues.ALLOW); + GeolocationSetting blockSetting = + new GeolocationSetting(ContentSettingValues.BLOCK, ContentSettingValues.BLOCK); + runGeolocationTest(allowSetting, blockSetting, "Allowed", "Blocked"); + } + + @Test + @SmallTest + @EnableFeatures(PermissionsAndroidFeatureList.APPROXIMATE_GEOLOCATION_PERMISSION) + public void testApproximateGeolocationPermission() { + GeolocationSetting allowSetting = + new GeolocationSetting(ContentSettingValues.ALLOW, ContentSettingValues.BLOCK); + GeolocationSetting blockSetting = + new GeolocationSetting(ContentSettingValues.BLOCK, ContentSettingValues.BLOCK); + runGeolocationTest(allowSetting, blockSetting, "Allowed • Approximate", "Blocked"); + } + + @Test + @SmallTest + @EnableFeatures(PermissionsAndroidFeatureList.APPROXIMATE_GEOLOCATION_PERMISSION) + public void testOneTimeApproximateGeolocationPermission() { + GeolocationSetting allowSetting = + new GeolocationSetting(ContentSettingValues.ALLOW, ContentSettingValues.BLOCK); + GeolocationSetting askSetting = + new GeolocationSetting(ContentSettingValues.ASK, ContentSettingValues.ASK); + + Website website = + createWebsiteWithGeolocationPermission(allowSetting, SessionModel.ONE_TIME); + SettingsActivity settingsActivity = + SiteSettingsTestUtils.startSingleWebsitePreferences(website); + var websitePreferences = (SingleWebsiteSettings) settingsActivity.getMainFragment(); + + // Check initial state + String preferenceKey = + SingleWebsiteSettings.getPreferenceKey( + ContentSettingsType.GEOLOCATION_WITH_OPTIONS); + Preference preference = websitePreferences.findPreference(preferenceKey); + assertNotNull("Geolocation Preference not found.", preference); + assertEquals("Allowed this time • Approximate", preference.getSummary()); + assertEquals(allowSetting, getGeolocationSetting(website)); + + // Delete one time permission. + onView(withId(R.id.image_view_widget)).perform(click()); + assertNull(websitePreferences.findPreference(preferenceKey)); + assertEquals(askSetting, getGeolocationSetting(website)); + + settingsActivity.finish(); + } + + private static void runGeolocationTest( + GeolocationSetting allowSetting, + GeolocationSetting blockSetting, + String allowedText, + String blockedText) { + Website website = + createWebsiteWithGeolocationPermission(allowSetting, SessionModel.DURABLE); + SettingsActivity settingsActivity = + SiteSettingsTestUtils.startSingleWebsitePreferences(website); + var websitePreferences = (SingleWebsiteSettings) settingsActivity.getMainFragment(); + + // Check initial state + String preferenceKey = + SingleWebsiteSettings.getPreferenceKey( + ContentSettingsType.GEOLOCATION_WITH_OPTIONS); + Preference preference = websitePreferences.findPreference(preferenceKey); + assertNotNull("Geolocation Preference not found.", preference); + assertEquals(allowedText, preference.getSummary()); + assertEquals(allowSetting, getGeolocationSetting(website)); + + // Change to block. + onView(withText(containsString("Location"))).perform(click()); + assertEquals(blockedText, preference.getSummary()); + assertEquals(blockSetting, getGeolocationSetting(website)); + + // Change back to allow. + onView(withText(containsString("Location"))).perform(click()); + assertEquals(allowedText, preference.getSummary()); + assertEquals(allowSetting, getGeolocationSetting(website)); + + settingsActivity.finish(); + } + + private static GeolocationSetting getGeolocationSetting(Website website) { + return ThreadUtils.runOnUiThreadBlocking( + () -> { + return website.getPermissionInfo(ContentSettingsType.GEOLOCATION_WITH_OPTIONS) + .getGeolocationSetting(ProfileManager.getLastUsedRegularProfile()); + }); + } + + @Test + @SmallTest public void testDesktopSiteException() { SettingsActivity settingsActivity = SiteSettingsTestUtils.startSingleWebsitePreferences( @@ -145,7 +268,7 @@ () -> { var websitePreferences = (SingleWebsiteSettings) settingsActivity.getMainFragment(); - Assert.assertNotNull( + assertNotNull( "Desktop site preference should be present.", websitePreferences.findPreference( SingleWebsiteSettings.getPreferenceKey( @@ -289,7 +412,7 @@ @ContentSettingsType.EnumType int contentSettingsType, @ContentSettingValues int contentSettingValue) { String prefKey = SingleWebsiteSettings.getPreferenceKey(contentSettingsType); - Assert.assertNotNull( + assertNotNull( "Preference key is missing for ContentSettingsType <" + contentSettingsType + ">.", prefKey); @@ -313,9 +436,17 @@ } public void run() { - Website website = - createWebsiteWithContentSettingException( - mContentSettingsType, mContentSettingValue); + Website website; + if (mContentSettingsType == ContentSettingsType.GEOLOCATION_WITH_OPTIONS) { + website = + createWebsiteWithGeolocationPermission( + new GeolocationSetting(mContentSettingValue, mContentSettingValue), + SessionModel.DURABLE); + } else { + website = + createWebsiteWithContentSettingException( + mContentSettingsType, mContentSettingValue); + } mSettingsActivity = SiteSettingsTestUtils.startSingleWebsitePreferences(website); ThreadUtils.runOnUiThreadBlocking( @@ -331,7 +462,7 @@ protected void doTest(SingleWebsiteSettings websitePreferences) { String prefKey = SingleWebsiteSettings.getPreferenceKey(mContentSettingsType); ChromeSwitchPreference switchPref = websitePreferences.findPreference(prefKey); - Assert.assertNotNull("Preference cannot be found on screen.", switchPref); + assertNotNull("Preference cannot be found on screen.", switchPref); assertEquals( "Switch check state is different than test setting.", mContentSettingValue @@ -356,6 +487,25 @@ return website; } + private static Website createWebsiteWithGeolocationPermission( + GeolocationSetting setting, int sessionModel) { + WebsiteAddress address = WebsiteAddress.create(EXAMPLE_ADDRESS); + Website website = new Website(address, address); + PermissionInfo info = + new PermissionInfo( + ContentSettingsType.GEOLOCATION_WITH_OPTIONS, + website.getAddress().getOrigin(), + website.getAddress().getOrigin(), + /* isEmbargoed= */ false, + sessionModel); + ThreadUtils.runOnUiThreadBlocking( + () -> + info.setGeolocationSetting( + ProfileManager.getLastUsedRegularProfile(), setting)); + website.setPermissionInfo(info); + return website; + } + private static Website createWebsiteWithStorageAccessPermission( String origin, String embedder, @ContentSettingValues int setting) { Website website =
diff --git a/chrome/browser/policy/networking/network_configuration_updater_ash_unittest.cc b/chrome/browser/policy/networking/network_configuration_updater_ash_unittest.cc index 37d2cf70..89e0a9af 100644 --- a/chrome/browser/policy/networking/network_configuration_updater_ash_unittest.cc +++ b/chrome/browser/policy/networking/network_configuration_updater_ash_unittest.cc
@@ -128,19 +128,6 @@ return count; } - void ImportAllCertificatesUserInitiated( - const std::vector<OncParsedCertificates::ServerOrAuthorityCertificate>& - server_or_authority_certificates, - const std::vector<OncParsedCertificates::ClientCertificate>& - client_certificates, - DoneCallback done_callback) override { - // As policy-provided server and authority certificates are not permanently - // imported, only ImportClientCertificaates should be called. - // ImportAllCertificatesUserInitiated should never be called from - // UserNetworkConfigurationUpdater. - NOTREACHED(); - } - void ImportClientCertificates( const std::vector<OncParsedCertificates::ClientCertificate>& client_certificates,
diff --git a/chrome/browser/ui/webui/history/history_sign_in_state_watcher_unittest.cc b/chrome/browser/ui/webui/history/history_sign_in_state_watcher_unittest.cc new file mode 100644 index 0000000..fded6b8 --- /dev/null +++ b/chrome/browser/ui/webui/history/history_sign_in_state_watcher_unittest.cc
@@ -0,0 +1,156 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/history/history_sign_in_state_watcher.h" + +#include "base/functional/bind.h" +#include "base/test/mock_callback.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/task_environment.h" +#include "components/signin/public/identity_manager/identity_test_environment.h" +#include "components/sync/base/features.h" +#include "components/sync/test/test_sync_service.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +using testing::StrictMock; + +class HistorySignInStateWatcherTestBase : public testing::Test { + public: + explicit HistorySignInStateWatcherTestBase(bool replace_sync_with_signin) { + feature_list_.InitWithFeatureState( + syncer::kReplaceSyncPromosWithSignInPromos, replace_sync_with_signin); + // Start with no signed-in user (this makes the TestSyncService consistent + // with the IdentityTestEnvironment). + sync_service_.SetSignedOut(); + } + + protected: + base::test::ScopedFeatureList feature_list_; + base::test::TaskEnvironment task_environment_; + signin::IdentityTestEnvironment identity_test_env_; + syncer::TestSyncService sync_service_; +}; + +class HistorySignInStateWatcherTest : public HistorySignInStateWatcherTestBase, + public testing::WithParamInterface<bool> { + public: + HistorySignInStateWatcherTest() + : HistorySignInStateWatcherTestBase( + /*replace_sync_with_signin=*/GetParam()) {} +}; + +TEST_P(HistorySignInStateWatcherTest, SignedOut) { + // Initially, user is signed out and sync is off. + ASSERT_FALSE(identity_test_env_.identity_manager()->HasPrimaryAccount( + signin::ConsentLevel::kSignin)); + ASSERT_FALSE(sync_service_.IsSyncFeatureEnabled()); + + StrictMock<base::MockCallback<base::RepeatingClosure>> callback; + HistorySignInStateWatcher watcher(identity_test_env_.identity_manager(), + &sync_service_, callback.Get()); + + EXPECT_EQ(HistorySignInState::kSignedOut, watcher.GetSignInState()); +} + +TEST_P(HistorySignInStateWatcherTest, NullServices) { + StrictMock<base::MockCallback<base::RepeatingClosure>> callback; + HistorySignInStateWatcher watcher(nullptr, nullptr, callback.Get()); + + EXPECT_EQ(HistorySignInState::kSignedOut, watcher.GetSignInState()); +} + +class HistorySignInStateWatcherSyncToSigninTest + : public HistorySignInStateWatcherTestBase { + public: + HistorySignInStateWatcherSyncToSigninTest() + : HistorySignInStateWatcherTestBase(/*replace_sync_with_signin=*/true) {} +}; + +TEST_F(HistorySignInStateWatcherSyncToSigninTest, NotifiesAboutStateChanges) { + StrictMock<base::MockCallback<base::RepeatingClosure>> callback; + HistorySignInStateWatcher watcher(identity_test_env_.identity_manager(), + &sync_service_, callback.Get()); + ASSERT_EQ(HistorySignInState::kSignedOut, watcher.GetSignInState()); + + // Signing in, but without history, should not change the state, nor trigger a + // notification yet. + CoreAccountInfo account_info = identity_test_env_.MakePrimaryAccountAvailable( + "test@example.com", signin::ConsentLevel::kSignin); + sync_service_.SetSignedIn(signin::ConsentLevel::kSignin, account_info); + sync_service_.GetUserSettings()->SetSelectedType( + syncer::UserSelectableType::kHistory, false); + sync_service_.FireStateChanged(); + EXPECT_EQ(HistorySignInState::kSignedOut, watcher.GetSignInState()); + + // Opting in to history should change the state and trigger a notification. + sync_service_.GetUserSettings()->SetSelectedType( + syncer::UserSelectableType::kHistory, true); + EXPECT_CALL(callback, Run()); + sync_service_.FireStateChanged(); + EXPECT_EQ(HistorySignInState::kSignedIn, watcher.GetSignInState()); + +#if !BUILDFLAG(IS_CHROMEOS) + // Signing out again should once again change the state and trigger a + // notification. + identity_test_env_.ClearPrimaryAccount(); + sync_service_.SetSignedOut(); + EXPECT_CALL(callback, Run()); + sync_service_.FireStateChanged(); + EXPECT_EQ(HistorySignInState::kSignedOut, watcher.GetSignInState()); +#endif // BUILDFLAG(IS_CHROMEOS) +} + +class HistorySignInStateWatcherWithoutSyncToSigninTest + : public HistorySignInStateWatcherTestBase { + public: + HistorySignInStateWatcherWithoutSyncToSigninTest() + : HistorySignInStateWatcherTestBase(/*replace_sync_with_signin=*/false) {} +}; + +TEST_F(HistorySignInStateWatcherWithoutSyncToSigninTest, + NotifiesAboutStateChanges) { + StrictMock<base::MockCallback<base::RepeatingClosure>> callback; + HistorySignInStateWatcher watcher(identity_test_env_.identity_manager(), + &sync_service_, callback.Get()); + ASSERT_EQ(HistorySignInState::kSignedOut, watcher.GetSignInState()); + + // Just signing in (without enabling Sync) should *not* change the state, nor + // trigger a notification. + CoreAccountInfo account_info = identity_test_env_.MakePrimaryAccountAvailable( + "test@example.com", signin::ConsentLevel::kSignin); + sync_service_.SetSignedIn(signin::ConsentLevel::kSignin, account_info); + sync_service_.FireStateChanged(); + EXPECT_EQ(HistorySignInState::kSignedOut, watcher.GetSignInState()); + + // Enabling Sync should change the state and trigger a notification. + account_info = identity_test_env_.MakePrimaryAccountAvailable( + "test@example.com", signin::ConsentLevel::kSync); + sync_service_.SetSignedIn(signin::ConsentLevel::kSync, account_info); + EXPECT_CALL(callback, Run()); + sync_service_.FireStateChanged(); + EXPECT_EQ(HistorySignInState::kSignedIn, watcher.GetSignInState()); + +#if !BUILDFLAG(IS_CHROMEOS) + // Signing out and disabling Sync again should once again change the state and + // trigger a notification. + sync_service_.SetSignedOut(); + identity_test_env_.ClearPrimaryAccount(); + EXPECT_CALL(callback, Run()); + sync_service_.FireStateChanged(); + EXPECT_EQ(HistorySignInState::kSignedOut, watcher.GetSignInState()); +#endif // BUILDFLAG(IS_CHROMEOS) +} + +INSTANTIATE_TEST_SUITE_P(, + HistorySignInStateWatcherTest, + testing::Bool(), + [](const testing::TestParamInfo<bool>& info) { + return info.param ? "WithSyncToSignin" + : "WithoutSyncToSignin"; + }); + +} // namespace
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 43a591785..497aa71 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -8193,6 +8193,7 @@ "../browser/ui/webui/flags/flags_ui_handler_unittest.cc", "../browser/ui/webui/history/browsing_history_handler_unittest.cc", "../browser/ui/webui/history/foreign_session_handler_unittest.cc", + "../browser/ui/webui/history/history_sign_in_state_watcher_unittest.cc", "../browser/ui/webui/managed_ui_handler_unittest.cc", "../browser/ui/webui/metrics_reporter/metrics_reporter_unittest.cc", "../browser/ui/webui/metrics_reporter/mock_metrics_reporter.cc",
diff --git a/chromeos/ash/components/network/onc/onc_certificate_importer.h b/chromeos/ash/components/network/onc/onc_certificate_importer.h index 59fcde9..da65fe6 100644 --- a/chromeos/ash/components/network/onc/onc_certificate_importer.h +++ b/chromeos/ash/components/network/onc/onc_certificate_importer.h
@@ -28,23 +28,6 @@ virtual ~CertificateImporter() {} - // This is intended for user-initiated ONC imports. - // Permanently imports server, authority and client certificates from - // |certificates|. Certificates will be given web trust if requested. - // If the "Remove" field of a certificate is enabled, then removes the - // certificate from the store instead of importing. - // When the import is completed, |done_callback| will be called with |success| - // equal to true if all certificates were imported successfully. - // Never calls |done_callback| after this importer is destructed. - virtual void ImportAllCertificatesUserInitiated( - const std::vector< - chromeos::onc::OncParsedCertificates::ServerOrAuthorityCertificate>& - server_or_authority_certificates, - const std::vector< - chromeos::onc::OncParsedCertificates::ClientCertificate>& - client_certificates, - DoneCallback done_callback) = 0; - // Permanently imports the client certificates given by |client_certificates|. // When the import is completed, |done_callback| will be called with |success| // equal to true if all certificates were imported successfully.
diff --git a/chromeos/ash/components/network/onc/onc_certificate_importer_impl.cc b/chromeos/ash/components/network/onc/onc_certificate_importer_impl.cc index b05b46736..b9c7dec 100644 --- a/chromeos/ash/components/network/onc/onc_certificate_importer_impl.cc +++ b/chromeos/ash/components/network/onc/onc_certificate_importer_impl.cc
@@ -36,23 +36,6 @@ CertificateImporterImpl::~CertificateImporterImpl() = default; -void CertificateImporterImpl::ImportAllCertificatesUserInitiated( - const std::vector< - chromeos::onc::OncParsedCertificates::ServerOrAuthorityCertificate>& - server_or_authority_certificates, - const std::vector<chromeos::onc::OncParsedCertificates::ClientCertificate>& - client_certificates, - DoneCallback done_callback) { - VLOG(2) << "Importing " << server_or_authority_certificates.size() - << " server/authority certificates and " << client_certificates.size() - << " client certificates"; - RunTaskOnIOTaskRunnerAndCallDoneCallback( - base::BindOnce(&StoreAllCertificatesUserInitiated, - server_or_authority_certificates, client_certificates, - target_nssdb_), - std::move(done_callback)); -} - void CertificateImporterImpl::ImportClientCertificates( const std::vector<chromeos::onc::OncParsedCertificates::ClientCertificate>& client_certificates,
diff --git a/chromeos/ash/components/network/onc/onc_certificate_importer_impl.h b/chromeos/ash/components/network/onc/onc_certificate_importer_impl.h index 102f5ae3..9cd289d 100644 --- a/chromeos/ash/components/network/onc/onc_certificate_importer_impl.h +++ b/chromeos/ash/components/network/onc/onc_certificate_importer_impl.h
@@ -48,15 +48,6 @@ ~CertificateImporterImpl() override; // CertificateImporter overrides - void ImportAllCertificatesUserInitiated( - const std::vector< - chromeos::onc::OncParsedCertificates::ServerOrAuthorityCertificate>& - server_or_authority_certificates, - const std::vector< - chromeos::onc::OncParsedCertificates::ClientCertificate>& - client_certificates, - DoneCallback done_callback) override; - void ImportClientCertificates( const std::vector< chromeos::onc::OncParsedCertificates::ClientCertificate>&
diff --git a/chromeos/ash/components/network/onc/onc_certificate_importer_impl_unittest.cc b/chromeos/ash/components/network/onc/onc_certificate_importer_impl_unittest.cc index 2a01355b..ba450b4 100644 --- a/chromeos/ash/components/network/onc/onc_certificate_importer_impl_unittest.cc +++ b/chromeos/ash/components/network/onc/onc_certificate_importer_impl_unittest.cc
@@ -65,14 +65,11 @@ } // Runs the import on the certificates specified in |filename|. - // |import_type| specifies if only client certificates should be imported, or - // if all certificates should be imported. // |expected_parse_success| should be true if at least one certificate in // |filename| is expected to have parse errors. // |expected_import_success| is the expected result of importing the // certificates which did not have parsing errors. void AddCertificatesFromFile(const std::string& filename, - ImportType import_type, bool expected_parse_success, bool expected_import_success) { base::Value::Dict onc = @@ -86,23 +83,10 @@ std::make_unique<chromeos::onc::OncParsedCertificates>( onc_certificates_); EXPECT_EQ(expected_parse_success, !onc_parsed_certificates->has_error()); - switch (import_type) { - case ImportType::kClientCertificatesOnly: - importer.ImportClientCertificates( - onc_parsed_certificates->client_certificates(), - base::BindOnce(&ONCCertificateImporterImplTest::OnImportCompleted, - base::Unretained(this), expected_import_success)); - break; - case ImportType::kAllCertificates: - importer.ImportAllCertificatesUserInitiated( - onc_parsed_certificates->server_or_authority_certificates(), - onc_parsed_certificates->client_certificates(), - base::BindOnce(&ONCCertificateImporterImplTest::OnImportCompleted, - base::Unretained(this), expected_import_success)); - break; - default: - NOTREACHED(); - } + importer.ImportClientCertificates( + onc_parsed_certificates->client_certificates(), + base::BindOnce(&ONCCertificateImporterImplTest::OnImportCompleted, + base::Unretained(this), expected_import_success)); task_runner_->RunUntilIdle(); @@ -111,15 +95,13 @@ } void AddCertificateFromFile(const std::string& filename, - ImportType import_type, net::CertType expected_type, std::string* guid) { std::string guid_temporary; if (!guid) guid = &guid_temporary; - AddCertificatesFromFile(filename, import_type, - true /* expected_parse_success */, + AddCertificatesFromFile(filename, true /* expected_parse_success */, true /* expected_import_success */); if (expected_type == net::SERVER_CERT || expected_type == net::CA_CERT) { @@ -184,39 +166,22 @@ } }; -TEST_F(ONCCertificateImporterImplTest, MultipleCertificates) { - AddCertificatesFromFile("managed_toplevel2.onc", ImportType::kAllCertificates, - true /* expected_parse_success */, - true /* expected_import_success */); - EXPECT_EQ(onc_certificates_.size(), public_list_.size()); - EXPECT_TRUE(private_list_.empty()); - EXPECT_EQ(2ul, public_list_.size()); -} TEST_F(ONCCertificateImporterImplTest, OnlyClientCertificatesImpored) { - AddCertificatesFromFile( - "managed_toplevel2.onc", ImportType::kClientCertificatesOnly, - true /* expected_parse_success */, true /* expected_import_success */); - AddCertificatesFromFile( - "certificate-client.onc", ImportType::kClientCertificatesOnly, - true /* expected_parse_success */, true /* expected_import_success */); + AddCertificatesFromFile("managed_toplevel2.onc", + true /* expected_parse_success */, + true /* expected_import_success */); + AddCertificatesFromFile("certificate-client.onc", + true /* expected_parse_success */, + true /* expected_import_success */); EXPECT_EQ(0ul, public_list_.size()); EXPECT_EQ(1ul, private_list_.size()); } -TEST_F(ONCCertificateImporterImplTest, MultipleCertificatesWithFailures) { - AddCertificatesFromFile( - "toplevel_partially_invalid.onc", ImportType::kAllCertificates, - false /* expected_parse_success */, true /* expected_import_success */); - EXPECT_EQ(3ul, onc_certificates_.size()); - EXPECT_EQ(1ul, private_list_.size()); - EXPECT_TRUE(public_list_.empty()); -} TEST_F(ONCCertificateImporterImplTest, AddClientCertificate) { std::string guid; - AddCertificateFromFile("certificate-client.onc", ImportType::kAllCertificates, - net::USER_CERT, &guid); + AddCertificateFromFile("certificate-client.onc", net::USER_CERT, &guid); EXPECT_EQ(1ul, private_list_.size()); EXPECT_TRUE(public_list_.empty()); @@ -252,107 +217,28 @@ } } -TEST_F(ONCCertificateImporterImplTest, AddServerCertificateWithWebTrust) { - AddCertificateFromFile("certificate-server.onc", ImportType::kAllCertificates, - net::SERVER_CERT, NULL); - - SECKEYPrivateKeyList* privkey_list = - PK11_ListPrivKeysInSlot(private_nssdb_.slot(), NULL, NULL); - EXPECT_FALSE(privkey_list); - - SECKEYPublicKeyList* pubkey_list = - PK11_ListPublicKeysInSlot(private_nssdb_.slot(), NULL); - EXPECT_FALSE(pubkey_list); - - ASSERT_EQ(1u, public_list_.size()); - EXPECT_TRUE(private_list_.empty()); -} - -TEST_F(ONCCertificateImporterImplTest, AddWebAuthorityCertificateWithWebTrust) { - AddCertificateFromFile("certificate-web-authority.onc", - ImportType::kAllCertificates, net::CA_CERT, NULL); - - SECKEYPrivateKeyList* privkey_list = - PK11_ListPrivKeysInSlot(private_nssdb_.slot(), NULL, NULL); - EXPECT_FALSE(privkey_list); - - SECKEYPublicKeyList* pubkey_list = - PK11_ListPublicKeysInSlot(private_nssdb_.slot(), NULL); - EXPECT_FALSE(pubkey_list); - - ASSERT_EQ(1u, public_list_.size()); - EXPECT_TRUE(private_list_.empty()); -} - -TEST_F(ONCCertificateImporterImplTest, AddAuthorityCertificateWithoutWebTrust) { - AddCertificateFromFile("certificate-authority.onc", - ImportType::kAllCertificates, net::CA_CERT, NULL); - SECKEYPrivateKeyList* privkey_list = - PK11_ListPrivKeysInSlot(private_nssdb_.slot(), NULL, NULL); - EXPECT_FALSE(privkey_list); - - SECKEYPublicKeyList* pubkey_list = - PK11_ListPublicKeysInSlot(private_nssdb_.slot(), NULL); - EXPECT_FALSE(pubkey_list); -} - -struct CertParam { - CertParam(net::CertType certificate_type, - const char* original_filename, - const char* update_filename) - : cert_type(certificate_type), - original_file(original_filename), - update_file(update_filename) {} - - net::CertType cert_type; - const char* original_file; - const char* update_file; -}; - -class ONCCertificateImporterImplTestWithParam : - public ONCCertificateImporterImplTest, - public testing::WithParamInterface<CertParam> { -}; - -TEST_P(ONCCertificateImporterImplTestWithParam, UpdateCertificate) { +TEST_F(ONCCertificateImporterImplTest, UpdateCertificate) { // First we import a certificate. { SCOPED_TRACE("Import original certificate"); - AddCertificateFromFile(GetParam().original_file, - ImportType::kAllCertificates, GetParam().cert_type, - NULL); + AddCertificateFromFile("certificate-client.onc", net::USER_CERT, NULL); } // Now we import the same certificate with a different GUID. In case of a // client cert, the cert should be retrievable via the new GUID. { SCOPED_TRACE("Import updated certificate"); - AddCertificateFromFile(GetParam().update_file, ImportType::kAllCertificates, - GetParam().cert_type, NULL); - } -} - -TEST_P(ONCCertificateImporterImplTestWithParam, ReimportCertificate) { - // Verify that reimporting a client certificate works. - for (int i = 0; i < 2; ++i) { - SCOPED_TRACE("Import certificate, iteration " + base::NumberToString(i)); - AddCertificateFromFile(GetParam().original_file, - ImportType::kAllCertificates, GetParam().cert_type, + AddCertificateFromFile("certificate-client-update.onc", net::USER_CERT, NULL); } } -INSTANTIATE_TEST_SUITE_P( - ONCCertificateImporterImplTestWithParam, - ONCCertificateImporterImplTestWithParam, - ::testing::Values(CertParam(net::USER_CERT, - "certificate-client.onc", - "certificate-client-update.onc"), - CertParam(net::SERVER_CERT, - "certificate-server.onc", - "certificate-server-update.onc"), - CertParam(net::CA_CERT, - "certificate-web-authority.onc", - "certificate-web-authority-update.onc"))); +TEST_F(ONCCertificateImporterImplTest, ReimportCertificate) { + // Verify that reimporting a client certificate works. + for (int i = 0; i < 2; ++i) { + SCOPED_TRACE("Import certificate, iteration " + base::NumberToString(i)); + AddCertificateFromFile("certificate-client.onc", net::USER_CERT, NULL); + } +} } // namespace ash::onc
diff --git a/clank b/clank index 722cdc7..2f030b8 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 722cdc7d46bd7c87d9b93b991d5ae1cc55205a0e +Subproject commit 2f030b8b2858ba5b64842bf5a6268933929fddec
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index f86c8f7..9ed7be1a 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -542,7 +542,7 @@ // TODO(crbug.com/324199622) When abandoned, remove FormFieldData::is_visible. BASE_FEATURE(kAutofillDetectFieldVisibility, "AutofillDetectFieldVisibility", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // If enabled, new heuristics are applied for disambiguating multiple possible // types in a form field. Otherwise, only the already established heuristic for
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java index 897cc27..daebcd5 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java
@@ -820,15 +820,25 @@ return getResourceItem(contentType).getDefaultDisabledValue(); } + public static int getCategorySummary(@ContentSettingValues int value, boolean isOneTime) { + return getCategorySummary(value, isOneTime, /* isApproximateGeolocation= */ false); + } + /** * Returns the string resource id for a given ContentSetting to show with a permission category. * * @param value The ContentSetting for which we want the resource. * @param isOneTime Whether the content setting value has a OneTime session model. */ - public static int getCategorySummary(@ContentSettingValues int value, boolean isOneTime) { + public static int getCategorySummary( + @ContentSettingValues int value, boolean isOneTime, boolean isApproximateGeolocation) { switch (value) { case ContentSettingValues.ALLOW: + if (isApproximateGeolocation) { + return isOneTime + ? R.string.website_settings_category_approx_geo_allowed_this_time + : R.string.website_settings_category_approx_geo_allowed; + } return isOneTime ? R.string.website_settings_category_allowed_this_time : R.string.website_settings_category_allowed;
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 index 56aa1a71..d2792b3 100644 --- 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
@@ -167,6 +167,8 @@ return "camera_permission_list"; case ContentSettingsType.GEOLOCATION: return "location_access_list"; + case ContentSettingsType.GEOLOCATION_WITH_OPTIONS: + return "location_with_options_access_list"; case ContentSettingsType.HAND_TRACKING: return "hand_tracking_permission_list"; case ContentSettingsType.MEDIASTREAM_MIC: @@ -253,6 +255,10 @@ // Maximum value used for the order of the permissions private int mMaxPermissionOrder; + // Stores whether the location permission was initially approximate to ensure we toggle between + // permissions consistently. + private boolean mHasApproximateLocationGrant; + private final ObservableSupplierImpl<String> mPageTitle = new ObservableSupplierImpl<>(); private class SingleWebsitePermissionsPopulator @@ -608,6 +614,8 @@ setUpJavascriptPreference(preference); } else if (type == ContentSettingsType.GEOLOCATION) { setUpLocationPreference(preference); + } else if (type == ContentSettingsType.GEOLOCATION_WITH_OPTIONS) { + setUpLocationWithOptionsPreference(preference); } else if (type == ContentSettingsType.NOTIFICATIONS) { setUpNotificationsPreference(preference, mSite.isEmbargoed(type)); } else if (type == ContentSettingsType.AUTO_PICTURE_IN_PICTURE) { @@ -618,8 +626,7 @@ } else { setupContentSettingsPreference( preference, - mSite.getContentSetting( - getSiteSettingsDelegate().getBrowserContextHandle(), type), + mSite.getContentSetting(getBrowserContextHandle(), type), mSite.isEmbargoed(type), isOneTime(type)); } @@ -640,8 +647,7 @@ Context context = preference.getContext(); preference.setTitle(SiteSettingsUtil.generateStorageUsageText(context, usage, cookies)); preference.setDataForDisplay(mSite.getTitle(), appFound, /* isGroup= */ false); - if (mSite.isCookieDeletionDisabled( - getSiteSettingsDelegate().getBrowserContextHandle())) { + if (mSite.isCookieDeletionDisabled(getBrowserContextHandle())) { preference.setEnabled(false); } } else { @@ -658,7 +664,7 @@ : R.string.website_reset_full); preference.setOrder(mMaxPermissionOrder + 1); preference.setOnPreferenceClickListener(this); - if (mSite.isCookieDeletionDisabled(getSiteSettingsDelegate().getBrowserContextHandle())) { + if (mSite.isCookieDeletionDisabled(getBrowserContextHandle())) { preference.setEnabled(false); } } @@ -746,8 +752,7 @@ private void setUpNotificationsPreference(Preference preference, boolean isEmbargoed) { @ContentSettingsType.EnumType int notificationType = ContentSettingsType.NOTIFICATIONS; final @ContentSettingValues @Nullable Integer value = - mSite.getContentSetting( - getSiteSettingsDelegate().getBrowserContextHandle(), notificationType); + mSite.getContentSetting(getBrowserContextHandle(), notificationType); if (setupAppDelegatePreference( preference, R.string.website_notification_settings, notificationType, value)) { return; @@ -801,7 +806,7 @@ // just-in-time if the user tries to change to setting. if (assumeNonNull(mSite).isEmbargoed(ContentSettingsType.NOTIFICATIONS)) { mSite.setContentSetting( - getSiteSettingsDelegate().getBrowserContextHandle(), + getBrowserContextHandle(), ContentSettingsType.NOTIFICATIONS, ContentSettingValues.BLOCK); } @@ -826,8 +831,7 @@ // Store current value of permission to allow comparison against new value at return. mPreviousNotificationPermission = mSite.getContentSetting( - getSiteSettingsDelegate().getBrowserContextHandle(), - ContentSettingsType.NOTIFICATIONS); + getBrowserContextHandle(), ContentSettingsType.NOTIFICATIONS); Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); intent.putExtra(Settings.EXTRA_CHANNEL_ID, channelId); @@ -852,8 +856,7 @@ @ContentSettingValues Integer newPermission = mSite.getContentSetting( - getSiteSettingsDelegate().getBrowserContextHandle(), - ContentSettingsType.NOTIFICATIONS); + getBrowserContextHandle(), ContentSettingsType.NOTIFICATIONS); assumeNonNull(newPermission); // User has navigated back from system channel settings on O+. Ensure notification // preference is up to date, since they might have toggled it from channel settings. @@ -873,7 +876,7 @@ && newPermission != ContentSettingValues.ALLOW) { org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridgeJni.get() .reportNotificationRevokedForOrigin( - getSiteSettingsDelegate().getBrowserContextHandle(), + getBrowserContextHandle(), mSite.getAddress().getOrigin(), newPermission); mPreviousNotificationPermission = null; @@ -903,7 +906,7 @@ R.drawable.ic_delete_white_24dp, R.string.website_settings_revoke_device_permission, (View view) -> { - info.revoke(getSiteSettingsDelegate().getBrowserContextHandle()); + info.revoke(getBrowserContextHandle()); preferenceScreen.removePreference(preference); mChooserPermissionPreferences.remove(preference); @@ -941,7 +944,7 @@ @RequiresNonNull({"mSite"}) private void setUpEmbeddedContentSettingPreferences() { PreferenceScreen preferenceScreen = getPreferenceScreen(); - BrowserContextHandle handle = getSiteSettingsDelegate().getBrowserContextHandle(); + BrowserContextHandle handle = getBrowserContextHandle(); for (List<ContentSettingException> entries : mSite.getEmbeddedPermissions().values()) { for (ContentSettingException info : entries) { @@ -1094,8 +1097,7 @@ boolean adBlockingActivated = SiteSettingsCategory.adsCategoryEnabled() && WebsitePreferenceBridge.getAdBlockingActivated( - getSiteSettingsDelegate().getBrowserContextHandle(), - mSite.getAddress().getOrigin()) + getBrowserContextHandle(), mSite.getAddress().getOrigin()) && findPreference(assumeNonNull(getPreferenceKey(ContentSettingsType.ADS))) != null; @@ -1112,8 +1114,7 @@ // the user to the same location. It is preferrable, however, that we give Geolocation some // priority because that category is the only one that potentially shows an additional // warning (when Location is turned off globally). - BrowserContextHandle browserContextHandle = - getSiteSettingsDelegate().getBrowserContextHandle(); + BrowserContextHandle browserContextHandle = getBrowserContextHandle(); if (showWarningFor(SiteSettingsCategory.Type.DEVICE_LOCATION)) { return SiteSettingsCategory.createFromType( browserContextHandle, SiteSettingsCategory.Type.DEVICE_LOCATION); @@ -1144,8 +1145,7 @@ @RequiresNonNull({"mSite"}) private boolean showWarningFor(@SiteSettingsCategory.Type int type) { - BrowserContextHandle browserContextHandle = - getSiteSettingsDelegate().getBrowserContextHandle(); + BrowserContextHandle browserContextHandle = getBrowserContextHandle(); var content_settings_type = SiteSettingsCategory.contentSettingsType(type); @@ -1191,6 +1191,7 @@ return false; } + @RequiresNonNull({"mSite"}) private void setupContentSettingsPreference( Preference preference, @ContentSettingValues @Nullable Integer value, @@ -1201,19 +1202,34 @@ preference.setOnPreferenceChangeListener(this); @ContentSettingsType.EnumType int contentType = getContentSettingsTypeFromPreferenceKey(preference.getKey()); + boolean isApproximateGeolocation = + contentType == ContentSettingsType.GEOLOCATION_WITH_OPTIONS + && mHasApproximateLocationGrant; preference.setSummary( isEmbargoed ? getString(R.string.automatically_blocked) - : getString(ContentSettingsResources.getCategorySummary(value, isOneTime))); + : getString( + ContentSettingsResources.getCategorySummary( + value, isOneTime, isApproximateGeolocation))); if (preference instanceof ChromeImageViewPreference) { ChromeImageViewPreference oneTimePreference = (ChromeImageViewPreference) preference; oneTimePreference.setImageView( R.drawable.material_ic_close_24dp, R.string.website_settings_revoke_permission, (View view) -> { - // TODO(crbug.com/418941286): Revoke the permission by calling - // onPreferenceChanged() with the new value. + assumeNonNull(mSite); + PermissionInfo permissionInfo = + assumeNonNull(mSite.getPermissionInfo(contentType)); + if (contentType == ContentSettingsType.GEOLOCATION_WITH_OPTIONS) { + permissionInfo.setGeolocationSetting(getBrowserContextHandle(), null); + } else { + permissionInfo.setContentSetting( + getBrowserContextHandle(), ContentSettingValues.DEFAULT); + } getPreferenceScreen().removePreference(oneTimePreference); + if (mWebsiteSettingsObserver != null) { + mWebsiteSettingsObserver.onPermissionChanged(); + } }); if (contentType == mHighlightedPermission) { oneTimePreference.setBackgroundColor(mHighlightColor); @@ -1249,7 +1265,7 @@ SiteSettingsCategory category = SiteSettingsCategory.createFromContentSettingsType( - getSiteSettingsDelegate().getBrowserContextHandle(), contentType); + getBrowserContextHandle(), contentType); if (category != null && value != null && value != ContentSettingValues.BLOCK @@ -1269,11 +1285,13 @@ @RequiresNonNull({"mSite"}) private void setUpLocationPreference(Preference preference) { + if (PermissionsAndroidFeatureMap.isEnabled( + PermissionsAndroidFeatureList.APPROXIMATE_GEOLOCATION_PERMISSION)) { + return; + } @ContentSettingValues @Nullable Integer permission = - mSite.getContentSetting( - getSiteSettingsDelegate().getBrowserContextHandle(), - ContentSettingsType.GEOLOCATION); + mSite.getContentSetting(getBrowserContextHandle(), ContentSettingsType.GEOLOCATION); if (setupAppDelegatePreference( preference, R.string.website_location_settings, @@ -1290,13 +1308,44 @@ } @RequiresNonNull({"mSite"}) + private void setUpLocationWithOptionsPreference(Preference preference) { + if (!PermissionsAndroidFeatureMap.isEnabled( + PermissionsAndroidFeatureList.APPROXIMATE_GEOLOCATION_PERMISSION)) { + return; + } + var info = mSite.getPermissionInfo(ContentSettingsType.GEOLOCATION_WITH_OPTIONS); + if (info == null) { + return; + } + GeolocationSetting permission = info.getGeolocationSetting(getBrowserContextHandle()); + + if (permission.mApproximate == ContentSettingValues.ALLOW + && permission.mApproximate != permission.mPrecise) { + mHasApproximateLocationGrant = true; + } + + if (setupAppDelegatePreference( + preference, + R.string.website_location_settings, + ContentSettingsType.GEOLOCATION_WITH_OPTIONS, + permission.mApproximate)) { + return; + } + + setupContentSettingsPreference( + preference, + permission.mApproximate, + mSite.isEmbargoed(ContentSettingsType.GEOLOCATION_WITH_OPTIONS), + isOneTime(ContentSettingsType.GEOLOCATION_WITH_OPTIONS)); + } + + @RequiresNonNull({"mSite"}) private void setUpSoundPreference(Preference preference) { if (!getArguments().getBoolean(EXTRA_SHOW_SOUND, true)) { return; } - BrowserContextHandle browserContextHandle = - getSiteSettingsDelegate().getBrowserContextHandle(); + BrowserContextHandle browserContextHandle = getBrowserContextHandle(); @ContentSettingValues @Nullable Integer currentValue = mSite.getContentSetting(browserContextHandle, ContentSettingsType.SOUND); @@ -1327,8 +1376,7 @@ return; } - BrowserContextHandle browserContextHandle = - getSiteSettingsDelegate().getBrowserContextHandle(); + BrowserContextHandle browserContextHandle = getBrowserContextHandle(); @ContentSettingValues @Nullable Integer currentValue = mSite.getContentSetting( @@ -1355,8 +1403,7 @@ @RequiresNonNull({"mSite"}) private void setUpJavascriptPreference(Preference preference) { - BrowserContextHandle browserContextHandle = - getSiteSettingsDelegate().getBrowserContextHandle(); + BrowserContextHandle browserContextHandle = getBrowserContextHandle(); @ContentSettingValues @Nullable Integer currentValue = mSite.getContentSetting(browserContextHandle, ContentSettingsType.JAVASCRIPT); @@ -1377,15 +1424,13 @@ /** * Updates the ads list preference based on whether the site is a candidate for blocking. This - * has some custom behavior. - * 1. If the site is a candidate and has activation, the permission should show up even if it - * is set as the default (e.g. |preference| is null). - * 2. The BLOCK string is custom. + * has some custom behavior. 1. If the site is a candidate and has activation, the permission + * should show up even if it is set as the default (e.g. |preference| is null). 2. The BLOCK + * string is custom. */ @RequiresNonNull({"mSite"}) private void setUpAdsPreference(Preference preference) { - BrowserContextHandle browserContextHandle = - getSiteSettingsDelegate().getBrowserContextHandle(); + BrowserContextHandle browserContextHandle = getBrowserContextHandle(); // Do not show the setting if the category is not enabled. if (!SiteSettingsCategory.adsCategoryEnabled()) { setupContentSettingsPreference( @@ -1471,8 +1516,9 @@ // It is possible that this UI is destroyed while a dialog is open because // incognito mode is closed through the system notification. if (getView() == null) return true; - BrowserContextHandle browserContextHandle = - getSiteSettingsDelegate().getBrowserContextHandle(); + assumeNonNull(mSite); + + BrowserContextHandle browserContextHandle = getBrowserContextHandle(); int type = getContentSettingsTypeFromPreferenceKey(preference.getKey()); if (type == ContentSettingsType.DEFAULT) return false; @@ -1483,11 +1529,29 @@ permission = (Integer) newValue; } - assumeNonNull(mSite).setContentSetting(browserContextHandle, type, permission); + if (type == ContentSettingsType.GEOLOCATION_WITH_OPTIONS) { + PermissionInfo permissionInfo = assumeNonNull(mSite.getPermissionInfo(type)); + var oldSetting = permissionInfo.getGeolocationSetting(browserContextHandle); + var newPreciseValue = permission; + if (mHasApproximateLocationGrant && permission == ContentSettingValues.ALLOW) { + newPreciseValue = oldSetting.mPrecise; + } + permissionInfo.setGeolocationSetting( + browserContextHandle, + new GeolocationSetting( + /* approximate= */ permission, /* precise= */ newPreciseValue)); + } else { + mSite.setContentSetting(browserContextHandle, type, permission); + } // In Clank, one time grants are only possible via prompt, not via page // info. preference.setSummary( - getString(ContentSettingsResources.getCategorySummary(permission, false))); + getString( + ContentSettingsResources.getCategorySummary( + permission, + false, + type == ContentSettingsType.GEOLOCATION_WITH_OPTIONS + && mHasApproximateLocationGrant))); preference.setIcon(getContentSettingsIcon(type, permission)); if (mWebsiteSettingsObserver != null) { @@ -1536,8 +1600,7 @@ boolean finishActivityImmediately = assumeNonNull(mSite).getTotalUsage() == 0 && !hasManagedChooserPermissions(); - SiteDataCleaner.resetPermissions( - getSiteSettingsDelegate().getBrowserContextHandle(), mSite); + SiteDataCleaner.resetPermissions(getBrowserContextHandle(), mSite); SiteDataCleaner.clearData(getSiteSettingsDelegate(), mSite, mDataClearedCallback); RecordHistogram.recordEnumeratedHistogram( @@ -1604,8 +1667,7 @@ R.string.reset, (dialog, which) -> { SiteDataCleaner.resetPermissions( - getSiteSettingsDelegate().getBrowserContextHandle(), - assumeNonNull(mSite)); + getBrowserContextHandle(), assumeNonNull(mSite)); if (mWebsiteSettingsObserver != null) { mWebsiteSettingsObserver.onPermissionsReset(); } @@ -1654,6 +1716,10 @@ return false; } + private BrowserContextHandle getBrowserContextHandle() { + return getSiteSettingsDelegate().getBrowserContextHandle(); + } + @Override public @AnimationType int getAnimationType() { return AnimationType.PROPERTY;
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsUtil.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsUtil.java index 70f1a8d4..2221371 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsUtil.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsUtil.java
@@ -27,6 +27,7 @@ public static final int[] SETTINGS_ORDER = { ContentSettingsType.COOKIES, ContentSettingsType.GEOLOCATION, + ContentSettingsType.GEOLOCATION_WITH_OPTIONS, ContentSettingsType.MEDIASTREAM_CAMERA, ContentSettingsType.MEDIASTREAM_MIC, ContentSettingsType.NOTIFICATIONS,
diff --git a/components/browser_ui/strings/android/site_settings.grdp b/components/browser_ui/strings/android/site_settings.grdp index a4ed0c6e..9cb4f2296 100644 --- a/components/browser_ui/strings/android/site_settings.grdp +++ b/components/browser_ui/strings/android/site_settings.grdp
@@ -145,6 +145,12 @@ <message name="IDS_WEBSITE_SETTINGS_CATEGORY_ALLOWED_THIS_TIME" desc="Summary text explaining that a permission is allowed ephemerally, e.g. JavaScript: allowed."> Allowed this time </message> + <message name="IDS_WEBSITE_SETTINGS_CATEGORY_APPROX_GEO_ALLOWED" desc="Summary text explaining that the approximate location permission is allowed."> + Allowed • Approximate + </message> + <message name="IDS_WEBSITE_SETTINGS_CATEGORY_APPROX_GEO_ALLOWED_THIS_TIME" desc="Summary text explaining that the approximate location permission is allowed ephemerally."> + Allowed this time • Approximate + </message> <message name="IDS_WEBSITE_SETTINGS_CATEGORY_ALLOWED_EXCEPT_THIRD_PARTY" desc="Summary text for when only third-party cookies are blocked."> Allowed, except third-party </message>
diff --git a/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_APPROX_GEO_ALLOWED.png.sha1 b/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_APPROX_GEO_ALLOWED.png.sha1 new file mode 100644 index 0000000..bf3556f --- /dev/null +++ b/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_APPROX_GEO_ALLOWED.png.sha1
@@ -0,0 +1 @@ +8408cf4108789f4986a550558df613b32df76599 \ No newline at end of file
diff --git a/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_APPROX_GEO_ALLOWED_THIS_TIME.png.sha1 b/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_APPROX_GEO_ALLOWED_THIS_TIME.png.sha1 new file mode 100644 index 0000000..4f9d79db --- /dev/null +++ b/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_CATEGORY_APPROX_GEO_ALLOWED_THIS_TIME.png.sha1
@@ -0,0 +1 @@ +a3b3ffb47941df9378b4fa3eb6d80b6516cb2c8c \ No newline at end of file
diff --git a/components/history/core/browser/web_history_service.cc b/components/history/core/browser/web_history_service.cc index 16982a5a1..ace729f 100644 --- a/components/history/core/browser/web_history_service.cc +++ b/components/history/core/browser/web_history_service.cc
@@ -42,8 +42,6 @@ namespace { -const char kHistoryOAuthScope[] = "https://www.googleapis.com/auth/chromesync"; - const char kHistoryQueryHistoryUrl[] = "https://history.google.com/history/api/lookup?client=chrome"; @@ -160,9 +158,6 @@ // Tells the request to do its thang. void Start() override { - signin::ScopeSet oauth_scopes; - oauth_scopes.insert(kHistoryOAuthScope); - // TODO(crbug.com/40066882): Simplify this once // kReplaceSyncPromosWithSignInPromos has rolled out on all platforms. signin::ConsentLevel consent_level = signin::ConsentLevel::kSync; @@ -173,7 +168,7 @@ access_token_fetcher_ = std::make_unique<signin::PrimaryAccountAccessTokenFetcher>( - "web_history", identity_manager_, oauth_scopes, + signin::OAuthConsumerId::kWebHistoryService, identity_manager_, base::BindOnce(&RequestImpl::OnAccessTokenFetchComplete, base::Unretained(this)), signin::PrimaryAccountAccessTokenFetcher::Mode::kImmediate, @@ -193,11 +188,9 @@ // If the response code indicates that the token might not be valid, // invalidate the token and try again. if (response_code_ == net::HTTP_UNAUTHORIZED && ++auth_retry_count_ <= 1) { - signin::ScopeSet oauth_scopes; - oauth_scopes.insert(kHistoryOAuthScope); identity_manager_->RemoveAccessTokenFromCache( identity_manager_->GetPrimaryAccountId(signin::ConsentLevel::kSignin), - oauth_scopes, access_token_); + signin::OAuthConsumerId::kWebHistoryService, access_token_); access_token_.clear(); Start();
diff --git a/components/omnibox/browser/document_suggestions_service.cc b/components/omnibox/browser/document_suggestions_service.cc index 9eabe74..5dd253f 100644 --- a/components/omnibox/browser/document_suggestions_service.cc +++ b/components/omnibox/browser/document_suggestions_service.cc
@@ -156,11 +156,8 @@ std::move(creation_callback).Run(request.get()); - // Create and fetch an OAuth2 token. - signin::ScopeSet scopes; - scopes.insert(GaiaConstants::kCloudSearchQueryOAuth2Scope); token_fetcher_ = std::make_unique<signin::PrimaryAccountAccessTokenFetcher>( - "document_suggestions_service", identity_manager_, scopes, + signin::OAuthConsumerId::kDocumentSuggestionsService, identity_manager_, base::BindOnce(&DocumentSuggestionsService::AccessTokenAvailable, base::Unretained(this), std::move(request), std::move(request_body), traffic_annotation,
diff --git a/components/omnibox/browser/enterprise_search_aggregator_suggestions_service.cc b/components/omnibox/browser/enterprise_search_aggregator_suggestions_service.cc index 1f3a3bad..42b7818a 100644 --- a/components/omnibox/browser/enterprise_search_aggregator_suggestions_service.cc +++ b/components/omnibox/browser/enterprise_search_aggregator_suggestions_service.cc
@@ -137,18 +137,8 @@ } })"); - // Create and fetch an OAuth2 token. - signin::ScopeSet scopes; - - if (omnibox_feature_configs::SearchAggregatorProvider::Get() - .use_discovery_engine_oauth_scope) { - scopes.insert(GaiaConstants::kDiscoveryEngineCompleteQueryOAuth2Scope); - } else { - scopes.insert(GaiaConstants::kCloudSearchQueryOAuth2Scope); - } token_fetcher_ = std::make_unique<signin::PrimaryAccountAccessTokenFetcher>( - "enterprise_search_aggregator_suggestions_service", identity_manager_, - scopes, + signin::OAuthConsumerId::kEnterpriseSearchAggregator, identity_manager_, base::BindOnce( &EnterpriseSearchAggregatorSuggestionsService::AccessTokenAvailable, base::Unretained(this), std::move(requests), std::move(query),
diff --git a/components/omnibox/composebox/composebox_query_controller.cc b/components/omnibox/composebox/composebox_query_controller.cc index 131458db..4d0a295 100644 --- a/components/omnibox/composebox/composebox_query_controller.cc +++ b/components/omnibox/composebox/composebox_query_controller.cc
@@ -55,7 +55,6 @@ constexpr char kContentTypeKey[] = "Content-Type"; constexpr char kContentType[] = "application/x-protobuf"; -constexpr char kOAuthConsumerName[] = "ComposeboxQueryController"; constexpr char kSessionIdQueryParameterKey[] = "gsessionid"; // TODO(crbug.com/432348301): Move away from hardcoded entrypoint and lns @@ -360,7 +359,7 @@ signin::ScopeSet oauth_scopes; oauth_scopes.insert(GaiaConstants::kLensOAuth2Scope); return std::make_unique<signin::PrimaryAccountAccessTokenFetcher>( - kOAuthConsumerName, identity_manager_, oauth_scopes, + signin::OAuthConsumerId::kComposeboxQueryController, identity_manager_, std::move(token_callback), signin::PrimaryAccountAccessTokenFetcher::Mode::kWaitUntilAvailable, signin::ConsentLevel::kSignin);
diff --git a/components/password_manager/core/browser/sharing/password_sharing_recipients_downloader.cc b/components/password_manager/core/browser/sharing/password_sharing_recipients_downloader.cc index 27255632..4ffbede 100644 --- a/components/password_manager/core/browser/sharing/password_sharing_recipients_downloader.cc +++ b/components/password_manager/core/browser/sharing/password_sharing_recipients_downloader.cc
@@ -27,8 +27,6 @@ namespace { -constexpr char kPasswordSharingRecipientsOAuthConsumerName[] = - "PasswordSharingRecipients"; constexpr char kPasswordSharingRecipientsEndpoint[] = "password_sharing_recipients"; constexpr base::TimeDelta kRequestTimeout = base::Seconds(10); @@ -250,8 +248,8 @@ CHECK(!ongoing_access_token_fetch_); ongoing_access_token_fetch_ = std::make_unique<signin::PrimaryAccountAccessTokenFetcher>( - kPasswordSharingRecipientsOAuthConsumerName, identity_manager_, - signin::ScopeSet{GaiaConstants::kChromeSyncOAuth2Scope}, + signin::OAuthConsumerId::kPasswordSharingRecipientsDownloader, + identity_manager_, base::BindOnce( &PasswordSharingRecipientsDownloader::AccessTokenFetched, base::Unretained(this)),
diff --git a/components/signin/internal/identity_manager/oauth_consumer_registry.cc b/components/signin/internal/identity_manager/oauth_consumer_registry.cc index 2c3435f..e86b40fb 100644 --- a/components/signin/internal/identity_manager/oauth_consumer_registry.cc +++ b/components/signin/internal/identity_manager/oauth_consumer_registry.cc
@@ -47,6 +47,14 @@ constexpr char kPushNotificationName[] = "push_notification"; constexpr char kKAnonymityServiceName[] = "k_anonymity_service"; constexpr char kFeedbackUploaderName[] = "feedback_uploader"; +constexpr char kPasswordSharingRecipientsDownloaderName[] = + "password_sharing_recipients_downloader"; +constexpr char kWebHistoryServiceName[] = "web_history"; +constexpr char kComposeboxQueryControllerName[] = "ComposeboxQueryController"; +constexpr char kDocumentSuggestionsServiceName[] = + "document_suggestions_service"; +constexpr char kEnterpriseSearchAggregatorName[] = + "enterprise_search_aggregator"; } // namespace @@ -207,6 +215,26 @@ return OAuthConsumer( /*name=*/kFeedbackUploaderName, /*scopes=*/{GaiaConstants::kSupportContentOAuth2Scope}); + case OAuthConsumerId::kPasswordSharingRecipientsDownloader: + return OAuthConsumer( + /*name=*/kPasswordSharingRecipientsDownloaderName, + /*scopes=*/{GaiaConstants::kChromeSyncOAuth2Scope}); + case OAuthConsumerId::kWebHistoryService: + return OAuthConsumer( + /*name=*/kWebHistoryServiceName, + /*scopes=*/{GaiaConstants::kChromeSyncOAuth2Scope}); + case OAuthConsumerId::kComposeboxQueryController: + return OAuthConsumer( + /*name=*/kComposeboxQueryControllerName, + /*scopes=*/{GaiaConstants::kLensOAuth2Scope}); + case OAuthConsumerId::kDocumentSuggestionsService: + return OAuthConsumer( + /*name=*/kDocumentSuggestionsServiceName, + /*scopes=*/{GaiaConstants::kCloudSearchQueryOAuth2Scope}); + case OAuthConsumerId::kEnterpriseSearchAggregator: + return OAuthConsumer( + /*name=*/kEnterpriseSearchAggregatorName, + /*scopes=*/{GaiaConstants::kDiscoveryEngineCompleteQueryOAuth2Scope}); } NOTREACHED(); }
diff --git a/components/signin/public/identity_manager/oauth_consumer_ids.h b/components/signin/public/identity_manager/oauth_consumer_ids.h index 4280db30..8326e863 100644 --- a/components/signin/public/identity_manager/oauth_consumer_ids.h +++ b/components/signin/public/identity_manager/oauth_consumer_ids.h
@@ -43,7 +43,12 @@ kPushNotification = 28, kKAnonymityService = 29, kFeedbackUploader = 30, - kMaxValue = kFeedbackUploader, + kPasswordSharingRecipientsDownloader = 31, + kWebHistoryService = 32, + kComposeboxQueryController = 33, + kDocumentSuggestionsService = 34, + kEnterpriseSearchAggregator = 35, + kMaxValue = kEnterpriseSearchAggregator, }; // LINT.ThenChange(//tools/metrics/histograms/metadata/signin/enums.xml:OAuthConsumerId)
diff --git a/ios/chrome/browser/providers/BUILD.gn b/ios/chrome/browser/providers/BUILD.gn index 3962d324..6e209de 100644 --- a/ios/chrome/browser/providers/BUILD.gn +++ b/ios/chrome/browser/providers/BUILD.gn
@@ -19,6 +19,7 @@ "//ios/chrome/browser/providers/follow:chromium_follow", "//ios/chrome/browser/providers/font:chromium_font", "//ios/chrome/browser/providers/fullscreen:chromium_fullscreen", + "//ios/chrome/browser/providers/glow_effect:chromium_glow_effect", "//ios/chrome/browser/providers/google_one:chromium_google_one", "//ios/chrome/browser/providers/keyboard:chromium_keyboard", "//ios/chrome/browser/providers/lens:chromium_lens",
diff --git a/ios/chrome/browser/providers/glow_effect/BUILD.gn b/ios/chrome/browser/providers/glow_effect/BUILD.gn new file mode 100644 index 0000000..fe7ce1fe --- /dev/null +++ b/ios/chrome/browser/providers/glow_effect/BUILD.gn
@@ -0,0 +1,11 @@ +# Copyright 2025 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("chromium_glow_effect") { + sources = [ "chromium_glow_effect.mm" ] + deps = [ + "//base", + "//ios/public/provider/chrome/browser/glow_effect:glow_effect_api", + ] +}
diff --git a/ios/chrome/browser/providers/glow_effect/chromium_glow_effect.mm b/ios/chrome/browser/providers/glow_effect/chromium_glow_effect.mm new file mode 100644 index 0000000..79e594a --- /dev/null +++ b/ios/chrome/browser/providers/glow_effect/chromium_glow_effect.mm
@@ -0,0 +1,17 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/public/provider/chrome/browser/glow_effect/glow_effect_api.h" + +namespace ios { +namespace provider { + +UIView<GlowEffect>* CreateGlowEffect(CGRect frame, + CGFloat cornerRadius, + CGFloat borderWidth) { + return nil; +} + +} // namespace provider +} // namespace ios
diff --git a/ios/public/provider/chrome/browser/glow_effect/BUILD.gn b/ios/public/provider/chrome/browser/glow_effect/BUILD.gn new file mode 100644 index 0000000..02288bc --- /dev/null +++ b/ios/public/provider/chrome/browser/glow_effect/BUILD.gn
@@ -0,0 +1,10 @@ +# Copyright 2025 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/ios/ios_sdk.gni") + +source_set("glow_effect_api") { + sources = [ "glow_effect_api.h" ] + deps = [ "//base" ] +}
diff --git a/ios/public/provider/chrome/browser/glow_effect/glow_effect_api.h b/ios/public/provider/chrome/browser/glow_effect/glow_effect_api.h new file mode 100644 index 0000000..93a422aa --- /dev/null +++ b/ios/public/provider/chrome/browser/glow_effect/glow_effect_api.h
@@ -0,0 +1,41 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_PUBLIC_PROVIDER_CHROME_BROWSER_GLOW_EFFECT_GLOW_EFFECT_API_H_ +#define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_GLOW_EFFECT_GLOW_EFFECT_API_H_ + +#import <UIKit/UIKit.h> + +// Public API for the Glow Effect. +@protocol GlowEffect <NSObject> + +// The duration in seconds for one full 360-degree rotation. +@property(nonatomic, assign) CFTimeInterval rotationSpeedDuration; + +// The duration of the glow fade-in and fade-out animation. +@property(nonatomic, assign) CFTimeInterval fadeAnimationDuration; + +// Starts the glow animation. +- (void)startGlow; + +// Stops the glow animation. +- (void)stopGlow; + +@end + +namespace ios { +namespace provider { + +// Creates and returns a view that applies a glow effect on its border. `frame` +// is optional. +// TODO(crbug.com/440074963): This is used in a prototype, it has not been UX +// approved yet and should not be reused for now. +UIView<GlowEffect>* CreateGlowEffect(CGRect frame, + CGFloat cornerRadius, + CGFloat borderWidth); + +} // namespace provider +} // namespace ios + +#endif // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_GLOW_EFFECT_GLOW_EFFECT_API_H_
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 8d70d7ed..d113012 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2220,28 +2220,6 @@ ] } ], - "AutofillDetectFieldVisibility": [ - { - "platforms": [ - "android", - "android_webview", - "chromeos", - "chromeos_lacros", - "ios", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled_20250523", - "enable_features": [ - "AutofillDetectFieldVisibility" - ] - } - ] - } - ], "AutofillEnableBuyNowPayLaterDesktop": [ { "platforms": [
diff --git a/third_party/blink/renderer/core/frame/ad_tracker.cc b/third_party/blink/renderer/core/frame/ad_tracker.cc index c7959ab68..f75b40d7c 100644 --- a/third_party/blink/renderer/core/frame/ad_tracker.cc +++ b/third_party/blink/renderer/core/frame/ad_tracker.cc
@@ -195,8 +195,8 @@ return; } - auto it = ad_script_ids_.find(probe.function->ScriptId()); - if (it != ad_script_ids_.end() && !bottom_most_ad_script_.has_value()) { + auto it = ad_script_data_.find(probe.function->ScriptId()); + if (it != ad_script_data_.end() && !bottom_most_ad_script_.has_value()) { bottom_most_ad_script_ = probe.function->ScriptId(); } } @@ -349,9 +349,9 @@ // of script ids for ad frames. if (bottom_most_ad_script_.has_value()) { if (out_ad_script) { - auto it = ad_script_ids_.find(bottom_most_ad_script_.value()); - if (it != ad_script_ids_.end()) { - *out_ad_script = it->value; + auto it = ad_script_data_.find(bottom_most_ad_script_.value()); + if (it != ad_script_data_.end()) { + *out_ad_script = it->value.id; } } return true; @@ -362,7 +362,7 @@ // If we're not aware of any ad scripts at all, or any scripts in this // context, don't bother looking at the stack. - if (ad_script_ids_.empty()) { + if (ad_script_data_.empty()) { return false; } auto it = context_known_ad_scripts_.find(execution_context); @@ -379,12 +379,12 @@ return false; } - auto script_it = ad_script_ids_.find(top_script_id); - if (script_it != ad_script_ids_.end() && out_ad_script) { - *out_ad_script = script_it->value; + auto script_it = ad_script_data_.find(top_script_id); + if (script_it != ad_script_data_.end() && out_ad_script) { + *out_ad_script = script_it->value.id; } - return script_it != ad_script_ids_.end(); + return script_it != ad_script_data_.end(); } bool AdTracker::IsKnownAdScript(ExecutionContext* execution_context, @@ -436,11 +436,6 @@ auto it = context_known_ad_scripts_.find(execution_context); DCHECK(it != context_known_ad_scripts_.end()); - AdScriptIdentifier current_ad_script = AdScriptIdentifier( - GetDebuggerIdForContext(v8_context), script_id, script_name); - - ad_script_ids_.insert(script_id, current_ad_script); - const HashMap<String, std::unique_ptr<AdProvenance>>& known_ad_scripts_and_provenance = it->value; @@ -456,7 +451,11 @@ // URL, and are intended to share the same provenance. While this approach // might not perfectly mirror the script loading ancestry in all complex // scenarios, it's considered sufficient for our tracking purposes. - ad_script_provenances_.insert(current_ad_script, ad_provenance->Clone()); + ad_script_data_.insert( + script_id, + AdScriptData(AdScriptIdentifier(GetDebuggerIdForContext(v8_context), + script_id, script_name), + ad_provenance->Clone())); } AdTracker::AdScriptAncestry AdTracker::GetAncestry( @@ -469,18 +468,17 @@ bool max_size_reached = false; // TODO(yaoxia): Determine if we should CHECK that that the script ID in each - // step is guaranteed to be present in `ad_script_provenances_`. - auto provenance_it = ad_script_provenances_.find(ad_script); - if (provenance_it == ad_script_provenances_.end()) { + // step is guaranteed to be present in `ad_script_data_`. + auto provenance_it = ad_script_data_.find(ad_script.id); + if (provenance_it == ad_script_data_.end()) { return ancestry; } - // The input `ad_script` may not have a name set, but anything stored in - // ad_script_provenances_ should, so prefer that AdScriptIdentifier. - ancestry.ancestry_chain.push_back(provenance_it->key); + ancestry.ancestry_chain.push_back(provenance_it->value.id); - while (provenance_it != ad_script_provenances_.end()) { - const std::unique_ptr<AdProvenance>& ad_provenance = provenance_it->value; + while (provenance_it != ad_script_data_.end()) { + const std::unique_ptr<AdProvenance>& ad_provenance = + provenance_it->value.provenance; bool root_reached = false; switch (ad_provenance->Type()) { @@ -511,7 +509,7 @@ break; } - provenance_it = ad_script_provenances_.find(ancestry.ancestry_chain.back()); + provenance_it = ad_script_data_.find(ancestry.ancestry_chain.back().id); } base::UmaHistogramBoolean(
diff --git a/third_party/blink/renderer/core/frame/ad_tracker.h b/third_party/blink/renderer/core/frame/ad_tracker.h index b3a2039d..153e8ee 100644 --- a/third_party/blink/renderer/core/frame/ad_tracker.h +++ b/third_party/blink/renderer/core/frame/ad_tracker.h
@@ -202,6 +202,11 @@ friend class AdTrackerSimTest; friend class AdTrackerTest; + struct AdScriptData { + AdScriptIdentifier id; + std::unique_ptr<AdProvenance> provenance; + }; + // Similar to the public IsAdScriptInStack method but instead of returning an // ancestry chain, it returns only one script (the most immediate one). bool IsAdScriptInStackHelper( @@ -255,19 +260,11 @@ HeapHashMap<WeakMember<ExecutionContext>, KnownAdScriptsAndProvenance> context_known_ad_scripts_; - // Maps the identifier of a detected ad script to its AdProvenance. - HashMap<AdScriptIdentifier, std::unique_ptr<AdProvenance>> - ad_script_provenances_; + // A map of all known ad script ids to their metadata. + HashMap<int, AdScriptData> ad_script_data_; // The number of ad-related async tasks currently running in the stack. int running_ad_async_tasks_ = 0; - - // The known ad-related script ids. - // TODO(jkarlin): We don't use the debugger id in the - // AdScriptIdentifier for the AdTracker itself, it's just for dev-tools. See - // if we can remove it completely and just use script ids within the - // AdTracker. - HashMap<int, AdScriptIdentifier> ad_script_ids_; }; template <>
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index d240b7d..646e7ba0 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit d240b7de4d30af0769390eea62a27c1e648e8401 +Subproject commit 646e7ba054335255c4186c6be09fee796b518b48
diff --git a/tools/metrics/histograms/metadata/signin/enums.xml b/tools/metrics/histograms/metadata/signin/enums.xml index cb0a991..a7cf7d5 100644 --- a/tools/metrics/histograms/metadata/signin/enums.xml +++ b/tools/metrics/histograms/metadata/signin/enums.xml
@@ -735,6 +735,11 @@ <int value="28" label="Push Notification"/> <int value="29" label="K-Anonymity Service"/> <int value="30" label="Feedback Uploader"/> + <int value="31" label="Password Sharing Recipients Downloader"/> + <int value="32" label="Web History Service"/> + <int value="33" label="Composebox Query Controller"/> + <int value="34" label="Document Suggestions Service"/> + <int value="35" label="Enterprise Search Aggregator"/> </enum> <!-- LINT.ThenChange(//components/signin/public/identity_manager/oauth_consumer_ids.h:OAuthConsumerId) -->