diff --git a/.gn b/.gn index 7fd46d2c..4025cb90 100644 --- a/.gn +++ b/.gn
@@ -66,10 +66,11 @@ "//extensions/browser:*", # 20 errors "//extensions:*", # 75 errors "//headless:*", # 167 errors + "//ppapi/native_client/src/untrusted/pnacl_irt_shim:*", # 197 errors "//ppapi/proxy:ipc_sources", # 13 errors "//ppapi/proxy:proxy", # 5 errors "//ppapi/thunk:*", # 1071 errors - "//remoting/host/security_key:*", # 68 errors + "//remoting/host/security_key:*", # 10 errors "//remoting/host/win:*", # 43 errors "//remoting/ios/app/settings:*", # 6 errors "//remoting/protocol:*", # 3 errors
diff --git a/DEPS b/DEPS index e476285..e29e844 100644 --- a/DEPS +++ b/DEPS
@@ -222,7 +222,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '1c467774e56e591519bfd112e517705dec1e88dc', + 'skia_revision': 'e9ab391765c7a604a45a2c56a83ce77d3f5f4b4f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -238,7 +238,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': 'a3726e06b4f12ce30e754656c6214847f4da3864', + 'swiftshader_revision': '69deca60e70d2992ee3f49c1a981b8432864abc0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -581,7 +581,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '1d7b5f2e794c97d6a979961dca88b6c2a6a40c69', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'be99633db632f35459756a4ee33356e1d18d7aed', 'condition': 'checkout_ios', }, @@ -1343,7 +1343,7 @@ Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '3dd5b80bc4f172dd82925bb259cb7c82348409c5', 'src/third_party/openscreen/src': - Var('chromium_git') + '/openscreen' + '@' + '2e2730fe0190f72dadd631176d2f380b4a6186a8', + Var('chromium_git') + '/openscreen' + '@' + '223797e8b6f8e52f3b84c6e4240e2d941b46c6cb', 'src/third_party/openxr/src': { 'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + 'bf21ccb1007bb531b45d9978919a56ea5059c245', @@ -1360,7 +1360,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'b0345c864e4a2ddeeb3b5084fb6fc7b856957ac8', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f4ffdc1c0d10c444b6ca626319d6cdb20f8edae4', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1653,7 +1653,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@cf94984a3675b4f4ba8b1704caf84ddc9a64a833', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@1e4e6269e94b15d1aa0d48c1c5676060148dfc0f', 'condition': 'checkout_src_internal', }, @@ -1683,7 +1683,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': '5AGO5EZqpK0ZND-uQWyf96pSLYa3XMbKq1kjkswnThcC', + 'version': 'd_dtMSh01ZuOaZzP6xcjbXtXOzuNoI8_MzWVrH4BQNoC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/WATCHLISTS b/WATCHLISTS index 934082c..8d8a0fbb 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -1722,6 +1722,10 @@ 'startup': { 'filepath': 'chrome/browser/ui/startup/', }, + 'status_area': { + 'filepath': 'ash/system/'\ + '|google_apis/calendar/', + }, 'storage_service' : { 'filepath': 'components/services/storage/', }, @@ -2748,6 +2752,7 @@ 'timvolodine@chromium.org'], 'startup': ['grt+watch@chromium.org', 'pastarmovj+watch@chromium.org'], + 'status_area': ['cros-status-area-eng+watchlist@google.com'], 'storage_service': ['dmurph+watching-storageservice@chromium.org'], 'structured_headers': ['iclelland+watch@chromium.org'], 'styleguide': ['danakj+watch@chromium.org',
diff --git a/android_webview/browser/gfx/root_frame_sink.cc b/android_webview/browser/gfx/root_frame_sink.cc index b3e3afd..a47c826 100644 --- a/android_webview/browser/gfx/root_frame_sink.cc +++ b/android_webview/browser/gfx/root_frame_sink.cc
@@ -7,7 +7,6 @@ #include "android_webview/browser/gfx/child_frame.h" #include "android_webview/browser/gfx/display_scheduler_webview.h" #include "android_webview/browser/gfx/viz_compositor_thread_runner_webview.h" -#include "base/no_destructor.h" #include "base/trace_event/trace_event.h" #include "components/viz/common/surfaces/frame_sink_id_allocator.h" #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" @@ -18,8 +17,8 @@ namespace { viz::FrameSinkId AllocateParentSinkId() { - static base::NoDestructor<viz::FrameSinkIdAllocator> allocator(0u); - return allocator->NextFrameSinkId(); + static viz::FrameSinkIdAllocator allocator(0u); + return allocator.NextFrameSinkId(); } } // namespace
diff --git a/android_webview/browser/metrics/visibility_metrics_logger.cc b/android_webview/browser/metrics/visibility_metrics_logger.cc index 4686d59..c5cf6d7 100644 --- a/android_webview/browser/metrics/visibility_metrics_logger.cc +++ b/android_webview/browser/metrics/visibility_metrics_logger.cc
@@ -5,13 +5,11 @@ #include "android_webview/browser/metrics/visibility_metrics_logger.h" #include "base/metrics/histogram_macros.h" -#include "base/no_destructor.h" #include "base/rand_util.h" #include "base/time/time.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" -using base::NoDestructor; using content::BrowserThread; namespace android_webview { @@ -27,50 +25,45 @@ } base::HistogramBase* VisibilityMetricsLogger::GetGlobalVisibilityHistogram() { - static NoDestructor<base::HistogramBase*> histogram( - CreateHistogramForDurationTracking( - "Android.WebView.Visibility.Global", - static_cast<int>(VisibilityMetricsLogger::Visibility::kMaxValue))); - return *histogram; + static base::HistogramBase* histogram(CreateHistogramForDurationTracking( + "Android.WebView.Visibility.Global", + static_cast<int>(VisibilityMetricsLogger::Visibility::kMaxValue))); + return histogram; } base::HistogramBase* VisibilityMetricsLogger::GetPerWebViewVisibilityHistogram() { - static NoDestructor<base::HistogramBase*> histogram( - CreateHistogramForDurationTracking( - "Android.WebView.Visibility.PerWebView", - static_cast<int>(VisibilityMetricsLogger::Visibility::kMaxValue))); - return *histogram; + static base::HistogramBase* histogram(CreateHistogramForDurationTracking( + "Android.WebView.Visibility.PerWebView", + static_cast<int>(VisibilityMetricsLogger::Visibility::kMaxValue))); + return histogram; } base::HistogramBase* VisibilityMetricsLogger::GetGlobalOpenWebVisibilityHistogram() { - static NoDestructor<base::HistogramBase*> histogram( - CreateHistogramForDurationTracking( - "Android.WebView.WebViewOpenWebVisible.Global", - static_cast<int>( - VisibilityMetricsLogger::WebViewOpenWebVisibility::kMaxValue))); - return *histogram; + static base::HistogramBase* histogram(CreateHistogramForDurationTracking( + "Android.WebView.WebViewOpenWebVisible.Global", + static_cast<int>( + VisibilityMetricsLogger::WebViewOpenWebVisibility::kMaxValue))); + return histogram; } base::HistogramBase* VisibilityMetricsLogger::GetPerWebViewOpenWebVisibilityHistogram() { - static NoDestructor<base::HistogramBase*> histogram( - CreateHistogramForDurationTracking( - "Android.WebView.WebViewOpenWebVisible.PerWebView", - static_cast<int>( - VisibilityMetricsLogger::WebViewOpenWebVisibility::kMaxValue))); - return *histogram; + static base::HistogramBase* histogram(CreateHistogramForDurationTracking( + "Android.WebView.WebViewOpenWebVisible.PerWebView", + static_cast<int>( + VisibilityMetricsLogger::WebViewOpenWebVisibility::kMaxValue))); + return histogram; } base::HistogramBase* VisibilityMetricsLogger::GetOpenWebVisibileScreenPortionHistogram() { - static NoDestructor<base::HistogramBase*> histogram( - CreateHistogramForDurationTracking( - "Android.WebView.WebViewOpenWebVisible.ScreenPortion", - static_cast<int>(VisibilityMetricsLogger:: - WebViewOpenWebScreenPortion::kMaxValue))); - return *histogram; + static base::HistogramBase* histogram(CreateHistogramForDurationTracking( + "Android.WebView.WebViewOpenWebVisible.ScreenPortion", + static_cast<int>( + VisibilityMetricsLogger::WebViewOpenWebScreenPortion::kMaxValue))); + return histogram; } VisibilityMetricsLogger::VisibilityMetricsLogger() { @@ -318,4 +311,4 @@ } } -} // namespace android_webview \ No newline at end of file +} // namespace android_webview
diff --git a/android_webview/common/aw_content_client.cc b/android_webview/common/aw_content_client.cc index 41011ec..7083785 100644 --- a/android_webview/common/aw_content_client.cc +++ b/android_webview/common/aw_content_client.cc
@@ -46,7 +46,7 @@ base::StringPiece AwContentClient::GetDataResource( int resource_id, - ui::ScaleFactor scale_factor) { + ui::ResourceScaleFactor scale_factor) { // TODO(boliu): Used only by WebKit, so only bundle those resources for // Android WebView. return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(
diff --git a/android_webview/common/aw_content_client.h b/android_webview/common/aw_content_client.h index aa78102..6f103bb 100644 --- a/android_webview/common/aw_content_client.h +++ b/android_webview/common/aw_content_client.h
@@ -27,8 +27,9 @@ // ContentClient implementation. void AddAdditionalSchemes(Schemes* schemes) override; std::u16string GetLocalizedString(int message_id) override; - base::StringPiece GetDataResource(int resource_id, - ui::ScaleFactor scale_factor) override; + base::StringPiece GetDataResource( + int resource_id, + ui::ResourceScaleFactor scale_factor) override; base::RefCountedMemory* GetDataResourceBytes(int resource_id) override; void SetGpuInfo(const gpu::GPUInfo& gpu_info) override; bool UsingSynchronousCompositing() override;
diff --git a/android_webview/common/aw_resource_bundle.cc b/android_webview/common/aw_resource_bundle.cc index 2997db6..9bddb3d 100644 --- a/android_webview/common/aw_resource_bundle.cc +++ b/android_webview/common/aw_resource_bundle.cc
@@ -47,7 +47,7 @@ ui::ResourceBundle::InitSharedInstanceWithPakFileRegion(base::File(pak_fd), pak_region); - std::pair<int, ui::ScaleFactor> extra_paks[] = { + std::pair<int, ui::ResourceScaleFactor> extra_paks[] = { {kAndroidWebViewMainPakDescriptor, ui::SCALE_FACTOR_NONE}, {kAndroidWebView100PercentPakDescriptor, ui::SCALE_FACTOR_100P}};
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/ComponentsProviderServiceTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/ComponentsProviderServiceTest.java index ac982171..a841bc6 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/services/ComponentsProviderServiceTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/ComponentsProviderServiceTest.java
@@ -11,6 +11,7 @@ import android.os.ParcelFileDescriptor; import android.os.ResultReceiver; +import androidx.test.filters.MediumTest; import androidx.test.filters.SmallTest; import org.junit.After; @@ -20,21 +21,30 @@ import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; +import org.chromium.android_webview.common.SafeModeController; +import org.chromium.android_webview.common.services.ISafeModeService; +import org.chromium.android_webview.nonembedded.ComponentUpdaterResetSafeModeAction; import org.chromium.android_webview.services.ComponentsProviderService; +import org.chromium.android_webview.services.SafeModeService; import org.chromium.android_webview.test.AwActivityTestRule; import org.chromium.android_webview.test.AwJUnit4ClassRunner; +import org.chromium.android_webview.variations.VariationsSeedSafeModeAction; import org.chromium.base.ContextUtils; import org.chromium.base.FileUtils; import org.chromium.base.PathUtils; import org.chromium.base.test.util.Batch; +import org.chromium.base.test.util.Feature; import org.chromium.components.background_task_scheduler.TaskIds; import org.chromium.components.component_updater.IComponentsProviderService; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -48,6 +58,7 @@ */ @RunWith(Enclosed.class) public class ComponentsProviderServiceTest { + public static final String TEST_WEBVIEW_PACKAGE_NAME = "org.chromium.android_webview.shell"; private static final String TEST_FILE_NAME = "%s_%s_%s_testfile.tmp"; private static final File sDirectory = new File(PathUtils.getDataDirectory(), "components/cps/"); @@ -83,6 +94,7 @@ @Test @SmallTest + @Feature({"AndroidWebView"}) public void testInvalidComponent() throws Exception { final String componentId = "someInvalidComponentId"; final Bundle resultBundle = getFilesForComponentSync(componentId); @@ -91,6 +103,7 @@ @Test @SmallTest + @Feature({"AndroidWebView"}) public void testValidComponent() throws Exception { final String componentId = "testComponentA"; final String sequenceNumber = "1"; @@ -103,6 +116,7 @@ @Test @SmallTest + @Feature({"AndroidWebView"}) public void testMultipleVersions() throws Exception { final String componentId = "testComponentB"; final String sequenceNumber1 = "1"; @@ -121,6 +135,75 @@ assertBundleForValidComponent(resultBundle2, componentId, sequenceNumber2, version2); } + @Test + @MediumTest + @Feature({"AndroidWebView"}) + public void testComponentUpdaterReset() throws Throwable { + final String componentId = "testComponentA"; + final String sequenceNumber = "1"; + final String version = "2.3.4"; + createComponentFiles(componentId, sequenceNumber, version); + Bundle resultBundle = getFilesForComponentSync(componentId); + assertBundleForValidComponent(resultBundle, componentId, sequenceNumber, version); + + Intent intent = new Intent(ContextUtils.getApplicationContext(), SafeModeService.class); + final String componentUpdaterResetActionId = + new ComponentUpdaterResetSafeModeAction().getId(); + try (ServiceConnectionHelper helper = + new ServiceConnectionHelper(intent, Context.BIND_AUTO_CREATE)) { + ISafeModeService service = ISafeModeService.Stub.asInterface(helper.getBinder()); + service.setSafeMode(Arrays.asList(componentUpdaterResetActionId)); + } + + Assert.assertTrue("SafeMode should be enabled", + SafeModeController.getInstance().isSafeModeEnabled(TEST_WEBVIEW_PACKAGE_NAME)); + Set<String> actions = new HashSet<>(); + actions.add(componentUpdaterResetActionId); + Assert.assertEquals("Querying the ContentProvider should yield the action we set", + actions, + SafeModeController.getInstance().queryActions(TEST_WEBVIEW_PACKAGE_NAME)); + + resultBundle = getFilesForComponentSync(componentId); + Assert.assertNull(componentId + + " must return a null result Bundle while ComponentUpdaterReset is on", + resultBundle); + } + + @Test + @MediumTest + @Feature({"AndroidWebView"}) + public void testCPSIgnoresIrrelevantSafeModeAction() throws Throwable { + final String componentId = "testComponentA"; + final String sequenceNumber = "1"; + final String version = "2.3.4"; + createComponentFiles(componentId, sequenceNumber, version); + Bundle resultBundle = getFilesForComponentSync(componentId); + assertBundleForValidComponent(resultBundle, componentId, sequenceNumber, version); + + Intent intent = new Intent(ContextUtils.getApplicationContext(), SafeModeService.class); + final String variationsSeedSafeModeActionId = + new VariationsSeedSafeModeAction().getId(); + + try (ServiceConnectionHelper helper = + new ServiceConnectionHelper(intent, Context.BIND_AUTO_CREATE)) { + ISafeModeService service = ISafeModeService.Stub.asInterface(helper.getBinder()); + service.setSafeMode(Arrays.asList(variationsSeedSafeModeActionId)); + } + + Assert.assertTrue("SafeMode should be enabled", + SafeModeController.getInstance().isSafeModeEnabled(TEST_WEBVIEW_PACKAGE_NAME)); + Set<String> actions = new HashSet<>(); + actions.add(variationsSeedSafeModeActionId); + Assert.assertEquals("Querying the ContentProvider should yield the action we set", + actions, + SafeModeController.getInstance().queryActions(TEST_WEBVIEW_PACKAGE_NAME)); + + resultBundle = getFilesForComponentSync(componentId); + Assert.assertNotNull(componentId + + " must return a non-null Bundle while ComponentUpdaterReset is off", + resultBundle); + } + private Bundle getFilesForComponentSync(String componentId) throws Exception { final CountDownLatch latch = new CountDownLatch(1); final Bundle result = new Bundle(); @@ -180,6 +263,7 @@ @After public void tearDown() { cleanupFiles(); + SafeModeService.clearSharedPrefsForTesting(); } @Test @@ -238,6 +322,29 @@ /* expected = */ sequenceNumber + "_" + version, /* actual = */ files[0].getName()); } + + @Test + @MediumTest + @Feature({"AndroidWebView"}) + public void testComponentUpdaterResetCancelsUpdaterJob() throws Throwable { + final String componentUpdaterResetActionId = + new ComponentUpdaterResetSafeModeAction().getId(); + Intent intent = new Intent(ContextUtils.getApplicationContext(), SafeModeService.class); + try (ServiceConnectionHelper helper = + new ServiceConnectionHelper(intent, Context.BIND_AUTO_CREATE)) { + ISafeModeService safeModeService = + ISafeModeService.Stub.asInterface(helper.getBinder()); + safeModeService.setSafeMode(Arrays.asList(componentUpdaterResetActionId)); + } + + JobScheduler jobScheduler = + (JobScheduler) ContextUtils.getApplicationContext().getSystemService( + Context.JOB_SCHEDULER_SERVICE); + mService.onCreate(); + Assert.assertFalse("Service should have no updater job scheduled", + ComponentsProviderService.isJobScheduled( + jobScheduler, TaskIds.WEBVIEW_COMPONENT_UPDATE_JOB_ID)); + } } private static void createComponentFiles(
diff --git a/android_webview/nonembedded/BUILD.gn b/android_webview/nonembedded/BUILD.gn index 65054fdb..2b661a8b 100644 --- a/android_webview/nonembedded/BUILD.gn +++ b/android_webview/nonembedded/BUILD.gn
@@ -21,9 +21,11 @@ sources = [ "java/src/org/chromium/android_webview/nonembedded/AwComponentUpdateService.java", "java/src/org/chromium/android_webview/nonembedded/AwNonembeddedUmaRecorder.java", + "java/src/org/chromium/android_webview/nonembedded/ComponentUpdaterResetSafeModeAction.java", "java/src/org/chromium/android_webview/nonembedded/LicenseActivity.java", "java/src/org/chromium/android_webview/nonembedded/LicenseContentProvider.java", "java/src/org/chromium/android_webview/nonembedded/NetworkFetcherTask.java", + "java/src/org/chromium/android_webview/nonembedded/NonembeddedSafeModeActionsList.java", "java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java", ] deps = [ @@ -91,6 +93,7 @@ "java/src/org/chromium/android_webview/services/AwMinidumpUploadJobService.java", "java/src/org/chromium/android_webview/services/AwMinidumpUploaderDelegate.java", "java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java", + "java/src/org/chromium/android_webview/services/ComponentUpdaterSafeModeUtils.java", "java/src/org/chromium/android_webview/services/ComponentsProviderPathUtil.java", "java/src/org/chromium/android_webview/services/ComponentsProviderService.java", "java/src/org/chromium/android_webview/services/CrashReceiverService.java",
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwComponentUpdateService.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwComponentUpdateService.java index 8fbe05f0..ba934d0 100644 --- a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwComponentUpdateService.java +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwComponentUpdateService.java
@@ -10,6 +10,7 @@ import android.content.SharedPreferences; import android.os.SystemClock; +import org.chromium.android_webview.services.ComponentUpdaterSafeModeUtils; import org.chromium.android_webview.services.ComponentsProviderPathUtil; import org.chromium.base.Callback; import org.chromium.base.FileUtils; @@ -70,14 +71,18 @@ public boolean onStartJob(JobParameters params) { assert mJobParameters == null; mJobParameters = params; - return startUpdates(); + return maybeStartUpdates(); } // Called by JobScheduler. @Override public boolean onStopJob(JobParameters params) { + ComponentUpdaterSafeModeUtils.executeSafeModeIfEnabled( + new File(ComponentsProviderPathUtil.getComponentUpdateServiceDirectoryPath())); + // TODO(https://crbug.com/1221092): Stop native updates when onStopJob, onDestroy are // called. + setUnexpectedExit(false); mJobParameters = null; @@ -96,7 +101,7 @@ // Always keep the most recent startId as this is the one that should be used to stop // the service. mServiceStartedId = startId; - if (!startUpdates()) { + if (!maybeStartUpdates()) { stopSelf(startId); mServiceStartedId = 0; } @@ -109,10 +114,16 @@ * @return {@code true} if it successfully triggers component updates or if component are * already updating, {@code false} if it fails to trigger the updates. */ - private boolean startUpdates() { + private boolean maybeStartUpdates() { if (mIsUpdating) { return true; } + + if (ComponentUpdaterSafeModeUtils.executeSafeModeIfEnabled(new File( + ComponentsProviderPathUtil.getComponentUpdateServiceDirectoryPath()))) { + return false; + } + maybeRecordUnexpectedExit(); // TODO(http://crbug.com/1179297) look at doing this in a task on a background thread @@ -138,6 +149,9 @@ // Call the appropriate stop method according to how the service is launched. private void stopService() { mIsUpdating = false; + ComponentUpdaterSafeModeUtils.executeSafeModeIfEnabled( + new File(ComponentsProviderPathUtil.getComponentUpdateServiceDirectoryPath())); + // Service is launched as a started service. if (mServiceStartedId > 0) { stopSelf(mServiceStartedId);
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/ComponentUpdaterResetSafeModeAction.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/ComponentUpdaterResetSafeModeAction.java new file mode 100644 index 0000000..9348979 --- /dev/null +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/ComponentUpdaterResetSafeModeAction.java
@@ -0,0 +1,31 @@ +// Copyright 2021 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.android_webview.nonembedded; + +import androidx.annotation.NonNull; + +import org.chromium.android_webview.common.SafeModeAction; + +/** + * A {@link SafeModeAction} to reset Component Updater. + */ +public class ComponentUpdaterResetSafeModeAction implements SafeModeAction { + private static final String TAG = "WebViewSafeMode"; + + // This ID should not be changed or reused. + private static final String ID = "reset_component_updater"; + + @Override + @NonNull + public String getId() { + return ID; + } + + @Override + public void execute() { + // Each Component Updater Service will take requisite steps on startup. + // Do nothing here. + } +}
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/NonembeddedSafeModeActionsList.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/NonembeddedSafeModeActionsList.java new file mode 100644 index 0000000..25cf42050 --- /dev/null +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/NonembeddedSafeModeActionsList.java
@@ -0,0 +1,24 @@ +// Copyright 2021 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.android_webview.nonembedded; + +import org.chromium.android_webview.common.SafeModeAction; + +/** + * Exposes the SafeModeActions supported by nonembedded Component Updater services. + */ +public final class NonembeddedSafeModeActionsList { + // Do not instantiate this class. + private NonembeddedSafeModeActionsList() {} + + /** + * A list of SafeModeActions supported by nonembedded WebView processes. The set of actions to + * be executed will be specified by the nonembedded SafeModeService, however each action (if + * specified by the service) will be executed in the order listed below. + */ + public static final SafeModeAction[] sList = { + new ComponentUpdaterResetSafeModeAction(), + }; +}
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java index da53823..024a90b 100644 --- a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java
@@ -15,6 +15,7 @@ import org.chromium.android_webview.AwLocaleConfig; import org.chromium.android_webview.ProductConfig; import org.chromium.android_webview.common.CommandLineUtil; +import org.chromium.android_webview.common.SafeModeController; import org.chromium.android_webview.devui.util.WebViewPackageHelper; import org.chromium.base.ContextUtils; import org.chromium.base.Log; @@ -62,6 +63,12 @@ // MonochromeApplication has its own locale configuration already, so call this here // rather than in maybeInitProcessGlobals. ResourceBundle.setAvailablePakLocales(AwLocaleConfig.getWebViewSupportedPakLocales()); + + // Only register nonembedded SafeMode actions for webview_apk or webview_service processes. + if (isWebViewProcess()) { + SafeModeController controller = SafeModeController.getInstance(); + controller.registerActions(NonembeddedSafeModeActionsList.sList); + } } @Override
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/ComponentUpdaterSafeModeUtils.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/ComponentUpdaterSafeModeUtils.java new file mode 100644 index 0000000..ed498fd4 --- /dev/null +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/ComponentUpdaterSafeModeUtils.java
@@ -0,0 +1,53 @@ +// Copyright 2021 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.android_webview.services; + +import org.chromium.android_webview.common.SafeModeController; +import org.chromium.base.ContextUtils; +import org.chromium.base.FileUtils; +import org.chromium.base.Log; +import org.chromium.base.metrics.RecordHistogram; + +import java.io.File; +import java.util.Set; + +/** + * A util class for Component Updater Safe Mode operations. + */ +public class ComponentUpdaterSafeModeUtils { + private static final String TAG = "AwCUSafeMode"; + private static final String HISTOGRAM_COMPONENT_UPDATER_SAFEMODE_EXECUTED = + "Android.WebView.ComponentUpdater.SafeModeActionExecuted"; + + // Keep in sync with the ID in ComponentUpdaterResetSafeModeAction. + private static final String RESET_COMPONENT_UPDATER_SAFEMODE_ACTION_ID = + "reset_component_updater"; + + // Don't instantiate this class. + private ComponentUpdaterSafeModeUtils() {} + + /** + * Executes Component Updater Safe Mode actions, if Safe Mode is enabled. + * @param configDir The directory containing dynamic configs. + * @return true if any SafeMode actions were executed, false otherwise. + */ + public static boolean executeSafeModeIfEnabled(File configDir) { + SafeModeController controller = SafeModeController.getInstance(); + Set<String> actions = + controller.queryActions(ContextUtils.getApplicationContext().getPackageName()); + + if (actions.isEmpty() || !actions.contains(RESET_COMPONENT_UPDATER_SAFEMODE_ACTION_ID)) { + RecordHistogram.recordBooleanHistogram( + HISTOGRAM_COMPONENT_UPDATER_SAFEMODE_EXECUTED, false); + return false; + } + + if (!FileUtils.recursivelyDeleteFile(configDir, null)) { + Log.w(TAG, "Failed to delete " + configDir.getAbsolutePath()); + } + RecordHistogram.recordBooleanHistogram(HISTOGRAM_COMPONENT_UPDATER_SAFEMODE_EXECUTED, true); + return true; + } +}
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/ComponentsProviderService.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/ComponentsProviderService.java index d56b03d..2405517 100644 --- a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/ComponentsProviderService.java +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/ComponentsProviderService.java
@@ -66,15 +66,17 @@ // can't be reused. @IntDef({GetFilesResultCode.SUCCESS, GetFilesResultCode.FAILED_NOT_INSTALLED, GetFilesResultCode.FAILED_NO_VERSIONS, GetFilesResultCode.FAILED_NO_FDS, - GetFilesResultCode.FAILED_OPENING_FDS}) + GetFilesResultCode.FAILED_OPENING_FDS, + GetFilesResultCode.FAILED_COMPONENT_UPDATER_SAFEMODE_ENABLED}) private @interface GetFilesResultCode { int SUCCESS = 0; int FAILED_NOT_INSTALLED = 1; int FAILED_NO_VERSIONS = 2; int FAILED_NO_FDS = 3; int FAILED_OPENING_FDS = 4; + int FAILED_COMPONENT_UPDATER_SAFEMODE_ENABLED = 5; // Keep this one at the end and increment appropriately when adding new entries. - int COUNT = 5; + int COUNT = 6; } private File mDirectory; @@ -85,6 +87,16 @@ public void getFilesForComponent(String componentId, ResultReceiver resultReceiver) { final long startTime = System.currentTimeMillis(); + if (ComponentUpdaterSafeModeUtils.executeSafeModeIfEnabled(mDirectory)) { + Log.w(TAG, + "Component Updater Reset Mode enabled. Not handing out configs. " + + componentId); + resultReceiver.send(RESULT_FAILED, /* resultData = */ null); + recordGetFilesResultAndDuration( + GetFilesResultCode.FAILED_COMPONENT_UPDATER_SAFEMODE_ENABLED, startTime); + return; + } + // Note that there's no need to sanitize input because this method will check if there // is an existing folder under `mDirectory` with a name that equals the received // `componentId`. Because `mDirectory` is inside this application's data dir, only @@ -144,6 +156,14 @@ @Override public void onCreate() { mDirectory = new File(ComponentsProviderPathUtil.getComponentsServingDirectoryPath()); + if (ComponentUpdaterSafeModeUtils.executeSafeModeIfEnabled(mDirectory)) { + JobScheduler jobScheduler = + (JobScheduler) ContextUtils.getApplicationContext().getSystemService( + Context.JOB_SCHEDULER_SERVICE); + jobScheduler.cancel(JOB_ID); + return; + } + if (!mDirectory.exists() && !mDirectory.mkdirs()) { Log.e(TAG, "Failed to create directory " + mDirectory.getAbsolutePath()); return;
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index ecf2b079..0a4bee22 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -998,7 +998,6 @@ "system/holding_space/holding_space_tray_icon_preview.h", "system/holding_space/holding_space_util.cc", "system/holding_space/holding_space_util.h", - "system/holding_space/holding_space_view_builder.h", "system/holding_space/holding_space_view_delegate.cc", "system/holding_space/holding_space_view_delegate.h", "system/holding_space/pinned_files_bubble.cc", @@ -1627,6 +1626,8 @@ "wm/overview/overview_item.h", "wm/overview/overview_item_view.cc", "wm/overview/overview_item_view.h", + "wm/overview/overview_metrics.cc", + "wm/overview/overview_metrics.h", "wm/overview/overview_observer.h", "wm/overview/overview_session.cc", "wm/overview/overview_session.h",
diff --git a/ash/accelerators/accelerator_controller_impl.cc b/ash/accelerators/accelerator_controller_impl.cc index 96b0ea7..6be4ffb 100644 --- a/ash/accelerators/accelerator_controller_impl.cc +++ b/ash/accelerators/accelerator_controller_impl.cc
@@ -912,9 +912,9 @@ base::RecordAction(base::UserMetricsAction("Accel_Overview_F5")); OverviewController* overview_controller = Shell::Get()->overview_controller(); if (overview_controller->InOverviewSession()) - overview_controller->EndOverview(); + overview_controller->EndOverview(OverviewEndAction::kAccelerator); else - overview_controller->StartOverview(); + overview_controller->StartOverview(OverviewStartAction::kAccelerator); } void HandleToggleUnifiedDesktop() {
diff --git a/ash/accelerometer/accelerometer_reader.h b/ash/accelerometer/accelerometer_reader.h index ad19703c..91f8010 100644 --- a/ash/accelerometer/accelerometer_reader.h +++ b/ash/accelerometer/accelerometer_reader.h
@@ -10,12 +10,10 @@ #include "ash/public/cpp/tablet_mode_observer.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/no_destructor.h" #include "base/observer_list.h" namespace base { -template <typename T> -class NoDestructor; - class SequencedTaskRunner; } // namespace base
diff --git a/ash/accessibility/chromevox/touch_exploration_manager.cc b/ash/accessibility/chromevox/touch_exploration_manager.cc index 8c0c0e02..1efca099 100644 --- a/ash/accessibility/chromevox/touch_exploration_manager.cc +++ b/ash/accessibility/chromevox/touch_exploration_manager.cc
@@ -45,7 +45,6 @@ Shell::Get()->accessibility_controller()->AddObserver(this); Shell::Get()->activation_client()->AddObserver(this); keyboard::KeyboardUIController::Get()->AddObserver(this); - display::Screen::GetScreen()->AddObserver(this); UpdateTouchExplorationState(); } @@ -56,7 +55,6 @@ Shell::Get()->accessibility_controller()->RemoveObserver(this); Shell::Get()->activation_client()->RemoveObserver(this); keyboard::KeyboardUIController::Get()->RemoveObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); Shell::Get()->RemoveShellObserver(this); if (observing_window_) observing_window_->RemoveObserver(this);
diff --git a/ash/accessibility/chromevox/touch_exploration_manager.h b/ash/accessibility/chromevox/touch_exploration_manager.h index 6d0f8c07..da3939d 100644 --- a/ash/accessibility/chromevox/touch_exploration_manager.h +++ b/ash/accessibility/chromevox/touch_exploration_manager.h
@@ -96,6 +96,7 @@ RootWindowController* root_window_controller_; CrasAudioHandler* audio_handler_; aura::Window* observing_window_; + display::ScopedDisplayObserver display_observer_{this}; DISALLOW_COPY_AND_ASSIGN(TouchExplorationManager); };
diff --git a/ash/accessibility/magnifier/docked_magnifier_controller.cc b/ash/accessibility/magnifier/docked_magnifier_controller.cc index 2216d45f..2382331 100644 --- a/ash/accessibility/magnifier/docked_magnifier_controller.cc +++ b/ash/accessibility/magnifier/docked_magnifier_controller.cc
@@ -550,7 +550,8 @@ split_view_controller->EndSplitView( SplitViewController::EndReason::kNormal); } - overview_controller->EndOverview(); + overview_controller->EndOverview( + OverviewEndAction::kEnabledDockedMagnifier); } if (new_enabled) {
diff --git a/ash/accessibility/magnifier/docked_magnifier_controller_unittest.cc b/ash/accessibility/magnifier/docked_magnifier_controller_unittest.cc index 45f6f25..32168fe 100644 --- a/ash/accessibility/magnifier/docked_magnifier_controller_unittest.cc +++ b/ash/accessibility/magnifier/docked_magnifier_controller_unittest.cc
@@ -478,7 +478,7 @@ // Enable overview mode followed by the magnifier. auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); controller()->SetEnabled(true); EXPECT_TRUE(controller()->GetEnabled()); @@ -500,9 +500,8 @@ auto window = CreateTestWindow(); controller()->SetEnabled(true); - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); auto* root_window = Shell::GetPrimaryRootWindow(); const auto* desk_bar_view = GetOverviewSession() @@ -559,7 +558,7 @@ // Simulate going into split view, by enabling overview mode, and snapping // a window to the left. auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); split_view_controller()->SnapWindow(window.get(), SplitViewController::LEFT); EXPECT_EQ(split_view_controller()->state(), @@ -604,7 +603,7 @@ .Build(); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); EXPECT_EQ(split_view_controller()->InSplitViewMode(), false);
diff --git a/ash/accessibility/ui/accessibility_panel_layout_manager.cc b/ash/accessibility/ui/accessibility_panel_layout_manager.cc index 351c2488..b6872ec 100644 --- a/ash/accessibility/ui/accessibility_panel_layout_manager.cc +++ b/ash/accessibility/ui/accessibility_panel_layout_manager.cc
@@ -15,7 +15,6 @@ namespace ash { AccessibilityPanelLayoutManager::AccessibilityPanelLayoutManager() { - display::Screen::GetScreen()->AddObserver(this); Shell::Get()->activation_client()->AddObserver(this); Shell::Get()->AddShellObserver(this); } @@ -23,7 +22,6 @@ AccessibilityPanelLayoutManager::~AccessibilityPanelLayoutManager() { Shell::Get()->RemoveShellObserver(this); Shell::Get()->activation_client()->RemoveObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); } void AccessibilityPanelLayoutManager::SetAlwaysVisible(bool always_visible) {
diff --git a/ash/accessibility/ui/accessibility_panel_layout_manager.h b/ash/accessibility/ui/accessibility_panel_layout_manager.h index c42e3a2..18ba7d8c 100644 --- a/ash/accessibility/ui/accessibility_panel_layout_manager.h +++ b/ash/accessibility/ui/accessibility_panel_layout_manager.h
@@ -81,6 +81,8 @@ // Window bounds when not in fullscreen gfx::Rect panel_bounds_ = gfx::Rect(0, 0, 0, 0); + display::ScopedDisplayObserver display_observer_{this}; + // Determines whether panel is hidden when browser is in fullscreen. bool always_visible_ = false;
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc index cfc364f..4600725 100644 --- a/ash/app_list/app_list_controller_impl.cc +++ b/ash/app_list/app_list_controller_impl.cc
@@ -827,8 +827,10 @@ // If overview session is active (e.g. on one side of the split view), end // it immediately, to prevent overview UI being visible while transitioning // to home screen. - if (overview_controller->InOverviewSession()) - overview_controller->EndOverview(OverviewEnterExitType::kImmediateExit); + if (overview_controller->InOverviewSession()) { + overview_controller->EndOverview(OverviewEndAction::kEnterHomeLauncher, + OverviewEnterExitType::kImmediateExit); + } // End split view mode. split_view_controller->EndSplitView( @@ -838,7 +840,8 @@ // If overview is active (if overview was active in split view, it exited by // this point), just fade it out to home screen. if (overview_controller->InOverviewSession()) { - overview_controller->EndOverview(OverviewEnterExitType::kFadeOutExit); + overview_controller->EndOverview(OverviewEndAction::kEnterHomeLauncher, + OverviewEnterExitType::kFadeOutExit); return true; }
diff --git a/ash/app_list/app_list_controller_impl_unittest.cc b/ash/app_list/app_list_controller_impl_unittest.cc index f6cdafd..b634e99 100644 --- a/ash/app_list/app_list_controller_impl_unittest.cc +++ b/ash/app_list/app_list_controller_impl_unittest.cc
@@ -611,20 +611,20 @@ // closed. TEST_F(AppListControllerImplTest, CloseAppListShownFromOverviewAfterTabletExit) { + auto* shell = Shell::Get(); + auto* tablet_mode_controller = shell->tablet_mode_controller(); // Move to tablet mode and back. - Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); - Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false); + tablet_mode_controller->SetEnabledForTest(true); + tablet_mode_controller->SetEnabledForTest(false); std::unique_ptr<aura::Window> w( AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400))); - OverviewController* const overview_controller = - Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); // Press home button - verify overview exits and the app list is shown. PressHomeButton(); - EXPECT_FALSE(overview_controller->InOverviewSession()); + EXPECT_FALSE(shell->overview_controller()->InOverviewSession()); EXPECT_EQ(AppListViewState::kPeeking, GetAppListView()->app_list_state()); GetAppListTestHelper()->CheckVisibility(true); ASSERT_TRUE(GetAppListView()->GetWidget()); @@ -911,14 +911,13 @@ TEST_F(AppListControllerImplTest, HomeScreenVisibleAfterDisplayUpdateInOverview) { Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); - OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); // Trigger a display configuration change, this simulates screen rotation. Shell::Get()->app_list_controller()->OnDisplayConfigurationChanged(); // End overview mode, the home launcher should be visible. - overview_controller->EndOverview(); + ExitOverview(); ShellTestApi().WaitForOverviewAnimationState( OverviewAnimationState::kExitAnimationComplete);
diff --git a/ash/app_list/app_list_presenter_impl.cc b/ash/app_list/app_list_presenter_impl.cc index 4994e6a..0e90195 100644 --- a/ash/app_list/app_list_presenter_impl.cc +++ b/ash/app_list/app_list_presenter_impl.cc
@@ -127,7 +127,6 @@ AppListPresenterImpl::AppListPresenterImpl(AppListControllerImpl* controller) : controller_(controller) { DCHECK(controller_); - display_observation_.Observe(display::Screen::GetScreen()); } AppListPresenterImpl::~AppListPresenterImpl() {
diff --git a/ash/app_list/app_list_presenter_impl.h b/ash/app_list/app_list_presenter_impl.h index 6eeda62..bcecda6 100644 --- a/ash/app_list/app_list_presenter_impl.h +++ b/ash/app_list/app_list_presenter_impl.h
@@ -21,7 +21,6 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/scoped_multi_source_observation.h" -#include "base/scoped_observation.h" #include "ui/aura/client/focus_change_observer.h" #include "ui/aura/window_observer.h" #include "ui/compositor/layer_animation_observer.h" @@ -212,8 +211,7 @@ std::unique_ptr<AppListPresenterEventFilter> event_filter_; // An observer that notifies AppListView when the display has changed. - base::ScopedObservation<display::Screen, display::DisplayObserver> - display_observation_{this}; + display::ScopedDisplayObserver display_observer_{this}; // An observer that notifies AppListView when the shelf state has changed. base::ScopedMultiSourceObservation<Shelf, ShelfObserver> shelf_observation_{
diff --git a/ash/app_list/app_list_presenter_unittest.cc b/ash/app_list/app_list_presenter_unittest.cc index 265d42a..34c18ce 100644 --- a/ash/app_list/app_list_presenter_unittest.cc +++ b/ash/app_list/app_list_presenter_unittest.cc
@@ -4211,14 +4211,13 @@ GetAppListTestHelper()->CheckVisibility(true); // Enable overview mode. - OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); // Test that the AppListView is transparent. EXPECT_EQ(0.0f, GetAppListView()->GetWidget()->GetLayer()->opacity()); // Disable overview mode. - overview_controller->EndOverview(); + ExitOverview(); // Show the launcher, test that the opacity is restored. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); @@ -4263,13 +4262,13 @@ // Enable overview mode. OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); ui::Layer* layer = GetAppListView()->GetWidget()->GetNativeWindow()->layer(); EXPECT_EQ(0.0f, layer->opacity()); // Disable overview mode. - overview_controller->EndOverview(); + ExitOverview(); EXPECT_FALSE(overview_controller->InOverviewSession()); EXPECT_EQ(1.0f, layer->opacity()); } @@ -4300,12 +4299,11 @@ AppListShownAfterWallpaperPreviewAndExitOverviewMode) { EnableTabletMode(true); wallpaper_test_api_->StartWallpaperPreview(); - OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_FALSE(IsAppListVisible()); // Disable overview mode. - overview_controller->EndOverview(); + ExitOverview(); EXPECT_TRUE(IsAppListVisible()); } @@ -4367,7 +4365,7 @@ GetAppListTestHelper()->CheckVisibility(true); std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0)); OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); GoHome(); @@ -4387,7 +4385,7 @@ std::unique_ptr<aura::Window> dummy_window(CreateTestWindowInShellWithId(1)); OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); split_view_controller()->SnapWindow(window.get(), SplitViewController::LEFT);
diff --git a/ash/app_list/views/assistant/assistant_test_api_impl.cc b/ash/app_list/views/assistant/assistant_test_api_impl.cc index 2b9d9ac..d399398b 100644 --- a/ash/app_list/views/assistant/assistant_test_api_impl.cc +++ b/ash/app_list/views/assistant/assistant_test_api_impl.cc
@@ -145,7 +145,8 @@ } void AssistantTestApiImpl::StartOverview() { - Shell::Get()->overview_controller()->StartOverview(); + Shell::Get()->overview_controller()->StartOverview( + OverviewStartAction::kTests); } void AssistantTestApiImpl::SetConsentStatus(
diff --git a/ash/capture_mode/capture_mode_session.cc b/ash/capture_mode/capture_mode_session.cc index aec3db6..c4d0c3e 100644 --- a/ash/capture_mode/capture_mode_session.cc +++ b/ash/capture_mode/capture_mode_session.cc
@@ -567,7 +567,7 @@ TabletModeController::Get()->AddObserver(this); current_root_->AddObserver(this); - display::Screen::GetScreen()->AddObserver(this); + display_observer_.emplace(this); // Our event handling code assumes the capture bar widget has been initialized // already. So we start handling events after everything has been setup. aura::Env::GetInstance()->AddPreTargetHandler( @@ -588,7 +588,7 @@ is_shutting_down_ = true; aura::Env::GetInstance()->RemovePreTargetHandler(this); - display::Screen::GetScreen()->RemoveObserver(this); + display_observer_.reset(); current_root_->RemoveObserver(this); TabletModeController::Get()->RemoveObserver(this); if (input_capture_window_) {
diff --git a/ash/capture_mode/capture_mode_session.h b/ash/capture_mode/capture_mode_session.h index 634bdce..4b8601c 100644 --- a/ash/capture_mode/capture_mode_session.h +++ b/ash/capture_mode/capture_mode_session.h
@@ -359,6 +359,9 @@ // False only when we end the session to start recording. bool a11y_alert_on_session_exit_ = true; + // The display observer between init/shutdown. + absl::optional<display::ScopedDisplayObserver> display_observer_; + // True once Shutdown() is called. bool is_shutting_down_ = false;
diff --git a/ash/capture_mode/capture_mode_unittests.cc b/ash/capture_mode/capture_mode_unittests.cc index 319068c..7d6cdc4 100644 --- a/ash/capture_mode/capture_mode_unittests.cc +++ b/ash/capture_mode/capture_mode_unittests.cc
@@ -1719,7 +1719,7 @@ // Activation changes (such as opening overview) should not terminate the // countdown. start_countdown(); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); EXPECT_TRUE(controller->IsActive()); EXPECT_FALSE(controller->is_recording_in_progress());
diff --git a/ash/capture_mode/video_recording_watcher.cc b/ash/capture_mode/video_recording_watcher.cc index 69d46f3..25f8607 100644 --- a/ash/capture_mode/video_recording_watcher.cc +++ b/ash/capture_mode/video_recording_watcher.cc
@@ -203,7 +203,6 @@ if (recording_source_ == CaptureModeSource::kRegion) partial_region_bounds_ = controller_->user_capture_region(); - display::Screen::GetScreen()->AddObserver(this); window_being_recorded_->AddObserver(this); TabletModeController::Get()->AddObserver(this); @@ -233,7 +232,6 @@ ->cursor_window_controller() ->RemoveObserver(this); } - display::Screen::GetScreen()->RemoveObserver(this); window_being_recorded_->RemoveObserver(this); }
diff --git a/ash/capture_mode/video_recording_watcher.h b/ash/capture_mode/video_recording_watcher.h index 0846beb..6f90467f 100644 --- a/ash/capture_mode/video_recording_watcher.h +++ b/ash/capture_mode/video_recording_watcher.h
@@ -252,6 +252,9 @@ // If |window_being_recorded_| is not a root window, we must make a request to // make it capturable by the |FrameSinkVideoCapturer|. aura::ScopedWindowCaptureRequest non_root_window_capture_request_; + + // Register for DisplayObserver callbacks. + display::ScopedDisplayObserver display_observer_{this}; }; } // namespace ash
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 7729e88..1224a5c 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -418,6 +418,10 @@ const base::Feature kEnableNetworkingInDiagnosticsApp{ "EnableNetworkingInDiagnosticsApp", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables OAuth support when printing via the IPP protocol. +const base::Feature kEnableOAuthIpp{"EnableOAuthIpp", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables the OOBE ChromeVox hint dialog and announcement feature. const base::Feature kEnableOobeChromeVoxHint{"EnableOobeChromeVoxHint", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -1289,6 +1293,10 @@ base::FeatureList::IsEnabled(kDiagnosticsAppNavigation); } +bool IsOAuthIppEnabled() { + return base::FeatureList::IsEnabled(kEnableOAuthIpp); +} + bool IsNewOobeLayoutEnabled() { return base::FeatureList::IsEnabled(kNewOobeLayout); }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 2715a4f..011d0d80 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -168,6 +168,7 @@ extern const base::Feature kEnableLocalSearchService; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kEnableNetworkingInDiagnosticsApp; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kEnableOAuthIpp; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kEnableOobeChromeVoxHint; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kEnablePciguardUi; @@ -464,6 +465,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsNotificationScrollBarEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsNotificationsInContextMenuEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsNotificationsRefreshEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsOAuthIppEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsOobeChromeVoxHintEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPciguardUiEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPerDeskShelfEnabled();
diff --git a/ash/display/cros_display_config.cc b/ash/display/cros_display_config.cc index 6f2834f..b4214e1 100644 --- a/ash/display/cros_display_config.cc +++ b/ash/display/cros_display_config.cc
@@ -515,7 +515,6 @@ public ScreenOrientationController::Observer { public: explicit ObserverImpl() { - display::Screen::GetScreen()->AddObserver(this); Shell::Get()->tablet_mode_controller()->AddObserver(this); Shell::Get()->screen_orientation_controller()->AddObserver(this); } @@ -523,7 +522,6 @@ ~ObserverImpl() override { Shell::Get()->screen_orientation_controller()->RemoveObserver(this); Shell::Get()->tablet_mode_controller()->RemoveObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); } void AddObserver( @@ -564,6 +562,7 @@ } mojo::AssociatedRemoteSet<mojom::CrosDisplayConfigObserver> observers_; + display::ScopedDisplayObserver display_observer_{this}; DISALLOW_COPY_AND_ASSIGN(ObserverImpl); };
diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc index 851a1d70..3111c9e 100644 --- a/ash/display/display_manager_unittest.cc +++ b/ash/display/display_manager_unittest.cc
@@ -83,12 +83,12 @@ void SetUp() override { AshTestBase::SetUp(); - display::Screen::GetScreen()->AddObserver(this); + display_observer_.emplace(this); Shell::GetPrimaryRootWindow()->AddObserver(this); } void TearDown() override { Shell::GetPrimaryRootWindow()->RemoveObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); + display_observer_.reset(); AshTestBase::TearDown(); } @@ -182,6 +182,8 @@ bool root_window_destroyed_ = false; uint32_t changed_metrics_ = 0u; + absl::optional<display::ScopedDisplayObserver> display_observer_; + DISALLOW_COPY_AND_ASSIGN(DisplayManagerTest); };
diff --git a/ash/display/output_protection_delegate.cc b/ash/display/output_protection_delegate.cc index cc0bf1eb..aa90a2c 100644 --- a/ash/display/output_protection_delegate.cc +++ b/ash/display/output_protection_delegate.cc
@@ -49,14 +49,12 @@ return; window_->AddObserver(this); - display::Screen::GetScreen()->AddObserver(this); } OutputProtectionDelegate::~OutputProtectionDelegate() { if (!window_) return; - display::Screen::GetScreen()->RemoveObserver(this); window_->RemoveObserver(this); MaybeSetCaptureModeWindowProtection(window_, display::CONTENT_PROTECTION_METHOD_NONE); @@ -86,7 +84,7 @@ void OutputProtectionDelegate::OnWindowDestroying(aura::Window* window) { DCHECK_EQ(window, window_); - display::Screen::GetScreen()->RemoveObserver(this); + display_observer_.reset(); window_->RemoveObserver(this); MaybeSetCaptureModeWindowProtection(window_, display::CONTENT_PROTECTION_METHOD_NONE);
diff --git a/ash/display/output_protection_delegate.h b/ash/display/output_protection_delegate.h index 7bde0d1..e62fb71 100644 --- a/ash/display/output_protection_delegate.h +++ b/ash/display/output_protection_delegate.h
@@ -11,6 +11,7 @@ #include "ash/ash_export.h" #include "base/macros.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" #include "ui/display/display_observer.h" @@ -61,6 +62,8 @@ struct ClientIdHolder; std::unique_ptr<ClientIdHolder> client_; + absl::optional<display::ScopedDisplayObserver> display_observer_{this}; + DISALLOW_COPY_AND_ASSIGN(OutputProtectionDelegate); };
diff --git a/ash/display/overscan_calibrator.cc b/ash/display/overscan_calibrator.cc index b2148726..afb834e6 100644 --- a/ash/display/overscan_calibrator.cc +++ b/ash/display/overscan_calibrator.cc
@@ -20,7 +20,6 @@ #include "ui/compositor/paint_recorder.h" #include "ui/display/manager/display_manager.h" #include "ui/display/manager/managed_display_info.h" -#include "ui/display/screen.h" #include "ui/gfx/canvas.h" namespace ash { @@ -125,11 +124,9 @@ Shell::Get()->window_tree_host_manager()->SetOverscanInsets(display_.id(), gfx::Insets()); UpdateUILayer(); - display::Screen::GetScreen()->AddObserver(this); } OverscanCalibrator::~OverscanCalibrator() { - display::Screen::GetScreen()->RemoveObserver(this); // Overscan calibration has finished without commit, so the display has to // be the original offset. if (!committed_) {
diff --git a/ash/display/overscan_calibrator.h b/ash/display/overscan_calibrator.h index 87d8dfb..0e864d0 100644 --- a/ash/display/overscan_calibrator.h +++ b/ash/display/overscan_calibrator.h
@@ -70,6 +70,9 @@ // The visualization layer for the current calibration region. std::unique_ptr<ui::Layer> calibration_layer_; + // Register for DisplayObserver callbacks. + display::ScopedDisplayObserver display_observer_{this}; + DISALLOW_COPY_AND_ASSIGN(OverscanCalibrator); };
diff --git a/ash/display/persistent_window_controller.cc b/ash/display/persistent_window_controller.cc index 81613b9..443daf2f 100644 --- a/ash/display/persistent_window_controller.cc +++ b/ash/display/persistent_window_controller.cc
@@ -14,7 +14,6 @@ #include "base/containers/adapters.h" #include "base/metrics/histogram_macros.h" #include "ui/display/manager/display_manager.h" -#include "ui/display/screen.h" namespace ash { @@ -44,13 +43,9 @@ constexpr char PersistentWindowController::kNumOfWindowsRestoredHistogramName[]; -PersistentWindowController::PersistentWindowController() { - display::Screen::GetScreen()->AddObserver(this); -} +PersistentWindowController::PersistentWindowController() = default; -PersistentWindowController::~PersistentWindowController() { - display::Screen::GetScreen()->RemoveObserver(this); -} +PersistentWindowController::~PersistentWindowController() = default; void PersistentWindowController::OnWillProcessDisplayChanges() { if (!ShouldProcessWindowList())
diff --git a/ash/display/persistent_window_controller.h b/ash/display/persistent_window_controller.h index 85e64bd5..f3dbb747 100644 --- a/ash/display/persistent_window_controller.h +++ b/ash/display/persistent_window_controller.h
@@ -42,6 +42,9 @@ // Temporary storage that stores windows that may need persistent info // stored on display removal. Cleared when display changes are processed. aura::WindowTracker need_persistent_info_windows_; + + // Register for DisplayObserver callbacks. + display::ScopedDisplayObserver display_observer_{this}; }; } // namespace ash
diff --git a/ash/display/resolution_notification_controller.cc b/ash/display/resolution_notification_controller.cc index 2559a166..af5be2317 100644 --- a/ash/display/resolution_notification_controller.cc +++ b/ash/display/resolution_notification_controller.cc
@@ -21,7 +21,6 @@ #include "ui/display/display_features.h" #include "ui/display/manager/display_manager.h" #include "ui/display/manager/managed_display_info.h" -#include "ui/display/screen.h" namespace ash { @@ -67,12 +66,10 @@ ResolutionNotificationController::ResolutionNotificationController() { Shell::Get()->window_tree_host_manager()->AddObserver(this); - display::Screen::GetScreen()->AddObserver(this); } ResolutionNotificationController::~ResolutionNotificationController() { Shell::Get()->window_tree_host_manager()->RemoveObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); } bool ResolutionNotificationController::PrepareNotificationAndSetDisplayMode(
diff --git a/ash/display/resolution_notification_controller.h b/ash/display/resolution_notification_controller.h index 7de11c5..59b8100 100644 --- a/ash/display/resolution_notification_controller.h +++ b/ash/display/resolution_notification_controller.h
@@ -93,6 +93,8 @@ std::unique_ptr<ResolutionChangeInfo> change_info_; + display::ScopedDisplayObserver display_observer_{this}; + base::WeakPtr<DisplayChangeDialog> confirmation_dialog_; base::WeakPtrFactory<ResolutionNotificationController> weak_factory_{this};
diff --git a/ash/display/screen_orientation_controller.cc b/ash/display/screen_orientation_controller.cc index e5b91c513..a674638 100644 --- a/ash/display/screen_orientation_controller.cc +++ b/ash/display/screen_orientation_controller.cc
@@ -21,7 +21,6 @@ #include "ui/display/display.h" #include "ui/display/manager/display_manager.h" #include "ui/display/manager/managed_display_info.h" -#include "ui/display/screen.h" #include "ui/gfx/geometry/size.h" #include "ui/wm/public/activation_client.h" @@ -221,14 +220,12 @@ current_rotation_(display::Display::ROTATE_0) { Shell::Get()->tablet_mode_controller()->AddObserver(this); SplitViewController::Get(Shell::GetPrimaryRootWindow())->AddObserver(this); - display::Screen::GetScreen()->AddObserver(this); Shell::Get()->window_tree_host_manager()->AddObserver(this); AccelerometerReader::GetInstance()->AddObserver(this); } ScreenOrientationController::~ScreenOrientationController() { Shell::Get()->window_tree_host_manager()->RemoveObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); SplitViewController::Get(Shell::GetPrimaryRootWindow())->RemoveObserver(this); Shell::Get()->tablet_mode_controller()->RemoveObserver(this); AccelerometerReader::GetInstance()->RemoveObserver(this);
diff --git a/ash/display/screen_orientation_controller.h b/ash/display/screen_orientation_controller.h index 98283d22..355eb0a 100644 --- a/ash/display/screen_orientation_controller.h +++ b/ash/display/screen_orientation_controller.h
@@ -297,6 +297,9 @@ // orientation. std::unordered_map<aura::Window*, LockInfo> lock_info_map_; + // Register for DisplayObserver callbacks. + display::ScopedDisplayObserver display_observer_{this}; + DISALLOW_COPY_AND_ASSIGN(ScreenOrientationController); };
diff --git a/ash/display/window_tree_host_manager.cc b/ash/display/window_tree_host_manager.cc index de388a6f..63f0305 100644 --- a/ash/display/window_tree_host_manager.cc +++ b/ash/display/window_tree_host_manager.cc
@@ -235,7 +235,7 @@ WindowTreeHostManager::~WindowTreeHostManager() = default; void WindowTreeHostManager::Start() { - display::Screen::GetScreen()->AddObserver(this); + display_observer_.emplace(this); Shell::Get() ->display_configurator() ->content_protection_manager() @@ -269,7 +269,7 @@ ->display_configurator() ->content_protection_manager() ->RemoveObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); + display_observer_.reset(); int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
diff --git a/ash/display/window_tree_host_manager.h b/ash/display/window_tree_host_manager.h index 64d4365..d11c1cd 100644 --- a/ash/display/window_tree_host_manager.h +++ b/ash/display/window_tree_host_manager.h
@@ -205,6 +205,9 @@ // should be moved after a display configuration change. int64_t cursor_display_id_for_restore_; + // Receive DisplayObserver callbacks between Start and Shutdown. + absl::optional<display::ScopedDisplayObserver> display_observer_; + // A repeating timer to trigger sending UMA metrics for primary display's // effective resolution at fixed intervals. std::unique_ptr<base::RepeatingTimer> effective_resolution_UMA_timer_;
diff --git a/ash/display/window_tree_host_manager_unittest.cc b/ash/display/window_tree_host_manager_unittest.cc index c91454c..8547e32 100644 --- a/ash/display/window_tree_host_manager_unittest.cc +++ b/ash/display/window_tree_host_manager_unittest.cc
@@ -70,7 +70,6 @@ public: TestObserver() { Shell::Get()->window_tree_host_manager()->AddObserver(this); - display::Screen::GetScreen()->AddObserver(this); aura::client::GetFocusClient(Shell::GetPrimaryRootWindow()) ->AddObserver(this); ::wm::GetActivationClient(Shell::GetPrimaryRootWindow())->AddObserver(this); @@ -78,7 +77,6 @@ ~TestObserver() override { Shell::Get()->window_tree_host_manager()->RemoveObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); aura::client::GetFocusClient(Shell::GetPrimaryRootWindow()) ->RemoveObserver(this); ::wm::GetActivationClient(Shell::GetPrimaryRootWindow()) @@ -166,6 +164,8 @@ int focus_changed_count_ = 0; int activation_changed_count_ = 0; + display::ScopedDisplayObserver display_observer_{this}; + DISALLOW_COPY_AND_ASSIGN(TestObserver); };
diff --git a/ash/drag_drop/tab_drag_drop_delegate_unittest.cc b/ash/drag_drop/tab_drag_drop_delegate_unittest.cc index 909fdf1..44199a1 100644 --- a/ash/drag_drop/tab_drag_drop_delegate_unittest.cc +++ b/ash/drag_drop/tab_drag_drop_delegate_unittest.cc
@@ -74,7 +74,7 @@ // Create a dummy window and exit overview mode since drags can't be // initiated from overview mode. dummy_window_ = CreateToplevelTestWindow(); - ASSERT_TRUE(Shell::Get()->overview_controller()->EndOverview()); + ASSERT_TRUE(ExitOverview()); } void TearDown() override {
diff --git a/ash/frame/wide_frame_view.cc b/ash/frame/wide_frame_view.cc index 0f2dbfb..9100866 100644 --- a/ash/frame/wide_frame_view.cc +++ b/ash/frame/wide_frame_view.cc
@@ -92,7 +92,6 @@ std::make_unique<FrameContextMenuController>(target_, this)) { // WideFrameView is owned by its client, not by Views. SetOwnedByWidget(false); - display::Screen::GetScreen()->AddObserver(this); aura::Window* target_window = target->GetNativeWindow(); target_window->AddObserver(this); @@ -138,7 +137,6 @@ WideFrameView::~WideFrameView() { if (widget_) widget_->CloseNow(); - display::Screen::GetScreen()->RemoveObserver(this); if (target_) { HeaderView* target_header_view = GetTargetHeaderView(); target_header_view->SetShouldPaintHeader(true);
diff --git a/ash/frame/wide_frame_view.h b/ash/frame/wide_frame_view.h index eb0c116..73e55b9 100644 --- a/ash/frame/wide_frame_view.h +++ b/ash/frame/wide_frame_view.h
@@ -88,6 +88,8 @@ std::unique_ptr<views::Widget> widget_; + display::ScopedDisplayObserver display_observer_{this}; + HeaderView* header_view_ = nullptr; std::unique_ptr<FrameContextMenuController> frame_context_menu_controller_;
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc index 6b5a4a8..669a983 100644 --- a/ash/login/ui/lock_contents_view.cc +++ b/ash/login/ui/lock_contents_view.cc
@@ -588,7 +588,6 @@ std::make_unique<AutoLoginUserActivityHandler>(); data_dispatcher_->AddObserver(this); - display_observation_.Observe(display::Screen::GetScreen()); Shell::Get()->system_tray_notifier()->AddSystemTrayObserver(this); keyboard::KeyboardUIController::Get()->AddObserver(this);
diff --git a/ash/login/ui/lock_contents_view.h b/ash/login/ui/lock_contents_view.h index 4e46760..dbcb47c 100644 --- a/ash/login/ui/lock_contents_view.h +++ b/ash/login/ui/lock_contents_view.h
@@ -26,7 +26,6 @@ #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/scoped_observation.h" #include "chromeos/dbus/power/power_manager_client.h" #include "chromeos/dbus/power_manager/power_supply_properties.pb.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -465,8 +464,7 @@ // all actions are executed. std::vector<DisplayLayoutAction> layout_actions_; - base::ScopedObservation<display::Screen, display::DisplayObserver> - display_observation_{this}; + display::ScopedDisplayObserver display_observer_{this}; // All error bubbles and the tooltip view are child views of LockContentsView, // and will be torn down when LockContentsView is torn down.
diff --git a/ash/multi_user/user_switch_animator.cc b/ash/multi_user/user_switch_animator.cc index 14a8ea9f..145d328 100644 --- a/ash/multi_user/user_switch_animator.cc +++ b/ash/multi_user/user_switch_animator.cc
@@ -94,7 +94,8 @@ animation_step_(ANIMATION_STEP_HIDE_OLD_USER), screen_cover_(GetScreenCover(NULL)), windows_by_account_id_() { - Shell::Get()->overview_controller()->EndOverview(); + Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kUserSwitch); BuildUserToWindowsListMap(); AdvanceUserTransitionAnimation();
diff --git a/ash/public/cpp/app_list/app_list_config.h b/ash/public/cpp/app_list/app_list_config.h index e10589b3..0501c75 100644 --- a/ash/public/cpp/app_list/app_list_config.h +++ b/ash/public/cpp/app_list/app_list_config.h
@@ -7,15 +7,11 @@ #include "ash/public/cpp/app_list/app_list_types.h" #include "ash/public/cpp/ash_public_export.h" +#include "base/no_destructor.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/size.h" -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - namespace gfx { class FontList; }
diff --git a/ash/public/cpp/holding_space/holding_space_constants.h b/ash/public/cpp/holding_space/holding_space_constants.h index 66fa51a8..0386331 100644 --- a/ash/public/cpp/holding_space/holding_space_constants.h +++ b/ash/public/cpp/holding_space/holding_space_constants.h
@@ -71,8 +71,10 @@ // Note that this is not enforced for pinned items. constexpr base::TimeDelta kMaxFileAge = base::TimeDelta::FromDays(1); -// The maximum allowed number of downloads to display in holding space UI. +// The maximum allowed number of downloads to display in holding space UI in the +// default case or in the case in-progress downloads integration is enabled. constexpr size_t kMaxDownloads = 2u; +constexpr size_t kMaxDownloadsWithInProgressDownloadIntegration = 4u; // The maximum allowed number of screen captures to display in holding space UI. constexpr size_t kMaxScreenCaptures = 3u;
diff --git a/ash/public/cpp/holding_space/holding_space_progress.cc b/ash/public/cpp/holding_space/holding_space_progress.cc index 67dca09..5fc06ad8 100644 --- a/ash/public/cpp/holding_space/holding_space_progress.cc +++ b/ash/public/cpp/holding_space/holding_space_progress.cc
@@ -4,9 +4,24 @@ #include "ash/public/cpp/holding_space/holding_space_progress.h" +#include <limits> + #include "base/check_op.h" namespace ash { +namespace { + +// Helpers --------------------------------------------------------------------- + +// Returns whether or not the specified byte counts indicate completion. +bool CalculateComplete(const absl::optional<int64_t>& current_bytes, + const absl::optional<int64_t>& total_bytes) { + return current_bytes.has_value() && current_bytes == total_bytes; +} + +} // namespace + +// HoldingSpaceProgress -------------------------------------------------------- HoldingSpaceProgress::HoldingSpaceProgress() : HoldingSpaceProgress(/*current_bytes=*/0, @@ -15,11 +30,32 @@ HoldingSpaceProgress::HoldingSpaceProgress( const absl::optional<int64_t>& current_bytes, const absl::optional<int64_t>& total_bytes) - : current_bytes_(current_bytes), total_bytes_(total_bytes) { + : HoldingSpaceProgress(current_bytes, + total_bytes, + /*complete=*/absl::nullopt) {} + +HoldingSpaceProgress::HoldingSpaceProgress( + const absl::optional<int64_t>& current_bytes, + const absl::optional<int64_t>& total_bytes, + const absl::optional<bool>& complete) + : current_bytes_(current_bytes), + total_bytes_(total_bytes), + complete_( + complete.value_or(CalculateComplete(current_bytes_, total_bytes_))) { DCHECK_GE(current_bytes_.value_or(0), 0); DCHECK_GE(total_bytes_.value_or(0), 0); - if (current_bytes_.has_value() && total_bytes_.has_value()) - DCHECK_LE(current_bytes_.value(), total_bytes_.value()); + + if (!current_bytes_.has_value() || !total_bytes_.has_value()) { + DCHECK(!complete_); + return; + } + + if (complete_) { + DCHECK_EQ(current_bytes_.value(), total_bytes_.value()); + return; + } + + DCHECK_LE(current_bytes_.value(), total_bytes_.value()); } HoldingSpaceProgress::HoldingSpaceProgress(const HoldingSpaceProgress&) = @@ -31,8 +67,8 @@ HoldingSpaceProgress::~HoldingSpaceProgress() = default; bool HoldingSpaceProgress::operator==(const HoldingSpaceProgress& rhs) const { - return std::tie(current_bytes_, total_bytes_) == - std::tie(rhs.current_bytes_, rhs.total_bytes_); + return std::tie(current_bytes_, total_bytes_, complete_) == + std::tie(rhs.current_bytes_, rhs.total_bytes_, complete_); } HoldingSpaceProgress& HoldingSpaceProgress::operator+=( @@ -42,17 +78,16 @@ current_bytes_ = temp.current_bytes_; total_bytes_ = temp.total_bytes_; + complete_ = temp.complete_; return *this; } HoldingSpaceProgress HoldingSpaceProgress::operator+( const HoldingSpaceProgress& rhs) const { - absl::optional<int64_t> current_bytes(current_bytes_); - absl::optional<int64_t> total_bytes(total_bytes_); - // The number of `current_bytes` should only be present if present for both // the lhs and `rhs` instances. Otherwise `current_bytes` is indeterminate. + absl::optional<int64_t> current_bytes(current_bytes_); if (current_bytes.has_value()) { current_bytes = rhs.current_bytes_.has_value() ? absl::make_optional(current_bytes.value() + @@ -62,6 +97,7 @@ // The number of `total_bytes` should only be present if present for both the // lhs and `rhs` instances. Otherwise `total_bytes` is indeterminate. + absl::optional<int64_t> total_bytes(total_bytes_); if (total_bytes.has_value()) { total_bytes = rhs.total_bytes_.has_value() ? absl::make_optional(total_bytes.value() + @@ -69,20 +105,31 @@ : absl::nullopt; } - return HoldingSpaceProgress(current_bytes, total_bytes); + // The result of summing lhs and `rhs` instances is `complete` if and only if + // both the lhs and `rhs` are themselves complete. + const bool complete = complete_ && rhs.complete_; + + return HoldingSpaceProgress(current_bytes, total_bytes, complete); } absl::optional<float> HoldingSpaceProgress::GetValue() const { if (IsComplete()) return 1.f; + if (IsIndeterminate()) return absl::nullopt; + + // If `current_bytes_` == `total_bytes_` but progress is not complete, + // return a value that is extremely close but not equal to `1.f`. + if (current_bytes_.value() == total_bytes_.value()) + return 1.f - std::numeric_limits<float>::epsilon(); + return static_cast<double>(current_bytes_.value()) / static_cast<double>(total_bytes_.value()); } bool HoldingSpaceProgress::IsComplete() const { - return !IsIndeterminate() && current_bytes_ == total_bytes_; + return complete_; } bool HoldingSpaceProgress::IsIndeterminate() const {
diff --git a/ash/public/cpp/holding_space/holding_space_progress.h b/ash/public/cpp/holding_space/holding_space_progress.h index 8f96ca9..fa67f26 100644 --- a/ash/public/cpp/holding_space/holding_space_progress.h +++ b/ash/public/cpp/holding_space/holding_space_progress.h
@@ -21,6 +21,14 @@ HoldingSpaceProgress(const absl::optional<int64_t>& current_bytes, const absl::optional<int64_t>& total_bytes); + // Creates an instance for the specified `current_bytes` and `total_bytes` + // which is explicitly `complete` or incomplete. If absent, completion will be + // calculated based on `current_bytes` and `total_bytes`. If `true`, then it + // must also be true that `current_bytes.value()` == `total_bytes.value()`. + HoldingSpaceProgress(const absl::optional<int64_t>& current_bytes, + const absl::optional<int64_t>& total_bytes, + const absl::optional<bool>& complete); + HoldingSpaceProgress(const HoldingSpaceProgress&); HoldingSpaceProgress& operator=(const HoldingSpaceProgress&); ~HoldingSpaceProgress(); @@ -44,6 +52,7 @@ private: absl::optional<int64_t> current_bytes_; absl::optional<int64_t> total_bytes_; + bool complete_; }; } // namespace ash
diff --git a/ash/public/cpp/holding_space/holding_space_progress_unittest.cc b/ash/public/cpp/holding_space/holding_space_progress_unittest.cc index 9d92900..15b26e1 100644 --- a/ash/public/cpp/holding_space/holding_space_progress_unittest.cc +++ b/ash/public/cpp/holding_space/holding_space_progress_unittest.cc
@@ -4,6 +4,7 @@ #include "ash/public/cpp/holding_space/holding_space_progress.h" +#include <limits> #include <vector> #include "testing/gtest/include/gtest/gtest.h" @@ -20,24 +21,97 @@ EXPECT_FALSE(progress.IsIndeterminate()); } -// Verifies that `HoldingSpaceProgress(int64_t, int64_t)` is WAI. +// Verifies that `HoldingSpaceProgress(...)` is WAI. TEST_F(HoldingSpaceProgressTest, ExplicitConstructor) { - HoldingSpaceProgress progress(/*current_bytes=*/50, /*total_bytes=*/100); - EXPECT_EQ(progress.GetValue(), 0.5f); - EXPECT_FALSE(progress.IsComplete()); - EXPECT_FALSE(progress.IsIndeterminate()); + { + HoldingSpaceProgress progress(/*current_bytes=*/0, /*total_bytes=*/0); + EXPECT_EQ(progress.GetValue(), 1.f); + EXPECT_TRUE(progress.IsComplete()); + EXPECT_FALSE(progress.IsIndeterminate()); + } + { + HoldingSpaceProgress progress(/*current_bytes=*/0, /*total_bytes=*/0, + /*complete=*/false); + EXPECT_EQ(progress.GetValue(), 1.f - std::numeric_limits<float>::epsilon()); + EXPECT_FALSE(progress.IsComplete()); + EXPECT_FALSE(progress.IsIndeterminate()); + } + { + HoldingSpaceProgress progress(/*current_bytes=*/0, /*total_bytes=*/0, + /*complete=*/true); + EXPECT_EQ(progress.GetValue(), 1.f); + EXPECT_TRUE(progress.IsComplete()); + EXPECT_FALSE(progress.IsIndeterminate()); + } + { + HoldingSpaceProgress progress(/*current_bytes=*/50, /*total_bytes=*/100); + EXPECT_EQ(progress.GetValue(), 0.5f); + EXPECT_FALSE(progress.IsComplete()); + EXPECT_FALSE(progress.IsIndeterminate()); + } + { + HoldingSpaceProgress progress(/*current_bytes=*/50, /*total_bytes=*/100, + /*complete=*/false); + EXPECT_EQ(progress.GetValue(), 0.5f); + EXPECT_FALSE(progress.IsComplete()); + EXPECT_FALSE(progress.IsIndeterminate()); + } + { + HoldingSpaceProgress progress(/*current_bytes=*/100, /*total_bytes=*/100); + EXPECT_EQ(progress.GetValue(), 1.f); + EXPECT_TRUE(progress.IsComplete()); + EXPECT_FALSE(progress.IsIndeterminate()); + } + { + HoldingSpaceProgress progress(/*current_bytes=*/100, /*total_bytes=*/100, + /*complete=*/false); + EXPECT_EQ(progress.GetValue(), 1.f - std::numeric_limits<float>::epsilon()); + EXPECT_FALSE(progress.IsComplete()); + EXPECT_FALSE(progress.IsIndeterminate()); + } + { + HoldingSpaceProgress progress(/*current_bytes=*/100, /*total_bytes=*/100, + /*complete=*/true); + EXPECT_EQ(progress.GetValue(), 1.f); + EXPECT_TRUE(progress.IsComplete()); + EXPECT_FALSE(progress.IsIndeterminate()); + } } // Verifies that `HoldingSpaceProgress(const HoldingSpaceProgress&)` is WAI. TEST_F(HoldingSpaceProgressTest, CopyConstructor) { - HoldingSpaceProgress progress(/*current_bytes=*/50, /*total_bytes=*/100); + { + HoldingSpaceProgress progress(/*current_bytes=*/100, /*total_bytes=*/100); - HoldingSpaceProgress copy(progress); - EXPECT_EQ(copy.GetValue(), 0.5f); - EXPECT_FALSE(copy.IsComplete()); - EXPECT_FALSE(copy.IsIndeterminate()); + HoldingSpaceProgress copy(progress); + EXPECT_EQ(copy.GetValue(), 1.f); + EXPECT_TRUE(copy.IsComplete()); + EXPECT_FALSE(copy.IsIndeterminate()); - EXPECT_EQ(progress, copy); + EXPECT_EQ(progress, copy); + } + { + HoldingSpaceProgress progress(/*current_bytes=*/100, /*total_bytes=*/100, + /*complete=*/false); + + HoldingSpaceProgress copy(progress); + EXPECT_EQ(copy.GetValue(), 1.f - std::numeric_limits<float>::epsilon()); + EXPECT_FALSE(copy.IsComplete()); + EXPECT_FALSE(copy.IsIndeterminate()); + + EXPECT_EQ(progress, copy); + } + { + HoldingSpaceProgress progress(/*current_bytes=*/100, /*total_bytes=*/100, + /*complete=*/true); + + HoldingSpaceProgress copy(progress); + EXPECT_EQ(copy.GetValue(), 1.f); + EXPECT_TRUE(copy.IsComplete()); + EXPECT_FALSE(copy.IsIndeterminate()); + + EXPECT_EQ(progress, copy); + } } // Verifies that the `+` operator is WAI. @@ -48,23 +122,25 @@ HoldingSpaceProgress expected_result; }; - std::vector<TestCase> test_cases({ - {HoldingSpaceProgress(), HoldingSpaceProgress(), HoldingSpaceProgress()}, - {HoldingSpaceProgress(), HoldingSpaceProgress(absl::nullopt, 0), - HoldingSpaceProgress(absl::nullopt, 0)}, - {HoldingSpaceProgress(), HoldingSpaceProgress(0, absl::nullopt), - HoldingSpaceProgress(0, absl::nullopt)}, - {HoldingSpaceProgress(absl::nullopt, 1), - HoldingSpaceProgress(absl::nullopt, 1), - HoldingSpaceProgress(absl::nullopt, 2)}, - {HoldingSpaceProgress(1, absl::nullopt), - HoldingSpaceProgress(1, absl::nullopt), - HoldingSpaceProgress(2, absl::nullopt)}, - {HoldingSpaceProgress(50, 100), HoldingSpaceProgress(50, 100), - HoldingSpaceProgress(100, 200)}, - {HoldingSpaceProgress(100, 100), HoldingSpaceProgress(100, 100), - HoldingSpaceProgress(200, 200)}, - }); + std::vector<TestCase> test_cases( + {{HoldingSpaceProgress(), HoldingSpaceProgress(), HoldingSpaceProgress()}, + {HoldingSpaceProgress(), HoldingSpaceProgress(absl::nullopt, 0), + HoldingSpaceProgress(absl::nullopt, 0)}, + {HoldingSpaceProgress(), HoldingSpaceProgress(0, absl::nullopt), + HoldingSpaceProgress(0, absl::nullopt)}, + {HoldingSpaceProgress(absl::nullopt, 1), + HoldingSpaceProgress(absl::nullopt, 1), + HoldingSpaceProgress(absl::nullopt, 2)}, + {HoldingSpaceProgress(1, absl::nullopt), + HoldingSpaceProgress(1, absl::nullopt), + HoldingSpaceProgress(2, absl::nullopt)}, + {HoldingSpaceProgress(50, 100), HoldingSpaceProgress(50, 100), + HoldingSpaceProgress(100, 200)}, + {HoldingSpaceProgress(100, 100), HoldingSpaceProgress(100, 100), + HoldingSpaceProgress(200, 200)}, + {HoldingSpaceProgress(100, 100, true), + HoldingSpaceProgress(100, 100, false), + HoldingSpaceProgress(200, 200, false)}}); for (const auto& test_case : test_cases) EXPECT_EQ(test_case.lhs + test_case.rhs, test_case.expected_result); @@ -79,15 +155,17 @@ // Verifies that `HoldingSpaceProgress::GetValue()` is WAI. TEST_F(HoldingSpaceProgressTest, GetValue) { - std::vector<TestCase<absl::optional<float>>> test_cases({ - {HoldingSpaceProgress(), 1.f}, - {HoldingSpaceProgress(0, 0), 1.f}, - {HoldingSpaceProgress(absl::nullopt, absl::nullopt), absl::nullopt}, - {HoldingSpaceProgress(absl::nullopt, 0), absl::nullopt}, - {HoldingSpaceProgress(0, absl::nullopt), absl::nullopt}, - {HoldingSpaceProgress(50, 100), 0.5f}, - {HoldingSpaceProgress(100, 100), 1.f}, - }); + std::vector<TestCase<absl::optional<float>>> test_cases( + {{HoldingSpaceProgress(), 1.f}, + {HoldingSpaceProgress(0, 0), 1.f}, + {HoldingSpaceProgress(absl::nullopt, absl::nullopt), absl::nullopt}, + {HoldingSpaceProgress(absl::nullopt, 0), absl::nullopt}, + {HoldingSpaceProgress(0, absl::nullopt), absl::nullopt}, + {HoldingSpaceProgress(50, 100), 0.5f}, + {HoldingSpaceProgress(100, 100), 1.f}, + {HoldingSpaceProgress(100, 100, true), 1.f}, + {HoldingSpaceProgress(100, 100, false), + 1.f - std::numeric_limits<float>::epsilon()}}); for (const auto& test_case : test_cases) EXPECT_EQ(test_case.progress.GetValue(), test_case.expected_result); @@ -103,6 +181,8 @@ {HoldingSpaceProgress(0, absl::nullopt), false}, {HoldingSpaceProgress(50, 100), false}, {HoldingSpaceProgress(100, 100), true}, + {HoldingSpaceProgress(100, 100, true), true}, + {HoldingSpaceProgress(100, 100, false), false}, }); for (const auto& test_case : test_cases) @@ -119,6 +199,8 @@ {HoldingSpaceProgress(0, absl::nullopt), true}, {HoldingSpaceProgress(50, 100), false}, {HoldingSpaceProgress(100, 100), false}, + {HoldingSpaceProgress(100, 100, true), false}, + {HoldingSpaceProgress(100, 100, false), false}, }); for (const auto& test_case : test_cases)
diff --git a/ash/public/cpp/shelf_config.h b/ash/public/cpp/shelf_config.h index 01265b06..0b2b8f3 100644 --- a/ash/public/cpp/shelf_config.h +++ b/ash/public/cpp/shelf_config.h
@@ -16,6 +16,7 @@ #include "base/macros.h" #include "base/observer_list.h" #include "base/observer_list_types.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/display/display_observer.h" #include "ui/gfx/animation/tween.h" @@ -338,6 +339,9 @@ // config. std::unique_ptr<ShelfAccessibilityObserver> accessibility_observer_; + // Receive callbacks from DisplayObserver. + absl::optional<display::ScopedDisplayObserver> display_observer_; + base::ObserverList<Observer> observers_; DISALLOW_COPY_AND_ASSIGN(ShelfConfig);
diff --git a/ash/shelf/drag_window_from_shelf_controller.cc b/ash/shelf/drag_window_from_shelf_controller.cc index b450a597..4da046fb 100644 --- a/ash/shelf/drag_window_from_shelf_controller.cc +++ b/ash/shelf/drag_window_from_shelf_controller.cc
@@ -189,7 +189,9 @@ if (std::abs(scroll_y) <= kOpenOverviewThreshold && !overview_controller->InOverviewSession() && windows_hider_->WindowsMinimized()) { - overview_controller->StartOverview(OverviewEnterExitType::kImmediateEnter); + overview_controller->StartOverview( + OverviewStartAction::kDragWindowFromShelf, + OverviewEnterExitType::kImmediateEnter); OnWindowDragStartedInOverview(); } @@ -257,8 +259,10 @@ window_drag_result_ = absl::nullopt; if (ShouldGoToHomeScreen(location_in_screen, velocity_y)) { DCHECK(!in_splitview); - if (in_overview) - overview_controller->EndOverview(OverviewEnterExitType::kFadeOutExit); + if (in_overview) { + overview_controller->EndOverview(OverviewEndAction::kDragWindowFromShelf, + OverviewEnterExitType::kFadeOutExit); + } window_drag_result_ = ShelfWindowDragResult::kGoToHomeScreen; } else if (ShouldRestoreToOriginalBounds(location_in_screen, velocity_y)) { window_drag_result_ = ShelfWindowDragResult::kRestoreToOriginalBounds; @@ -299,8 +303,10 @@ // End overview if it was opened during dragging. OverviewController* overview_controller = Shell::Get()->overview_controller(); - if (overview_controller->InOverviewSession()) - overview_controller->EndOverview(OverviewEnterExitType::kImmediateExit); + if (overview_controller->InOverviewSession()) { + overview_controller->EndOverview(OverviewEndAction::kDragWindowFromShelf, + OverviewEnterExitType::kImmediateExit); + } ReshowHiddenWindowsOnDragEnd(); window_drag_result_ = ShelfWindowDragResult::kDragCanceled; @@ -719,6 +725,7 @@ base::AutoReset<bool> auto_reset(&during_window_restoration_callback_, true); if (end_overview) { Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kDragWindowFromShelf, OverviewEnterExitType::kImmediateExit); } ReshowHiddenWindowsOnDragEnd();
diff --git a/ash/shelf/drag_window_from_shelf_controller_unittest.cc b/ash/shelf/drag_window_from_shelf_controller_unittest.cc index 444a84b..99bb54b51 100644 --- a/ash/shelf/drag_window_from_shelf_controller_unittest.cc +++ b/ash/shelf/drag_window_from_shelf_controller_unittest.cc
@@ -280,7 +280,7 @@ EXPECT_TRUE(overview_controller->overview_session()->IsWindowInOverview( window1.get())); EXPECT_FALSE(window2->IsVisible()); - overview_controller->EndOverview(); + ExitOverview(); // If the dragged window is snapped in splitview, while the other windows are // showing in overview, do not reshow the hidden windows. @@ -518,7 +518,7 @@ EXPECT_TRUE(split_view_controller()->InSplitViewMode()); EXPECT_FALSE(split_view_controller()->IsWindowInSplitView(window1.get())); EXPECT_TRUE(split_view_controller()->IsWindowInSplitView(window2.get())); - overview_controller->EndOverview(); + ExitOverview(); // If the window is flung with a small velocity: StartDrag(window1.get(), shelf_bounds.left_center()); @@ -548,7 +548,7 @@ EXPECT_TRUE(split_view_controller()->InSplitViewMode()); EXPECT_FALSE(split_view_controller()->IsWindowInSplitView(window1.get())); EXPECT_TRUE(split_view_controller()->IsWindowInSplitView(window2.get())); - overview_controller->EndOverview(); + ExitOverview(); } // Test wallpaper should be blurred as in overview, even though overview might
diff --git a/ash/shelf/home_to_overview_nudge_controller_unittest.cc b/ash/shelf/home_to_overview_nudge_controller_unittest.cc index 59f61fc..57c6a61c 100644 --- a/ash/shelf/home_to_overview_nudge_controller_unittest.cc +++ b/ash/shelf/home_to_overview_nudge_controller_unittest.cc
@@ -256,13 +256,13 @@ EXPECT_FALSE(GetNudgeController()->HasHideTimerForTesting()); // Transitioning to overview should hide the nudge. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); EXPECT_FALSE(GetNudgeController()->nudge_for_testing()); // Ending overview, and transitioning to the home screen again should not show // the nudge. - Shell::Get()->overview_controller()->EndOverview(); + ExitOverview(); EXPECT_FALSE(GetNudgeController()->nudge_for_testing()); EXPECT_EQ(gfx::Transform(), GetHotseatWidget()->GetLayerForNudgeAnimation()->transform());
diff --git a/ash/shelf/hotseat_widget_unittest.cc b/ash/shelf/hotseat_widget_unittest.cc index c31dd9f..cc78e15 100644 --- a/ash/shelf/hotseat_widget_unittest.cc +++ b/ash/shelf/hotseat_widget_unittest.cc
@@ -179,7 +179,7 @@ // toggle overview. if (!navigation_buttons_shown_in_tablet_mode_ && Shell::Get()->tablet_mode_controller()->InTabletMode()) { - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); return; } @@ -199,7 +199,7 @@ // toggle overview. if (!navigation_buttons_shown_in_tablet_mode_ && Shell::Get()->tablet_mode_controller()->InTabletMode()) { - Shell::Get()->overview_controller()->EndOverview(); + ExitOverview(); return; } @@ -770,8 +770,7 @@ // Go into split view mode by first going into overview, and then snapping // the open window on one side. - OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); SplitViewController* split_view_controller = SplitViewController::Get(Shell::GetPrimaryRootWindow()); split_view_controller->SnapWindow(window.get(), SplitViewController::LEFT); @@ -1244,13 +1243,13 @@ { HotseatStateWatcher watcher(GetShelfLayoutManager()); // Enter overview by using the controller. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); WaitForOverviewAnimation(/*enter=*/true); watcher.CheckEqual({HotseatState::kExtended}); } - Shell::Get()->overview_controller()->EndOverview(); + ExitOverview(); WaitForOverviewAnimation(/*enter=*/false); // Test in-app -> overview again with the autohide shown shelf. @@ -1261,7 +1260,7 @@ { HotseatStateWatcher watcher(GetShelfLayoutManager()); // Enter overview by using the controller. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); WaitForOverviewAnimation(/*enter=*/true); watcher.CheckEqual({}); @@ -1277,11 +1276,11 @@ TabletModeControllerTestApi().EnterTabletMode(); DisplayWorkAreaChangeCounter counter; - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); WaitForOverviewAnimation(/*enter=*/true); EXPECT_EQ(0, counter.count()); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); WaitForOverviewAnimation(/*enter=*/true); EXPECT_EQ(0, counter.count()); } @@ -1442,7 +1441,7 @@ // This point will not be visible. auto* overview_controller = Shell::Get()->overview_controller(); auto* hotseat_widget = GetPrimaryShelf()->hotseat_widget(); - overview_controller->StartOverview(); + EnterOverview(); ASSERT_TRUE(overview_controller->InOverviewSession()); ASSERT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state()); gfx::Point far_left_point = @@ -1772,7 +1771,7 @@ wm::ActivateWindow(window.get()); OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); Shelf* const shelf = GetPrimaryShelf(); @@ -1822,7 +1821,7 @@ wm::ActivateWindow(window.get()); OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); SplitViewController* split_view_controller = SplitViewController::Get(Shell::GetPrimaryRootWindow());
diff --git a/ash/shelf/scrollable_shelf_view_unittest.cc b/ash/shelf/scrollable_shelf_view_unittest.cc index a74f46b..648a96a 100644 --- a/ash/shelf/scrollable_shelf_view_unittest.cc +++ b/ash/shelf/scrollable_shelf_view_unittest.cc
@@ -1458,7 +1458,7 @@ // Pin an app icon then enter the overview mode. Verify that app scaling is // turned on. const ShelfID shelf_id = AddAppShortcut(); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); WaitForOverviewAnimation(/*enter=*/true); EXPECT_EQ(HotseatDensity::kSemiDense, hotseat_widget->target_hotseat_density()); @@ -1470,7 +1470,7 @@ EXPECT_EQ(HotseatDensity::kNormal, hotseat_widget->target_hotseat_density()); // Exit overview mode. Verify the hotseat density. - Shell::Get()->overview_controller()->EndOverview(); + ExitOverview(); WaitForOverviewAnimation(/*enter=*/false); EXPECT_EQ(HotseatDensity::kNormal, hotseat_widget->target_hotseat_density()); }
diff --git a/ash/shelf/shelf_config.cc b/ash/shelf/shelf_config.cc index 2c7146a7..562334e 100644 --- a/ash/shelf/shelf_config.cc +++ b/ash/shelf/shelf_config.cc
@@ -158,7 +158,7 @@ Shell* const shell = Shell::Get(); shell->app_list_controller()->AddObserver(this); - display::Screen::GetScreen()->AddObserver(this); + display_observer_.emplace(this); shell->system_tray_model()->virtual_keyboard()->AddObserver(this); shell->overview_controller()->AddObserver(this); shell->session_controller()->AddObserver(this); @@ -175,7 +175,7 @@ shell->session_controller()->RemoveObserver(this); shell->overview_controller()->RemoveObserver(this); shell->system_tray_model()->virtual_keyboard()->RemoveObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); + display_observer_.reset(); shell->app_list_controller()->RemoveObserver(this); }
diff --git a/ash/shelf/shelf_config_unittest.cc b/ash/shelf/shelf_config_unittest.cc index 0df0f3f..a83fb2ec 100644 --- a/ash/shelf/shelf_config_unittest.cc +++ b/ash/shelf/shelf_config_unittest.cc
@@ -176,12 +176,11 @@ EXPECT_TRUE(ShelfConfig::Get()->is_in_app()); // Now go into overview. - OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(ShelfConfig::Get()->is_in_app()); // Back to the app. - overview_controller->EndOverview(); + ExitOverview(); EXPECT_TRUE(ShelfConfig::Get()->is_in_app()); // Leave the session.
diff --git a/ash/shelf/shelf_drag_handle_unittest.cc b/ash/shelf/shelf_drag_handle_unittest.cc index b45d102..850d3ea7 100644 --- a/ash/shelf/shelf_drag_handle_unittest.cc +++ b/ash/shelf/shelf_drag_handle_unittest.cc
@@ -790,7 +790,7 @@ DragHandle* const drag_handle = shelf_widget->GetDragHandle(); ASSERT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing()); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); ASSERT_FALSE(drag_handle->has_show_drag_handle_timer_for_testing()); } @@ -812,7 +812,7 @@ TabletModeControllerTestApi().LeaveTabletMode(); TabletModeControllerTestApi().EnterTabletMode(); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); ASSERT_FALSE(drag_handle->has_show_drag_handle_timer_for_testing()); GetEventGenerator()->GestureTapAt( @@ -844,8 +844,7 @@ // Go into split view mode by first going into overview, and then snapping // the open window on one side. - OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); SplitViewController* split_view_controller = SplitViewController::Get(shelf_widget->GetNativeWindow()); split_view_controller->SnapWindow(window.get(), SplitViewController::LEFT); @@ -875,8 +874,7 @@ // Go into split view mode by first going into overview, and then snapping // the open window on one side. - OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); SplitViewController* split_view_controller = SplitViewController::Get(shelf_widget->GetNativeWindow()); split_view_controller->SnapWindow(window.get(), SplitViewController::LEFT);
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 97dd6cb..ac56193 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -381,7 +381,6 @@ for (auto& observer : observers_) observer.WillDeleteShelfLayoutManager(); - display::Screen::GetScreen()->RemoveObserver(this); auto* shell = Shell::Get(); shell->locale_update_controller()->RemoveObserver(this); shell->RemoveShellObserver(this); @@ -405,7 +404,6 @@ state_.session_state = shell->session_controller()->GetSessionState(); shelf_background_type_ = GetShelfBackgroundType(); wallpaper_controller_observation_.Observe(shell->wallpaper_controller()); - display::Screen::GetScreen()->AddObserver(this); // DesksController could be null when virtual desks feature is not enabled. if (DesksController::Get())
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h index cb698048..a8ce5af 100644 --- a/ash/shelf/shelf_layout_manager.h +++ b/ash/shelf/shelf_layout_manager.h
@@ -637,6 +637,8 @@ base::ScopedObservation<WallpaperController, WallpaperControllerObserver> wallpaper_controller_observation_{this}; + display::ScopedDisplayObserver display_observer_{this}; + // Location of the most recent mouse drag event in screen coordinate. gfx::Point last_mouse_drag_position_;
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc index 33625ec..6acf153 100644 --- a/ash/shelf/shelf_layout_manager_unittest.cc +++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -154,10 +154,8 @@ class TestDisplayObserver : public display::DisplayObserver { public: - TestDisplayObserver() { display::Screen::GetScreen()->AddObserver(this); } - ~TestDisplayObserver() override { - display::Screen::GetScreen()->RemoveObserver(this); - } + TestDisplayObserver() = default; + ~TestDisplayObserver() override = default; int metrics_change_count() const { return metrics_change_count_; } @@ -168,6 +166,7 @@ metrics_change_count_++; } + display::ScopedDisplayObserver display_observer_{this}; int metrics_change_count_ = 0; DISALLOW_COPY_AND_ASSIGN(TestDisplayObserver); @@ -627,9 +626,8 @@ ShelfConfig::Get()->hidden_shelf_in_screen_portion(), GetShelfWidget()->GetWindowBoundsInScreen().y()); - OverviewController* overview_controller = Shell::Get()->overview_controller(); // Tests that the shelf is visible when in overview mode. - overview_controller->StartOverview(); + EnterOverview(); ShellTestApi().WaitForOverviewAnimationState( OverviewAnimationState::kEnterAnimationComplete); @@ -639,7 +637,7 @@ GetShelfWidget()->GetBackgroundType()); // Test that on exiting overview mode, the shelf returns to auto hide state. - overview_controller->EndOverview(); + ExitOverview(); ShellTestApi().WaitForOverviewAnimationState( OverviewAnimationState::kExitAnimationComplete); @@ -3071,8 +3069,7 @@ wm::ActivateWindow(window1.get()); // Starts the drag from the center of the shelf's bottom. - OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); gfx::Point start = shelf_widget_bounds.bottom_center(); StartScroll(start); UpdateScroll(-shelf_size - hotseat_size - hotseat_padding_size); @@ -3085,9 +3082,9 @@ SplitViewController::Get(Shell::GetPrimaryRootWindow()); split_view_controller->SnapWindow(window1.get(), SplitViewController::LEFT); split_view_controller->SnapWindow(window2.get(), SplitViewController::RIGHT); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(split_view_controller->InSplitViewMode()); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); StartScroll(shelf_widget_bounds.bottom_right()); UpdateScroll(-shelf_size - hotseat_size - hotseat_padding_size); EXPECT_FALSE(IsWindowDragInProgress()); @@ -3108,8 +3105,7 @@ window1->Hide(); EXPECT_EQ(HotseatState::kShownHomeLauncher, GetHotseatWidget()->state()); - OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); GetHotseatWidget()->SetState(HotseatState::kShownHomeLauncher); const gfx::Rect hotseat_bounds = GetHotseatWidget()->GetTargetBounds(); @@ -3123,7 +3119,7 @@ -(DragWindowFromShelfController::kVelocityToHomeScreenThreshold + 10)); // We should exit overview mode after completing the fling gesture. - EXPECT_FALSE(overview_controller->InOverviewSession()); + EXPECT_FALSE(Shell::Get()->overview_controller()->InOverviewSession()); } // Test that upward fling in overview transitions from overview to home. @@ -3137,8 +3133,7 @@ AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400)); wm::ActivateWindow(window1.get()); - OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); base::HistogramTester histogram_tester; HotseatStateWatcher watcher(GetShelfLayoutManager()); @@ -3150,7 +3145,7 @@ true /* is_fling */, -(DragWindowFromShelfController::kVelocityToHomeScreenThreshold + 10)); - EXPECT_FALSE(overview_controller->InOverviewSession()); + EXPECT_FALSE(Shell::Get()->overview_controller()->InOverviewSession()); watcher.WaitUntilStateChanged(); watcher.CheckEqual({HotseatState::kShownHomeLauncher}); @@ -3176,7 +3171,7 @@ WindowState::Get(window1.get())->Minimize(); OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); base::HistogramTester histogram_tester; @@ -3216,7 +3211,7 @@ split_view_controller->SnapWindow(window1.get(), SplitViewController::LEFT); split_view_controller->SnapWindow(window2.get(), SplitViewController::RIGHT); OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state()); @@ -3278,7 +3273,7 @@ split_view_controller->SnapWindow(window1.get(), SplitViewController::LEFT); split_view_controller->SnapWindow(window2.get(), SplitViewController::RIGHT); OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state()); @@ -3820,13 +3815,12 @@ ui::SHOW_STATE_FULLSCREEN); wm::ActivateWindow(fullscreen.get()); - OverviewController* overview_controller = Shell::Get()->overview_controller(); TestDisplayObserver observer; - overview_controller->StartOverview(); + EnterOverview(); WaitForOverviewAnimation(/*enter=*/true); ASSERT_TRUE(TabletModeControllerTestApi().IsTabletModeStarted()); EXPECT_EQ(0, observer.metrics_change_count()); - overview_controller->EndOverview(); + ExitOverview(); WaitForOverviewAnimation(/*enter=*/false); ASSERT_TRUE(TabletModeControllerTestApi().IsTabletModeStarted()); EXPECT_EQ(0, observer.metrics_change_count()); @@ -3851,8 +3845,7 @@ display_bounds.height()); // Change alignment during overview enter animation. - OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); // When setting the shelf alignment, bounds aren't expected to animate. shelf->SetAlignment(ShelfAlignment::kLeft); // Setting alignment exits overview which we should wait for. @@ -3860,9 +3853,9 @@ EXPECT_EQ(left_shelf_bounds, GetShelfWidget()->GetWindowBoundsInScreen()); // Change alignment during overview exit animation. - overview_controller->StartOverview(); + EnterOverview(); WaitForOverviewAnimation(/*enter=*/true); - overview_controller->EndOverview(); + ExitOverview(); // When setting the shelf alignment, bounds aren't expected to animate. shelf->SetAlignment(ShelfAlignment::kBottom); WaitForOverviewAnimation(/*enter=*/false);
diff --git a/ash/shelf/swipe_home_to_overview_controller.cc b/ash/shelf/swipe_home_to_overview_controller.cc index f21518ed..3ed3dd0d 100644 --- a/ash/shelf/swipe_home_to_overview_controller.cc +++ b/ash/shelf/swipe_home_to_overview_controller.cc
@@ -196,7 +196,8 @@ // NOTE: No need to update the home launcher opacity and scale here - the // AppListControllerImpl will update the home launcher state when it detects // that the overview is starting. - Shell::Get()->overview_controller()->StartOverview(); + Shell::Get()->overview_controller()->StartOverview( + OverviewStartAction::kExitHomeLauncher); // No need to keep blur disabled for the drag - note that blur might remain // disabled at this point due to the started overview transition (which
diff --git a/ash/shell_unittest.cc b/ash/shell_unittest.cc index d704db05..5f5b0170 100644 --- a/ash/shell_unittest.cc +++ b/ash/shell_unittest.cc
@@ -552,12 +552,11 @@ // Confirm that pressing tab when overview mode is open does not go to home // button. Tab should be handled by overview mode and not hit the shell event // handler. - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); generator->PressKey(ui::VKEY_TAB, ui::EF_NONE); generator->ReleaseKey(ui::VKEY_TAB, ui::EF_NONE); EXPECT_FALSE(home_button->GetNativeView()->HasFocus()); - overview_controller->EndOverview(); + ExitOverview(); // Hit shift tab and expect that focus is on status widget. generator->PressKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
diff --git a/ash/system/audio/display_speaker_controller.cc b/ash/system/audio/display_speaker_controller.cc index c0722f2..432430a92 100644 --- a/ash/system/audio/display_speaker_controller.cc +++ b/ash/system/audio/display_speaker_controller.cc
@@ -9,7 +9,6 @@ #include "third_party/cros_system_api/dbus/service_constants.h" #include "ui/display/manager/display_manager.h" #include "ui/display/manager/managed_display_info.h" -#include "ui/display/screen.h" inline cras::DisplayRotation ToCRASDisplayRotation( display::Display::Rotation rotation) { @@ -28,13 +27,11 @@ namespace ash { DisplaySpeakerController::DisplaySpeakerController() { - display::Screen::GetScreen()->AddObserver(this); chromeos::PowerManagerClient::Get()->AddObserver(this); } DisplaySpeakerController::~DisplaySpeakerController() { chromeos::PowerManagerClient::Get()->RemoveObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); } void DisplaySpeakerController::OnDisplayAdded(
diff --git a/ash/system/audio/display_speaker_controller.h b/ash/system/audio/display_speaker_controller.h index 336e8bf..8985e71 100644 --- a/ash/system/audio/display_speaker_controller.h +++ b/ash/system/audio/display_speaker_controller.h
@@ -31,6 +31,9 @@ private: // Update the state of internal speakers based on orientation. void UpdateInternalSpeakerForDisplayRotation(); + + display::ScopedDisplayObserver display_observer_{this}; + DISALLOW_COPY_AND_ASSIGN(DisplaySpeakerController); };
diff --git a/ash/system/holding_space/downloads_section.cc b/ash/system/holding_space/downloads_section.cc index 6280d51..97a18ab 100644 --- a/ash/system/holding_space/downloads_section.cc +++ b/ash/system/holding_space/downloads_section.cc
@@ -6,6 +6,7 @@ #include "ash/bubble/bubble_utils.h" #include "ash/bubble/simple_grid_layout.h" +#include "ash/constants/ash_features.h" #include "ash/public/cpp/holding_space/holding_space_client.h" #include "ash/public/cpp/holding_space/holding_space_constants.h" #include "ash/public/cpp/holding_space/holding_space_controller.h" @@ -138,7 +139,10 @@ HoldingSpaceItem::Type::kLacrosDownload, HoldingSpaceItem::Type::kNearbyShare, HoldingSpaceItem::Type::kPrintedPdf, HoldingSpaceItem::Type::kScan}, - /*max_count=*/kMaxDownloads) {} + /*max_count=*/ + features::IsHoldingSpaceInProgressDownloadsIntegrationEnabled() + ? kMaxDownloadsWithInProgressDownloadIntegration + : kMaxDownloads) {} DownloadsSection::~DownloadsSection() = default;
diff --git a/ash/system/holding_space/holding_space_item_chip_view.cc b/ash/system/holding_space/holding_space_item_chip_view.cc index 2b85d9e3..4e93a1ba 100644 --- a/ash/system/holding_space/holding_space_item_chip_view.cc +++ b/ash/system/holding_space/holding_space_item_chip_view.cc
@@ -17,7 +17,6 @@ #include "ash/style/ash_color_provider.h" #include "ash/system/holding_space/holding_space_item_view.h" #include "ash/system/holding_space/holding_space_progress_ring.h" -#include "ash/system/holding_space/holding_space_view_builder.h" #include "ash/system/holding_space/holding_space_view_delegate.h" #include "base/bind.h" #include "ui/base/metadata/metadata_impl_macros.h" @@ -37,7 +36,6 @@ #include "ui/views/layout/box_layout_view.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/layout/flex_layout.h" -#include "ui/views/metadata/view_factory.h" namespace ash { namespace { @@ -95,6 +93,19 @@ using Callback = base::RepeatingCallback<void(views::Label*, gfx::Canvas*)>; void SetCallback(Callback callback) { callback_ = std::move(callback); } + void SetPaintToLayer(bool fills_bounds_opaquely) { + views::Label::SetPaintToLayer(); + layer()->SetFillsBoundsOpaquely(fills_bounds_opaquely); + } + + void SetStyle(bubble_utils::LabelStyle style) { + bubble_utils::ApplyStyle(this, style); + } + + void SetViewAccessibilityIsIgnored(bool is_ignored) { + GetViewAccessibility().OverrideIsIgnored(is_ignored); + } + private: // views::Label: void OnPaint(gfx::Canvas* canvas) override { @@ -108,6 +119,9 @@ BEGIN_VIEW_BUILDER(/*no export*/, PaintCallbackLabel, views::Label) VIEW_BUILDER_PROPERTY(PaintCallbackLabel::Callback, Callback) +VIEW_BUILDER_PROPERTY(bubble_utils::LabelStyle, Style) +VIEW_BUILDER_PROPERTY(bool, PaintToLayer) +VIEW_BUILDER_PROPERTY(bool, ViewAccessibilityIsIgnored) END_VIEW_BUILDER // ProgressRingView ------------------------------------------------------------ @@ -162,38 +176,24 @@ // Helpers --------------------------------------------------------------------- -// Returns a label builder with given `style`, `elide_behavior`, and `callback`. -std::unique_ptr<HoldingSpaceViewBuilder<views::Label>> CreateLabelBuilder( - bubble_utils::LabelStyle style, - gfx::ElideBehavior elide_behavior, - PaintCallbackLabel::Callback callback) { - auto label = views::Builder<PaintCallbackLabel>() - .SetCallback(std::move(callback)) - .SetElideBehavior(elide_behavior) - .SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT) - .SetPaintToLayer() - .Build(); - - // NOTE: A11y events are handled by `HoldingSpaceItemChipView`. - label->GetViewAccessibility().OverrideIsIgnored(true); - label->layer()->SetFillsBoundsOpaquely(false); - bubble_utils::ApplyStyle(label.get(), style); - return std::make_unique<HoldingSpaceViewBuilder<views::Label>>( - std::move(label)); +// Returns a label builder. +// NOTE: A11y events are handled by `HoldingSpaceItemChipView`. +views::Builder<PaintCallbackLabel> CreateLabelBuilder() { + auto label = views::Builder<PaintCallbackLabel>(); + label.SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT) + .SetPaintToLayer(/*fills_bounds_opaquely=*/false) + .SetViewAccessibilityIsIgnored(true); + return label; } -// Returns a secondary action builder that invokes `callback` on press. -std::unique_ptr<views::Builder<views::ImageButton>> -CreateSecondaryActionBuilder(views::ImageButton::PressedCallback callback) { +// Returns a secondary action builder. +views::Builder<views::ImageButton> CreateSecondaryActionBuilder() { using HorizontalAlignment = views::ImageButton::HorizontalAlignment; using VerticalAlignment = views::ImageButton::VerticalAlignment; - auto secondary_action = - std::make_unique<views::Builder<views::ImageButton>>(); - secondary_action->SetCallback(std::move(callback)) - .SetFocusBehavior(views::View::FocusBehavior::NEVER) + auto secondary_action = views::Builder<views::ImageButton>(); + secondary_action.SetFocusBehavior(views::View::FocusBehavior::NEVER) .SetImageHorizontalAlignment(HorizontalAlignment::ALIGN_CENTER) - .SetImageVerticalAlignment(VerticalAlignment::ALIGN_MIDDLE) - .SetVisible(false); + .SetImageVerticalAlignment(VerticalAlignment::ALIGN_MIDDLE); return secondary_action; } @@ -231,74 +231,71 @@ base::BindRepeating(&HoldingSpaceItemChipView::OnSecondaryActionPressed, base::Unretained(this)); - HoldingSpaceViewBuilder<HoldingSpaceItemChipView>(this) + views::Builder<HoldingSpaceItemChipView>(this) .SetPreferredSize(gfx::Size(kPreferredWidth, kPreferredHeight)) .SetLayoutManager(std::move(layout_manager)) .AddChild( - HoldingSpaceViewBuilder<views::View>( - views::Builder<ProgressRingView>() - .SetHoldingSpaceItem(item) - .SetUseDefaultFillLayout(true)) + views::Builder<ProgressRingView>() + .SetHoldingSpaceItem(item) + .SetUseDefaultFillLayout(true) + .AddChild(views::Builder<ObservableRoundedImageView>() + .SetCornerRadius(kHoldingSpaceChipIconSize / 2) + .SetBoundsChangedCallback(base::BindRepeating( + &HoldingSpaceItemChipView::UpdateImageTransform, + base::Unretained(this))) + .CopyAddressTo(&image_) + .SetID(kHoldingSpaceItemImageId)) + .AddChild(CreateCheckmarkBuilder()) .AddChild( - HoldingSpaceViewBuilder<RoundedImageView>( - views::Builder<ObservableRoundedImageView>() - .SetCornerRadius(kHoldingSpaceChipIconSize / 2) - .SetBoundsChangedCallback(base::BindRepeating( - &HoldingSpaceItemChipView::UpdateImageTransform, - base::Unretained(this)))) - .CopyAddressTo(&image_) - .SetID(kHoldingSpaceItemImageId)) - .AddChild(CreateCheckmark()) - .AddChild( - HoldingSpaceViewBuilder<views::View>( - views::Builder<views::View>() - .CopyAddressTo(&secondary_action_container_) - .SetID(kHoldingSpaceItemSecondaryActionContainerId) - .SetUseDefaultFillLayout(true) - .SetVisible(false)) - .AddChild(CreateSecondaryActionBuilder( - secondary_action_callback) - ->CopyAddressTo(&secondary_action_pause_) - .SetID(kHoldingSpaceItemPauseButtonId)) - .AddChild(CreateSecondaryActionBuilder( - secondary_action_callback) - ->CopyAddressTo(&secondary_action_resume_) + views::Builder<views::View>() + .CopyAddressTo(&secondary_action_container_) + .SetID(kHoldingSpaceItemSecondaryActionContainerId) + .SetUseDefaultFillLayout(true) + .SetVisible(false) + .AddChild(CreateSecondaryActionBuilder() + .CopyAddressTo(&secondary_action_pause_) + .SetID(kHoldingSpaceItemPauseButtonId) + .SetCallback(secondary_action_callback) + .SetVisible(false)) + .AddChild(CreateSecondaryActionBuilder() + .CopyAddressTo(&secondary_action_resume_) .SetID(kHoldingSpaceItemResumeButtonId) - .SetFlipCanvasOnPaintForRTLUI(false)))) + .SetCallback(secondary_action_callback) + .SetFlipCanvasOnPaintForRTLUI(false) + .SetVisible(false)))) .AddChild( - HoldingSpaceViewBuilder<views::View>( - views::Builder<views::View>() - .SetUseDefaultFillLayout(true) - .SetProperty(views::kFlexBehaviorKey, - views::FlexSpecification( - views::MinimumFlexSizeRule::kScaleToZero, - views::MaximumFlexSizeRule::kUnbounded))) + views::Builder<views::View>() + .SetUseDefaultFillLayout(true) + .SetProperty(views::kFlexBehaviorKey, + views::FlexSpecification( + views::MinimumFlexSizeRule::kScaleToZero, + views::MaximumFlexSizeRule::kUnbounded)) .AddChild( - HoldingSpaceViewBuilder<views::View>( - views::Builder<views::BoxLayoutView>() - .SetOrientation(Orientation::kVertical) - .SetMainAxisAlignment(MainAxisAlignment::kCenter) - .SetCrossAxisAlignment(CrossAxisAlignment::kStretch) - .SetInsideBorderInsets(kLabelMargins)) - .AddChild(CreateLabelBuilder( - bubble_utils::LabelStyle::kChipTitle, - gfx::ELIDE_MIDDLE, - paint_label_mask_callback) - ->CopyAddressTo(&primary_label_) - .SetID(kHoldingSpaceItemPrimaryChipLabelId)) + views::Builder<views::BoxLayoutView>() + .SetOrientation(Orientation::kVertical) + .SetMainAxisAlignment(MainAxisAlignment::kCenter) + .SetCrossAxisAlignment(CrossAxisAlignment::kStretch) + .SetInsideBorderInsets(kLabelMargins) .AddChild( - CreateLabelBuilder( - bubble_utils::LabelStyle::kChipBody, - gfx::FADE_TAIL, paint_label_mask_callback) - ->CopyAddressTo(&secondary_label_) - .SetID(kHoldingSpaceItemSecondaryChipLabelId))) - .AddChild( - HoldingSpaceViewBuilder<views::BoxLayoutView>( - views::Builder<views::BoxLayoutView>() - .SetOrientation(Orientation::kHorizontal) - .SetMainAxisAlignment(MainAxisAlignment::kEnd) - .SetCrossAxisAlignment(CrossAxisAlignment::kCenter)) - .AddChild(CreatePrimaryAction(/*min_size=*/gfx::Size())))) + CreateLabelBuilder() + .CopyAddressTo(&primary_label_) + .SetID(kHoldingSpaceItemPrimaryChipLabelId) + .SetStyle(bubble_utils::LabelStyle::kChipTitle) + .SetElideBehavior(gfx::ELIDE_MIDDLE) + .SetCallback(paint_label_mask_callback)) + .AddChild( + CreateLabelBuilder() + .CopyAddressTo(&secondary_label_) + .SetID(kHoldingSpaceItemSecondaryChipLabelId) + .SetStyle(bubble_utils::LabelStyle::kChipBody) + .SetElideBehavior(gfx::FADE_TAIL) + .SetCallback(paint_label_mask_callback))) + .AddChild(views::Builder<views::BoxLayoutView>() + .SetOrientation(Orientation::kHorizontal) + .SetMainAxisAlignment(MainAxisAlignment::kEnd) + .SetCrossAxisAlignment(CrossAxisAlignment::kCenter) + .AddChild(CreatePrimaryActionBuilder( + /*min_size=*/gfx::Size())))) .BuildChildren(); // Subscribe to be notified of changes to `item_`'s image.
diff --git a/ash/system/holding_space/holding_space_item_chip_view.h b/ash/system/holding_space/holding_space_item_chip_view.h index 0b287b26..5199673 100644 --- a/ash/system/holding_space/holding_space_item_chip_view.h +++ b/ash/system/holding_space/holding_space_item_chip_view.h
@@ -9,6 +9,7 @@ #include "ash/public/cpp/holding_space/holding_space_image.h" #include "ash/system/holding_space/holding_space_item_view.h" #include "ui/base/metadata/metadata_header_macros.h" +#include "ui/views/metadata/view_factory.h" namespace views { class ImageButton; @@ -67,6 +68,13 @@ base::CallbackListSubscription image_subscription_; }; +BEGIN_VIEW_BUILDER(/* no export */, + HoldingSpaceItemChipView, + HoldingSpaceItemView) +END_VIEW_BUILDER + } // namespace ash +DEFINE_VIEW_BUILDER(/* no export */, ash::HoldingSpaceItemChipView) + #endif // ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ITEM_CHIP_VIEW_H_
diff --git a/ash/system/holding_space/holding_space_item_screen_capture_view.cc b/ash/system/holding_space/holding_space_item_screen_capture_view.cc index 41e11ecd..3d8e6f3 100644 --- a/ash/system/holding_space/holding_space_item_screen_capture_view.cc +++ b/ash/system/holding_space/holding_space_item_screen_capture_view.cc
@@ -10,7 +10,6 @@ #include "ash/public/cpp/rounded_image_view.h" #include "ash/style/ash_color_provider.h" #include "ash/system/holding_space/holding_space_util.h" -#include "ash/system/holding_space/holding_space_view_builder.h" #include "ash/system/tray/tray_constants.h" #include "base/bind.h" #include "components/vector_icons/vector_icons.h" @@ -24,7 +23,6 @@ #include "ui/views/layout/box_layout_view.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/layout/flex_layout_view.h" -#include "ui/views/metadata/view_factory.h" namespace ash { @@ -40,45 +38,42 @@ using CrossAxisAlignment = views::BoxLayout::CrossAxisAlignment; using MainAxisAlignment = views::BoxLayout::MainAxisAlignment; - HoldingSpaceViewBuilder<HoldingSpaceItemScreenCaptureView>(this) - .SetPreferredSize(kHoldingSpaceScreenCaptureSize) + views::Builder<HoldingSpaceItemScreenCaptureView> builder(this); + builder.SetPreferredSize(kHoldingSpaceScreenCaptureSize) .SetLayoutManager(std::make_unique<views::FillLayout>()) .AddChild(views::Builder<RoundedImageView>() .CopyAddressTo(&image_) .SetID(kHoldingSpaceItemImageId) - .SetCornerRadius(kHoldingSpaceCornerRadius)) - .AddChildIf( - item->type() == HoldingSpaceItem::Type::kScreenRecording, - base::BindOnce( - [](views::ImageView** play_icon) -> std::unique_ptr<views::View> { - return views::Builder<views::BoxLayoutView>() - .SetOrientation(views::BoxLayout::Orientation::kHorizontal) - .SetMainAxisAlignment(MainAxisAlignment::kCenter) - .SetCrossAxisAlignment(CrossAxisAlignment::kCenter) - .SetFocusBehavior(views::View::FocusBehavior::NEVER) - .AddChild( - views::Builder<views::ImageView>() - .CopyAddressTo(play_icon) - .SetID(kHoldingSpaceScreenCapturePlayIconId) - .SetPreferredSize(kPlayIconSize) - .SetImageSize(gfx::Size(kHoldingSpaceIconSize, - kHoldingSpaceIconSize))) - .Build(); - }, - &play_icon_)) - .AddChild(HoldingSpaceViewBuilder<views::FlexLayoutView>( - views::Builder<views::FlexLayoutView>() - .SetOrientation(views::LayoutOrientation::kHorizontal) - .SetCrossAxisAlignment(views::LayoutAlignment::kStart) - .SetInteriorMargin( - kCheckmarkAndPrimaryActionContainerPadding)) - .AddChild(CreateCheckmark()) - .AddChild(views::Builder<views::View>().SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification( - views::MinimumFlexSizeRule::kScaleToZero, - views::MaximumFlexSizeRule::kUnbounded))) - .AddChild(CreatePrimaryAction(kPrimaryActionSize))) + .SetCornerRadius(kHoldingSpaceCornerRadius)); + + if (item->type() == HoldingSpaceItem::Type::kScreenRecording) { + builder.AddChild( + views::Builder<views::BoxLayoutView>() + .SetOrientation(views::BoxLayout::Orientation::kHorizontal) + .SetMainAxisAlignment(MainAxisAlignment::kCenter) + .SetCrossAxisAlignment(CrossAxisAlignment::kCenter) + .SetFocusBehavior(views::View::FocusBehavior::NEVER) + .AddChild(views::Builder<views::ImageView>() + .CopyAddressTo(&play_icon_) + .SetID(kHoldingSpaceScreenCapturePlayIconId) + .SetPreferredSize(kPlayIconSize) + .SetImageSize(gfx::Size(kHoldingSpaceIconSize, + kHoldingSpaceIconSize)))); + } + + builder + .AddChild( + views::Builder<views::FlexLayoutView>() + .SetOrientation(views::LayoutOrientation::kHorizontal) + .SetCrossAxisAlignment(views::LayoutAlignment::kStart) + .SetInteriorMargin(kCheckmarkAndPrimaryActionContainerPadding) + .AddChild(CreateCheckmarkBuilder()) + .AddChild(views::Builder<views::View>().SetProperty( + views::kFlexBehaviorKey, + views::FlexSpecification( + views::MinimumFlexSizeRule::kScaleToZero, + views::MaximumFlexSizeRule::kUnbounded))) + .AddChild(CreatePrimaryActionBuilder(kPrimaryActionSize))) .BuildChildren(); // Subscribe to be notified of changes to `item_`'s image.
diff --git a/ash/system/holding_space/holding_space_item_screen_capture_view.h b/ash/system/holding_space/holding_space_item_screen_capture_view.h index 3e1629c..cbca273a 100644 --- a/ash/system/holding_space/holding_space_item_screen_capture_view.h +++ b/ash/system/holding_space/holding_space_item_screen_capture_view.h
@@ -9,6 +9,7 @@ #include "ash/public/cpp/holding_space/holding_space_image.h" #include "ash/system/holding_space/holding_space_item_view.h" #include "ui/base/metadata/metadata_header_macros.h" +#include "ui/views/metadata/view_factory.h" namespace views { class ImageView; @@ -49,6 +50,13 @@ base::CallbackListSubscription image_subscription_; }; +BEGIN_VIEW_BUILDER(/* no export */, + HoldingSpaceItemScreenCaptureView, + HoldingSpaceItemView) +END_VIEW_BUILDER + } // namespace ash +DEFINE_VIEW_BUILDER(/* no export */, ash::HoldingSpaceItemScreenCaptureView) + #endif // ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ITEM_SCREEN_CAPTURE_VIEW_H_
diff --git a/ash/system/holding_space/holding_space_item_view.cc b/ash/system/holding_space/holding_space_item_view.cc index d12bf5a..7fb592c 100644 --- a/ash/system/holding_space/holding_space_item_view.cc +++ b/ash/system/holding_space/holding_space_item_view.cc
@@ -27,7 +27,6 @@ #include "ui/views/controls/button/image_button.h" #include "ui/views/controls/image_view.h" #include "ui/views/layout/fill_layout.h" -#include "ui/views/metadata/view_factory.h" #include "ui/views/painter.h" #include "ui/views/style/platform_style.h" #include "ui/views/vector_icons.h" @@ -329,16 +328,17 @@ OnSelectionUiChanged(); } -std::unique_ptr<views::ImageView> HoldingSpaceItemView::CreateCheckmark() { +views::Builder<views::ImageView> +HoldingSpaceItemView::CreateCheckmarkBuilder() { DCHECK(!checkmark_); - return views::Builder<views::ImageView>() - .CopyAddressTo(&checkmark_) + auto checkmark = views::Builder<views::ImageView>(); + checkmark.CopyAddressTo(&checkmark_) .SetID(kHoldingSpaceItemCheckmarkId) - .SetVisible(selected()) - .Build(); + .SetVisible(selected()); + return checkmark; } -std::unique_ptr<views::View> HoldingSpaceItemView::CreatePrimaryAction( +views::Builder<views::View> HoldingSpaceItemView::CreatePrimaryActionBuilder( const gfx::Size& min_size) { DCHECK(!primary_action_container_); DCHECK(!primary_action_cancel_); @@ -350,8 +350,8 @@ gfx::Size preferred_size(kHoldingSpaceIconSize, kHoldingSpaceIconSize); preferred_size.SetToMax(min_size); - return views::Builder<views::View>() - .CopyAddressTo(&primary_action_container_) + auto primary_action = views::Builder<views::View>(); + primary_action.CopyAddressTo(&primary_action_container_) .SetID(kHoldingSpaceItemPrimaryActionContainerId) .SetUseDefaultFillLayout(true) .SetVisible(false) @@ -378,8 +378,8 @@ .SetImageHorizontalAlignment(HorizontalAlignment::ALIGN_CENTER) .SetImageVerticalAlignment(VerticalAlignment::ALIGN_MIDDLE) .SetPreferredSize(preferred_size) - .SetVisible(false)) - .Build(); + .SetVisible(false)); + return primary_action; } void HoldingSpaceItemView::OnSelectionUiChanged() {
diff --git a/ash/system/holding_space/holding_space_item_view.h b/ash/system/holding_space/holding_space_item_view.h index 5b3de88e..d440edf 100644 --- a/ash/system/holding_space/holding_space_item_view.h +++ b/ash/system/holding_space/holding_space_item_view.h
@@ -13,6 +13,7 @@ #include "base/callback_list.h" #include "base/scoped_observation.h" #include "ui/base/metadata/metadata_header_macros.h" +#include "ui/views/metadata/view_factory.h" #include "ui/views/view.h" namespace views { @@ -80,8 +81,10 @@ bool selected() const { return selected_; } protected: - std::unique_ptr<views::ImageView> CreateCheckmark(); - std::unique_ptr<views::View> CreatePrimaryAction(const gfx::Size& min_size); + views::Builder<views::ImageView> CreateCheckmarkBuilder(); + views::Builder<views::View> CreatePrimaryActionBuilder( + const gfx::Size& min_size); + virtual void OnPrimaryActionVisibilityChanged(bool visible) {} virtual void OnSelectionUiChanged(); @@ -128,6 +131,11 @@ base::WeakPtrFactory<HoldingSpaceItemView> weak_factory_{this}; }; +BEGIN_VIEW_BUILDER(/* no export */, HoldingSpaceItemView, views::View) +END_VIEW_BUILDER + } // namespace ash +DEFINE_VIEW_BUILDER(/* no export */, ash::HoldingSpaceItemView) + #endif // ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ITEM_VIEW_H_
diff --git a/ash/system/holding_space/holding_space_tray_unittest.cc b/ash/system/holding_space/holding_space_tray_unittest.cc index 42b68a4b0..f2944b1 100644 --- a/ash/system/holding_space/holding_space_tray_unittest.cc +++ b/ash/system/holding_space/holding_space_tray_unittest.cc
@@ -8,6 +8,7 @@ #include <deque> #include <vector> +#include "ash/constants/ash_features.h" #include "ash/public/cpp/holding_space/holding_space_client.h" #include "ash/public/cpp/holding_space/holding_space_constants.h" #include "ash/public/cpp/holding_space/holding_space_controller.h" @@ -37,6 +38,7 @@ #include "base/strings/strcat.h" #include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "testing/gmock/include/gmock/gmock.h" #include "ui/compositor/layer.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" @@ -745,7 +747,7 @@ // Transition to overview, the shelf is expected to remain in home screen // style state. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); ShellTestApi().WaitForOverviewAnimationState( OverviewAnimationState::kEnterAnimationComplete); @@ -900,24 +902,51 @@ } // Base class for tests of the holding space downloads section parameterized by -// the set of holding space item types which are expected to appear there. +// the set of holding space item types which are expected to appear there and +// whether or not the in-progress downloads integration feature is enabled. class HoldingSpaceTrayDownloadsSectionTest : public HoldingSpaceTrayTest, - public ::testing::WithParamInterface<HoldingSpaceItem::Type> { + public ::testing::WithParamInterface< + std::tuple<HoldingSpaceItem::Type, bool>> { public: - HoldingSpaceItem::Type GetType() const { return GetParam(); } + HoldingSpaceTrayDownloadsSectionTest() { + scoped_feature_list_.InitWithFeatureState( + features::kHoldingSpaceInProgressDownloadsIntegration, + IsInProgressDownloadsIntegrationEnabled()); + } + + // Returns the max number of downloads given the test parameterization. + size_t GetMaxNumberOfDownloads() const { + return IsInProgressDownloadsIntegrationEnabled() + ? kMaxDownloadsWithInProgressDownloadIntegration + : kMaxDownloads; + } + + // Returns the holding space item type given the test parameterization. + HoldingSpaceItem::Type GetType() const { return std::get<0>(GetParam()); } + + // Returns whether in-progress downloads integration is enabled given test + // parameterization. + bool IsInProgressDownloadsIntegrationEnabled() const { + return std::get<1>(GetParam()); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; }; INSTANTIATE_TEST_SUITE_P( All, HoldingSpaceTrayDownloadsSectionTest, - ::testing::Values(HoldingSpaceItem::Type::kArcDownload, - HoldingSpaceItem::Type::kDiagnosticsLog, - HoldingSpaceItem::Type::kDownload, - HoldingSpaceItem::Type::kLacrosDownload, - HoldingSpaceItem::Type::kNearbyShare, - HoldingSpaceItem::Type::kPrintedPdf, - HoldingSpaceItem::Type::kScan)); + ::testing::Combine( + ::testing::Values(HoldingSpaceItem::Type::kArcDownload, + HoldingSpaceItem::Type::kDiagnosticsLog, + HoldingSpaceItem::Type::kDownload, + HoldingSpaceItem::Type::kLacrosDownload, + HoldingSpaceItem::Type::kNearbyShare, + HoldingSpaceItem::Type::kPrintedPdf, + HoldingSpaceItem::Type::kScan), + ::testing::Bool())); // Tests how download chips are updated during item addition, removal and // initialization. @@ -931,7 +960,8 @@ EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); // Add a download item and verify recent file bubble gets shown. - HoldingSpaceItem* item_1 = AddItem(GetType(), base::FilePath("/tmp/fake_1")); + std::vector<HoldingSpaceItem*> items; + items.push_back(AddItem(GetType(), base::FilePath("/tmp/fake_1"))); EXPECT_TRUE(test_api()->PinnedFilesBubbleShown()); EXPECT_TRUE(test_api()->RecentFilesBubbleShown()); @@ -942,65 +972,77 @@ // Add partially initialized download item - verify it doesn't get shown in // the UI yet. - HoldingSpaceItem* item_2 = - AddPartiallyInitializedItem(GetType(), base::FilePath("/tmp/fake_2")); + items.push_back( + AddPartiallyInitializedItem(GetType(), base::FilePath("/tmp/fake_2"))); EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); EXPECT_TRUE(test_api()->GetScreenCaptureViews().empty()); std::vector<views::View*> download_chips = test_api()->GetDownloadChips(); ASSERT_EQ(1u, download_chips.size()); - EXPECT_EQ(item_1->id(), + EXPECT_EQ(items[0]->id(), HoldingSpaceItemView::Cast(download_chips[0])->item()->id()); - // Add another download, and verify it's shown in the UI. - HoldingSpaceItem* item_3 = AddItem(GetType(), base::FilePath("/tmp/fake_3")); + // Add a few more download items until the section reaches capacity. + for (size_t i = 2; i <= GetMaxNumberOfDownloads(); ++i) { + items.push_back(AddItem( + GetType(), base::FilePath("/tmp/fake_" + base::NumberToString(i)))); + } EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); EXPECT_TRUE(test_api()->GetScreenCaptureViews().empty()); download_chips = test_api()->GetDownloadChips(); - ASSERT_EQ(2u, download_chips.size()); - EXPECT_EQ(item_3->id(), - HoldingSpaceItemView::Cast(download_chips[0])->item()->id()); - EXPECT_EQ(item_1->id(), - HoldingSpaceItemView::Cast(download_chips[1])->item()->id()); + ASSERT_EQ(GetMaxNumberOfDownloads(), download_chips.size()); + + // All downloads should be visible except for that which is associated with + // the partially initialized item at index == `1`. + for (int download_chip_index = 0, item_index = items.size() - 1; + item_index >= 0; --item_index) { + if (item_index != 1) { + HoldingSpaceItemView* download_chip = + HoldingSpaceItemView::Cast(download_chips.at(download_chip_index++)); + EXPECT_EQ(download_chip->item()->id(), items[item_index]->id()); + } + } // Fully initialize partially initialized item, and verify it gets added to // the section, in the order of addition, replacing the oldest item. - model()->InitializeOrRemoveItem(item_2->id(), GURL("filesystem:fake_2")); + model()->InitializeOrRemoveItem(items[1]->id(), GURL("filesystem:fake_2")); EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); EXPECT_TRUE(test_api()->GetScreenCaptureViews().empty()); download_chips = test_api()->GetDownloadChips(); - ASSERT_EQ(2u, download_chips.size()); - EXPECT_EQ(item_3->id(), - HoldingSpaceItemView::Cast(download_chips[0])->item()->id()); - EXPECT_EQ(item_2->id(), - HoldingSpaceItemView::Cast(download_chips[1])->item()->id()); + + for (int download_chip_index = 0, item_index = items.size() - 1; + item_index > 0; ++download_chip_index, --item_index) { + HoldingSpaceItemView* download_chip = + HoldingSpaceItemView::Cast(download_chips.at(download_chip_index)); + EXPECT_EQ(download_chip->item()->id(), items[item_index]->id()); + } // Remove the newest item, and verify the section gets updated. - model()->RemoveItem(item_3->id()); + auto item_it = items.end() - 1; + model()->RemoveItem((*item_it)->id()); + items.erase(item_it); EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); EXPECT_TRUE(test_api()->GetScreenCaptureViews().empty()); download_chips = test_api()->GetDownloadChips(); - ASSERT_EQ(2u, download_chips.size()); - EXPECT_EQ(item_2->id(), - HoldingSpaceItemView::Cast(download_chips[0])->item()->id()); - EXPECT_EQ(item_1->id(), - HoldingSpaceItemView::Cast(download_chips[1])->item()->id()); + ASSERT_EQ(GetMaxNumberOfDownloads(), download_chips.size()); - // Remove other items, and verify the recent files bubble gets hidden. - model()->RemoveItem(item_2->id()); + for (int download_chip_index = 0, item_index = items.size() - 1; + item_index >= 0; ++download_chip_index, --item_index) { + HoldingSpaceItemView* download_chip = + HoldingSpaceItemView::Cast(download_chips.at(download_chip_index)); + EXPECT_EQ(download_chip->item()->id(), items[item_index]->id()); + } - EXPECT_TRUE(test_api()->RecentFilesBubbleShown()); - download_chips = test_api()->GetDownloadChips(); - ASSERT_EQ(1u, download_chips.size()); - EXPECT_EQ(item_1->id(), - HoldingSpaceItemView::Cast(download_chips[0])->item()->id()); + // Remove other items and verify the recent files bubble gets hidden. + while (!items.empty()) { + model()->RemoveItem(items.front()->id()); + items.erase(items.begin()); + } - model()->RemoveItem(item_1->id()); EXPECT_TRUE(test_api()->GetDownloadChips().empty()); - EXPECT_FALSE(test_api()->RecentFilesBubbleShown()); // Pinned bubble is showing "educational" info, and it should remain shown. @@ -1016,7 +1058,7 @@ // Add a number of initialized download items. std::deque<HoldingSpaceItem*> items; - for (size_t i = 0; i < kMaxDownloads; ++i) { + for (size_t i = 0; i < GetMaxNumberOfDownloads(); ++i) { items.push_back(AddItem( GetType(), base::FilePath("/tmp/fake_" + base::NumberToString(i)))); } @@ -1048,45 +1090,59 @@ // Add partially initialized download item - verify it doesn't get shown in // the UI yet. - HoldingSpaceItem* item_1 = - AddPartiallyInitializedItem(GetType(), base::FilePath("/tmp/fake_1")); + std::vector<HoldingSpaceItem*> items; + items.push_back( + AddPartiallyInitializedItem(GetType(), base::FilePath("/tmp/fake_1"))); - // Add two download items. - HoldingSpaceItem* item_2 = AddItem(GetType(), base::FilePath("/tmp/fake_2")); - HoldingSpaceItem* item_3 = AddItem(GetType(), base::FilePath("/tmp/fake_3")); + // Add download items until the section reaches capacity. + for (size_t i = 1; i < GetMaxNumberOfDownloads() + 1; ++i) { + items.push_back(AddItem( + GetType(), base::FilePath("/tmp/fake_" + base::NumberToString(i)))); + } + EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); EXPECT_TRUE(test_api()->GetScreenCaptureViews().empty()); std::vector<views::View*> download_chips = test_api()->GetDownloadChips(); - ASSERT_EQ(2u, download_chips.size()); - EXPECT_EQ(item_3->id(), - HoldingSpaceItemView::Cast(download_chips[0])->item()->id()); - EXPECT_EQ(item_2->id(), - HoldingSpaceItemView::Cast(download_chips[1])->item()->id()); + ASSERT_EQ(GetMaxNumberOfDownloads(), download_chips.size()); + + for (size_t download_chip_index = 0, item_index = items.size() - 1; + item_index > 0; ++download_chip_index, --item_index) { + HoldingSpaceItemView* download_chip = + HoldingSpaceItemView::Cast(download_chips.at(download_chip_index)); + EXPECT_EQ(download_chip->item()->id(), items[item_index]->id()); + } // Fully initialize partially initialized item, and verify it's not added to // the section. - model()->InitializeOrRemoveItem(item_1->id(), GURL("filesystem:fake_1")); + model()->InitializeOrRemoveItem(items[0]->id(), GURL("filesystem:fake_1")); EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); EXPECT_TRUE(test_api()->GetScreenCaptureViews().empty()); download_chips = test_api()->GetDownloadChips(); - ASSERT_EQ(2u, download_chips.size()); - EXPECT_EQ(item_3->id(), - HoldingSpaceItemView::Cast(download_chips[0])->item()->id()); - EXPECT_EQ(item_2->id(), - HoldingSpaceItemView::Cast(download_chips[1])->item()->id()); + ASSERT_EQ(GetMaxNumberOfDownloads(), download_chips.size()); + + for (size_t download_chip_index = 0, item_index = items.size() - 1; + item_index > 0; ++download_chip_index, --item_index) { + HoldingSpaceItemView* download_chip = + HoldingSpaceItemView::Cast(download_chips.at(download_chip_index)); + EXPECT_EQ(download_chip->item()->id(), items[item_index]->id()); + } // Remove the oldest item, and verify the section doesn't get updated. - model()->RemoveItem(item_1->id()); + model()->RemoveItem(items.front()->id()); + items.erase(items.begin()); EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); EXPECT_TRUE(test_api()->GetScreenCaptureViews().empty()); download_chips = test_api()->GetDownloadChips(); - ASSERT_EQ(2u, download_chips.size()); - EXPECT_EQ(item_3->id(), - HoldingSpaceItemView::Cast(download_chips[0])->item()->id()); - EXPECT_EQ(item_2->id(), - HoldingSpaceItemView::Cast(download_chips[1])->item()->id()); + ASSERT_EQ(GetMaxNumberOfDownloads(), download_chips.size()); + + for (int download_chip_index = 0, item_index = items.size() - 1; + item_index >= 0; ++download_chip_index, --item_index) { + HoldingSpaceItemView* download_chip = + HoldingSpaceItemView::Cast(download_chips.at(download_chip_index)); + EXPECT_EQ(download_chip->item()->id(), items[item_index]->id()); + } } // Tests that a partially initialized download item does not get shown if a full
diff --git a/ash/system/holding_space/holding_space_view_builder.h b/ash/system/holding_space/holding_space_view_builder.h deleted file mode 100644 index 394fe3e..0000000 --- a/ash/system/holding_space/holding_space_view_builder.h +++ /dev/null
@@ -1,132 +0,0 @@ -// Copyright 2021 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. - -#ifndef ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_VIEW_BUILDER_H_ -#define ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_VIEW_BUILDER_H_ - -#include "memory" -#include "vector" - -#include "base/callback.h" -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "ui/gfx/geometry/size.h" -#include "ui/views/view.h" - -namespace views { -class LayoutManager; -} // namespace views - -namespace ash { - -// A class which facilitates building of a view hierarchy. It is designed to be -// used similarly to (and conjunction with) `views::Builder` but differs in that -// it uses `std::unique_ptr<ViewType>` as its underlying storage mechanism -// rather than wrapped `views::Builder<ViewType>` references. This allows it to -// interop with both builders as well as traditionally constructed views. -// NOTE: The intention is to remove this class once changes have been made at -// the views framework level to support improved child lifetime management in -// `views::Builder>. That effort is being tracked in https://crbug.com/1218115. -template <typename ViewType> -class HoldingSpaceViewBuilder { - public: - // Constructs an instance from a `builder`. - template <typename BuilderType> - HoldingSpaceViewBuilder(BuilderType& builder) - : HoldingSpaceViewBuilder(builder.Build()) {} - - // Constructs an instance from an owned `root_view`. - explicit HoldingSpaceViewBuilder(std::unique_ptr<ViewType> root_view) - : owned_root_view_(std::move(root_view)), - root_view_(owned_root_view_.get()) { - DCHECK(owned_root_view_); - DCHECK(root_view_); - } - - // Constructs an instance from an unowned `root_view`. - explicit HoldingSpaceViewBuilder(ViewType* root_view) - : root_view_(root_view) { - DCHECK(root_view_); - } - - HoldingSpaceViewBuilder(const HoldingSpaceViewBuilder&) = delete; - HoldingSpaceViewBuilder& operator=(const HoldingSpaceViewBuilder&) = delete; - ~HoldingSpaceViewBuilder() = default; - - // Builds and returns an `owned_root_view_`. - std::unique_ptr<ViewType> Build() { - DCHECK(owned_root_view_); - BuildChildren(); - return std::move(owned_root_view_); - } - - // Builds children for a potentially unowned `root_view_`. - void BuildChildren() { - for (auto& child : children_) - root_view_->AddChildView(std::move(child)); - children_.clear(); - } - - // Adds a pending child to be added to `root_view_` at `Build*()` time, - // returning a reference to `this` as a convenience. - template <typename BuilderType> - HoldingSpaceViewBuilder<ViewType>& AddChild(BuilderType& builder) { - return AddChild(builder.Build()); - } - - // Adds a pending `child` to be added to `root_view_` at `Build*()` time, - // returning a reference to `this` as a convenience. - HoldingSpaceViewBuilder<ViewType>& AddChild( - std::unique_ptr<views::View> child) { - children_.push_back(std::move(child)); - return *this; - } - - // Adds a pending `child` to be added to `root_view_` at `Build*()` time if - // the specified `condition` is `true`, returning a reference to `this` as a - // convenience. - HoldingSpaceViewBuilder<ViewType>& AddChildIf( - bool condition, - base::OnceCallback<std::unique_ptr<views::View>()> callback) { - return condition ? AddChild(std::move(callback).Run()) : *this; - } - - // Copies the address of `root_view_` to the specified `address_ptr`, - // returning a reference to `this` as a convenience. - HoldingSpaceViewBuilder<ViewType>& CopyAddressTo(ViewType** address_ptr) { - *address_ptr = root_view_; - return *this; - } - - // Sets the `id` for `root_view_`, returning a reference to `this` as a - // convenience. - HoldingSpaceViewBuilder<ViewType>& SetID(int id) { - root_view_->SetID(id); - return *this; - } - - // Sets the `layout_manager` for `root_view_`, returning a reference to `this` - // as a convenience. - HoldingSpaceViewBuilder<ViewType>& SetLayoutManager( - std::unique_ptr<views::LayoutManager> layout_manager) { - root_view_->SetLayoutManager(std::move(layout_manager)); - return *this; - } - - // Sets the `preferred_size` for `root_view`, returning a reference to `this` - // as a convenience. - HoldingSpaceViewBuilder<ViewType>& SetPreferredSize( - const gfx::Size& preferred_size) { - root_view_->SetPreferredSize(preferred_size); - return *this; - } - - private: - std::unique_ptr<ViewType> owned_root_view_; - ViewType* const root_view_; - std::vector<std::unique_ptr<views::View>> children_; -}; - -} // namespace ash - -#endif // ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_VIEW_BUILDER_H_
diff --git a/ash/system/message_center/ash_message_popup_collection_unittest.cc b/ash/system/message_center/ash_message_popup_collection_unittest.cc index 9e5f5e6..3d91a37e 100644 --- a/ash/system/message_center/ash_message_popup_collection_unittest.cc +++ b/ash/system/message_center/ash_message_popup_collection_unittest.cc
@@ -406,12 +406,12 @@ EXPECT_NE(baseline_with_visible_shelf, baseline_with_hidden_shelf); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); const int baseline_in_overview = popup_collection()->GetBaseline(); EXPECT_EQ(baseline_in_overview, baseline_with_visible_shelf); - overview_controller->EndOverview(); + ExitOverview(); EXPECT_FALSE(overview_controller->InOverviewSession()); const int baseline_no_overview = popup_collection()->GetBaseline(); EXPECT_EQ(baseline_no_overview, baseline_with_hidden_shelf);
diff --git a/ash/system/overview/overview_button_tray.cc b/ash/system/overview/overview_button_tray.cc index fdf3fb7e..6a92649 100644 --- a/ash/system/overview/overview_button_tray.cc +++ b/ash/system/overview/overview_button_tray.cc
@@ -146,9 +146,9 @@ : absl::make_optional(event.time_stamp()); if (overview_controller->InOverviewSession()) - overview_controller->EndOverview(); + overview_controller->EndOverview(OverviewEndAction::kOverviewButton); else - overview_controller->StartOverview(); + overview_controller->StartOverview(OverviewStartAction::kOverviewButton); Shell::Get()->metrics()->RecordUserMetricsAction(UMA_TRAY_OVERVIEW); // The return value doesn't matter here. OnOverviewModeStarting() and
diff --git a/ash/system/overview/overview_button_tray_unittest.cc b/ash/system/overview/overview_button_tray_unittest.cc index 5ba75c7..cffde86 100644 --- a/ash/system/overview/overview_button_tray_unittest.cc +++ b/ash/system/overview/overview_button_tray_unittest.cc
@@ -312,11 +312,11 @@ std::unique_ptr<aura::Window> window( CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20))); - EXPECT_TRUE(Shell::Get()->overview_controller()->StartOverview()); + EXPECT_TRUE(EnterOverview()); EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); EXPECT_TRUE(GetTray()->is_active()); - EXPECT_TRUE(Shell::Get()->overview_controller()->EndOverview()); + EXPECT_TRUE(ExitOverview()); EXPECT_FALSE(Shell::Get()->overview_controller()->InOverviewSession()); EXPECT_FALSE(GetTray()->is_active()); } @@ -399,7 +399,7 @@ // Enter splitview mode. Snap |window1| to the left, this will be the default // splitview window. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); split_view_controller()->SnapWindow(window1.get(), SplitViewController::LEFT); split_view_controller()->SnapWindow(window2.get(), SplitViewController::RIGHT); @@ -615,7 +615,7 @@ // Create a window to show in overview. std::unique_ptr<aura::Window> window( CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20))); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); EXPECT_FALSE(GetTray()->GetVisible());
diff --git a/ash/system/power/power_button_menu_screen_view.cc b/ash/system/power/power_button_menu_screen_view.cc index 479d7be..3c2ec589 100644 --- a/ash/system/power/power_button_menu_screen_view.cc +++ b/ash/system/power/power_button_menu_screen_view.cc
@@ -129,14 +129,10 @@ power_button_menu_view_ = new PowerButtonMenuView(power_button_position_); AddChildView(power_button_menu_view_); - display::Screen::GetScreen()->AddObserver(this); - AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); } -PowerButtonMenuScreenView::~PowerButtonMenuScreenView() { - display::Screen::GetScreen()->RemoveObserver(this); -} +PowerButtonMenuScreenView::~PowerButtonMenuScreenView() = default; void PowerButtonMenuScreenView::ScheduleShowHideAnimation(bool show) { power_button_screen_background_shield_->ScheduleShowHideAnimation(show);
diff --git a/ash/system/power/power_button_menu_screen_view.h b/ash/system/power/power_button_menu_screen_view.h index 7b6a6ca..c6f4b07 100644 --- a/ash/system/power/power_button_menu_screen_view.h +++ b/ash/system/power/power_button_menu_screen_view.h
@@ -94,6 +94,8 @@ // The origin of the menu bounds in different screen orientations. std::unordered_map<OrientationLockType, gfx::Point> menu_bounds_origins_; + + display::ScopedDisplayObserver display_observer_{this}; }; } // namespace ash
diff --git a/ash/system/toast/toast_overlay.cc b/ash/system/toast/toast_overlay.cc index e08b499..7d474da 100644 --- a/ash/system/toast/toast_overlay.cc +++ b/ash/system/toast/toast_overlay.cc
@@ -108,13 +108,9 @@ // ToastDisplayObserver class ToastOverlay::ToastDisplayObserver : public display::DisplayObserver { public: - ToastDisplayObserver(ToastOverlay* overlay) : overlay_(overlay) { - display::Screen::GetScreen()->AddObserver(this); - } + ToastDisplayObserver(ToastOverlay* overlay) : overlay_(overlay) {} - ~ToastDisplayObserver() override { - display::Screen::GetScreen()->RemoveObserver(this); - } + ~ToastDisplayObserver() override {} void OnDisplayMetricsChanged(const display::Display& display, uint32_t changed_metrics) override { @@ -123,6 +119,9 @@ private: ToastOverlay* const overlay_; + + display::ScopedDisplayObserver display_observer_{this}; + DISALLOW_COPY_AND_ASSIGN(ToastDisplayObserver); };
diff --git a/ash/system/unified/unified_system_tray_model.cc b/ash/system/unified/unified_system_tray_model.cc index de1806c..f8a3ebf 100644 --- a/ash/system/unified/unified_system_tray_model.cc +++ b/ash/system/unified/unified_system_tray_model.cc
@@ -68,6 +68,8 @@ UnifiedSystemTrayModel* const owner_; + display::ScopedDisplayObserver display_observer_{this}; + // Keep track of current system tray size. UnifiedSystemTrayModel::SystemTrayButtonSize system_tray_size_; }; @@ -113,13 +115,11 @@ UnifiedSystemTrayModel::SizeObserver::SizeObserver( UnifiedSystemTrayModel* owner) : owner_(owner) { - display::Screen::GetScreen()->AddObserver(this); Shell::Get()->AddShellObserver(this); system_tray_size_ = owner_->GetSystemTrayButtonSize(); } UnifiedSystemTrayModel::SizeObserver::~SizeObserver() { - display::Screen::GetScreen()->RemoveObserver(this); Shell::Get()->RemoveShellObserver(this); }
diff --git a/ash/system/unified/user_chooser_detailed_view_controller_unittest.cc b/ash/system/unified/user_chooser_detailed_view_controller_unittest.cc index 55bdd96..872d7491 100644 --- a/ash/system/unified/user_chooser_detailed_view_controller_unittest.cc +++ b/ash/system/unified/user_chooser_detailed_view_controller_unittest.cc
@@ -55,7 +55,7 @@ TEST_F(UserChooserDetailedViewControllerTest, ShowMultiProfileLoginWithOverview) { // Enter ovewview mode. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); // Show system tray. @@ -84,7 +84,7 @@ std::unique_ptr<views::Widget> widget = CreateTestWidget(); // Enter overview mode. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); // Show system tray.
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc index 0b9e227..1879d92 100644 --- a/ash/test/ash_test_base.cc +++ b/ash/test/ash_test_base.cc
@@ -32,6 +32,7 @@ #include "ash/test_screenshot_delegate.h" #include "ash/test_shell_delegate.h" #include "ash/utility/screenshot_controller.h" +#include "ash/wm/overview/overview_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_positioner.h" #include "ash/wm/work_area_insets.h" @@ -473,6 +474,16 @@ event_generator->ClickLeftButton(); } +bool AshTestBase::EnterOverview(OverviewEnterExitType type) { + return Shell::Get()->overview_controller()->StartOverview( + OverviewStartAction::kTests, type); +} + +bool AshTestBase::ExitOverview(OverviewEnterExitType type) { + return Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kTests, type); +} + void AshTestBase::SwapPrimaryDisplay() { if (display::Screen::GetScreen()->GetNumDisplays() <= 1) return;
diff --git a/ash/test/ash_test_base.h b/ash/test/ash_test_base.h index e580e76..f46c24cb 100644 --- a/ash/test/ash_test_base.h +++ b/ash/test/ash_test_base.h
@@ -15,6 +15,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/session/test_session_controller_client.h" #include "ash/wm/desks/desks_util.h" +#include "ash/wm/overview/overview_types.h" #include "base/compiler_specific.h" #include "base/macros.h" #include "base/test/task_environment.h" @@ -193,6 +194,12 @@ void SimulateMouseClickAt(ui::test::EventGenerator* event_generator, const views::View* target_view); + // Enters/Exits overview mode with the given animation type `type`. + bool EnterOverview( + OverviewEnterExitType type = OverviewEnterExitType::kNormal); + bool ExitOverview( + OverviewEnterExitType type = OverviewEnterExitType::kNormal); + protected: enum UserSessionBlockReason { FIRST_BLOCK_REASON,
diff --git a/ash/touch/touch_observer_hud.cc b/ash/touch/touch_observer_hud.cc index 5796c4f7..5608d2a 100644 --- a/ash/touch/touch_observer_hud.cc +++ b/ash/touch/touch_observer_hud.cc
@@ -10,7 +10,6 @@ #include "ash/shell.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/display/display.h" -#include "ui/display/screen.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/views/widget/widget.h" @@ -47,7 +46,6 @@ widget_->AddObserver(this); // Observe changes in display size and mode to update touch HUD. - display::Screen::GetScreen()->AddObserver(this); Shell::Get()->display_configurator()->AddObserver(this); Shell::Get()->window_tree_host_manager()->AddObserver(this); root_window_->AddPreTargetHandler(this); @@ -56,7 +54,6 @@ TouchObserverHud::~TouchObserverHud() { Shell::Get()->window_tree_host_manager()->RemoveObserver(this); Shell::Get()->display_configurator()->RemoveObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); widget_->RemoveObserver(this); CHECK(!views::WidgetObserver::IsInObserverList());
diff --git a/ash/touch/touch_observer_hud.h b/ash/touch/touch_observer_hud.h index 5b4ba05..f4e1c1f 100644 --- a/ash/touch/touch_observer_hud.h +++ b/ash/touch/touch_observer_hud.h
@@ -84,6 +84,8 @@ views::Widget* widget_; + display::ScopedDisplayObserver display_observer_{this}; + DISALLOW_COPY_AND_ASSIGN(TouchObserverHud); };
diff --git a/ash/utility/occlusion_tracker_pauser.cc b/ash/utility/occlusion_tracker_pauser.cc index 35a3636..944740f6 100644 --- a/ash/utility/occlusion_tracker_pauser.cc +++ b/ash/utility/occlusion_tracker_pauser.cc
@@ -4,7 +4,6 @@ #include "ash/utility/occlusion_tracker_pauser.h" -#include "ash/accessibility/accessibility_controller_impl.h" #include "ash/shell.h" #include "base/bind.h" #include "ui/aura/window_tree_host.h" @@ -18,20 +17,6 @@ void OcclusionTrackerPauser::PauseUntilAnimationsEnd( const base::TimeDelta& extra_pause_duration) { - auto* a11y_controller = Shell::Get()->accessibility_controller(); - /* - * Ddo not pause the occlusion tracker when accessibility feature is enabled - * because it may add a permnent CompositorAnimationObserver. - * TODO(crbug.com/1222698): Remove this if when the accessibility layer - * migrates to use LayerAnimationElement. - */ - for (int type = AccessibilityControllerImpl::kAutoclick; - type < AccessibilityControllerImpl::kFeatureCount; type++) { - auto casted_type = - static_cast<AccessibilityControllerImpl::FeatureType>(type); - if (a11y_controller->GetFeature(casted_type).enabled()) - return; - } for (auto* root : Shell::GetAllRootWindows()) Pause(root->GetHost()->compositor(), extra_pause_duration); }
diff --git a/ash/utility/screenshot_controller.cc b/ash/utility/screenshot_controller.cc index 739b991b4..5e632ab 100644 --- a/ash/utility/screenshot_controller.cc +++ b/ash/utility/screenshot_controller.cc
@@ -388,7 +388,7 @@ in_screenshot_session_ = true; mode_ = WINDOW; - display::Screen::GetScreen()->AddObserver(this); + display_observer_.emplace(this); for (aura::Window* root : Shell::GetAllRootWindows()) { layers_[root] = std::make_unique<ScreenshotLayer>( this, @@ -411,7 +411,7 @@ return; in_screenshot_session_ = true; mode_ = PARTIAL; - display::Screen::GetScreen()->AddObserver(this); + display_observer_.emplace(this); for (aura::Window* root : Shell::GetAllRootWindows()) { layers_[root] = std::make_unique<ScreenshotLayer>( this, @@ -441,7 +441,7 @@ root_window_ = nullptr; SetSelectedWindow(nullptr); in_screenshot_session_ = false; - display::Screen::GetScreen()->RemoveObserver(this); + display_observer_.reset(); layers_.clear(); cursor_setter_.reset(); EnableMouseWarp(true);
diff --git a/ash/utility/screenshot_controller.h b/ash/utility/screenshot_controller.h index 3ba1019..89708d70 100644 --- a/ash/utility/screenshot_controller.h +++ b/ash/utility/screenshot_controller.h
@@ -15,6 +15,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/timer/timer.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/aura/window_observer.h" #include "ui/display/display_observer.h" #include "ui/events/event_handler.h" @@ -138,6 +139,9 @@ // The object to specify the crosshair cursor. std::unique_ptr<ScopedCursorSetter> cursor_setter_; + // The display observer while in a screenshot session. + absl::optional<display::ScopedDisplayObserver> display_observer_; + // True while taking a partial or window screen. bool in_screenshot_session_ = false;
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc index 2557e5e..d6f1e6f 100644 --- a/ash/wallpaper/wallpaper_controller_unittest.cc +++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -2187,7 +2187,7 @@ /*preview_mode=*/false, /*always_on_top=*/false); TestWallpaperControllerObserver observer(controller_); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); EXPECT_FALSE(controller_->IsWallpaperBlurredForLockState()); EXPECT_EQ(0, observer.blur_changed_count()); @@ -2370,7 +2370,7 @@ // the user wallpaper info remains unchanged, and enters overview mode // properly. ClearWallpaperCount(); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); RunAllTasksUntilIdle(); EXPECT_EQ(1, GetWallpaperCount()); EXPECT_NE(kWallpaperColor, GetWallpaperColor());
diff --git a/ash/webui/common/resources/navigation_icons.html b/ash/webui/common/resources/navigation_icons.html index 58dd798..aaba4a9 100644 --- a/ash/webui/common/resources/navigation_icons.html +++ b/ash/webui/common/resources/navigation_icons.html
@@ -3,6 +3,9 @@ <defs> <!-- TODO(jimmyxgong): Replace this stub icon with actual icons. --> <g id="laptop-chromebook" viewBox="0 0 24 24"><path d="M22 18V3H2v15H0v2h24v-2h-2zm-8 0h-4v-1h4v1zm6-3H4V5h16v10z"></path></g> + <g id="ethernet" viewBox="0 0 20 20"> + <path fill-rule="evenodd" clip-rule="evenodd" d="M14.0909 5L12.9373 6.175L16.6845 10L12.9373 13.825L14.0909 15L19 10L14.0909 5ZM7.06273 6.175L5.90909 5L1 10L5.90909 15L7.06273 13.825L3.31545 10L7.06273 6.175ZM7.05457 11C7.59682 11 8.03639 10.5523 8.03639 10C8.03639 9.44772 7.59682 9 7.05457 9C6.51233 9 6.07275 9.44772 6.07275 10C6.07275 10.5523 6.51233 11 7.05457 11ZM10 11C10.5422 11 10.9818 10.5523 10.9818 10C10.9818 9.44772 10.5422 9 10 9C9.45776 9 9.01819 9.44772 9.01819 10C9.01819 10.5523 9.45776 11 10 11ZM12.9454 11C13.4877 11 13.9273 10.5523 13.9273 10C13.9273 9.44772 13.4877 9 12.9454 9C12.4032 9 11.9636 9.44772 11.9636 10C11.9636 10.5523 12.4032 11 12.9454 11Z" /> + </g> </defs> </svg> </iron-iconset-svg>
diff --git a/ash/webui/diagnostics_ui/diagnostics_ui.cc b/ash/webui/diagnostics_ui/diagnostics_ui.cc index 53d42865..dca0aa16 100644 --- a/ash/webui/diagnostics_ui/diagnostics_ui.cc +++ b/ash/webui/diagnostics_ui/diagnostics_ui.cc
@@ -54,6 +54,7 @@ {"boardAndVersionInfo", IDS_DIAGNOSTICS_DEVICE_INFO_TEXT}, {"captivePortalRoutineText", IDS_NETWORK_DIAGNOSTICS_CAPTIVE_PORTAL}, {"chargeTestResultText", IDS_CHARGE_TEST_RESULT}, + {"connectivityText", IDS_DIAGNOSTICS_CONNECTIVITY}, {"cpuBannerMessage", IDS_DIAGNOSTICS_CPU_BANNER_MESSAGE}, {"cpuCacheRoutineText", IDS_DIAGNOSTICS_CPU_CACHE_ROUTINE_TEXT}, {"cpuChipText", IDS_DIAGNOSTICS_CPU_CHIP_TEXT}, @@ -98,6 +99,7 @@ {"memoryRoutineText", IDS_DIAGNOSTICS_MEMORY_ROUTINE_TEXT}, {"memoryTitle", IDS_DIAGNOSTICS_MEMORY_TITLE}, {"noEthernet", IDS_DIAGNOSTICS_NO_ETHERNET}, + {"overviewText", IDS_DIAGNOSTICS_OVERVIEW}, {"percentageLabel", IDS_DIAGNOSTICS_PERCENTAGE_LABEL}, {"remainingCharge", IDS_DIAGNOSTICS_REMAINING_CHARGE_LABEL}, {"routineEntryText", IDS_DIANOSTICS_ROUTINE_ENTRY_TEXT},
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_app.js b/ash/webui/diagnostics_ui/resources/diagnostics_app.js index bb85bbd18d..a6a3ef1 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_app.js +++ b/ash/webui/diagnostics_ui/resources/diagnostics_app.js
@@ -53,9 +53,15 @@ /** @override */ attached() { if (this.showNavPanel_) { - this.$$('#navigationPanel').addSelector('System', 'system-page'); + this.$$('#navigationPanel') + .addSelector( + loadTimeData.getString('overviewText'), 'system-page', + 'navigation-selector:laptop-chromebook'); if (this.isNetworkingEnabled_) { - this.$$('#navigationPanel').addSelector('Connectivity', 'network-list'); + this.$$('#navigationPanel') + .addSelector( + loadTimeData.getString('connectivityText'), 'network-list', + 'navigation-selector:ethernet'); } if (this.isInputEnabled_) { this.$$('#navigationPanel').addSelector('Input', 'input-list');
diff --git a/ash/wm/desks/desk.cc b/ash/wm/desks/desk.cc index fa23a99..8516ce9 100644 --- a/ash/wm/desks/desk.cc +++ b/ash/wm/desks/desk.cc
@@ -28,7 +28,6 @@ #include "base/containers/cxx20_erase.h" #include "base/macros.h" #include "base/metrics/histogram_functions.h" -#include "base/no_destructor.h" #include "base/strings/stringprintf.h" #include "chromeos/ui/base/window_properties.h" #include "ui/aura/client/aura_constants.h" @@ -132,12 +131,13 @@ // Returns Jan 1, 2010 00:00:00 as a base::Time object in the local timezone. base::Time GetLocalEpoch() { - static base::NoDestructor<base::Time> local_epoch; - if (local_epoch->is_null()) { + static const base::Time local_epoch = [] { + base::Time local_epoch; ignore_result(base::Time::FromLocalExploded({2010, 1, 5, 1, 0, 0, 0, 0}, - local_epoch.get())); - } - return *local_epoch; + &local_epoch)); + return local_epoch; + }(); + return local_epoch; } // Used to temporarily turn off the automatic window positioning while windows
diff --git a/ash/wm/desks/desk_animation_impl.cc b/ash/wm/desks/desk_animation_impl.cc index 132b2ac6..a999422 100644 --- a/ash/wm/desks/desk_animation_impl.cc +++ b/ash/wm/desks/desk_animation_impl.cc
@@ -253,6 +253,7 @@ // ending desk screenshot. This makes sure that the ending desk // screenshot will only show the windows in that desk, not overview stuff. Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kDeskActivation, OverviewEnterExitType::kImmediateExit); } SplitViewController* split_view_controller =
diff --git a/ash/wm/desks/desks_controller.cc b/ash/wm/desks/desks_controller.cc index 39e5592..ab29dc70 100644 --- a/ash/wm/desks/desks_controller.cc +++ b/ash/wm/desks/desks_controller.cc
@@ -549,6 +549,7 @@ // overview shutdown animation is complete. See https://crbug.com/1001586. const bool immediate_exit = source == DesksSwitchSource::kUserSwitch; overview_controller->EndOverview( + OverviewEndAction::kDeskActivation, immediate_exit ? OverviewEnterExitType::kImmediateExit : OverviewEnterExitType::kNormal); }
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc index 30e0ee2..c79e9e9 100644 --- a/ash/wm/desks/desks_unittests.cc +++ b/ash/wm/desks/desks_unittests.cc
@@ -405,7 +405,7 @@ auto* controller = DesksController::Get(); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); const auto* overview_grid = @@ -462,9 +462,9 @@ // Exit overview mode and re-enter. Since we have more than one pre-existing // desks, their mini_views should be created upon construction of the desks // bar. - overview_controller->EndOverview(); + ExitOverview(); EXPECT_FALSE(overview_controller->InOverviewSession()); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); // Get the new grid and the new desk_bar_view. @@ -484,9 +484,8 @@ TEST_F(DesksTest, RemoveDeskWithEmptyName) { auto* controller = DesksController::Get(); - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); @@ -581,9 +580,8 @@ // Test that gesture taps do not reset the button state to normal when the // button is disabled. https://crbug.com/1084241. TEST_F(DesksTest, GestureTapOnNewDeskButton) { - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); const auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); @@ -997,7 +995,7 @@ // desks mini views, and there are exactly two windows in the overview mode // grid. auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); const auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); @@ -1034,14 +1032,14 @@ // showing exactly one window. auto win2 = CreateAppWindow(gfx::Rect(50, 50, 200, 200)); wm::ActivateWindow(win2.get()); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); EXPECT_EQ(1u, overview_grid->window_list().size()); // When exiting overview mode without changing desks, the focus should be // restored to the same window. - overview_controller->EndOverview(); + ExitOverview(); EXPECT_FALSE(overview_controller->InOverviewSession()); // Run a loop since the overview session is destroyed async and until that // happens, focus will be on the dummy "OverviewModeFocusedWidget". @@ -1064,7 +1062,7 @@ // Enter overview mode. auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); auto roots = Shell::GetAllRootWindows(); @@ -1117,7 +1115,7 @@ ActivateDesk(desk_4); auto* overview_controller = Shell::Get()->overview_controller(); auto win3 = CreateAppWindow(gfx::Rect(50, 50, 200, 200)); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); const auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); @@ -1177,7 +1175,7 @@ // Exiting overview mode should not cause any mini_views refreshes, since the // destroyed overview-specific windows do not show up in the mini_view. - overview_controller->EndOverview(); + ExitOverview(); EXPECT_FALSE(overview_controller->InOverviewSession()); EXPECT_EQ(1, desk_4_observer.notify_counts()); desk_4->RemoveObserver(&desk_4_observer); @@ -1223,7 +1221,7 @@ // Enter overview mode, and remove desk_2 from its mini-view close button. auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); const auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); @@ -1286,7 +1284,7 @@ // Exiting overview mode should not cause any mini_views refreshes, since the // destroyed overview-specific windows do not show up in the mini_view. - overview_controller->EndOverview(); + ExitOverview(); EXPECT_FALSE(overview_controller->InOverviewSession()); EXPECT_EQ(1, desk_1_observer.notify_counts()); desk_1->RemoveObserver(&desk_1_observer); @@ -1303,7 +1301,7 @@ // Enter overview mode, and click on `desk_1`'s mini_view, and expect that // overview mode exits since this is the already active desk. auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); const auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); @@ -1415,7 +1413,7 @@ EXPECT_TRUE(shadow->layer()->GetTargetVisibility()); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); EXPECT_EQ(2u, overview_grid->size()); @@ -1501,7 +1499,7 @@ ASSERT_TRUE(window_state->IsMinimized()); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); auto* overview_session = overview_controller->overview_session(); @@ -1542,7 +1540,7 @@ ASSERT_EQ(2u, DesksController::Get()->desks().size()); auto win = CreateAppWindow(gfx::Rect(0, 0, 250, 100)); auto* overview_controller = Shell::Get()->overview_controller(); - ASSERT_TRUE(overview_controller->StartOverview()); + ASSERT_TRUE(EnterOverview()); auto* overview_session = overview_controller->overview_session(); DragItemToPoint(overview_session->GetOverviewItemForWindow(win.get()), GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()) @@ -1567,7 +1565,7 @@ EXPECT_EQ(window.get(), window_util::GetActiveWindow()); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); const auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); @@ -1706,9 +1704,8 @@ // The widgets created by overview mode, whose windows are added to the active // desk's container, should never result in mini_views updates since they're // not mirrored there at all. - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); EXPECT_EQ(0, desk_1_observer.notify_counts()); EXPECT_EQ(0, desk_2_observer.notify_counts()); @@ -1798,8 +1795,7 @@ NewDesk(); ASSERT_EQ(2u, controller->desks().size()); - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); const auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); const auto* desks_bar_view = overview_grid->desks_bar_view(); @@ -1856,7 +1852,7 @@ auto win = CreateAppWindow(gfx::Rect(0, 0, 250, 100)); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); auto* overview_session = overview_controller->overview_session(); auto* overview_item = overview_session->GetOverviewItemForWindow(win.get()); @@ -1899,7 +1895,7 @@ auto win = CreateAppWindow(gfx::Rect(0, 0, 250, 100)); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); auto* overview_session = overview_controller->overview_session(); auto* overview_item = overview_session->GetOverviewItemForWindow(win.get()); @@ -1978,8 +1974,7 @@ NewDesk(); controller_ = DesksController::Get(); - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); overview_grid_ = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); desks_bar_view_ = overview_grid_->desks_bar_view(); ASSERT_TRUE(desks_bar_view_); @@ -2028,8 +2023,7 @@ TEST_F(DesksEditableNamesTest, NamesSetByUsersAreNotOverwritten) { ASSERT_EQ(2u, controller()->desks().size()); - auto* overview_controller = Shell::Get()->overview_controller(); - ASSERT_TRUE(overview_controller->InOverviewSession()); + ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); // Change the name of the first desk. Adding/removing desks or // exiting/reentering overview should not cause changes to the desk's name. @@ -2083,8 +2077,8 @@ VerifyDesksRestoreData(GetPrimaryUserPrefService(), {std::string("code"), std::string()}); - overview_controller->EndOverview(); - overview_controller->StartOverview(); + ExitOverview(); + EnterOverview(); EXPECT_TRUE(desk_1->is_name_set_by_user()); EXPECT_FALSE(desk_3->is_name_set_by_user()); EXPECT_EQ(u"code", desk_1->name()); @@ -2159,8 +2153,7 @@ TEST_F(DesksEditableNamesTest, MaxLength) { ASSERT_EQ(2u, controller()->desks().size()); - auto* overview_controller = Shell::Get()->overview_controller(); - ASSERT_TRUE(overview_controller->InOverviewSession()); + ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); ClickOnDeskNameViewAtIndex(0); // Select all and delete. @@ -2245,7 +2238,7 @@ // Enter overview and expect that the backdrop is still present for desk_1 but // hidden. auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); ASSERT_TRUE(desk_1_backdrop_controller->backdrop_window()); EXPECT_FALSE(desk_1_backdrop_controller->backdrop_window()->IsVisible()); @@ -2276,7 +2269,7 @@ // Exit overview, and expect that desk_2's backdrop remains hidden since the // desk is not activated yet. - overview_controller->EndOverview(OverviewEnterExitType::kImmediateExit); + ExitOverview(OverviewEnterExitType::kImmediateExit); EXPECT_FALSE(overview_controller->InOverviewSession()); EXPECT_FALSE(desk_1_backdrop_controller->backdrop_window()); ASSERT_TRUE(desk_2_backdrop_controller->backdrop_window()); @@ -2312,7 +2305,7 @@ // Enter overview and expect that |desk_1| has a backdrop stacked under // |window| while desk_2 has none. auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); ASSERT_TRUE(desk_1_backdrop_controller->backdrop_window()); EXPECT_FALSE(desk_2_backdrop_controller->backdrop_window()); @@ -2375,7 +2368,7 @@ // Enter overview and expect that the DesksBar widget won't be created. auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); const auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); @@ -2391,10 +2384,10 @@ // Exit overview and add a new desk, then re-enter overview. Expect that now // the desks bar is visible. - overview_controller->EndOverview(); + ExitOverview(); EXPECT_FALSE(overview_controller->InOverviewSession()); NewDesk(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); desks_bar_view = overview_grid->desks_bar_view(); @@ -2495,7 +2488,7 @@ // end, but TabletModeWindowManager should not maximize the snapped windows // and they should retain their snapped state. auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); auto* desks_bar_view = overview_grid->desks_bar_view(); @@ -2520,7 +2513,7 @@ split_view_controller()->SnapWindow(win4.get(), SplitViewController::RIGHT); EXPECT_EQ(win3.get(), split_view_controller()->left_window()); EXPECT_EQ(win4.get(), split_view_controller()->right_window()); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); desks_bar_view = overview_grid->desks_bar_view(); @@ -2560,7 +2553,7 @@ std::unique_ptr<aura::Window> win3(CreateTestWindowInShellWithDelegate( &win3_delegate, /*id=*/-1, gfx::Rect(big))); OverviewController* overview_controller = Shell::Get()->overview_controller(); - EXPECT_TRUE(overview_controller->StartOverview()); + EXPECT_TRUE(EnterOverview()); split_view_controller()->SnapWindow(win1.get(), SplitViewController::LEFT); EXPECT_EQ(win1.get(), split_view_controller()->left_window()); EXPECT_FALSE(split_view_controller()->CanSnapWindow(win2.get())); @@ -2585,7 +2578,7 @@ EXPECT_FALSE(overview_controller->InOverviewSession()); // Switch back to |desk_1| and verify that split view is arranged as before. - EXPECT_TRUE(overview_controller->StartOverview()); + EXPECT_TRUE(EnterOverview()); ASSERT_TRUE(overview_controller->InOverviewSession()); overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); desks_bar_view = overview_grid->desks_bar_view(); @@ -2746,7 +2739,7 @@ EXPECT_EQ(win1.get(), window_util::GetActiveWindow()); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); auto* overview_session = overview_controller->overview_session(); @@ -2849,7 +2842,7 @@ NewDesk(); ASSERT_EQ(3u, controller->desks().size()); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); const auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); @@ -2975,7 +2968,7 @@ EXPECT_EQ(window.get(), window_util::GetActiveWindow()); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); @@ -3025,7 +3018,7 @@ auto win0 = CreateAppWindow(gfx::Rect(0, 0, 250, 100)); auto win1 = CreateAppWindow(gfx::Rect(50, 50, 200, 200)); auto* overview_controller = Shell::Get()->overview_controller(); - ASSERT_TRUE(overview_controller->StartOverview()); + ASSERT_TRUE(EnterOverview()); auto* overview_session = overview_controller->overview_session(); auto* generator = GetEventGenerator(); DragItemToPoint(overview_session->GetOverviewItemForWindow(win0.get()), @@ -3099,9 +3092,7 @@ EXPECT_EQ(desk3->GetDeskContainerForRoot(Shell::GetPrimaryRootWindow()), win0->parent()); - auto* overview_controller = Shell::Get()->overview_controller(); - ASSERT_TRUE(overview_controller->StartOverview()); - + ASSERT_TRUE(EnterOverview()); const gfx::Rect expected_clip = win0->layer()->GetTargetClipRect(); // Remove |desk3|. |win0| is now a child of |desk2|. @@ -3379,7 +3370,7 @@ TEST_F(DesksMultiUserTest, SwitchingUsersEndsOverview) { SimulateUserLogin(GetUser1AccountId()); OverviewController* overview_controller = Shell::Get()->overview_controller(); - EXPECT_TRUE(overview_controller->StartOverview()); + EXPECT_TRUE(EnterOverview()); EXPECT_TRUE(overview_controller->InOverviewSession()); SwitchActiveUser(GetUser2AccountId()); EXPECT_FALSE(overview_controller->InOverviewSession()); @@ -3677,7 +3668,7 @@ // Using the accelerator doesn't result in exiting overview. auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); SendAccelerator(ui::VKEY_OEM_MINUS, flags); ASSERT_EQ(1u, controller->desks().size()); @@ -3804,7 +3795,7 @@ EXPECT_EQ(win0.get(), window_util::GetActiveWindow()); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); const int flags = ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN; // In overview, while no window is highlighted, nothing should happen. @@ -4114,9 +4105,8 @@ auto* controller = DesksController::Get(); // Start overview. - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); // Hover over the new desk button. const auto* overview_grid = @@ -4157,9 +4147,8 @@ UpdateDisplay("800x800,800x800"); // Start overview. - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); // Retrieve the desks bar view for each root window. auto root_windows = Shell::GetAllRootWindows(); @@ -4188,8 +4177,8 @@ desk_name_view_2->GetText()); // Restart overview to reset the zero state. - overview_controller->EndOverview(); - overview_controller->StartOverview(); + ExitOverview(); + EnterOverview(); desks_bar_view_1 = GetOverviewGridForRoot(root_windows[0])->desks_bar_view(); desks_bar_view_2 = GetOverviewGridForRoot(root_windows[1])->desks_bar_view(); ASSERT_TRUE(desks_bar_view_1->IsZeroState()); @@ -4237,7 +4226,7 @@ // Start overview. auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); // Focus on a `DeskNameView`. @@ -4259,9 +4248,8 @@ TEST_F(DesksTest, ScrollableDesks) { UpdateDisplay("201x400"); - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); auto* root_window = Shell::GetPrimaryRootWindow(); const auto* desks_bar_view = @@ -4320,8 +4308,7 @@ auto* root_window = Shell::GetPrimaryRootWindow(); SplitViewController::Get(root_window) ->SnapWindow(window.get(), SplitViewController::LEFT); - auto* overview_controller = Shell::Get()->overview_controller(); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); auto* desks_bar = GetOverviewGridForRoot(root_window)->desks_bar_view(); auto* event_generator = GetEventGenerator(); event_generator->MoveMouseTo(desks_bar->GetBoundsInScreen().CenterPoint()); @@ -4364,7 +4351,7 @@ for (size_t i = 1; i < max_desks_size; i++) NewDesk(); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); auto* desks_bar = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow())->desks_bar_view(); @@ -4449,9 +4436,8 @@ auto* desks_controller = DesksController::Get(); EXPECT_EQ(desks_controller->desks().size(), max_desks_size); - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); auto* desks_bar = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow())->desks_bar_view(); @@ -4540,8 +4526,7 @@ auto* root_window = Shell::GetPrimaryRootWindow(); SplitViewController::Get(root_window) ->SnapWindow(window.get(), SplitViewController::LEFT); - auto* overview_controller = Shell::Get()->overview_controller(); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); auto* desks_bar = GetOverviewGridForRoot(root_window)->desks_bar_view(); auto mini_views = desks_bar->mini_views(); ASSERT_EQ(mini_views.size(), desks_util::kMaxNumberOfDesks); @@ -4827,8 +4812,7 @@ TEST_F(DesksTest, EnterOverviewWithCorrectDesksBarState) { auto* controller = DesksController::Get(); ASSERT_EQ(1u, controller->desks().size()); - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); auto* root_window = Shell::GetPrimaryRootWindow(); auto* desks_bar_view = GetOverviewGridForRoot(root_window)->desks_bar_view(); @@ -4841,11 +4825,11 @@ // Click new desk button in the zero state bar to create a new desk. ClickOnView(desks_bar_view->zero_state_new_desk_button(), GetEventGenerator()); - overview_controller->EndOverview(); + ExitOverview(); // Desks bar should not stay in zero state if there are more than one desks. EXPECT_EQ(2u, controller->desks().size()); - overview_controller->StartOverview(); + EnterOverview(); desks_bar_view = GetOverviewGridForRoot(root_window)->desks_bar_view(); EXPECT_EQ(2u, desks_bar_view->mini_views().size()); EXPECT_FALSE(desks_bar_view->IsZeroState()); @@ -4853,8 +4837,7 @@ // Tests the behavior of desks bar zero state. TEST_F(DesksTest, DesksBarZeroState) { - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); auto* root_window = Shell::GetPrimaryRootWindow(); auto* desks_bar_view = GetOverviewGridForRoot(root_window)->desks_bar_view(); @@ -4876,8 +4859,8 @@ EXPECT_FALSE(zero_state_default_desk_button->GetVisible()); EXPECT_FALSE(zero_state_new_desk_button->GetVisible()); - overview_controller->EndOverview(); - overview_controller->StartOverview(); + ExitOverview(); + EnterOverview(); desks_bar_view = GetOverviewGridForRoot(root_window)->desks_bar_view(); ASSERT_TRUE(desks_bar_view->IsZeroState()); @@ -4902,8 +4885,7 @@ TEST_F(DesksTest, NewDeskButton) { auto* controller = DesksController::Get(); - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); auto* root_window = Shell::GetPrimaryRootWindow(); auto* desks_bar_view = GetOverviewGridForRoot(root_window)->desks_bar_view(); @@ -4933,8 +4915,7 @@ TEST_F(DesksTest, ZeroStateDeskButtonText) { UpdateDisplay("1600x1200"); - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); auto* root_window = Shell::GetPrimaryRootWindow(); auto* desks_bar_view = GetOverviewGridForRoot(root_window)->desks_bar_view(); @@ -4955,8 +4936,8 @@ SendKey(ui::VKEY_S); SendKey(ui::VKEY_T); SendKey(ui::VKEY_RETURN); - overview_controller->EndOverview(); - overview_controller->StartOverview(); + ExitOverview(); + EnterOverview(); desks_bar_view = GetOverviewGridForRoot(root_window)->desks_bar_view(); EXPECT_TRUE(desks_bar_view->IsZeroState()); @@ -4983,8 +4964,8 @@ for (size_t i = 0; i < DeskNameView::kMaxLength + 5; i++) SendKey(ui::VKEY_A); SendKey(ui::VKEY_RETURN); - overview_controller->EndOverview(); - overview_controller->StartOverview(); + ExitOverview(); + EnterOverview(); desks_bar_view = GetOverviewGridForRoot(root_window)->desks_bar_view(); auto* zero_state_default_desk_button = @@ -5004,9 +4985,8 @@ TEST_F(DesksTest, ReorderDesksByMouse) { auto* desks_controller = DesksController::Get(); - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); auto* root_window = Shell::GetPrimaryRootWindow(); const auto* desks_bar_view = @@ -5075,9 +5055,8 @@ TEST_F(DesksTest, ReorderDesksByGesture) { auto* desks_controller = DesksController::Get(); - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); auto* root_window = Shell::GetPrimaryRootWindow(); const auto* desks_bar_view = @@ -5147,7 +5126,7 @@ auto* desks_controller = DesksController::Get(); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); auto* root_window = Shell::GetPrimaryRootWindow(); @@ -5234,7 +5213,7 @@ auto* desks_controller = DesksController::Get(); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); auto* root_window = Shell::GetPrimaryRootWindow(); @@ -5325,9 +5304,8 @@ auto* desks_controller = DesksController::Get(); EXPECT_EQ(desks_controller->desks().size(), max_desks_size); - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); auto* desks_bar = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow())->desks_bar_view(); @@ -5427,9 +5405,8 @@ // back, click its target location won't cause any crashes. // Regression test of https://crbug.com/1171880. TEST_F(DesksTest, ClickTargetLocationOfDroppedDesk) { - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - ASSERT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); const auto* desks_bar_view = overview_grid->desks_bar_view(); @@ -5461,9 +5438,8 @@ // Tests that while reordering desks by drag & drop, when a desk is snapping // back, dragging a desk preview on the shelf will start a new drag. TEST_F(DesksTest, DragNewDeskWhileSnappingBack) { - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - ASSERT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); const auto* desks_bar_view = overview_grid->desks_bar_view(); @@ -5498,9 +5474,8 @@ // mouse or exiting overview will not have UAF issues // (https://crbug.com/1222120). TEST_F(DesksTest, RemoveDeskWhileDragging) { - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - EXPECT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); const auto* desks_bar_view = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow())->desks_bar_view(); @@ -5541,7 +5516,7 @@ EXPECT_FALSE(desks_bar_view->IsDraggingDesk()); // Exiting overview will not have any issue. - overview_controller->EndOverview(); + ExitOverview(); } // Tests that the right desk containers are visible when switching between desks @@ -5609,9 +5584,8 @@ ASSERT_EQ(2u, DesksController::Get()->desks().size()); // Start overview. - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - ASSERT_TRUE(overview_controller->InOverviewSession()); + EnterOverview(); + ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); // Setup an internal keyboard and an external keyboard. ui::DeviceDataManagerTestApi().SetKeyboardDevices( @@ -5853,7 +5827,6 @@ // Tests the bar's visibility while entering or leaving overview mode. TEST_F(PersistentDesksBarTest, OverviewMode) { - auto* shell = Shell::Get(); auto* desks_controller = DesksController::Get(); ASSERT_EQ(1u, desks_controller->desks().size()); @@ -5861,35 +5834,34 @@ EXPECT_TRUE(GetBarWidget()); // Entering overview mode should destroy the bar. Exiting overview mode with // more than one desk should create the bar and show it. - auto* overview_controller = shell->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_FALSE(GetBarWidget()); EXPECT_EQ(2u, desks_controller->desks().size()); - overview_controller->EndOverview(); + ExitOverview(); EXPECT_TRUE(GetBarWidget()); EXPECT_TRUE(IsWidgetVisible()); // Exiting overview mode with only one desk should not create the bar. - overview_controller->StartOverview(); + EnterOverview(); EXPECT_FALSE(GetBarWidget()); RemoveDesk(desks_controller->desks()[1].get()); EXPECT_EQ(1u, desks_controller->desks().size()); - overview_controller->EndOverview(); + ExitOverview(); EXPECT_FALSE(GetBarWidget()); // Each desk button in the bar should show the corresponding desk's name. - overview_controller->StartOverview(); + EnterOverview(); NewDesk(); EXPECT_EQ(2u, desks_controller->desks().size()); desks_controller->desks()[1].get()->SetName(u"test", /*set_by_user=*/true); - overview_controller->EndOverview(); + ExitOverview(); auto desk_buttons = DesksTestApi::GetPersistentDesksBarDeskButtons(); for (size_t i = 0; i < desk_buttons.size(); i++) EXPECT_EQ(desk_buttons[i]->GetText(), desks_controller->desks()[i]->name()); // The desk buttons should have the same order as the desks after reordering. auto* event_generator = GetEventGenerator(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_EQ(u"test", desks_controller->desks()[1]->name()); const auto* desks_bar_view = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow())->desks_bar_view(); @@ -5899,7 +5871,7 @@ .CenterPoint()); event_generator->ReleaseLeftButton(); EXPECT_EQ(u"test", desks_controller->desks()[0]->name()); - overview_controller->EndOverview(); + ExitOverview(); desk_buttons = DesksTestApi::GetPersistentDesksBarDeskButtons(); for (size_t i = 0; i < desk_buttons.size(); i++) EXPECT_EQ(desk_buttons[i]->GetText(), desks_controller->desks()[i]->name()); @@ -5932,7 +5904,7 @@ // The bar should not be created after entering or leaving tablet mode with // overview mode on. auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); TabletModeControllerTestApi().EnterTabletMode(); EXPECT_TRUE(overview_controller->InOverviewSession()); EXPECT_FALSE(GetBarWidget()); @@ -5959,20 +5931,19 @@ // With the bar being set to hide, it should not be created after exiting // overview mode with more than one desk. - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); - overview_controller->EndOverview(); + EnterOverview(); + ExitOverview(); EXPECT_FALSE(GetBarWidget()); // With the bar being set to show, it should be created after exiting overview // mode with more than one desk. - overview_controller->StartOverview(); + EnterOverview(); context_menu = DesksTestApi::GetDesksBarContextMenu(); context_menu->ExecuteCommand( static_cast<int>( PersistentDesksBarContextMenu::CommandId::kShowOrHideBar), /*event_flags=*/0); - overview_controller->EndOverview(); + ExitOverview(); EXPECT_TRUE(GetBarWidget()); EXPECT_TRUE(IsWidgetVisible()); }
diff --git a/ash/wm/desks/persistent_desks_bar_button.cc b/ash/wm/desks/persistent_desks_bar_button.cc index adfd317..788880eb 100644 --- a/ash/wm/desks/persistent_desks_bar_button.cc +++ b/ash/wm/desks/persistent_desks_bar_button.cc
@@ -114,7 +114,8 @@ PersistentDesksBarOverviewButton::~PersistentDesksBarOverviewButton() = default; void PersistentDesksBarOverviewButton::OnButtonPressed() { - Shell::Get()->overview_controller()->StartOverview(); + Shell::Get()->overview_controller()->StartOverview( + OverviewStartAction::kBentoBar); } } // namespace ash
diff --git a/ash/wm/desks/persistent_desks_bar_controller.cc b/ash/wm/desks/persistent_desks_bar_controller.cc index 4b9defa..d01d0649 100644 --- a/ash/wm/desks/persistent_desks_bar_controller.cc +++ b/ash/wm/desks/persistent_desks_bar_controller.cc
@@ -14,6 +14,7 @@ #include "ash/wm/desks/persistent_desks_bar_view.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" +#include "base/metrics/histogram_macros.h" #include "ui/aura/window.h" #include "ui/display/screen.h" #include "ui/views/widget/widget.h" @@ -172,6 +173,8 @@ is_enabled_ = !is_enabled_; if (!is_enabled_) DestroyBarWidget(); + + UMA_HISTOGRAM_BOOLEAN("Ash.Desks.BentoBarEnabled", is_enabled_); } bool PersistentDesksBarController::ShouldPersistentDesksBarBeCreated() const {
diff --git a/ash/wm/desks/root_window_desk_switch_animator.cc b/ash/wm/desks/root_window_desk_switch_animator.cc index cd38d3a0..8411afe 100644 --- a/ash/wm/desks/root_window_desk_switch_animator.cc +++ b/ash/wm/desks/root_window_desk_switch_animator.cc
@@ -619,7 +619,14 @@ } int RootWindowDeskSwitchAnimator::GetXPositionOfScreenshot(int index) { + // TODO(crbug.com/1223866): Investigate if we can prevent this higher in the + // call stack. + if (index < 0 || index >= static_cast<int>(screenshot_layers_.size())) + return 0; ui::Layer* layer = screenshot_layers_[index]; + if (!layer) + return 0; + DCHECK(layer); return layer->bounds().x(); }
diff --git a/ash/wm/gestures/back_gesture/back_gesture_event_handler.cc b/ash/wm/gestures/back_gesture/back_gesture_event_handler.cc index 8720998..16c7763 100644 --- a/ash/wm/gestures/back_gesture/back_gesture_event_handler.cc +++ b/ash/wm/gestures/back_gesture/back_gesture_event_handler.cc
@@ -171,19 +171,14 @@ } // namespace -BackGestureEventHandler::BackGestureEventHandler() - : gesture_provider_(this, this) { +BackGestureEventHandler::BackGestureEventHandler() { if (features::AreContextualNudgesEnabled()) { nudge_controller_ = std::make_unique<BackGestureContextualNudgeControllerImpl>(); } - - display::Screen::GetScreen()->AddObserver(this); } -BackGestureEventHandler::~BackGestureEventHandler() { - display::Screen::GetScreen()->RemoveObserver(this); -} +BackGestureEventHandler::~BackGestureEventHandler() = default; void BackGestureEventHandler::OnDisplayMetricsChanged( const display::Display& display,
diff --git a/ash/wm/gestures/back_gesture/back_gesture_event_handler.h b/ash/wm/gestures/back_gesture/back_gesture_event_handler.h index c8b03330..e4b9e6f 100644 --- a/ash/wm/gestures/back_gesture/back_gesture_event_handler.h +++ b/ash/wm/gestures/back_gesture/back_gesture_event_handler.h
@@ -112,7 +112,10 @@ // OnTouchEvent session. This is done to avoid tap down event be used by the // window that is underneath to do other things (e.g, highlight a menu item) // instead of going back. - ui::GestureProviderAura gesture_provider_; + ui::GestureProviderAura gesture_provider_{this, this}; + + // Register for DisplayObserver callbacks. + display::ScopedDisplayObserver display_observer_{this}; // False if BackGestureEventHandler should not handle touch events directly in // OnTouchEvent(), but should wait after touch ack is received. This is needed
diff --git a/ash/wm/gestures/back_gesture/back_gesture_event_handler_unittest.cc b/ash/wm/gestures/back_gesture/back_gesture_event_handler_unittest.cc index db06809..52b7ffb 100644 --- a/ash/wm/gestures/back_gesture/back_gesture_event_handler_unittest.cc +++ b/ash/wm/gestures/back_gesture/back_gesture_event_handler_unittest.cc
@@ -204,7 +204,7 @@ WindowState::Get(top_window())->Unminimize(); ASSERT_FALSE(WindowState::Get(top_window())->IsMinimized()); auto* shell = Shell::Get(); - shell->overview_controller()->StartOverview(); + EnterOverview(); ASSERT_TRUE(shell->overview_controller()->InOverviewSession()); GenerateBackSequence(); // Should trigger go back instead of minimize the window since it is in @@ -213,9 +213,9 @@ // Swipe back at overview mode without opened window should still trigger // going back. - shell->overview_controller()->EndOverview(); + ExitOverview(); ResetTopWindow(); - shell->overview_controller()->StartOverview(); + EnterOverview(); GenerateBackSequence(); EXPECT_EQ(2, target_back_release.accelerator_count()); EXPECT_TRUE(shell->app_list_controller()->IsHomeScreenVisible()); @@ -376,7 +376,7 @@ // Start overview first and then snap window in splitview to make sure // window activation order remains the same. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); auto* split_view_controller = SplitViewController::Get(Shell::GetPrimaryRootWindow()); split_view_controller->SnapWindow(left_window.get(),
diff --git a/ash/wm/gestures/wm_gesture_handler.cc b/ash/wm/gestures/wm_gesture_handler.cc index ede3907..21505e1 100644 --- a/ash/wm/gestures/wm_gesture_handler.cc +++ b/ash/wm/gestures/wm_gesture_handler.cc
@@ -120,14 +120,15 @@ base::RecordAction(base::UserMetricsAction("Touchpad_Gesture_Overview")); if (overview_controller->AcceptSelection()) return true; - overview_controller->EndOverview(); + overview_controller->EndOverview(OverviewEndAction::k3FingerVerticalScroll); } else { auto* window_cycle_controller = Shell::Get()->window_cycle_controller(); if (window_cycle_controller->IsCycling()) window_cycle_controller->CancelCycling(); base::RecordAction(base::UserMetricsAction("Touchpad_Gesture_Overview")); - overview_controller->StartOverview(); + overview_controller->StartOverview( + OverviewStartAction::k3FingerVerticalScroll); } return true;
diff --git a/ash/wm/gestures/wm_gesture_handler_unittest.cc b/ash/wm/gestures/wm_gesture_handler_unittest.cc index fe486f9..1f09950 100644 --- a/ash/wm/gestures/wm_gesture_handler_unittest.cc +++ b/ash/wm/gestures/wm_gesture_handler_unittest.cc
@@ -211,7 +211,7 @@ // Enter overview mode as if using an accelerator. // Entering overview mode with an upwards three-finger scroll gesture would // have the same result (allow selection using horizontal scroll). - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); EXPECT_TRUE(InOverviewSession()); // Scrolls until a window is highlight, ignoring any desks items (if any). @@ -377,8 +377,7 @@ TEST_F(WmGestureHandlerTest, ActivateHighlightedDeskWithVerticalScroll) { auto* desks_controller = DesksController::Get(); - auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(InOverviewSession()); // Create a new desk (we have two desks now). @@ -389,7 +388,8 @@ EXPECT_EQ(0, desks_controller->GetActiveDeskIndex()); // Move highlight to the second desk. - OverviewSession* overview_session = overview_controller->overview_session(); + OverviewSession* overview_session = + Shell::Get()->overview_controller()->overview_session(); DeskMiniView* mini_view_1 = overview_session->GetGridWithRootWindow(Shell::GetPrimaryRootWindow()) ->desks_bar_view()
diff --git a/ash/wm/lock_state_controller_unittest.cc b/ash/wm/lock_state_controller_unittest.cc index 09128f6..8276c86 100644 --- a/ash/wm/lock_state_controller_unittest.cc +++ b/ash/wm/lock_state_controller_unittest.cc
@@ -729,9 +729,8 @@ ->wallpaper_widget_controller() ->wallpaper_view(); - auto* overview_controller = Shell::Get()->overview_controller(); // Enter Overview and verify wallpaper properties. - overview_controller->StartOverview(); + EnterOverview(); EXPECT_EQ(wallpaper_constants::kOverviewBlur, wallpaper_view->blur_sigma()); // Start lock animation and verify wallpaper properties.
diff --git a/ash/wm/overlay_layout_manager.cc b/ash/wm/overlay_layout_manager.cc index 8ac160f9..d93b313 100644 --- a/ash/wm/overlay_layout_manager.cc +++ b/ash/wm/overlay_layout_manager.cc
@@ -18,12 +18,9 @@ OverlayLayoutManager::OverlayLayoutManager(aura::Window* overlay_container) : overlay_container_(overlay_container) { DCHECK(overlay_container_); - Screen::GetScreen()->AddObserver(this); } -OverlayLayoutManager::~OverlayLayoutManager() { - Screen::GetScreen()->RemoveObserver(this); -} +OverlayLayoutManager::~OverlayLayoutManager() = default; void OverlayLayoutManager::OnDisplayMetricsChanged( const display::Display& display,
diff --git a/ash/wm/overlay_layout_manager.h b/ash/wm/overlay_layout_manager.h index db5a1040..e36fb9c 100644 --- a/ash/wm/overlay_layout_manager.h +++ b/ash/wm/overlay_layout_manager.h
@@ -31,6 +31,8 @@ private: aura::Window* overlay_container_; + display::ScopedDisplayObserver display_observer_{this}; + DISALLOW_COPY_AND_ASSIGN(OverlayLayoutManager); };
diff --git a/ash/wm/overview/overview_controller.cc b/ash/wm/overview/overview_controller.cc index 6fa0f13b..75bf195 100644 --- a/ash/wm/overview/overview_controller.cc +++ b/ash/wm/overview/overview_controller.cc
@@ -117,7 +117,8 @@ } } -bool OverviewController::StartOverview(OverviewEnterExitType type) { +bool OverviewController::StartOverview(OverviewStartAction action, + OverviewEnterExitType type) { // No need to start overview if overview is currently active. if (InOverviewSession()) return true; @@ -126,10 +127,12 @@ return false; ToggleOverview(type); + RecordOverviewStartAction(action); return true; } -bool OverviewController::EndOverview(OverviewEnterExitType type) { +bool OverviewController::EndOverview(OverviewEndAction action, + OverviewEnterExitType type) { // No need to end overview if overview is already ended. if (!InOverviewSession()) return true; @@ -138,6 +141,7 @@ return false; ToggleOverview(type); + RecordOverviewEndAction(action); return true; }
diff --git a/ash/wm/overview/overview_controller.h b/ash/wm/overview/overview_controller.h index 0200cf9e..beab8f52 100644 --- a/ash/wm/overview/overview_controller.h +++ b/ash/wm/overview/overview_controller.h
@@ -11,6 +11,7 @@ #include "ash/ash_export.h" #include "ash/wm/overview/delayed_animation_observer.h" #include "ash/wm/overview/overview_delegate.h" +#include "ash/wm/overview/overview_metrics.h" #include "ash/wm/overview/overview_observer.h" #include "ash/wm/overview/overview_session.h" #include "ash/wm/overview/overview_types.h" @@ -33,12 +34,15 @@ OverviewController(); ~OverviewController() override; - // Starts/Ends overview with |type|. Returns true if enter or exit overview - // successful. Depending on |type| the enter/exit animation will look - // different. + // Starts/Ends overview with `type`. Returns true if enter or exit overview + // successful. Depending on `type` the enter/exit animation will look + // different. `action` is used by UMA to record the reasons that trigger + // overview starts or ends. E.g, pressing the overview button. bool StartOverview( + OverviewStartAction action, OverviewEnterExitType type = OverviewEnterExitType::kNormal); - bool EndOverview(OverviewEnterExitType type = OverviewEnterExitType::kNormal); + bool EndOverview(OverviewEndAction action, + OverviewEnterExitType type = OverviewEnterExitType::kNormal); // Returns true if overview mode is active. bool InOverviewSession() const;
diff --git a/ash/wm/overview/overview_controller_unittest.cc b/ash/wm/overview/overview_controller_unittest.cc index ea877555..6b3496d 100644 --- a/ash/wm/overview/overview_controller_unittest.cc +++ b/ash/wm/overview/overview_controller_unittest.cc
@@ -216,7 +216,7 @@ TestOverviewObserver observer(/*should_monitor_animation_state = */ true); // Enter without windows. auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); EXPECT_EQ(TestOverviewObserver::COMPLETED, observer.starting_animation_state()); @@ -228,7 +228,7 @@ // Exiting overview has no animations until the overview animation is // complete. - overview_controller->EndOverview(); + ExitOverview(); EXPECT_FALSE(overview_controller->InOverviewSession()); EXPECT_EQ(TestOverviewObserver::UNKNOWN, observer.ending_animation_state()); EXPECT_EQ(wallpaper_constants::kOverviewBlur, @@ -253,7 +253,7 @@ ASSERT_EQ(TestOverviewObserver::UNKNOWN, observer.ending_animation_state()); // Enter with windows. - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); EXPECT_EQ(TestOverviewObserver::UNKNOWN, observer.starting_animation_state()); EXPECT_EQ(TestOverviewObserver::UNKNOWN, observer.ending_animation_state()); @@ -262,7 +262,7 @@ EXPECT_FALSE(wallpaper_widget_controller->IsAnimating()); // Exit with windows before starting animation ends. - overview_controller->EndOverview(); + ExitOverview(); EXPECT_FALSE(overview_controller->InOverviewSession()); EXPECT_EQ(TestOverviewObserver::CANCELED, observer.starting_animation_state()); @@ -275,7 +275,7 @@ observer.Reset(); // Enter again before exit animation ends. - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); EXPECT_EQ(TestOverviewObserver::UNKNOWN, observer.starting_animation_state()); EXPECT_EQ(TestOverviewObserver::CANCELED, observer.ending_animation_state()); @@ -323,7 +323,7 @@ EXPECT_EQ(OcclusionState::VISIBLE, window2->GetOcclusionState()); // Enter with windows. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); EXPECT_EQ(OcclusionState::OCCLUDED, window1->GetOcclusionState()); EXPECT_EQ(OcclusionState::VISIBLE, window2->GetOcclusionState()); @@ -335,7 +335,7 @@ EXPECT_EQ(OcclusionState::VISIBLE, window1->GetOcclusionState()); // Exit with windows. - Shell::Get()->overview_controller()->EndOverview(); + ExitOverview(); EXPECT_EQ(OcclusionState::VISIBLE, window1->GetOcclusionState()); EXPECT_EQ(OcclusionState::VISIBLE, window2->GetOcclusionState()); observer.WaitForEndingAnimationComplete(); @@ -347,7 +347,7 @@ observer.Reset(); // Enter again. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); EXPECT_EQ(OcclusionState::OCCLUDED, window1->GetOcclusionState()); EXPECT_EQ(OcclusionState::VISIBLE, window2->GetOcclusionState()); auto* active = window_util::GetActiveWindow(); @@ -381,7 +381,7 @@ CreateTestWindowInShellWithBounds(bounds)); WaitForShowAnimation(window.get()); auto* controller = Shell::Get()->overview_controller(); - controller->StartOverview(); + EnterOverview(); // Ensure |window| is in overview with window state non-PIP. EXPECT_TRUE(controller->overview_session()->IsWindowInOverview(window.get())); WMEvent pip_event(WM_EVENT_PIP); @@ -398,7 +398,7 @@ GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplay().id()); GetAppListTestHelper()->CheckVisibility(true); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); GetAppListTestHelper()->WaitUntilIdle(); GetAppListTestHelper()->CheckVisibility(false); } @@ -420,9 +420,8 @@ ASSERT_TRUE(window3->IsVisible()); // Enter overview. Only one of the three windows is in overview, and visible. - auto* controller = Shell::Get()->overview_controller(); - controller->StartOverview(); - auto* session = controller->overview_session(); + EnterOverview(); + auto* session = Shell::Get()->overview_controller()->overview_session(); ASSERT_TRUE(session); EXPECT_TRUE(session->IsWindowInOverview(window1.get())); EXPECT_FALSE(session->IsWindowInOverview(window2.get())); @@ -434,7 +433,7 @@ // On exiting overview, the windows should all be visible. Use a run loop // since |session| is destroyed in a post task, and the restoring windows' // previous visibility happens in the destructor. - controller->EndOverview(); + ExitOverview(); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(window1->IsVisible()); EXPECT_TRUE(window2->IsVisible()); @@ -467,15 +466,13 @@ // Tests the case where we enter without windows and do regular enter/exit // (wait for enter animation to finish before exiting). - auto* overview_controller = Shell::Get()->overview_controller(); - for (bool is_tablet_mode : {false, true}) { SCOPED_TRACE(is_tablet_mode ? "Tablet Mode" : "Clamshell Mode"); set_tablet_mode_enabled(is_tablet_mode); - overview_controller->StartOverview(); + EnterOverview(); wait_for_animation(/*enter=*/true); - overview_controller->EndOverview(); + ExitOverview(); wait_for_animation(/*enter=*/false); EXPECT_TRUE(observer.ObserverCountsEqual()); } @@ -489,26 +486,26 @@ // Tests the case where we enter with windows and do regular enter/exit // (wait for enter animation to finish before exiting). - overview_controller->StartOverview(); + EnterOverview(); wait_for_animation(/*enter=*/true); - overview_controller->EndOverview(); + ExitOverview(); wait_for_animation(/*enter=*/false); EXPECT_TRUE(observer.ObserverCountsEqual()); // Tests the case where we exit overview before the start animation has // completed. - overview_controller->StartOverview(); - overview_controller->EndOverview(); + EnterOverview(); + ExitOverview(); wait_for_animation(/*enter=*/false); EXPECT_TRUE(observer.ObserverCountsEqual()); // Tests the case where we enter overview before the exit animation has // completed. - overview_controller->StartOverview(); + EnterOverview(); wait_for_animation(/*enter=*/true); - overview_controller->EndOverview(); - overview_controller->StartOverview(); - overview_controller->EndOverview(); + ExitOverview(); + EnterOverview(); + ExitOverview(); wait_for_animation(/*enter=*/false); EXPECT_TRUE(observer.ObserverCountsEqual()); } @@ -528,13 +525,12 @@ std::unique_ptr<aura::Window> window( CreateTestWindowInShellWithBounds(bounds)); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); EXPECT_FALSE(observer.last_animation_was_fade()); // Exit to home launcher using fade out animation. This should minimize all // windows. - Shell::Get()->overview_controller()->EndOverview( - OverviewEnterExitType::kFadeOutExit); + ExitOverview(OverviewEnterExitType::kFadeOutExit); EXPECT_TRUE(observer.last_animation_was_fade()); @@ -543,7 +539,7 @@ // All windows are minimized, so we should use the fade in animation to enter // overview. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); EXPECT_TRUE(observer.last_animation_was_fade()); } @@ -556,17 +552,17 @@ std::unique_ptr<aura::Window> window( CreateTestWindowInShellWithBounds(bounds)); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); EXPECT_FALSE(observer.last_animation_was_fade()); - Shell::Get()->overview_controller()->EndOverview(); + ExitOverview(); EXPECT_FALSE(observer.last_animation_was_fade()); // Even with all window minimized, overview should not use fade animation to // enter. ASSERT_FALSE(Shell::Get()->overview_controller()->InOverviewSession()); WindowState::Get(window.get())->Minimize(); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); EXPECT_FALSE(observer.last_animation_was_fade()); } @@ -579,8 +575,7 @@ ui::ScopedAnimationDurationScaleMode non_zero( ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); - Shell::Get()->overview_controller()->StartOverview( - OverviewEnterExitType::kFadeInEnter); + EnterOverview(OverviewEnterExitType::kFadeInEnter); auto* wallpaper_widget_controller = Shell::GetPrimaryRootWindowController()->wallpaper_widget_controller(); EXPECT_GT(wallpaper_widget_controller->GetWallpaperBlur(), 0); @@ -603,13 +598,12 @@ // started asynchronously. ui::ScopedAnimationDurationScaleMode non_zero( ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); // Exit to home launcher using fade out animation. This should minimize all // windows. TestOverviewObserver observer(/*should_monitor_animation_state = */ true); - Shell::Get()->overview_controller()->EndOverview( - OverviewEnterExitType::kFadeOutExit); + ExitOverview(OverviewEnterExitType::kFadeOutExit); EXPECT_TRUE(observer.last_animation_was_fade()); @@ -631,7 +625,7 @@ ui::ScopedAnimationDurationScaleMode non_zero( ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); // Destroy a window during the enter animation. window1.reset(); @@ -639,7 +633,7 @@ OverviewAnimationState::kEnterAnimationComplete); ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); - Shell::Get()->overview_controller()->EndOverview(); + ExitOverview(); // Destroy a window during the exit animation. window2.reset(); @@ -667,7 +661,8 @@ // DeskSwitchAnimationWaiter: void OnDeskActivationChanged(const Desk* activated, const Desk* deactivated) override { - Shell::Get()->overview_controller()->StartOverview(); + Shell::Get()->overview_controller()->StartOverview( + OverviewStartAction::kTests); } }; @@ -690,7 +685,7 @@ waiter.Wait(); EXPECT_FALSE(Shell::Get()->overview_controller()->InOverviewSession()); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); // Tests that exiting overview works as it is part of the desk switch @@ -727,7 +722,7 @@ keyboard_ui_controller()->ShowKeyboard(false /* locked */); ASSERT_TRUE(keyboard::WaitUntilShown()); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); // Timeout failure here if the keyboard does not hide. keyboard::WaitUntilHidden(); @@ -738,7 +733,7 @@ keyboard_ui_controller()->ShowKeyboard(true /* locked */); ASSERT_TRUE(keyboard::WaitUntilShown()); - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); EXPECT_FALSE(keyboard::IsKeyboardHiding()); } @@ -767,16 +762,15 @@ arc_windows[i] = created_windows[i + browser_window_count].get(); } - auto* controller = Shell::Get()->overview_controller(); EXPECT_CALL(observer, OnThrottlingStarted( testing::UnorderedElementsAreArray(arc_windows), frame_throttling_controller->throttled_fps())); - controller->StartOverview(); + EnterOverview(); EXPECT_THAT(frame_throttling_controller->GetFrameSinkIdsToThrottle(), ::testing::UnorderedElementsAreArray(ids)); EXPECT_CALL(observer, OnThrottlingEnded()); - controller->EndOverview(); + ExitOverview(); EXPECT_TRUE(frame_throttling_controller->GetFrameSinkIdsToThrottle().empty()); frame_throttling_controller->RemoveArcObserver(&observer);
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index cb58ad8..a946230 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -953,7 +953,7 @@ (split_view_controller->InClamshellSplitViewMode() && overview_session_->IsEmpty())) { overview_session_->RestoreWindowActivation(false); - overview_controller->EndOverview(); + overview_controller->EndOverview(OverviewEndAction::kSplitView); return; }
diff --git a/ash/wm/overview/overview_grid_event_handler.cc b/ash/wm/overview/overview_grid_event_handler.cc index ff9214c..1277bcd 100644 --- a/ash/wm/overview/overview_grid_event_handler.cc +++ b/ash/wm/overview/overview_grid_event_handler.cc
@@ -64,7 +64,8 @@ // ui::GESTURE_END_EVENT which may cause a bad state. if (event->type() == ui::ET_MOUSE_PRESSED && !overview_session_->CanProcessEvent()) { - Shell::Get()->overview_controller()->EndOverview(); + Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kClickingOutsideWindowsInOverview); event->StopPropagation(); event->SetHandled(); return; @@ -156,7 +157,8 @@ Shell::Get()->app_list_controller()->GoHome(display_id); } } else { - Shell::Get()->overview_controller()->EndOverview(); + Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kClickingOutsideWindowsInOverview); } event->StopPropagation(); }
diff --git a/ash/wm/overview/overview_grid_unittest.cc b/ash/wm/overview/overview_grid_unittest.cc index 2374162..7165fc23 100644 --- a/ash/wm/overview/overview_grid_unittest.cc +++ b/ash/wm/overview/overview_grid_unittest.cc
@@ -279,8 +279,7 @@ // We cannot create a grid object like in the other tests because creating a // grid calls |GetGridBoundsInScreen| with split view state both snapped which // is an unnatural state. - Shell::Get()->overview_controller()->StartOverview( - OverviewEnterExitType::kNormal); + EnterOverview(); // Tests that |window3| is not animated even though its bounds are larger than // |window2| because it is fully occluded by |window1| + |window2| and the
diff --git a/ash/wm/overview/overview_metrics.cc b/ash/wm/overview/overview_metrics.cc new file mode 100644 index 0000000..7f2f1ce --- /dev/null +++ b/ash/wm/overview/overview_metrics.cc
@@ -0,0 +1,22 @@ +// Copyright 2021 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. + +#include "ash/wm/overview/overview_metrics.h" + +#include "base/metrics/histogram_macros.h" + +namespace ash { + +constexpr char kOverviewStartActionHistogram[] = "Ash.Overview.StartAction"; +constexpr char kOverviewEndActionHistogram[] = "Ash.Overview.EndAction"; + +void RecordOverviewStartAction(OverviewStartAction type) { + UMA_HISTOGRAM_ENUMERATION(kOverviewStartActionHistogram, type); +} + +void RecordOverviewEndAction(OverviewEndAction type) { + UMA_HISTOGRAM_ENUMERATION(kOverviewEndActionHistogram, type); +} + +} // namespace ash
diff --git a/ash/wm/overview/overview_metrics.h b/ash/wm/overview/overview_metrics.h new file mode 100644 index 0000000..767acdd --- /dev/null +++ b/ash/wm/overview/overview_metrics.h
@@ -0,0 +1,57 @@ +// Copyright 2021 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. + +#ifndef ASH_WM_OVERVIEW_OVERVIEW_METRICS_H_ +#define ASH_WM_OVERVIEW_OVERVIEW_METRICS_H_ + +namespace ash { + +// Used for histograms. See OverviewStartAction at +// tools/metrics/histograms/enums.xml. +enum class OverviewStartAction { + kSplitView, + kAccelerator, + kDragWindowFromShelf, + kExitHomeLauncher, + kOverviewButton, + kOverviewButtonLongPress, + kBentoBar, + k3FingerVerticalScroll, + kDevTools, + kTests, + kMaxValue = kTests, +}; +void RecordOverviewStartAction(OverviewStartAction type); + +// Used for histograms. See OverviewEndAction at +// tools/metrics/histograms/enums.xml. +enum class OverviewEndAction { + kSplitView, + kDragWindowFromShelf, + kEnterHomeLauncher, + kClickingOutsideWindowsInOverview, + kWindowActivating, + kLastWindowRemoved, + kDisplayAdded, + kAccelerator, + kKeyEscapeOrBack, + kDeskActivation, + kOverviewButton, + kOverviewButtonLongPress, + k3FingerVerticalScroll, + kEnabledDockedMagnifier, + kUserSwitch, + kStartedWindowCycle, + kShuttingDown, + kAppListActivatedInClamshell, + kShelfAlignmentChanged, + kDevTools, + kTests, + kMaxValue = kTests, +}; +void RecordOverviewEndAction(OverviewEndAction type); + +} // namespace ash + +#endif // ASH_WM_OVERVIEW_OVERVIEW_METRICS_H_
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc index 08dfdc1..9954ee04 100644 --- a/ash/wm/overview/overview_session.cc +++ b/ash/wm/overview/overview_session.cc
@@ -52,7 +52,6 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/layer.h" #include "ui/compositor/scoped_layer_animation_settings.h" -#include "ui/display/screen.h" #include "ui/events/event.h" #include "ui/views/accessibility/view_accessibility.h" #include "ui/views/widget/widget.h" @@ -76,8 +75,8 @@ // Tries to end overview. Returns true if overview is successfully ended, or // just was not active in the first place. -bool EndOverview() { - return Shell::Get()->overview_controller()->EndOverview(); +bool EndOverview(OverviewEndAction action) { + return Shell::Get()->overview_controller()->EndOverview(action); } // A self-deleting window state observer that runs the given callback when its @@ -239,7 +238,7 @@ SplitViewController::Get(Shell::GetPrimaryRootWindow())->AddObserver(this); - display::Screen::GetScreen()->AddObserver(this); + display_observer_.emplace(this); base::RecordAction(base::UserMetricsAction("WindowSelector_Overview")); // Send an a11y alert. Shell::Get()->accessibility_controller()->TriggerAccessibilityAlert( @@ -261,7 +260,7 @@ // Stop observing screen metrics changes first to avoid auto-positioning // windows in response to work area changes from window activation. - display::Screen::GetScreen()->RemoveObserver(this); + display_observer_.reset(); // Stop observing split view state changes before restoring window focus. // Otherwise the activation of the window triggers OnSplitViewStateChanged() @@ -333,7 +332,7 @@ ->InTabletSplitViewMode()) { UpdateNoWindowsWidget(); } else { - EndOverview(); + EndOverview(OverviewEndAction::kLastWindowRemoved); } } @@ -737,7 +736,7 @@ // Cancel overview session and do not restore activation when active window // is set to nullptr. This happens when removing a display. RestoreWindowActivation(false); - EndOverview(); + EndOverview(OverviewEndAction::kWindowActivating); return; } @@ -769,7 +768,7 @@ if (gained_active == Shell::Get()->app_list_controller()->GetWindow() && !Shell::Get()->tablet_mode_controller()->InTabletMode()) { RestoreWindowActivation(false); - EndOverview(); + EndOverview(OverviewEndAction::kAppListActivatedInClamshell); return; } @@ -808,7 +807,7 @@ // Don't restore window activation on exit if a window was just activated. RestoreWindowActivation(false); - EndOverview(); + EndOverview(OverviewEndAction::kWindowActivating); } aura::Window* OverviewSession::GetOverviewFocusWindow() { @@ -927,10 +926,10 @@ } void OverviewSession::OnDisplayAdded(const display::Display& display) { - if (EndOverview()) + if (EndOverview(OverviewEndAction::kDisplayAdded)) return; SplitViewController::Get(Shell::GetPrimaryRootWindow())->EndSplitView(); - EndOverview(); + EndOverview(OverviewEndAction::kDisplayAdded); } void OverviewSession::OnDisplayMetricsChanged(const display::Display& display, @@ -1008,7 +1007,7 @@ switch (key_code) { case ui::VKEY_BROWSER_BACK: case ui::VKEY_ESCAPE: - EndOverview(); + EndOverview(OverviewEndAction::kKeyEscapeOrBack); break; case ui::VKEY_UP: ++num_key_presses_; @@ -1068,7 +1067,7 @@ void OverviewSession::OnShellDestroying() { // Cancel selection will call |Shutdown()|, which will remove observer. - EndOverview(); + EndOverview(OverviewEndAction::kShuttingDown); } void OverviewSession::OnShelfAlignmentChanged(aura::Window* root_window, @@ -1097,7 +1096,7 @@ // doesn't get updated anyways (see https://crbug.com/834400). In this case, // even updating the grid bounds won't make any difference, so we simply exit // overview. - EndOverview(); + EndOverview(OverviewEndAction::kShelfAlignmentChanged); } void OverviewSession::OnSplitViewStateChanged( @@ -1162,7 +1161,7 @@ } void OverviewSession::RemoveAllObservers() { - display::Screen::GetScreen()->RemoveObserver(this); + display_observer_.reset(); if (active_window_before_overview_) active_window_before_overview_->RemoveObserver(this); active_window_before_overview_ = nullptr;
diff --git a/ash/wm/overview/overview_session.h b/ash/wm/overview/overview_session.h index 791a285..8fbf2042 100644 --- a/ash/wm/overview/overview_session.h +++ b/ash/wm/overview/overview_session.h
@@ -410,6 +410,8 @@ std::unique_ptr<OverviewHighlightController> highlight_controller_; + absl::optional<display::ScopedDisplayObserver> display_observer_; + DISALLOW_COPY_AND_ASSIGN(OverviewSession); };
diff --git a/ash/wm/overview/overview_test_api.cc b/ash/wm/overview/overview_test_api.cc index 0151985..45e9f50 100644 --- a/ash/wm/overview/overview_test_api.cc +++ b/ash/wm/overview/overview_test_api.cc
@@ -40,8 +40,9 @@ : OverviewAnimationState::kExitAnimationComplete, std::move(done_callback)); - const bool animation_started = start ? overview_controller->StartOverview() - : overview_controller->EndOverview(); + const bool animation_started = + start ? overview_controller->StartOverview(OverviewStartAction::kTests) + : overview_controller->EndOverview(OverviewEndAction::kTests); if (!animation_started) waiter->Cancel();
diff --git a/ash/wm/overview/overview_test_util.cc b/ash/wm/overview/overview_test_util.cc index 9a21f46..3c4d7fc 100644 --- a/ash/wm/overview/overview_test_util.cc +++ b/ash/wm/overview/overview_test_util.cc
@@ -68,9 +68,9 @@ void ToggleOverview(OverviewEnterExitType type) { auto* overview_controller = Shell::Get()->overview_controller(); if (overview_controller->InOverviewSession()) - overview_controller->EndOverview(type); + overview_controller->EndOverview(OverviewEndAction::kTests, type); else - overview_controller->StartOverview(type); + overview_controller->StartOverview(OverviewStartAction::kTests, type); } void WaitForOverviewEnterAnimation() {
diff --git a/ash/wm/overview/overview_window_drag_controller_unittest.cc b/ash/wm/overview/overview_window_drag_controller_unittest.cc index a25144c..8f441c6 100644 --- a/ash/wm/overview/overview_window_drag_controller_unittest.cc +++ b/ash/wm/overview/overview_window_drag_controller_unittest.cc
@@ -109,7 +109,7 @@ base::RunLoop().RunUntilIdle(); Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); auto* overview_session = overview_controller->overview_session(); auto* overview_item = @@ -144,7 +144,7 @@ EXPECT_EQ(window.get(), window_util::GetActiveWindow()); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); auto* overview_session = overview_controller->overview_session(); const auto* overview_grid = @@ -196,7 +196,7 @@ std::unique_ptr<aura::Window> window = CreateAppWindow(gfx::Rect(0, 0, 250, 100)); auto* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); auto* overview_session = overview_controller->overview_session(); auto* overview_item = @@ -294,7 +294,7 @@ void StartDraggingAndValidateDesksBarShifted(aura::Window* window) { // Enter overview mode, and start dragging the window. Validate that the // desks bar widget is shifted down to make room for the indicators. - overview_controller()->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller()->InOverviewSession()); auto* overview_item = GetOverviewItemForWindow(window); ASSERT_TRUE(overview_item);
diff --git a/ash/wm/overview/overview_window_drag_histogram_unittests.cc b/ash/wm/overview/overview_window_drag_histogram_unittests.cc index e4575ac..0954408 100644 --- a/ash/wm/overview/overview_window_drag_histogram_unittests.cc +++ b/ash/wm/overview/overview_window_drag_histogram_unittests.cc
@@ -64,7 +64,7 @@ } gfx::Point EnterOverviewAndGetItemCenterPoint() { - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); return gfx::ToRoundedPoint( GetOverviewItemForWindow(window_.get())->target_bounds().CenterPoint()); }
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc index 961063db..4b3cdc4 100644 --- a/ash/wm/splitview/split_view_controller.cc +++ b/ash/wm/splitview/split_view_controller.cc
@@ -483,7 +483,8 @@ // just end overview mode which will then end splitview mode. // TODO(xdai): Handle this logic in OverivewSession::OnWindowActivating(). if (split_view_controller_->InClamshellSplitViewMode()) { - Shell::Get()->overview_controller()->EndOverview(); + Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kSplitView); return; } @@ -704,7 +705,6 @@ split_view_metrics_controller_( std::make_unique<SplitViewMetricsController>(this)) { Shell::Get()->accessibility_controller()->AddObserver(this); - display::Screen::GetScreen()->AddObserver(this); Shell::Get()->tablet_mode_controller()->AddObserver(this); split_view_type_ = Shell::Get()->tablet_mode_controller()->InTabletMode() ? SplitViewType::kTabletType @@ -714,7 +714,6 @@ SplitViewController::~SplitViewController() { if (Shell::Get()->tablet_mode_controller()) Shell::Get()->tablet_mode_controller()->RemoveObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); if (Shell::Get()->accessibility_controller()) Shell::Get()->accessibility_controller()->RemoveObserver(this); EndSplitView(); @@ -1263,7 +1262,8 @@ DCHECK(IsWindowInSplitView(target_window)); DCHECK(target_window); EndSplitView(); - overview_controller->EndOverview(); + overview_controller->EndOverview( + OverviewEndAction::kOverviewButtonLongPress); MaximizeIfSnapped(target_window); wm::ActivateWindow(target_window); base::RecordAction( @@ -1278,7 +1278,9 @@ } // Start overview mode if we aren't already in it. - overview_controller->StartOverview(OverviewEnterExitType::kImmediateEnter); + overview_controller->StartOverview( + OverviewStartAction::kOverviewButtonLongPress, + OverviewEnterExitType::kImmediateEnter); SnapWindow(target_window, SplitViewController::LEFT, /*activate_window=*/true); @@ -1343,7 +1345,8 @@ return; EndSplitView(); - Shell::Get()->overview_controller()->EndOverview(); + Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kSplitView); ShowAppCannotSnapToast(); } @@ -1364,7 +1367,8 @@ if (window_state->drag_details()->bounds_change == WindowResizer::kBoundsChange_Repositions) { // Ending overview will also end clamshell split view. - Shell::Get()->overview_controller()->EndOverview(); + Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kSplitView); return; } DCHECK(window_state->drag_details()->bounds_change & @@ -1405,7 +1409,8 @@ if (WindowState::Get(window)->drag_details()->window_component != GetWindowComponentForResize(window)) { // Ending overview will also end clamshell split view. - Shell::Get()->overview_controller()->EndOverview(); + Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kSplitView); return; } @@ -1435,7 +1440,8 @@ if (divider_position_ < GetDividerEndPosition() * kOneThirdPositionRatio || divider_position_ > GetDividerEndPosition() * kTwoThirdPositionRatio) { // Ending overview will also end clamshell split view. - Shell::Get()->overview_controller()->EndOverview(); + Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kSplitView); WindowState::Get(window)->Maximize(); } } @@ -1477,7 +1483,8 @@ // 3. A (clamshell or tablet) split view window gets maximized. // 4. A (clamshell or tablet) split view window becomes full screen. EndSplitView(); - Shell::Get()->overview_controller()->EndOverview(); + Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kSplitView); } else if (window_state->IsMinimized()) { OnSnappedWindowDetached(window_state->window(), WindowDetachedReason::kWindowMinimized); @@ -1488,10 +1495,12 @@ // the window is not supposed to be minmized in tablet mode. And in // clamshell splitview mode, we respect the minimization of the window // and end overview instead. - if (split_view_type_ == SplitViewType::kTabletType) + if (split_view_type_ == SplitViewType::kTabletType) { InsertWindowToOverview(window_state->window()); - else - Shell::Get()->overview_controller()->EndOverview(); + } else { + Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kSplitView); + } } } } @@ -1581,6 +1590,7 @@ // are in overview (see https://crbug.com/1027179). if (state_ == State::kLeftSnapped || state_ == State::kRightSnapped) { Shell::Get()->overview_controller()->StartOverview( + OverviewStartAction::kSplitView, OverviewEnterExitType::kImmediateEnter); } } @@ -1948,7 +1958,8 @@ insert_overview_window = GetDefaultSnappedWindow(); EndSplitView(); if (active_window) { - Shell::Get()->overview_controller()->EndOverview(); + Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kSplitView); wm::ActivateWindow(active_window); } else if (insert_overview_window) { InsertWindowToOverview(insert_overview_window, /*animate=*/false); @@ -1992,7 +2003,8 @@ if (!overview_controller->InOverviewSession() && split_view_type_ == SplitViewType::kTabletType && (state_ == State::kLeftSnapped || state_ == State::kRightSnapped)) { - overview_controller->StartOverview(OverviewEnterExitType::kNormal); + overview_controller->StartOverview(OverviewStartAction::kSplitView, + OverviewEnterExitType::kNormal); } } @@ -2035,6 +2047,7 @@ default_snap_position_ = left_window_ ? LEFT : RIGHT; UpdateStateAndNotifyObservers(); Shell::Get()->overview_controller()->StartOverview( + OverviewStartAction::kSplitView, reason == WindowDetachedReason::kWindowDragged ? OverviewEnterExitType::kImmediateEnter : OverviewEnterExitType::kNormal); @@ -2302,7 +2315,8 @@ // Activate the dragged window and end the overview. The dragged window // will be restored back to its previous state before dragging. wm::ActivateWindow(window); - Shell::Get()->overview_controller()->EndOverview(); + Shell::Get()->overview_controller()->EndOverview( + OverviewEndAction::kSplitView); // Update the dragged window's bounds. It's possible that the dragged // window's bounds was changed during dragging. Update its bounds after
diff --git a/ash/wm/splitview/split_view_controller.h b/ash/wm/splitview/split_view_controller.h index d8ab9ad..9dee64f 100644 --- a/ash/wm/splitview/split_view_controller.h +++ b/ash/wm/splitview/split_view_controller.h
@@ -551,6 +551,9 @@ // The metrics controller for the same root window. std::unique_ptr<SplitViewMetricsController> split_view_metrics_controller_; + // Register for DisplayObserver callbacks. + display::ScopedDisplayObserver display_observer_{this}; + // A pointer to the to-be-snapped window that will be activated after it's // snapped in splitview. There can be two cases when this value can be // non-nullptr, when SnapWindow() explicitly specifies the window needs to be
diff --git a/ash/wm/splitview/split_view_drag_indicators_unittest.cc b/ash/wm/splitview/split_view_drag_indicators_unittest.cc index 460857c..4753f63 100644 --- a/ash/wm/splitview/split_view_drag_indicators_unittest.cc +++ b/ash/wm/splitview/split_view_drag_indicators_unittest.cc
@@ -53,9 +53,9 @@ void ToggleOverview() { auto* overview_controller = Shell::Get()->overview_controller(); if (overview_controller->InOverviewSession()) - overview_controller->EndOverview(); + ExitOverview(); else - overview_controller->StartOverview(); + EnterOverview(); if (!overview_controller->InOverviewSession()) { overview_session_ = nullptr;
diff --git a/ash/wm/splitview/split_view_utils.cc b/ash/wm/splitview/split_view_utils.cc index b1f35eae..db892b0 100644 --- a/ash/wm/splitview/split_view_utils.cc +++ b/ash/wm/splitview/split_view_utils.cc
@@ -385,9 +385,9 @@ SplitViewController::State state = split_view_controller->state(); if (state == SplitViewController::State::kLeftSnapped || state == SplitViewController::State::kRightSnapped) { - overview_controller->StartOverview(); + overview_controller->StartOverview(OverviewStartAction::kSplitView); } else { - overview_controller->EndOverview(); + overview_controller->EndOverview(OverviewEndAction::kSplitView); } }
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.cc b/ash/wm/tablet_mode/tablet_mode_controller.cc index 983f365..5752b3e 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller.cc
@@ -1141,7 +1141,8 @@ SplitViewController::Get(Shell::GetPrimaryRootWindow())->state(); if (state == SplitViewController::State::kLeftSnapped || state == SplitViewController::State::kRightSnapped) { - Shell::Get()->overview_controller()->StartOverview(); + Shell::Get()->overview_controller()->StartOverview( + OverviewStartAction::kSplitView); } UpdateInternalInputDevicesEventBlocker();
diff --git a/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc b/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc index a2c85649a..0c265d4b 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc
@@ -617,7 +617,7 @@ ASSERT_FALSE(IsTabletModeStarted()); tablet_mode_controller()->SetEnabledForTest(true); - EXPECT_TRUE(Shell::Get()->overview_controller()->StartOverview()); + EXPECT_TRUE(EnterOverview()); UpdateDisplay("800x600"); base::RunLoop().RunUntilIdle(); @@ -1776,7 +1776,7 @@ window2->layer()->GetAnimator()->StopAnimating(); // Enter overview. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); ShellTestApi().WaitForOverviewAnimationState( OverviewAnimationState::kEnterAnimationComplete);
diff --git a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc index bbfd64782..27b36e4d 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc
@@ -174,7 +174,8 @@ ->overview_button_tray(); DCHECK(overview_button_tray); overview_button_tray->SnapRippleToActivated(); - controller->StartOverview(OverviewEnterExitType::kImmediateEnter); + controller->StartOverview(OverviewStartAction::kSplitView, + OverviewEnterExitType::kImmediateEnter); } if (controller->InOverviewSession()) {
diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager.cc b/ash/wm/tablet_mode/tablet_mode_window_manager.cc index 2dc6496..4fc424e 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_manager.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_manager.cc
@@ -161,7 +161,7 @@ ArrangeWindowsForTabletMode(); } AddWindowCreationObservers(); - display::Screen::GetScreen()->AddObserver(this); + display_observer_.emplace(this); SplitViewController::Get(Shell::GetPrimaryRootWindow())->AddObserver(this); Shell::Get()->session_controller()->AddObserver(this); Shell::Get()->overview_controller()->AddObserver(this); @@ -207,7 +207,7 @@ overview_controller->overview_session()->IsEmpty()) { split_view_controller->EndSplitView( SplitViewController::EndReason::kExitTabletMode); - overview_controller->EndOverview(); + overview_controller->EndOverview(OverviewEndAction::kSplitView); } } @@ -217,7 +217,7 @@ split_view_controller->RemoveObserver(this); Shell::Get()->session_controller()->RemoveObserver(this); Shell::Get()->overview_controller()->RemoveObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); + display_observer_.reset(); RemoveWindowCreationObservers(); ScopedObserveWindowAnimation scoped_observe(window_util::GetTopWindow(), this,
diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager.h b/ash/wm/tablet_mode/tablet_mode_window_manager.h index 724c1e9..a0bd695 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_manager.h +++ b/ash/wm/tablet_mode/tablet_mode_window_manager.h
@@ -188,6 +188,8 @@ std::unique_ptr<TabletModeToggleFullscreenEventHandler> event_handler_; + absl::optional<display::ScopedDisplayObserver> display_observer_; + // True when tablet mode is about to end. bool is_exiting_ = false;
diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc b/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc index c60537d..df4d93d 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc
@@ -1551,13 +1551,12 @@ EXPECT_TRUE(window_state->IsMinimized()); EXPECT_EQ(window->bounds(), rect); - OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_EQ(window->bounds(), rect); // Exit overview mode will update all windows' bounds. However, if the window // is minimized, the bounds will not be updated. - overview_controller->EndOverview(); + ExitOverview(); EXPECT_EQ(window->bounds(), rect); } @@ -1623,7 +1622,7 @@ // 1. Clamshell -> tablet. If overview is active, it should still be kept // active after transition. OverviewController* overview_controller = Shell::Get()->overview_controller(); - EXPECT_TRUE(overview_controller->StartOverview()); + EXPECT_TRUE(EnterOverview()); EXPECT_TRUE(overview_controller->InOverviewSession()); TabletModeWindowManager* manager = CreateTabletModeWindowManager(); EXPECT_TRUE(manager); @@ -1636,7 +1635,7 @@ // 3. Clamshell -> tablet. If overview is inactive, it should still be kept // inactive after transition. All windows will be maximized. - EXPECT_TRUE(overview_controller->EndOverview()); + EXPECT_TRUE(ExitOverview()); EXPECT_FALSE(overview_controller->InOverviewSession()); CreateTabletModeWindowManager(); EXPECT_FALSE(overview_controller->InOverviewSession()); @@ -1698,7 +1697,7 @@ // 10. Tablet -> Clamshell. If overview and splitview are both active, after // transition, they will remain both active. - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(split_view_controller()->InSplitViewMode()); EXPECT_TRUE(overview_controller->InOverviewSession()); DestroyTabletModeWindowManager(); @@ -1777,7 +1776,7 @@ // Clamshell -> Tablet mode transition. If overview is active, it will remain // in overview. OverviewController* overview_controller = Shell::Get()->overview_controller(); - EXPECT_TRUE(overview_controller->StartOverview()); + EXPECT_TRUE(EnterOverview()); EXPECT_TRUE(overview_controller->InOverviewSession()); TabletModeWindowManager* manager = CreateTabletModeWindowManager(); EXPECT_TRUE(manager);
diff --git a/ash/wm/toplevel_window_event_handler.cc b/ash/wm/toplevel_window_event_handler.cc index f8cf986e..43e8764e 100644 --- a/ash/wm/toplevel_window_event_handler.cc +++ b/ash/wm/toplevel_window_event_handler.cc
@@ -205,11 +205,9 @@ ToplevelWindowEventHandler::ToplevelWindowEventHandler() : first_finger_hittest_(HTNOWHERE) { Shell::Get()->window_tree_host_manager()->AddObserver(this); - display::Screen::GetScreen()->AddObserver(this); } ToplevelWindowEventHandler::~ToplevelWindowEventHandler() { - display::Screen::GetScreen()->RemoveObserver(this); Shell::Get()->window_tree_host_manager()->RemoveObserver(this); }
diff --git a/ash/wm/toplevel_window_event_handler.h b/ash/wm/toplevel_window_event_handler.h index 8d9bd16..c2792521 100644 --- a/ash/wm/toplevel_window_event_handler.h +++ b/ash/wm/toplevel_window_event_handler.h
@@ -176,6 +176,8 @@ std::unique_ptr<ScopedWindowResizer> window_resizer_; + display::ScopedDisplayObserver display_observer_{this}; + EndClosure end_closure_; // Are we running a nested run loop from RunMoveLoop().
diff --git a/ash/wm/window_cycle/window_cycle_controller.cc b/ash/wm/window_cycle/window_cycle_controller.cc index 8ce71f6..56654d6 100644 --- a/ash/wm/window_cycle/window_cycle_controller.cc +++ b/ash/wm/window_cycle/window_cycle_controller.cc
@@ -236,7 +236,8 @@ shell->event_rewriter_controller()->SetAltDownRemappingEnabled(false); // End overview as the window cycle list takes over window switching. - shell->overview_controller()->EndOverview(); + shell->overview_controller()->EndOverview( + OverviewEndAction::kStartedWindowCycle); WindowCycleController::WindowList window_list = CreateWindowList(); SaveCurrentActiveDeskAndWindow(window_list);
diff --git a/ash/wm/window_cycle/window_cycle_controller_unittest.cc b/ash/wm/window_cycle/window_cycle_controller_unittest.cc index 3d9e4f6..be25b55d 100644 --- a/ash/wm/window_cycle/window_cycle_controller_unittest.cc +++ b/ash/wm/window_cycle/window_cycle_controller_unittest.cc
@@ -1360,7 +1360,7 @@ EXPECT_TRUE(wm::IsActiveWindow(window2.get())); // Open an overview session. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); EXPECT_TRUE(InOverviewSession()); // Open the window cycle list. Scroll right to second item. Overview mode
diff --git a/ash/wm/window_cycle/window_cycle_list.cc b/ash/wm/window_cycle/window_cycle_list.cc index 9df3d9c..2dc13df 100644 --- a/ash/wm/window_cycle/window_cycle_list.cc +++ b/ash/wm/window_cycle/window_cycle_list.cc
@@ -1161,7 +1161,6 @@ params.parent = root_window->GetChildById(kShellWindowId_OverlayContainer); params.bounds = cycle_view_->GetTargetBounds(); - screen_observer_.Observe(display::Screen::GetScreen()); widget->Init(std::move(params)); widget->Show(); cycle_view_->FadeInLayer();
diff --git a/ash/wm/window_cycle/window_cycle_list.h b/ash/wm/window_cycle/window_cycle_list.h index 75af85e..1783a807 100644 --- a/ash/wm/window_cycle/window_cycle_list.h +++ b/ash/wm/window_cycle/window_cycle_list.h
@@ -11,7 +11,6 @@ #include "ash/ash_export.h" #include "ash/wm/window_cycle/window_cycle_controller.h" #include "ash/wm/window_cycle/window_cycle_tab_slider.h" -#include "base/scoped_observation.h" #include "base/timer/timer.h" #include "ui/aura/window_observer.h" #include "ui/display/display_observer.h" @@ -186,8 +185,7 @@ views::Widget* cycle_ui_widget_ = nullptr; // The window list will dismiss if the display metrics change. - base::ScopedObservation<display::Screen, display::DisplayObserver> - screen_observer_{this}; + display::ScopedDisplayObserver display_observer_{this}; // A timer to delay showing the UI. Quick Alt+Tab should not flash a UI. base::OneShotTimer show_ui_timer_;
diff --git a/ash/wm/window_finder_unittest.cc b/ash/wm/window_finder_unittest.cc index a42b8d8..fd00728 100644 --- a/ash/wm/window_finder_unittest.cc +++ b/ash/wm/window_finder_unittest.cc
@@ -88,7 +88,7 @@ CreateTestWindow(gfx::Rect(0, 0, 100, 100)); OverviewController* overview_controller = Shell::Get()->overview_controller(); - overview_controller->StartOverview(); + EnterOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); // Get |window1| and |window2|'s transformed bounds in overview.
diff --git a/ash/wm/workspace/multi_window_resize_controller_unittest.cc b/ash/wm/workspace/multi_window_resize_controller_unittest.cc index 40fb7be..3c7323bd 100644 --- a/ash/wm/workspace/multi_window_resize_controller_unittest.cc +++ b/ash/wm/workspace/multi_window_resize_controller_unittest.cc
@@ -667,7 +667,7 @@ EXPECT_TRUE(IsShowing()); // Tests that after starting overview, the widget is hidden. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); EXPECT_FALSE(HasPendingShow()); EXPECT_FALSE(IsShowing()); }
diff --git a/ash/wm/workspace/workspace_event_handler.cc b/ash/wm/workspace/workspace_event_handler.cc index 550b5ee..f6626a4 100644 --- a/ash/wm/workspace/workspace_event_handler.cc +++ b/ash/wm/workspace/workspace_event_handler.cc
@@ -143,7 +143,7 @@ DCHECK_EQ(gfx::Size(), target->delegate()->GetMaximumSize()); overview_controller->overview_session() ->SetWindowListNotAnimatedWhenExiting(target->GetRootWindow()); - overview_controller->EndOverview(); + overview_controller->EndOverview(OverviewEndAction::kSplitView); } const WMEvent wm_event(WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE);
diff --git a/ash/wm/workspace/workspace_layout_manager.cc b/ash/wm/workspace/workspace_layout_manager.cc index 29d9c37..49a98dc0 100644 --- a/ash/wm/workspace/workspace_layout_manager.cc +++ b/ash/wm/workspace/workspace_layout_manager.cc
@@ -108,7 +108,6 @@ Shell::Get()->AddShellObserver(this); Shell::Get()->activation_client()->AddObserver(this); root_window_->AddObserver(this); - display::Screen::GetScreen()->AddObserver(this); backdrop_controller_ = std::make_unique<BackdropController>(window_); keyboard::KeyboardUIController::Get()->AddObserver(this); settings_bubble_container_ = window->GetRootWindow()->GetChildById( @@ -131,7 +130,6 @@ window_state->RemoveObserver(this); window->RemoveObserver(this); } - display::Screen::GetScreen()->RemoveObserver(this); Shell::Get()->activation_client()->RemoveObserver(this); Shell::Get()->RemoveShellObserver(this); keyboard::KeyboardUIController::Get()->RemoveObserver(this);
diff --git a/ash/wm/workspace/workspace_layout_manager.h b/ash/wm/workspace/workspace_layout_manager.h index dc8e0da..15b5e78d 100644 --- a/ash/wm/workspace/workspace_layout_manager.h +++ b/ash/wm/workspace/workspace_layout_manager.h
@@ -169,6 +169,8 @@ aura::Window* accessibility_bubble_container_; BubbleWindowObserver accessibility_bubble_window_observer_; + display::ScopedDisplayObserver display_observer_{this}; + // Set of windows we're listening to. WindowSet windows_;
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc index 4ce3ef18..149190e 100644 --- a/ash/wm/workspace/workspace_layout_manager_unittest.cc +++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -1379,13 +1379,13 @@ } // Toggle overview. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); base::RunLoop().RunUntilIdle(); backdrop = test_helper.GetBackdropWindow(); ASSERT_TRUE(backdrop); EXPECT_FALSE(backdrop->IsVisible()); - Shell::Get()->overview_controller()->EndOverview(); + ExitOverview(); base::RunLoop().RunUntilIdle(); backdrop = test_helper.GetBackdropWindow(); ASSERT_TRUE(backdrop); @@ -1423,12 +1423,12 @@ } // Toggle overview with the delegate. - Shell::Get()->overview_controller()->StartOverview(); + EnterOverview(); base::RunLoop().RunUntilIdle(); backdrop = test_helper.GetBackdropWindow(); ASSERT_TRUE(backdrop); EXPECT_FALSE(backdrop->IsVisible()); - Shell::Get()->overview_controller()->EndOverview(); + ExitOverview(); base::RunLoop().RunUntilIdle(); backdrop = test_helper.GetBackdropWindow(); ASSERT_TRUE(backdrop);
diff --git a/base/BUILD.gn b/base/BUILD.gn index 565e289..a8f821d 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -3662,6 +3662,7 @@ "memory/weak_ptr_unittest.nc", "metrics/field_trial_params_unittest.nc", "metrics/histogram_unittest.nc", + "no_destructor_unittest.nc", "observer_list_unittest.nc", "sequence_checker_unittest.nc", "task/task_traits_extension_unittest.nc",
diff --git a/base/android/android_hardware_buffer_compat.cc b/base/android/android_hardware_buffer_compat.cc index 0f9dd0b..88feb411 100644 --- a/base/android/android_hardware_buffer_compat.cc +++ b/base/android/android_hardware_buffer_compat.cc
@@ -64,8 +64,8 @@ // static AndroidHardwareBufferCompat& AndroidHardwareBufferCompat::GetInstance() { - static base::NoDestructor<AndroidHardwareBufferCompat> compat; - return *compat; + static AndroidHardwareBufferCompat compat; + return compat; } void AndroidHardwareBufferCompat::Allocate(const AHardwareBuffer_Desc* desc,
diff --git a/base/android/android_image_reader_compat.cc b/base/android/android_image_reader_compat.cc index 4893446..ede7c576 100644 --- a/base/android/android_image_reader_compat.cc +++ b/base/android/android_image_reader_compat.cc
@@ -26,8 +26,8 @@ AndroidImageReader& AndroidImageReader::GetInstance() { // C++11 static local variable initialization is // thread-safe. - static base::NoDestructor<AndroidImageReader> instance; - return *instance; + static AndroidImageReader instance; + return instance; } bool AndroidImageReader::IsSupported() {
diff --git a/base/android/reached_addresses_bitset.cc b/base/android/reached_addresses_bitset.cc index e4fc1d1e..295635b 100644 --- a/base/android/reached_addresses_bitset.cc +++ b/base/android/reached_addresses_bitset.cc
@@ -7,7 +7,6 @@ #include "base/android/library_loader/anchor_functions.h" #include "base/android/library_loader/anchor_functions_buildflags.h" #include "base/check_op.h" -#include "base/no_destructor.h" namespace base { namespace android { @@ -25,9 +24,9 @@ // static ReachedAddressesBitset* ReachedAddressesBitset::GetTextBitset() { #if BUILDFLAG(SUPPORTS_CODE_ORDERING) - static base::NoDestructor<ReachedAddressesBitset> text_bitset( - kStartOfText, kEndOfText, g_text_bitfield, kTextBitfieldSize); - return text_bitset.get(); + static ReachedAddressesBitset text_bitset(kStartOfText, kEndOfText, + g_text_bitfield, kTextBitfieldSize); + return &text_bitset; #else return nullptr; #endif
diff --git a/base/android/reached_addresses_bitset.h b/base/android/reached_addresses_bitset.h index 1f4b8927..03c3a0e 100644 --- a/base/android/reached_addresses_bitset.h +++ b/base/android/reached_addresses_bitset.h
@@ -9,12 +9,10 @@ #include <vector> #include "base/base_export.h" +#include "base/no_destructor.h" namespace base { -template <typename T> -class NoDestructor; - namespace android { // ReachedAddressesBitset is a set that stores addresses for the
diff --git a/base/linux_util.cc b/base/linux_util.cc index c1512b84..ee511bd 100644 --- a/base/linux_util.cc +++ b/base/linux_util.cc
@@ -19,7 +19,6 @@ #include "base/files/dir_reader_posix.h" #include "base/files/file_util.h" #include "base/files/scoped_file.h" -#include "base/no_destructor.h" #include "base/strings/safe_sprintf.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" @@ -123,7 +122,7 @@ #if !BUILDFLAG(IS_CHROMEOS_ASH) // We do this check only once per process. If it fails, there's // little reason to believe it will work if we attempt to run it again. - static NoDestructor<DistroNameGetter> distro_name_getter; + static DistroNameGetter distro_name_getter; #endif return g_linux_distro; }
diff --git a/base/memory/checked_ptr.h b/base/memory/checked_ptr.h index 284f457..b68bffd 100644 --- a/base/memory/checked_ptr.h +++ b/base/memory/checked_ptr.h
@@ -9,11 +9,11 @@ #include <stdint.h> #include <cstddef> +#include <type_traits> #include <utility> #include "base/allocator/buildflags.h" -#include "base/allocator/partition_allocator/partition_alloc_config.h" -#include "base/check_op.h" +#include "base/check.h" #include "base/compiler_specific.h" #include "build/build_config.h" #include "build/buildflag.h" @@ -23,6 +23,7 @@ #if BUILDFLAG(USE_BACKUP_REF_PTR) #include "base/allocator/partition_allocator/address_pool_manager_bitmap.h" #include "base/allocator/partition_allocator/partition_address_space.h" +#include "base/allocator/partition_allocator/partition_alloc_config.h" #include "base/allocator/partition_allocator/partition_alloc_constants.h" #include "base/allocator/partition_allocator/partition_alloc_forward.h" #include "base/allocator/partition_allocator/partition_ref_count.h"
diff --git a/base/memory/nonscannable_memory.h b/base/memory/nonscannable_memory.h index dff6507..16500b5 100644 --- a/base/memory/nonscannable_memory.h +++ b/base/memory/nonscannable_memory.h
@@ -12,6 +12,7 @@ #include "base/allocator/buildflags.h" #include "base/base_export.h" +#include "base/no_destructor.h" #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) #include "base/allocator/partition_allocator/partition_alloc.h" @@ -25,9 +26,6 @@ namespace base { #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) -template <typename> -class NoDestructor; - namespace internal { // Represents allocator that contains memory for data-like objects (that don't @@ -53,7 +51,7 @@ void EnablePCScan(); private: - template <typename> + template <typename, typename> friend class base::NoDestructor; NonScannableAllocator();
diff --git a/base/no_destructor.h b/base/no_destructor.h index 21cfef8..be083ff 100644 --- a/base/no_destructor.h +++ b/base/no_destructor.h
@@ -6,9 +6,15 @@ #define BASE_NO_DESTRUCTOR_H_ #include <new> +#include <type_traits> #include <utility> namespace base { +// A tag type used for NoDestructor to allow it to be created for a type that +// has a trivial destructor. Use for cases where the same class might have +// different implementations that vary on destructor triviality or when the +// LSan hiding properties of NoDestructor are needed. +struct AllowForTriviallyDestructibleType; // A wrapper that makes it easy to create an object of type T with static // storage duration that: @@ -44,9 +50,20 @@ // Note that since the destructor is never run, this *will* leak memory if used // as a stack or member variable. Furthermore, a NoDestructor<T> should never // have global scope as that may require a static initializer. -template <typename T> +template <typename T, typename O = std::nullptr_t> class NoDestructor { public: + static_assert( + !std::is_trivially_destructible<T>::value || + std::is_same<O, AllowForTriviallyDestructibleType>::value, + "base::NoDestructor is not needed because the templated class has a " + "trivial destructor"); + + static_assert(std::is_same<O, AllowForTriviallyDestructibleType>::value || + std::is_same<O, std::nullptr_t>::value, + "AllowForTriviallyDestructibleType is the only valid option " + "for the second template parameter of NoDestructor"); + // Not constexpr; just write static constexpr T x = ...; if the value should // be a constexpr. template <typename... Args>
diff --git a/base/no_destructor_unittest.cc b/base/no_destructor_unittest.cc index 5c83366..ebe19be2 100644 --- a/base/no_destructor_unittest.cc +++ b/base/no_destructor_unittest.cc
@@ -39,6 +39,7 @@ UncopyableUnmovable& operator=(const UncopyableUnmovable&) = delete; int value = 1; + std::string something_with_a_nontrivial_destructor; }; struct CopyOnly { @@ -63,6 +64,8 @@ struct ForwardingTestStruct { ForwardingTestStruct(const CopyOnly&, MoveOnly&&) {} + + std::string something_with_a_nontrivial_destructor; }; TEST(NoDestructorTest, UncopyableUnmovable) { @@ -89,6 +92,11 @@ EXPECT_EQ(0, awesome.get()->compare("awesome")); } +TEST(NoDestructorTest, AllowForTriviallyDestructibleType) { + static NoDestructor<bool, AllowForTriviallyDestructibleType> + trivially_destructible_type; +} + // Passing initializer list to a NoDestructor like in this test // is ambiguous in GCC. // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84849
diff --git a/base/no_destructor_unittest.nc b/base/no_destructor_unittest.nc new file mode 100644 index 0000000..30b7dbd3 --- /dev/null +++ b/base/no_destructor_unittest.nc
@@ -0,0 +1,30 @@ +// Copyright 2021 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. + +// This is a "No Compile Test" suite. +// http://dev.chromium.org/developers/testing/no-compile-tests + +#include "base/no_destructor.h" + +#include <string> + +namespace base { + +#if defined(NCTEST_NODESTRUCTOR_REQUIRES_NONTRIVIAL_DESTRUCTOR) // [r"fatal error: static_assert failed due to requirement '!std::is_trivially_destructible<bool>::value || std::is_same<nullptr_t, base::AllowForTriviallyDestructibleType>::value' \"base::NoDestructor is not needed because the templated class has a trivial destructor\""] + +// Attempt to make a NoDestructor for a type with a trivial destructor. +void WontCompile() { + NoDestructor<bool> nd; +} + +#elif defined(NCTEST_NODESTRUCTOR_PARAMETER) // [r"fatal error: static_assert failed due to requirement 'std::is_same<std::string, base::AllowForTriviallyDestructibleType>::value || std::is_same<std::string, nullptr_t>::value' \"AllowForTriviallyDestructibleType is the only valid option for the second template parameter of NoDestructor\""] + +// Attempt to make a NoDestructor for a type with an invalid option. +void WontCompile() { + NoDestructor<std::string, std::string> nd; +} + +#endif + +} // namespace base
diff --git a/base/sampling_heap_profiler/poisson_allocation_sampler.h b/base/sampling_heap_profiler/poisson_allocation_sampler.h index f0f06a6..52ae551 100644 --- a/base/sampling_heap_profiler/poisson_allocation_sampler.h +++ b/base/sampling_heap_profiler/poisson_allocation_sampler.h
@@ -10,15 +10,13 @@ #include "base/base_export.h" #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/no_destructor.h" #include "base/sampling_heap_profiler/lock_free_address_hash_set.h" #include "base/synchronization/lock.h" #include "base/thread_annotations.h" namespace base { -template <typename T> -class NoDestructor; - // This singleton class implements Poisson sampling of the incoming allocations // stream. It hooks onto base::allocator and base::PartitionAlloc. // An extra custom allocator can be hooked via SetHooksInstallCallback method.
diff --git a/base/sampling_heap_profiler/sampling_heap_profiler.h b/base/sampling_heap_profiler/sampling_heap_profiler.h index 34b7cab..9908c19 100644 --- a/base/sampling_heap_profiler/sampling_heap_profiler.h +++ b/base/sampling_heap_profiler/sampling_heap_profiler.h
@@ -12,6 +12,7 @@ #include "base/base_export.h" #include "base/macros.h" +#include "base/no_destructor.h" #include "base/sampling_heap_profiler/poisson_allocation_sampler.h" #include "base/synchronization/lock.h" #include "base/thread_annotations.h" @@ -19,9 +20,6 @@ namespace base { -template <typename T> -class NoDestructor; - // The class implements sampling profiling of native memory heap. // It uses PoissonAllocationSampler to aggregate the heap allocations and // record samples.
diff --git a/base/strings/string_number_conversions_internal.h b/base/strings/string_number_conversions_internal.h index d35f3cf..ffc50f8 100644 --- a/base/strings/string_number_conversions_internal.h +++ b/base/strings/string_number_conversions_internal.h
@@ -14,7 +14,6 @@ #include "base/check_op.h" #include "base/logging.h" -#include "base/no_destructor.h" #include "base/numerics/safe_math.h" #include "base/strings/string_util.h" #include "base/third_party/double_conversion/double-conversion/double-conversion.h" @@ -229,10 +228,10 @@ static const double_conversion::DoubleToStringConverter* GetDoubleToStringConverter() { - static NoDestructor<double_conversion::DoubleToStringConverter> converter( + static double_conversion::DoubleToStringConverter converter( double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN, nullptr, nullptr, 'e', -6, 12, 0, 0); - return converter.get(); + return &converter; } // Converts a given (data, size) pair to a desired string type. For @@ -258,14 +257,14 @@ template <typename STRING, typename CHAR> bool StringToDoubleImpl(STRING input, const CHAR* data, double& output) { - static NoDestructor<double_conversion::StringToDoubleConverter> converter( + static double_conversion::StringToDoubleConverter converter( double_conversion::StringToDoubleConverter::ALLOW_LEADING_SPACES | double_conversion::StringToDoubleConverter::ALLOW_TRAILING_JUNK, 0.0, 0, nullptr, nullptr); int processed_characters_count; - output = converter->StringToDouble(data, input.size(), - &processed_characters_count); + output = + converter.StringToDouble(data, input.size(), &processed_characters_count); // Cases to return false: // - If the input string is empty, there was nothing to parse.
diff --git a/base/system/sys_info.cc b/base/system/sys_info.cc index 81edd158..b0e5f815 100644 --- a/base/system/sys_info.cc +++ b/base/system/sys_info.cc
@@ -11,7 +11,6 @@ #include "base/callback.h" #include "base/command_line.h" #include "base/location.h" -#include "base/no_destructor.h" #include "base/notreached.h" #include "base/system/sys_info_internal.h" #include "base/task/post_task.h" @@ -76,10 +75,8 @@ // static bool SysInfo::IsLowEndDeviceImpl() { - static base::NoDestructor< - internal::LazySysInfoValue<bool, DetectLowEndDevice>> - instance; - return instance->value(); + static internal::LazySysInfoValue<bool, DetectLowEndDevice> instance; + return instance.value(); } #endif
diff --git a/base/task/thread_pool/worker_thread.cc b/base/task/thread_pool/worker_thread.cc index 9165822..3787c58 100644 --- a/base/task/thread_pool/worker_thread.cc +++ b/base/task/thread_pool/worker_thread.cc
@@ -364,10 +364,23 @@ continue; } + // Alias pointer for investigation of memory corruption. crbug.com/1218384 + TaskSource* task_source_before_run = task_source.get(); + base::debug::Alias(&task_source_before_run); + task_source = task_tracker_->RunAndPopNextTask(std::move(task_source)); + // Alias pointer for investigation of memory corruption. crbug.com/1218384 + TaskSource* task_source_before_move = task_source.get(); + base::debug::Alias(&task_source_before_move); + delegate_->DidProcessTask(std::move(task_source)); + // Check that task_source is always cleared, to help investigation of memory + // corruption where task_source is non-null after being moved. + // crbug.com/1218384 + CHECK(!task_source); + // Calling WakeUp() guarantees that this WorkerThread will run Tasks from // TaskSources returned by the GetWork() method of |delegate_| until it // returns nullptr. Resetting |wake_up_event_| here doesn't break this
diff --git a/base/threading/platform_thread_posix.cc b/base/threading/platform_thread_posix.cc index dbf96f6..d37b50b 100644 --- a/base/threading/platform_thread_posix.cc +++ b/base/threading/platform_thread_posix.cc
@@ -19,7 +19,6 @@ #include "base/debug/activity_tracker.h" #include "base/lazy_instance.h" #include "base/logging.h" -#include "base/no_destructor.h" #include "base/threading/platform_thread_internal_posix.h" #include "base/threading/scoped_blocking_call.h" #include "base/threading/thread_id_name_manager.h" @@ -195,7 +194,7 @@ #if defined(OS_APPLE) return pthread_mach_thread_np(pthread_self()); #elif defined(OS_LINUX) || defined(OS_CHROMEOS) - static NoDestructor<InitAtFork> init_at_fork; + static InitAtFork init_at_fork; if (g_thread_id == -1) { g_thread_id = syscall(__NR_gettid); } else {
diff --git a/base/threading/thread.cc b/base/threading/thread.cc index 8834896..0454b1b0 100644 --- a/base/threading/thread.cc +++ b/base/threading/thread.cc
@@ -122,6 +122,22 @@ other.moved_from = true; } +Thread::Options& Thread::Options::operator=(Thread::Options&& other) { + DCHECK_NE(this, &other); + + message_pump_type = std::move(other.message_pump_type); + delegate = std::move(other.delegate); + timer_slack = std::move(other.timer_slack); + task_queue_time_domain = std::move(other.task_queue_time_domain); + message_pump_factory = std::move(other.message_pump_factory); + stack_size = std::move(other.stack_size); + priority = std::move(other.priority); + joinable = std::move(other.joinable); + other.moved_from = true; + + return *this; +} + Thread::Options::~Options() = default; Thread::Thread(const std::string& name) @@ -149,10 +165,10 @@ if (com_status_ == STA) options.message_pump_type = MessagePumpType::UI; #endif - return StartWithOptions(options); + return StartWithOptions(std::move(options)); } -bool Thread::StartWithOptions(const Options& options) { +bool Thread::StartWithOptions(Options options) { DCHECK(options.IsValid()); DCHECK(owning_sequence_checker_.CalledOnValidSequence()); DCHECK(!delegate_); @@ -175,7 +191,7 @@ if (options.delegate) { DCHECK(!options.message_pump_factory); DCHECK(!options.task_queue_time_domain); - delegate_ = WrapUnique(options.delegate); + delegate_ = std::move(options.delegate); } else if (options.message_pump_factory) { delegate_ = std::make_unique<SequenceManagerThreadDelegate>( MessagePumpType::CUSTOM, options.message_pump_factory,
diff --git a/base/threading/thread.h b/base/threading/thread.h index 72af7e3..27ef5ff 100644 --- a/base/threading/thread.h +++ b/base/threading/thread.h
@@ -80,7 +80,7 @@ Options(); Options(MessagePumpType type, size_t size); Options(Options&& other); - Options& operator=(const Options&& other) = delete; + Options& operator=(Options&& other); ~Options(); // Specifies the type of message pump that will be allocated on the thread. @@ -89,8 +89,7 @@ // An unbound Delegate that will be bound to the thread. Ownership // of |delegate| will be transferred to the thread. - // TODO(alexclarke): This should be a std::unique_ptr - Delegate* delegate = nullptr; + std::unique_ptr<Delegate> delegate = nullptr; // Specifies timer slack for thread message loop. TimerSlack timer_slack = TIMER_SLACK_NONE; @@ -171,7 +170,7 @@ // Note: This function can't be called on Windows with the loader lock held; // i.e. during a DllMain, global object construction or destruction, atexit() // callback. - bool StartWithOptions(const Options& options); + bool StartWithOptions(Options options); // Starts the thread and wait for the thread to start and run initialization // before returning. It's same as calling Start() and then
diff --git a/base/threading/thread_unittest.cc b/base/threading/thread_unittest.cc index 1a71f85..229bcf3 100644 --- a/base/threading/thread_unittest.cc +++ b/base/threading/thread_unittest.cc
@@ -157,7 +157,7 @@ #else options.stack_size = 3072 * sizeof(uintptr_t); #endif - EXPECT_TRUE(a.StartWithOptions(options)); + EXPECT_TRUE(a.StartWithOptions(std::move(options))); EXPECT_TRUE(a.task_runner()); EXPECT_TRUE(a.IsRunning()); @@ -180,7 +180,7 @@ Thread::Options options; options.joinable = false; - EXPECT_TRUE(a->StartWithOptions(options)); + EXPECT_TRUE(a->StartWithOptions(std::move(options))); EXPECT_TRUE(a->task_runner()); EXPECT_TRUE(a->IsRunning()); @@ -246,7 +246,7 @@ Thread a("DestroyWhileRunningNonJoinableIsSafe"); Thread::Options options; options.joinable = false; - EXPECT_TRUE(a.StartWithOptions(options)); + EXPECT_TRUE(a.StartWithOptions(std::move(options))); EXPECT_TRUE(a.WaitUntilThreadStarted()); } @@ -362,7 +362,7 @@ Thread::Options options; options.joinable = false; - EXPECT_TRUE(a->StartWithOptions(options)); + EXPECT_TRUE(a->StartWithOptions(std::move(options))); EXPECT_TRUE(a->task_runner()); EXPECT_TRUE(a->IsRunning()); @@ -585,14 +585,15 @@ TEST_F(ThreadTest, ProvidedThreadDelegate) { Thread thread("ThreadDelegate"); base::Thread::Options options; - options.delegate = new SequenceManagerThreadDelegate(); - thread.StartWithOptions(options); + options.delegate = std::make_unique<SequenceManagerThreadDelegate>(); + + scoped_refptr<base::SingleThreadTaskRunner> task_runner = + options.delegate->GetDefaultTaskRunner(); + thread.StartWithOptions(std::move(options)); base::WaitableEvent event; - - options.delegate->GetDefaultTaskRunner()->PostTask( - FROM_HERE, - base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&event))); + task_runner->PostTask(FROM_HERE, base::BindOnce(&base::WaitableEvent::Signal, + base::Unretained(&event))); event.Wait(); thread.Stop();
diff --git a/base/time/time.cc b/base/time/time.cc index d098b444..e8355ae 100644 --- a/base/time/time.cc +++ b/base/time/time.cc
@@ -17,7 +17,6 @@ #include <tuple> #include <utility> -#include "base/no_destructor.h" #include "base/strings/stringprintf.h" #include "base/third_party/nspr/prtime.h" #include "base/time/time_override.h" @@ -334,11 +333,11 @@ // static TimeTicks TimeTicks::UnixEpoch() { - static const NoDestructor<TimeTicks> epoch([]() { + static const TimeTicks epoch([]() { return subtle::TimeTicksNowIgnoringOverride() - (subtle::TimeNowIgnoringOverride() - Time::UnixEpoch()); }()); - return *epoch; + return epoch; } TimeTicks TimeTicks::SnappedToNextTick(TimeTicks tick_phase,
diff --git a/base/trace_event/trace_log.h b/base/trace_event/trace_log.h index 8e6c712..bbf35dc 100644 --- a/base/trace_event/trace_log.h +++ b/base/trace_event/trace_log.h
@@ -18,6 +18,7 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" +#include "base/no_destructor.h" #include "base/single_thread_task_runner.h" #include "base/time/time_override.h" #include "base/trace_event/category_registry.h" @@ -36,9 +37,6 @@ namespace base { class RefCountedString; -template <typename T> -class NoDestructor; - namespace tracing { class PerfettoPlatform; } // namespace tracing
diff --git a/base/unguessable_token.cc b/base/unguessable_token.cc index 432a2f2b..f74579e3e 100644 --- a/base/unguessable_token.cc +++ b/base/unguessable_token.cc
@@ -7,7 +7,6 @@ #include <ostream> #include "base/format_macros.h" -#include "base/no_destructor.h" #include "base/rand_util.h" namespace base { @@ -21,8 +20,8 @@ // static const UnguessableToken& UnguessableToken::Null() { - static const NoDestructor<UnguessableToken> null_token; - return *null_token; + static const UnguessableToken null_token{}; + return null_token; } // static
diff --git a/base/win/windows_version.cc b/base/win/windows_version.cc index 72d4d0d..97789dd 100644 --- a/base/win/windows_version.cc +++ b/base/win/windows_version.cc
@@ -57,12 +57,12 @@ } const _SYSTEM_INFO& GetSystemInfoStorage() { - static const NoDestructor<_SYSTEM_INFO> system_info([] { + static const _SYSTEM_INFO system_info = [] { _SYSTEM_INFO info = {}; ::GetNativeSystemInfo(&info); return info; - }()); - return *system_info; + }(); + return system_info; } } // namespace
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 819c3edc2..189cce11 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -1671,6 +1671,7 @@ "javatests/src/org/chromium/chrome/browser/vr/WebXrArDepthSensingTest.java", "javatests/src/org/chromium/chrome/browser/vr/WebXrArHitTestTest.java", "javatests/src/org/chromium/chrome/browser/vr/WebXrArLightEstimationTest.java", + "javatests/src/org/chromium/chrome/browser/vr/WebXrArSanityTest.java", "javatests/src/org/chromium/chrome/browser/vr/WebXrArSessionTest.java", "javatests/src/org/chromium/chrome/browser/vr/WebXrArTestFramework.java", "javatests/src/org/chromium/chrome/browser/vr/WebXrArViewportScaleTest.java",
diff --git a/chrome/android/features/tab_ui/java/res/values/colors.xml b/chrome/android/features/tab_ui/java/res/values/colors.xml index f2fcb3d..423e7c1 100644 --- a/chrome/android/features/tab_ui/java/res/values/colors.xml +++ b/chrome/android/features/tab_ui/java/res/values/colors.xml
@@ -8,8 +8,11 @@ <color name="tab_grid_card_view_tint_color">@color/popup_bg_color</color> <color name="tab_grid_card_view_tint_color_incognito">@color/default_bg_color_dark_elev_4</color> - <color name="tab_grid_card_title_text_color">@color/default_text_color</color> - <color name="tab_grid_card_title_text_color_incognito">@color/default_text_color_light</color> + <color name="tab_grid_card_title_text_color">@color/default_text_color_list</color> + <color name="tab_grid_card_title_text_color_incognito">@color/default_text_color_light_list</color> + + <color name="tab_group_number_text_color">@color/default_text_color</color> + <color name="tab_group_number_text_color_incognito">@color/default_text_color_light</color> <color name="tab_grid_card_action_button_tint_color">@color/default_icon_color</color> <color name="tab_grid_card_action_button_tint_color_incognito">@color/default_icon_color_light</color> @@ -40,4 +43,15 @@ <color name="new_tab_tile_plus_color">@color/default_icon_color_secondary</color> <color name="new_tab_tile_plus_color_incognito">@color/default_icon_color_secondary_light</color> + + <!-- Incognito colors for theme refactor 2021. --> + <!-- TODO(https://crbug.com/1223976): Use semantic colors for incognito. --> + <color name="incognito_tab_action_button_color">@color/baseline_neutral_variant_200</color> + <color name="incognito_tab_action_button_selected_color">@color/baseline_primary_800</color> + + <color name="incognito_tab_bg_color">@color/baseline_neutral_900_with_neutral_200_alpha_12_with_primary_200_alpha_2</color> + <color name="incognito_tab_bg_selected_color">@color/baseline_primary_200</color> + + <color name="incognito_tab_title_color">@color/baseline_neutral_100</color> + <color name="incognito_tab_title_selected_color">@color/baseline_primary_800</color> </resources>
diff --git a/chrome/android/features/tab_ui/java/res/values/dimens.xml b/chrome/android/features/tab_ui/java/res/values/dimens.xml index fe0d4904..0c182f74 100644 --- a/chrome/android/features/tab_ui/java/res/values/dimens.xml +++ b/chrome/android/features/tab_ui/java/res/values/dimens.xml
@@ -45,4 +45,7 @@ <dimen name="price_tracking_dialog_text_top_margin">24dp</dimen> <dimen name="price_tracking_dialog_items_margin">20dp</dimen> <dimen name="price_tracking_dialog_items_bottom_margin">34dp</dimen> + + <!-- Elevation --> + <dimen name="tab_bg_elevation">@dimen/default_elevation_4</dimen> </resources>
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java index 7b9879d..83d65f9 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java
@@ -301,7 +301,8 @@ TabUiColorProvider.getMiniThumbnailPlaceHolderColor(context, isIncognito)); mThumbnailFramePaint.setColor( TabUiColorProvider.getMiniThumbnailFrameColor(context, isIncognito)); - mTextPaint.setColor(TabUiColorProvider.getTitleTextColor(context, isIncognito)); + mTextPaint.setColor( + TabUiColorProvider.getTabGroupNumberTextColor(context, isIncognito)); mFaviconBackgroundPaint.setColor( TabUiColorProvider.getFaviconBackgroundColor(context, isIncognito)); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java index 8e37d92..f0d4866 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java
@@ -42,11 +42,9 @@ private final PropertyModelChangeProcessor mModelChangeProcessor; private final ViewGroup mRootView; private TabSelectionEditorCoordinator mTabSelectionEditorCoordinator; - private ViewGroup mContainerView; private TabGridDialogView mDialogView; - private boolean mIsInitialized; - TabGridDialogCoordinator(Context context, TabModelSelector tabModelSelector, + TabGridDialogCoordinator(Activity activity, TabModelSelector tabModelSelector, TabContentManager tabContentManager, TabCreatorManager tabCreatorManager, ViewGroup containerView, TabSwitcherMediator.ResetHandler resetHandler, TabListMediator.GridCardOnClickListenerProvider gridCardOnClickListenerProvider, @@ -57,42 +55,40 @@ : "TabGridDialogInSwitcher"; mModel = new PropertyModel(TabGridPanelProperties.ALL_KEYS); - mContainerView = containerView; mRootView = rootView; mDialogView = containerView.findViewById(R.id.dialog_parent_view); if (mDialogView == null) { - LayoutInflater.from(context).inflate( + LayoutInflater.from(activity).inflate( R.layout.tab_grid_dialog_layout, containerView, true); mDialogView = containerView.findViewById(R.id.dialog_parent_view); mDialogView.setupScrimCoordinator(scrimCoordinator); } - Activity activity = (Activity) context; SnackbarManager snackbarManager = new SnackbarManager(activity, mDialogView.getSnackBarContainer(), null); - mMediator = new TabGridDialogMediator(context, this, mModel, tabModelSelector, + mMediator = new TabGridDialogMediator(activity, this, mModel, tabModelSelector, tabCreatorManager, resetHandler, animationSourceViewProvider, shareDelegateSupplier, snackbarManager, mComponentName); // TODO(crbug.com/1031349) : Remove the inline mode logic here, make the constructor to take // in a mode parameter instead. mTabListCoordinator = new TabListCoordinator( - TabUiFeatureUtilities.isTabGroupsAndroidContinuationEnabled(context) + TabUiFeatureUtilities.isTabGroupsAndroidContinuationEnabled(activity) && SysUtils.isLowEndDevice() ? TabListCoordinator.TabListMode.LIST : TabListCoordinator.TabListMode.GRID, - context, tabModelSelector, tabContentManager::getTabThumbnailWithCallback, null, + activity, tabModelSelector, tabContentManager::getTabThumbnailWithCallback, null, false, gridCardOnClickListenerProvider, mMediator.getTabGridDialogHandler(), TabProperties.UiType.CLOSABLE, null, null, containerView, false, mComponentName, rootView); TabListRecyclerView recyclerView = mTabListCoordinator.getContainerView(); TabGroupUiToolbarView toolbarView = - (TabGroupUiToolbarView) LayoutInflater.from(context).inflate( + (TabGroupUiToolbarView) LayoutInflater.from(activity).inflate( R.layout.bottom_tab_grid_toolbar, recyclerView, false); toolbarView.setupDialogToolbarLayout(); - if (!TabUiFeatureUtilities.isTabGroupsAndroidContinuationEnabled(context)) { + if (!TabUiFeatureUtilities.isTabGroupsAndroidContinuationEnabled(activity)) { toolbarView.hideTabGroupsContinuationWidgets(); } mModelChangeProcessor = PropertyModelChangeProcessor.create(mModel, @@ -102,8 +98,6 @@ public void initWithNative(Context context, TabModelSelector tabModelSelector, TabContentManager tabContentManager, TabGroupTitleEditor tabGroupTitleEditor) { - if (mIsInitialized) return; - TabSelectionEditorCoordinator.TabSelectionEditorController controller = null; if (TabUiFeatureUtilities.isTabGroupsAndroidContinuationEnabled(context)) { @TabListCoordinator.TabListMode
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java index 39496fa7..ceb4a275 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java
@@ -634,6 +634,8 @@ ApiCompatibilityUtils.setTextAppearance( (TextView) (mAnimationCardView.findViewById(R.id.tab_title)), R.style.TextAppearance_TextMediumThick_Primary); + ((TextView) (mAnimationCardView.findViewById(R.id.tab_title))) + .setTextColor(((TextView) (view.findViewById(R.id.tab_title))).getTextColors()); ((ImageView) (mAnimationCardView.findViewById(R.id.tab_thumbnail))) .setImageDrawable(
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java index 52c02fb..e603e59 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
@@ -27,6 +27,8 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.Callback; import org.chromium.base.MathUtils; +import org.chromium.chrome.browser.flags.CachedFeatureFlags; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.tab_ui.R; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; @@ -108,25 +110,30 @@ tabTitleView.setContentDescription( view.getResources().getString(R.string.accessibility_tabstrip_tab, title)); } else if (TabProperties.IS_SELECTED == propertyKey) { - int selectedTabBackground = - model.get(TabProperties.SELECTED_TAB_BACKGROUND_DRAWABLE_ID); - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { - if (model.get(TabProperties.IS_SELECTED)) { - view.fastFindViewById(R.id.selected_view_below_lollipop) - .setBackgroundResource(selectedTabBackground); - view.fastFindViewById(R.id.selected_view_below_lollipop) - .setVisibility(View.VISIBLE); - } else { - view.fastFindViewById(R.id.selected_view_below_lollipop) - .setVisibility(View.GONE); - } + if (CachedFeatureFlags.isEnabled(ChromeFeatureList.THEME_REFACTOR_ANDROID)) { + updateColor(view, model.get(TabProperties.IS_INCOGNITO), + model.get(TabProperties.IS_SELECTED)); } else { - Resources res = view.getResources(); - Resources.Theme theme = view.getContext().getTheme(); - Drawable drawable = new InsetDrawable( - ResourcesCompat.getDrawable(res, selectedTabBackground, theme), - (int) res.getDimension(R.dimen.tab_list_selected_inset)); - view.setForeground(model.get(TabProperties.IS_SELECTED) ? drawable : null); + int selectedTabBackground = + model.get(TabProperties.SELECTED_TAB_BACKGROUND_DRAWABLE_ID); + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { + if (model.get(TabProperties.IS_SELECTED)) { + view.fastFindViewById(R.id.selected_view_below_lollipop) + .setBackgroundResource(selectedTabBackground); + view.fastFindViewById(R.id.selected_view_below_lollipop) + .setVisibility(View.VISIBLE); + } else { + view.fastFindViewById(R.id.selected_view_below_lollipop) + .setVisibility(View.GONE); + } + } else { + Resources res = view.getResources(); + Resources.Theme theme = view.getContext().getTheme(); + Drawable drawable = new InsetDrawable( + ResourcesCompat.getDrawable(res, selectedTabBackground, theme), + (int) res.getDimension(R.dimen.tab_list_selected_inset)); + view.setForeground(model.get(TabProperties.IS_SELECTED) ? drawable : null); + } } if (TabUiFeatureUtilities.ENABLE_SEARCH_CHIP.getValue()) { ChipView pageInfoButton = (ChipView) view.fastFindViewById(R.id.page_info_button); @@ -204,7 +211,10 @@ .scaleTabGridCardView( model.get(TabProperties.CARD_ANIMATION_STATUS), isSelected); } else if (TabProperties.IS_INCOGNITO == propertyKey) { - updateColor(view, model.get(TabProperties.IS_INCOGNITO), TabProperties.UiType.CLOSABLE); + updateColor(view, model.get(TabProperties.IS_INCOGNITO), + model.get(TabProperties.IS_SELECTED)); + updateColorForActionButton(view, model.get(TabProperties.IS_INCOGNITO), + model.get(TabProperties.IS_SELECTED)); } else if (TabProperties.ACCESSIBILITY_DELEGATE == propertyKey) { view.setAccessibilityDelegate(model.get(TabProperties.ACCESSIBILITY_DELEGATE)); } else if (TabProperties.SEARCH_QUERY == propertyKey) { @@ -287,6 +297,8 @@ pageInfoButton.setIcon(iconDrawableId, shouldTint); } else if (TabProperties.IS_SELECTED == propertyKey) { view.setSelected(model.get(TabProperties.IS_SELECTED)); + updateColorForActionButton(view, model.get(TabProperties.IS_INCOGNITO), + model.get(TabProperties.IS_SELECTED)); } else if (TabUiFeatureUtilities.isLaunchPolishEnabled() && TabProperties.CLOSE_BUTTON_DESCRIPTION_STRING == propertyKey) { view.fastFindViewById(R.id.action_button) @@ -334,8 +346,8 @@ .setSelectionDelegate(model.get(TabProperties.TAB_SELECTION_DELEGATE)); ((SelectableTabGridView) view).setItem(tabId); } else if (TabProperties.IS_INCOGNITO == propertyKey) { - updateColor( - view, model.get(TabProperties.IS_INCOGNITO), TabProperties.UiType.SELECTABLE); + updateColor(view, model.get(TabProperties.IS_INCOGNITO), + model.get(TabProperties.IS_SELECTED)); } } @@ -380,24 +392,25 @@ } } - private static void updateColor(ViewLookupCachingFrameLayout rootView, boolean isIncognito, - @TabProperties.UiType int viewType) { + private static void updateColor( + ViewLookupCachingFrameLayout rootView, boolean isIncognito, boolean isSelected) { View cardView = rootView.fastFindViewById(R.id.card_view); View dividerView = rootView.fastFindViewById(R.id.divider_view); + TextView titleView = (TextView) rootView.fastFindViewById(R.id.tab_title); ImageView thumbnail = (ImageView) rootView.fastFindViewById(R.id.tab_thumbnail); - ImageView actionButton = (ImageView) rootView.fastFindViewById(R.id.action_button); ChromeImageView backgroundView = (ChromeImageView) rootView.fastFindViewById(R.id.background_view); + cardView.getBackground().mutate(); ViewCompat.setBackgroundTintList(cardView, - TabUiColorProvider.getCardViewTintList(cardView.getContext(), isIncognito)); + TabUiColorProvider.getCardViewTintList( + cardView.getContext(), isIncognito, isSelected)); dividerView.setBackgroundColor( TabUiColorProvider.getDividerColor(dividerView.getContext(), isIncognito)); - ApiCompatibilityUtils.setTextAppearance( - ((TextView) rootView.fastFindViewById(R.id.tab_title)), - TabUiColorProvider.getTitleTextAppearance(isIncognito)); + titleView.setTextColor(TabUiColorProvider.getTitleTextColor( + titleView.getContext(), isIncognito, isSelected)); if (thumbnail.getDrawable() == null) { thumbnail.setImageResource( @@ -409,12 +422,14 @@ TabUiColorProvider.getHoveredCardBackgroundTintList( backgroundView.getContext(), isIncognito)); } + } - if (viewType == TabProperties.UiType.CLOSABLE) { - ApiCompatibilityUtils.setImageTintList(actionButton, - TabUiColorProvider.getActionButtonTintList( - actionButton.getContext(), isIncognito)); - } + private static void updateColorForActionButton( + ViewLookupCachingFrameLayout rootView, boolean isIncognito, boolean isSelected) { + ImageView actionButton = (ImageView) rootView.fastFindViewById(R.id.action_button); + ApiCompatibilityUtils.setImageTintList(actionButton, + TabUiColorProvider.getActionButtonTintList( + actionButton.getContext(), isIncognito, isSelected)); } @VisibleForTesting
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java index 07205fe..b3246c8 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
@@ -151,7 +151,7 @@ if (TabUiFeatureUtilities.isTabGroupsAndroidEnabled(activity) && mScrimCoordinator != null) { mTabGridDialogCoordinator = - new TabGridDialogCoordinator(mContext, mTabModelSelector, mTabContentManager, + new TabGridDialogCoordinator(mActivity, mTabModelSelector, mTabContentManager, mTabCreatorManager, mActivity.findViewById(R.id.coordinator), null, null, null, mShareDelegateSupplier, mScrimCoordinator, mRootView); mTabGridDialogCoordinator.initWithNative(mContext, mTabModelSelector,
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiColorProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiColorProvider.java index 89ef600..8828958 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiColorProvider.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiColorProvider.java
@@ -9,27 +9,54 @@ import android.graphics.drawable.Drawable; import androidx.annotation.ColorInt; +import androidx.annotation.ColorRes; import androidx.appcompat.content.res.AppCompatResources; +import com.google.android.material.color.MaterialColors; +import com.google.android.material.elevation.ElevationOverlayProvider; + import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.chrome.browser.flags.CachedFeatureFlags; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.tab_ui.R; /** * Color utility class for a Tab Grid card. */ public class TabUiColorProvider { + private static final String TAG = "TabUiColorProvider"; /** * Returns the {@link ColorStateList} to use for the tab grid card view background based on * incognito mode. * * @param context {@link Context} used to retrieve color. * @param isIncognito Whether the color is used for incognito mode. + * @param isSelected Whether the tab is currently selected. * @return The {@link ColorStateList} for tab grid card view background. */ - public static ColorStateList getCardViewTintList(Context context, boolean isIncognito) { - return AppCompatResources.getColorStateList(context, - isIncognito ? R.color.tab_grid_card_view_tint_color_incognito - : R.color.tab_grid_card_view_tint_color); + public static ColorStateList getCardViewTintList( + Context context, boolean isIncognito, boolean isSelected) { + if (!themeRefactorEnabled()) { + return AppCompatResources.getColorStateList(context, + isIncognito ? R.color.tab_grid_card_view_tint_color_incognito + : R.color.tab_grid_card_view_tint_color); + } + + if (isIncognito) { + // Incognito does not use dynamic colors, so it can use colors from resources. + @ColorRes + int colorRes = isSelected ? R.color.incognito_tab_bg_selected_color + : R.color.incognito_tab_bg_color; + return AppCompatResources.getColorStateList(context, colorRes); + } else { + float tabElevation = context.getResources().getDimension(R.dimen.tab_bg_elevation); + @ColorInt + int colorInt = isSelected + ? MaterialColors.getColor(context, R.attr.colorPrimary, TAG) + : new ElevationOverlayProvider(context) + .compositeOverlayWithThemeSurfaceColorIfNeeded(tabElevation); + return ColorStateList.valueOf(colorInt); + } } /** @@ -45,28 +72,44 @@ } /** - * Returns the title text color for the tab grid card based on the incognito mode. + * Returns the text color for the number used on the tab group cards based on the incognito + * mode. * * @param context {@link Context} used to retrieve color. * @param isIncognito Whether the color is used for incognito mode. - * @return The text color for the tab grid card title. + * @return The text color for the number used on the tab group cards. */ @ColorInt - public static int getTitleTextColor(Context context, boolean isIncognito) { + public static int getTabGroupNumberTextColor(Context context, boolean isIncognito) { return ApiCompatibilityUtils.getColor(context.getResources(), - isIncognito ? R.color.tab_grid_card_title_text_color_incognito - : R.color.tab_grid_card_title_text_color); + isIncognito ? R.color.tab_group_number_text_color_incognito + : R.color.tab_group_number_text_color); } /** * Returns the title text appearance for the tab grid card based on the incognito mode. * * @param isIncognito Whether the text appearance is used for incognito mode. + * @param isSelected Whether the tab is currently selected. * @return The text appearance for the tab grid card title. */ - public static int getTitleTextAppearance(boolean isIncognito) { - return isIncognito ? R.style.TextAppearance_TextMediumThick_Primary_Light - : R.style.TextAppearance_TextMediumThick_Primary; + @ColorInt + public static int getTitleTextColor(Context context, boolean isIncognito, boolean isSelected) { + if (!themeRefactorEnabled()) { + return ApiCompatibilityUtils.getColor(context.getResources(), + isIncognito ? R.color.tab_grid_card_title_text_color_incognito + : R.color.tab_grid_card_title_text_color); + } + + if (isIncognito) { + @ColorRes + int colorRes = isSelected ? R.color.incognito_tab_title_selected_color + : R.color.incognito_tab_title_color; + return ApiCompatibilityUtils.getColor(context.getResources(), colorRes); + } else { + return isSelected ? MaterialColors.getColor(context, R.attr.colorOnPrimary, TAG) + : MaterialColors.getColor(context, R.attr.colorOnSurface, TAG); + } } /** @@ -75,12 +118,29 @@ * * @param context {@link Context} used to retrieve color. * @param isIncognito Whether the color is used for incognito mode. + * @param isSelected Whether the tab is currently selected. * @return The {@link ColorStateList} for tab grid card action button. */ - public static ColorStateList getActionButtonTintList(Context context, boolean isIncognito) { - return AppCompatResources.getColorStateList(context, - isIncognito ? R.color.tab_grid_card_action_button_tint_color_incognito - : R.color.tab_grid_card_action_button_tint_color); + public static ColorStateList getActionButtonTintList( + Context context, boolean isIncognito, boolean isSelected) { + if (!themeRefactorEnabled()) { + return AppCompatResources.getColorStateList(context, + isIncognito ? R.color.tab_grid_card_action_button_tint_color_incognito + : R.color.tab_grid_card_action_button_tint_color); + } + + if (isIncognito) { + @ColorRes + int colorRes = isSelected ? R.color.incognito_tab_action_button_selected_color + : R.color.incognito_tab_action_button_color; + return AppCompatResources.getColorStateList(context, colorRes); + } else { + @ColorInt + int colorInt = isSelected + ? MaterialColors.getColor(context, R.attr.colorOnPrimary, TAG) + : MaterialColors.getColor(context, R.attr.colorOnSurfaceVariant, TAG); + return ColorStateList.valueOf(colorInt); + } } /** @@ -227,4 +287,8 @@ return AppCompatResources.getColorStateList(context, isIncognito ? R.color.default_icon_color_light : R.color.default_icon_color); } + + private static boolean themeRefactorEnabled() { + return CachedFeatureFlags.isEnabled(ChromeFeatureList.THEME_REFACTOR_ANDROID); + } }
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java index 22a358e..40eb48e2 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java
@@ -868,9 +868,8 @@ @Test @MediumTest @UiThreadTest - @CommandLineFlags. - Add({"force-fieldtrial-params=Study.Group:price_tracking_with_optimization_guide/true"}) public void testPriceDropEndToEnd() { + ShoppingPersistedTabData.enablePriceTrackingWithOptimizationGuideForTesting(); PersistedTabDataConfiguration.setUseTestConfig(true); PriceTrackingUtilities.ENABLE_PRICE_TRACKING.setForTesting(true); mockCurrencyFormatter();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java index fc29c6eb..54ac527 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -19,7 +19,6 @@ import org.chromium.chrome.browser.page_annotations.PageAnnotationsServiceConfig; import org.chromium.chrome.browser.paint_preview.StartupPaintPreviewHelper; import org.chromium.chrome.browser.subscriptions.CommerceSubscriptionsServiceConfig; -import org.chromium.chrome.browser.tab.state.ShoppingPersistedTabData; import org.chromium.chrome.browser.tasks.ConditionalTabStripUtils; import org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil; import org.chromium.chrome.browser.tasks.tab_management.PriceTrackingUtilities; @@ -126,10 +125,6 @@ MerchantViewerConfig.TRUST_SIGNALS_SHEET_USE_PAGE_TITLE, PageAnnotationsServiceConfig.PAGE_ANNOTATIONS_BASE_URL, ReturnToChromeExperimentsUtil.TAB_SWITCHER_ON_RETURN_MS, - ShoppingPersistedTabData.TIME_TO_LIVE_MS, - ShoppingPersistedTabData.DISPLAY_TIME_MS, - ShoppingPersistedTabData.STALE_TAB_THRESHOLD_SECONDS, - ShoppingPersistedTabData.PRICE_TRACKING_WITH_OPTIMIZATION_GUIDE, StartSurfaceConfiguration.HOME_BUTTON_ON_GRID_TAB_SWITCHER, StartSurfaceConfiguration.NEW_SURFACE_FROM_HOME_BUTTON, StartSurfaceConfiguration.OMNIBOX_FOCUSED_ON_NEW_TAB,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabHelpers.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabHelpers.java index a2bf660f..88f56e7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabHelpers.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabHelpers.java
@@ -42,7 +42,7 @@ // we should only do it if the user is eligible for the feature (e.g. has sync enabled). if (!tab.isIncognito() && !((TabImpl) tab).isCustomTab() && PriceTrackingUtilities.isPriceTrackingEligible() - && ShoppingPersistedTabData.PRICE_TRACKING_WITH_OPTIMIZATION_GUIDE.getValue()) { + && ShoppingPersistedTabData.isPriceTrackingWithOptimizationGuideEnabled()) { ShoppingPersistedTabData.from(tab); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrArSanityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrArSanityTest.java new file mode 100644 index 0000000..e70e0f3 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrArSanityTest.java
@@ -0,0 +1,112 @@ +// Copyright 2021 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.chrome.browser.vr; + +import static org.chromium.chrome.browser.vr.WebXrArTestFramework.PAGE_LOAD_TIMEOUT_S; +import static org.chromium.chrome.browser.vr.XrTestFramework.POLL_TIMEOUT_SHORT_MS; + +import android.os.Build; + +import androidx.test.filters.LargeTest; +import androidx.test.filters.MediumTest; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.RuleChain; +import org.junit.runner.RunWith; + +import org.chromium.base.test.params.ParameterAnnotations.ClassParameter; +import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate; +import org.chromium.base.test.params.ParameterSet; +import org.chromium.base.test.params.ParameterizedRunner; +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.MinAndroidSdkLevel; +import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.vr.rules.ArPlaybackFile; +import org.chromium.chrome.browser.vr.rules.XrActivityRestriction; +import org.chromium.chrome.browser.vr.util.ArTestRuleUtils; +import org.chromium.chrome.test.ChromeActivityTestRule; +import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; + +import java.util.List; +import java.util.concurrent.Callable; + +/** + * End-to-end test that enables all AR-related features and ensures that the session is stable. + */ +@RunWith(ParameterizedRunner.class) +@UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, + "enable-features=WebXRIncubations,LogJsConsoleMessages"}) +@MinAndroidSdkLevel(Build.VERSION_CODES.N) // WebXR for AR is only supported on N+ +public class WebXrArSanityTest { + @ClassParameter + private static List<ParameterSet> sClassParams = + ArTestRuleUtils.generateDefaultTestRuleParameters(); + @Rule + public RuleChain mRuleChain; + + private ChromeActivityTestRule mTestRule; + private WebXrArTestFramework mWebXrArTestFramework; + + public WebXrArSanityTest(Callable<ChromeActivityTestRule> callable) throws Exception { + mTestRule = callable.call(); + mRuleChain = ArTestRuleUtils.wrapRuleInActivityRestrictionRule(mTestRule); + } + + @Before + public void setUp() { + mWebXrArTestFramework = new WebXrArTestFramework(mTestRule); + } + + /** + * Tests that a session is functional with all AR-related features enabled - short recording. + */ + @Test + @MediumTest + @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) + @ArPlaybackFile("chrome/test/data/xr/ar_playback_datasets/floor_session_12s_30fps.mp4") + public void testShortRecording() { + mWebXrArTestFramework.loadFileAndAwaitInitialization( + "webxr_test_basic_all_ar_features", PAGE_LOAD_TIMEOUT_S); + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + mWebXrArTestFramework.runJavaScriptOrFail( + "disableCameraAccess()", POLL_TIMEOUT_SHORT_MS); + } + + mWebXrArTestFramework.enterSessionWithUserGestureOrFail(); + // The recording is 12 seconds long, let's tell the test to run for 10 seconds and wait for + // a bit more than that before timing out. + mWebXrArTestFramework.executeStepAndWait("stepStartTest(10)", 15 * 1000); + mWebXrArTestFramework.endTest(); + } + + /** + * Tests that a session is functional with all AR-related features enabled - long recording. + */ + @Test + @LargeTest + @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) + @ArPlaybackFile( + "chrome/test/data/xr/ar_playback_datasets/floor_session_with_tracking_loss_37s_30fps.mp4") + public void + testLongRecording() { + mWebXrArTestFramework.loadFileAndAwaitInitialization( + "webxr_test_basic_all_ar_features", PAGE_LOAD_TIMEOUT_S); + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + mWebXrArTestFramework.runJavaScriptOrFail( + "disableCameraAccess()", POLL_TIMEOUT_SHORT_MS); + } + + mWebXrArTestFramework.enterSessionWithUserGestureOrFail(); + // The recording is 37 seconds long, let's tell the test to run for 30 seconds and wait for + // a bit more than that before timing out. + mWebXrArTestFramework.executeStepAndWait("stepStartTest(30)", 40 * 1000); + mWebXrArTestFramework.endTest(); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/XrTestFramework.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/XrTestFramework.java index 2872989..77c1ecdc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/XrTestFramework.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/XrTestFramework.java
@@ -163,7 +163,10 @@ */ public static boolean pollJavaScriptBoolean( final String boolExpression, int timeoutMs, final WebContents webContents) { - if (DEBUG_LOGS) Log.i(TAG, "pollJavaScriptBoolean " + boolExpression); + if (DEBUG_LOGS) { + Log.i(TAG, "pollJavaScriptBoolean " + boolExpression + ", timeoutMs=" + timeoutMs); + } + try { CriteriaHelper.pollInstrumentationThread(() -> { String result = "false"; @@ -288,7 +291,7 @@ * @param timeoutMs Timeout (in milliseconds) to wait for the JavaScript step. */ public static void waitOnJavaScriptStep(WebContents webContents, int timeoutMs) { - if (DEBUG_LOGS) Log.i(TAG, "waitOnJavaScriptStep"); + if (DEBUG_LOGS) Log.i(TAG, "waitOnJavaScriptStep, timeoutMs=" + timeoutMs); // Make sure we aren't trying to wait on a JavaScript test step without the code to do so. Assert.assertTrue("Attempted to wait on a JavaScript step without the code to do so. You " + "either forgot to import webxr_e2e.js or are incorrectly using a "
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index 5b259cd..792b13e 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc
@@ -119,7 +119,7 @@ #include "ash/constants/ash_paths.h" #include "ash/constants/ash_switches.h" #include "base/system/sys_info.h" -#include "chrome/browser/ash/dbus/dbus_helper.h" +#include "chrome/browser/ash/dbus/ash_dbus_helper.h" #include "chrome/browser/chromeos/boot_times_recorder.h" #include "chrome/browser/chromeos/startup_settings_cache.h" #include "chromeos/dbus/constants/dbus_paths.h"
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index a81cbc7..d306a16 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -779,6 +779,24 @@ <message name="IDS_OS_SETTINGS_DARK_MODE_THEMED_OFF" desc="Label for the checkbox which set the color mode to default color than calculated from the current wallpaper."> Neutral </message> + <message name="IDS_SETTINGS_DARK_MODE_ON_AT_SUNSET" desc="The sub label for the automatic schedule which explains that Dark Mode will turn on automatically at sunset."> + Dark mode will turn on automatically at sunset + </message> + <message name="IDS_SETTINGS_DARK_MODE_OFF_AT_SUNRISE" desc="The sub label for the automatic schedule which explains that Dark Mode will turn off automatically at sunrise."> + Dark mode will turn off automatically at sunrise + </message> + <message name="IDS_SETTINGS_DARK_MODE_SCHEDULE_CUSTOM" desc="The label of the option to set a custom schedule of the Dark Mode feature."> + Custom + </message> + <message name="IDS_SETTINGS_DARK_MODE_SCHEDULE_LABEL" desc="The label for the automatic schedule section of the Dark Mode feature."> + Schedule + </message> + <message name="IDS_SETTINGS_DARK_MODE_SCHEDULE_NEVER" desc="The label of the option to turn off the automatic schedule of the Dark Mode feature."> + Never + </message> + <message name="IDS_SETTINGS_DARK_MODE_SCHEDULE_SUNSET_TO_SUNRISE" desc="The label of the option to set the automatic schedule of the Dark Mode feature to turn on at sunset and off at sunrise."> + Sunset to sunrise + </message> <!-- Search and Assistant section. --> <message name="IDS_OS_SETTINGS_SEARCH_ENGINE_LABEL" desc="Label in OS settings describing search engine behavior.">
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_OFF_AT_SUNRISE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_OFF_AT_SUNRISE.png.sha1 new file mode 100644 index 0000000..77a60d9 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_OFF_AT_SUNRISE.png.sha1
@@ -0,0 +1 @@ +2ae74995dc84c04a05374fc051fb2d5c5221da4a \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_ON_AT_SUNSET.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_ON_AT_SUNSET.png.sha1 new file mode 100644 index 0000000..a86088d0 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_ON_AT_SUNSET.png.sha1
@@ -0,0 +1 @@ +b31d7bb3136a7b999f3bfb2e514e1b85dc2f9b3e \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_SCHEDULE_CUSTOM.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_SCHEDULE_CUSTOM.png.sha1 new file mode 100644 index 0000000..87bba5d9 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_SCHEDULE_CUSTOM.png.sha1
@@ -0,0 +1 @@ +45f495409c99f9abf07d4000779a9e4617be5712 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_SCHEDULE_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_SCHEDULE_LABEL.png.sha1 new file mode 100644 index 0000000..87bba5d9 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_SCHEDULE_LABEL.png.sha1
@@ -0,0 +1 @@ +45f495409c99f9abf07d4000779a9e4617be5712 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_SCHEDULE_NEVER.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_SCHEDULE_NEVER.png.sha1 new file mode 100644 index 0000000..a86088d0 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_SCHEDULE_NEVER.png.sha1
@@ -0,0 +1 @@ +b31d7bb3136a7b999f3bfb2e514e1b85dc2f9b3e \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_SCHEDULE_SUNSET_TO_SUNRISE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_SCHEDULE_SUNSET_TO_SUNRISE.png.sha1 new file mode 100644 index 0000000..a86088d0 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_DARK_MODE_SCHEDULE_SUNSET_TO_SUNRISE.png.sha1
@@ -0,0 +1 @@ +b31d7bb3136a7b999f3bfb2e514e1b85dc2f9b3e \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index a9bf108..332ffb9 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1465,10 +1465,6 @@ "safe_browsing/metrics/safe_browsing_metrics_provider.h", "search/search.cc", "search/search.h", - "search/suggestions/suggestions_service_factory.cc", - "search/suggestions/suggestions_service_factory.h", - "search/suggestions/suggestions_ui.cc", - "search/suggestions/suggestions_ui.h", "search_engines/chrome_template_url_service_client.cc", "search_engines/chrome_template_url_service_client.h", "search_engines/template_url_fetcher_factory.cc", @@ -2210,7 +2206,6 @@ "//components/subresource_filter/core/browser", "//components/subresource_filter/core/common", "//components/subresource_redirect/common", - "//components/suggestions", "//components/sync", "//components/sync_bookmarks", "//components/sync_preferences",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 929ddd9..d666d047 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS
@@ -305,7 +305,6 @@ "+components/subresource_filter/core/common", "+components/subresource_filter/core/mojom", "+components/subresource_redirect/common", - "+components/suggestions", "+components/supervised_user_error_page", "+components/sync", "+components/sync_bookmarks",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 4e8e5b3..77034b30 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -4589,6 +4589,10 @@ flag_descriptions::kTabGroupsNewBadgePromoDescription, kOsDesktop, FEATURE_VALUE_TYPE(features::kTabGroupsNewBadgePromo)}, + {"tab-groups-save", flag_descriptions::kTabGroupsSaveName, + flag_descriptions::kTabGroupsSaveDescription, kOsDesktop, + FEATURE_VALUE_TYPE(features::kTabGroupsSave)}, + {"new-tabstrip-animation", flag_descriptions::kNewTabstripAnimationName, flag_descriptions::kNewTabstripAnimationDescription, kOsDesktop, FEATURE_VALUE_TYPE(features::kNewTabstripAnimation)}, @@ -5550,6 +5554,10 @@ flag_descriptions::kEnableNetworkingInDiagnosticsAppDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kEnableNetworkingInDiagnosticsApp)}, + {"enable-oauth-ipp", flag_descriptions::kEnableOAuthIppName, + flag_descriptions::kEnableOAuthIppDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kEnableOAuthIpp)}, + {"enable-shortcut-customization-app", flag_descriptions::kEnableShortcutCustomizationAppName, flag_descriptions::kEnableShortcutCustomizationAppDescription, kOsCrOS, @@ -7391,6 +7399,15 @@ FEATURE_VALUE_TYPE(features::kWin10TabSearchCaptionButton)}, #endif // defined(OS_WIN) +#if BUILDFLAG(IS_CHROMEOS_ASH) + {"enable-holding-space-in-progress-downloads-integration", + flag_descriptions::kHoldingSpaceInProgressDownloadsIntegrationName, + flag_descriptions::kHoldingSpaceInProgressDownloadsIntegrationDescription, + kOsCrOS, + FEATURE_VALUE_TYPE( + ash::features::kHoldingSpaceInProgressDownloadsIntegration)}, +#endif + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/android/profile_key_startup_accessor.cc b/chrome/browser/android/profile_key_startup_accessor.cc index b5c59e1..f33266d 100644 --- a/chrome/browser/android/profile_key_startup_accessor.cc +++ b/chrome/browser/android/profile_key_startup_accessor.cc
@@ -5,14 +5,13 @@ #include "chrome/browser/android/profile_key_startup_accessor.h" #include "base/check.h" -#include "base/no_destructor.h" ProfileKeyStartupAccessor::ProfileKeyStartupAccessor() : key_(nullptr) {} // static ProfileKeyStartupAccessor* ProfileKeyStartupAccessor::GetInstance() { - static base::NoDestructor<ProfileKeyStartupAccessor> instance; - return instance.get(); + static ProfileKeyStartupAccessor instance; + return &instance; } void ProfileKeyStartupAccessor::SetProfileKey(ProfileKey* key) {
diff --git a/chrome/browser/ash/accessibility/dictation.cc b/chrome/browser/ash/accessibility/dictation.cc index ca4bb73..577452e 100644 --- a/chrome/browser/ash/accessibility/dictation.cc +++ b/chrome/browser/ash/accessibility/dictation.cc
@@ -279,6 +279,7 @@ true); no_speech_timeout_ = kDeviceNoSpeechTimeout; no_new_speech_timeout_ = kDeviceNoNewSpeechTimeout; + used_on_device_speech_ = true; } else { speech_recognizer_ = std::make_unique<NetworkSpeechRecognizer>( weak_ptr_factory_.GetWeakPtr(), @@ -293,7 +294,9 @@ ? kDeviceNoSpeechTimeout : kNetworkNoSpeechTimeout; no_new_speech_timeout_ = kNetworkNoNewSpeechTimeout; + used_on_device_speech_ = false; } + listening_duration_timer_ = base::ElapsedTimer(); return true; } @@ -402,6 +405,17 @@ AccessibilityNotificationType::kToggleDictation, false /* enabled */); AccessibilityManager::Get()->NotifyAccessibilityStatusChanged(details); speech_recognizer_.reset(); + + // Duration matches the lifetime of the speech recognizer. + if (used_on_device_speech_) { + base::UmaHistogramLongTimes( + "Accessibility.CrosDictation.ListeningDuration.OnDeviceRecognition", + listening_duration_timer_.Elapsed()); + } else { + base::UmaHistogramLongTimes( + "Accessibility.CrosDictation.ListeningDuration.NetworkRecognition", + listening_duration_timer_.Elapsed()); + } } void Dictation::CommitCurrentText() {
diff --git a/chrome/browser/ash/accessibility/dictation.h b/chrome/browser/ash/accessibility/dictation.h index 8c51880..08a7fb6 100644 --- a/chrome/browser/ash/accessibility/dictation.h +++ b/chrome/browser/ash/accessibility/dictation.h
@@ -10,6 +10,7 @@ #include "base/containers/flat_map.h" #include "base/memory/weak_ptr.h" +#include "base/timer/elapsed_timer.h" #include "base/timer/timer.h" #include "chrome/browser/speech/speech_recognizer_delegate.h" #include "content/public/browser/speech_recognition_session_preamble.h" @@ -90,6 +91,10 @@ base::TimeDelta no_speech_timeout_; base::TimeDelta no_new_speech_timeout_; + // Used for metrics. + bool used_on_device_speech_ = false; + base::ElapsedTimer listening_duration_timer_; + base::WeakPtrFactory<Dictation> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(Dictation);
diff --git a/chrome/browser/ash/account_manager/account_manager_migrator.h b/chrome/browser/ash/account_manager/account_manager_migrator.h index cbe10f4c..11c82f2 100644 --- a/chrome/browser/ash/account_manager/account_manager_migrator.h +++ b/chrome/browser/ash/account_manager/account_manager_migrator.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/no_destructor.h" #include "chrome/browser/ash/account_manager/account_migration_runner.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "components/keyed_service/core/keyed_service.h" @@ -16,11 +17,6 @@ class Profile; -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - namespace ash { class AccountManagerMigrator : public KeyedService {
diff --git a/chrome/browser/ash/account_manager/account_manager_policy_controller_factory.h b/chrome/browser/ash/account_manager/account_manager_policy_controller_factory.h index e8f62a0b..b1ab2aa 100644 --- a/chrome/browser/ash/account_manager/account_manager_policy_controller_factory.h +++ b/chrome/browser/ash/account_manager/account_manager_policy_controller_factory.h
@@ -6,13 +6,9 @@ #define CHROME_BROWSER_ASH_ACCOUNT_MANAGER_ACCOUNT_MANAGER_POLICY_CONTROLLER_FACTORY_H_ #include "base/macros.h" +#include "base/no_destructor.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - namespace ash { class AccountManagerPolicyController;
diff --git a/chrome/browser/ash/crosapi/test_controller_ash.cc b/chrome/browser/ash/crosapi/test_controller_ash.cc index 5dbddf0..c30d10c 100644 --- a/chrome/browser/ash/crosapi/test_controller_ash.cc +++ b/chrome/browser/ash/crosapi/test_controller_ash.cc
@@ -88,13 +88,15 @@ void TestControllerAsh::EnterOverviewMode(EnterOverviewModeCallback callback) { overview_waiters_.push_back(std::make_unique<OverviewWaiter>( /*wait_for_enter=*/true, std::move(callback), this)); - ash::Shell::Get()->overview_controller()->StartOverview(); + ash::Shell::Get()->overview_controller()->StartOverview( + ash::OverviewStartAction::kTests); } void TestControllerAsh::ExitOverviewMode(ExitOverviewModeCallback callback) { overview_waiters_.push_back(std::make_unique<OverviewWaiter>( /*wait_for_enter=*/false, std::move(callback), this)); - ash::Shell::Get()->overview_controller()->EndOverview(); + ash::Shell::Get()->overview_controller()->EndOverview( + ash::OverviewEndAction::kTests); } void TestControllerAsh::EnterTabletMode(EnterTabletModeCallback callback) {
diff --git a/chrome/browser/ash/dbus/dbus_helper.cc b/chrome/browser/ash/dbus/ash_dbus_helper.cc similarity index 99% rename from chrome/browser/ash/dbus/dbus_helper.cc rename to chrome/browser/ash/dbus/ash_dbus_helper.cc index d660edb..f724925b 100644 --- a/chrome/browser/ash/dbus/dbus_helper.cc +++ b/chrome/browser/ash/dbus/ash_dbus_helper.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ash/dbus/dbus_helper.h" +#include "chrome/browser/ash/dbus/ash_dbus_helper.h" #include "ash/constants/ash_features.h" #include "ash/constants/ash_paths.h"
diff --git a/chrome/browser/ash/dbus/dbus_helper.h b/chrome/browser/ash/dbus/ash_dbus_helper.h similarity index 78% rename from chrome/browser/ash/dbus/dbus_helper.h rename to chrome/browser/ash/dbus/ash_dbus_helper.h index 051ec5b..bc6cbd6 100644 --- a/chrome/browser/ash/dbus/dbus_helper.h +++ b/chrome/browser/ash/dbus/ash_dbus_helper.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_ASH_DBUS_DBUS_HELPER_H_ -#define CHROME_BROWSER_ASH_DBUS_DBUS_HELPER_H_ +#ifndef CHROME_BROWSER_ASH_DBUS_ASH_DBUS_HELPER_H_ +#define CHROME_BROWSER_ASH_DBUS_ASH_DBUS_HELPER_H_ namespace chromeos { @@ -19,4 +19,4 @@ } // namespace chromeos -#endif // CHROME_BROWSER_ASH_DBUS_DBUS_HELPER_H_ +#endif // CHROME_BROWSER_ASH_DBUS_ASH_DBUS_HELPER_H_
diff --git a/chrome/browser/ash/file_manager/file_manager_jstest.cc b/chrome/browser/ash/file_manager/file_manager_jstest.cc index 8fe7ed1..12d47da 100644 --- a/chrome/browser/ash/file_manager/file_manager_jstest.cc +++ b/chrome/browser/ash/file_manager/file_manager_jstest.cc
@@ -98,7 +98,8 @@ RunTestURL("common/js/files_app_entry_types_unittest.m_gen.html"); } -IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FilesDisplayPanel) { +// Test is flaky. See crbug.com/1226141 +IN_PROC_BROWSER_TEST_F(FileManagerJsTest, DISABLED_FilesDisplayPanel) { RunTestURL("foreground/elements/files_xf_elements_unittest.m_gen.html"); }
diff --git a/chrome/browser/ash/login/session/user_session_manager.cc b/chrome/browser/ash/login/session/user_session_manager.cc index 383c24f..9c92729 100644 --- a/chrome/browser/ash/login/session/user_session_manager.cc +++ b/chrome/browser/ash/login/session/user_session_manager.cc
@@ -632,6 +632,10 @@ // TODO(nkostylev): Fix this hack by improving Authenticator dependencies. authenticator_->SetConsumer(consumer); } + + for (auto& observer : authenticator_observer_list_) { + observer.OnAuthAttemptStarted(); + } return authenticator_; } @@ -984,6 +988,16 @@ session_state_observer_list_.RemoveObserver(observer); } +void UserSessionManager::AddUserAuthenticatorObserver( + ash::UserAuthenticatorObserver* observer) { + authenticator_observer_list_.AddObserver(observer); +} + +void UserSessionManager::RemoveUserAuthenticatorObserver( + ash::UserAuthenticatorObserver* observer) { + authenticator_observer_list_.RemoveObserver(observer); +} + void UserSessionManager::OnSessionRestoreStateChanged( Profile* user_profile, OAuth2LoginManager::SessionRestoreState state) {
diff --git a/chrome/browser/ash/login/session/user_session_manager.h b/chrome/browser/ash/login/session/user_session_manager.h index 9fdcc5b..816045d 100644 --- a/chrome/browser/ash/login/session/user_session_manager.h +++ b/chrome/browser/ash/login/session/user_session_manager.h
@@ -92,6 +92,12 @@ virtual ~UserSessionStateObserver(); }; +class UserAuthenticatorObserver : public base::CheckedObserver { + public: + // Called when authentication is started. + virtual void OnAuthAttemptStarted() {} +}; + // UserSessionManager is responsible for starting user session which includes: // * load and initialize Profile (including custom Profile preferences), // * mark user as logged in and notify observers, @@ -276,6 +282,10 @@ void AddSessionStateObserver(ash::UserSessionStateObserver* observer); void RemoveSessionStateObserver(ash::UserSessionStateObserver* observer); + void AddUserAuthenticatorObserver(ash::UserAuthenticatorObserver* observer); + void RemoveUserAuthenticatorObserver( + ash::UserAuthenticatorObserver* observer); + void ActiveUserChanged(user_manager::User* active_user) override; // Returns default IME state for user session. @@ -588,6 +598,9 @@ base::ObserverList<ash::UserSessionStateObserver>::Unchecked session_state_observer_list_; + base::ObserverList<ash::UserAuthenticatorObserver> + authenticator_observer_list_; + // Set of user_id for those users that we should restore authentication // session when notified about online state change. SigninSessionRestoreStateSet pending_signin_restore_sessions_;
diff --git a/chrome/browser/ash/notifications/request_system_proxy_credentials_view.cc b/chrome/browser/ash/notifications/request_system_proxy_credentials_view.cc index e842169..baa1a2fa9 100644 --- a/chrome/browser/ash/notifications/request_system_proxy_credentials_view.cc +++ b/chrome/browser/ash/notifications/request_system_proxy_credentials_view.cc
@@ -19,6 +19,7 @@ #include "components/vector_icons/vector_icons.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/base/models/image_model.h" #include "ui/base/resource/resource_bundle.h" #include "ui/events/event.h" #include "ui/gfx/color_palette.h" @@ -30,6 +31,35 @@ #include "ui/views/layout/grid_layout.h" #include "ui/views/widget/widget.h" +namespace { + +class ErrorLabelView : public views::Label { + public: + METADATA_HEADER(ErrorLabelView); + + explicit ErrorLabelView(bool show_error_label) + : Label(l10n_util::GetStringUTF16( + IDS_SYSTEM_PROXY_AUTH_DIALOG_ERROR_LABEL)) { + SetEnabled(true); + SetVisible(show_error_label); + } + ErrorLabelView(const ErrorLabelView&) = delete; + ErrorLabelView& operator=(const ErrorLabelView&) = delete; + ~ErrorLabelView() override = default; + + // views::View: + void OnThemeChanged() override { + Label::OnThemeChanged(); + SetEnabledColor(GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_AlertSeverityHigh)); + } +}; + +BEGIN_METADATA(ErrorLabelView, views::Label) +END_METADATA + +} // namespace + namespace ash { RequestSystemProxyCredentialsView::RequestSystemProxyCredentialsView( @@ -155,20 +185,15 @@ related_vertical_spacing); auto error_icon = std::make_unique<views::ImageView>(); const int kIconSize = 18; - error_icon->SetImage( - gfx::CreateVectorIcon(vector_icons::kInfoOutlineIcon, kIconSize, - GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_AlertSeverityHigh))); + error_icon->SetImage(ui::ImageModel::FromVectorIcon( + vector_icons::kInfoOutlineIcon, + ui::NativeTheme::kColorId_AlertSeverityHigh, kIconSize)); error_icon->SetImageSize(gfx::Size(kIconSize, kIconSize)); error_icon->SetVisible(show_error_label_); layout->AddView(std::move(error_icon)); - auto error_label = std::make_unique<views::Label>( - l10n_util::GetStringUTF16(IDS_SYSTEM_PROXY_AUTH_DIALOG_ERROR_LABEL)); - error_label->SetEnabled(true); - error_label->SetVisible(show_error_label_); - error_label->SetEnabledColor(error_label->GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_AlertSeverityHigh)); - error_label_ = layout->AddView(std::move(error_label)); + + error_label_ = + layout->AddView(std::make_unique<ErrorLabelView>(show_error_label_)); } BEGIN_METADATA(RequestSystemProxyCredentialsView, views::DialogDelegateView)
diff --git a/chrome/browser/autofill/mock_autofill_popup_controller.h b/chrome/browser/autofill/mock_autofill_popup_controller.h index 1466d9d4..25c6f88 100644 --- a/chrome/browser/autofill/mock_autofill_popup_controller.h +++ b/chrome/browser/autofill/mock_autofill_popup_controller.h
@@ -37,8 +37,8 @@ MOCK_CONST_METHOD0(container_view, gfx::NativeView()); MOCK_CONST_METHOD0(GetWebContents, content::WebContents*()); const gfx::RectF& element_bounds() const override { - static base::NoDestructor<gfx::RectF> bounds({100, 100, 250, 50}); - return *bounds; + static const gfx::RectF bounds(100, 100, 250, 50); + return bounds; } MOCK_CONST_METHOD0(IsRTL, bool());
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 504f3f3..95e64ad4 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1175,14 +1175,14 @@ "../ash/customization/customization_wallpaper_downloader.h", "../ash/customization/customization_wallpaper_util.cc", "../ash/customization/customization_wallpaper_util.h", + "../ash/dbus/ash_dbus_helper.cc", + "../ash/dbus/ash_dbus_helper.h", "../ash/dbus/chrome_features_service_provider.cc", "../ash/dbus/chrome_features_service_provider.h", "../ash/dbus/component_updater_service_provider.cc", "../ash/dbus/component_updater_service_provider.h", "../ash/dbus/cryptohome_key_delegate_service_provider.cc", "../ash/dbus/cryptohome_key_delegate_service_provider.h", - "../ash/dbus/dbus_helper.cc", - "../ash/dbus/dbus_helper.h", "../ash/dbus/dlp_files_policy_service_provider.cc", "../ash/dbus/dlp_files_policy_service_provider.h", "../ash/dbus/drive_file_stream_service_provider.cc", @@ -2929,8 +2929,6 @@ "policy/server_backed_state/server_backed_state_keys_broker.h", "policy/status_collector/activity_storage.cc", "policy/status_collector/activity_storage.h", - "policy/status_collector/affiliated_session_service.cc", - "policy/status_collector/affiliated_session_service.h", "policy/status_collector/app_info_generator.cc", "policy/status_collector/app_info_generator.h", "policy/status_collector/child_activity_storage.cc", @@ -2942,6 +2940,8 @@ "policy/status_collector/enterprise_activity_storage.cc", "policy/status_collector/enterprise_activity_storage.h", "policy/status_collector/interval_map.h", + "policy/status_collector/managed_session_service.cc", + "policy/status_collector/managed_session_service.h", "policy/status_collector/status_collector.cc", "policy/status_collector/status_collector.h", "policy/status_collector/status_collector_state.cc", @@ -4213,10 +4213,10 @@ "policy/server_backed_state/device_cloud_state_keys_uploader_unittest.cc", "policy/server_backed_state/server_backed_state_keys_broker_unittest.cc", "policy/status_collector/activity_storage_unittest.cc", - "policy/status_collector/affiliated_session_service_unittest.cc", "policy/status_collector/app_info_generator_unittest.cc", "policy/status_collector/enterprise_activity_storage_unittest.cc", "policy/status_collector/interval_map_unittest.cc", + "policy/status_collector/managed_session_service_unittest.cc", "policy/uploading/heartbeat_scheduler_unittest.cc", "policy/uploading/status_uploader_unittest.cc", "policy/uploading/system_log_uploader_unittest.cc", @@ -4609,6 +4609,7 @@ "//chromeos/dbus:dbus", "//chromeos/tpm", "//components:components_tests_pak", + "//components/policy/core/browser:internal", "//third_party/libprotobuf-mutator", "//ui/resources:ui_test_pak", ]
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index 3b89aff..cb84c03e 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -54,10 +54,10 @@ #include "chrome/browser/ash/crosapi/crosapi_manager.h" #include "chrome/browser/ash/crostini/crostini_unsupported_action_notifier.h" #include "chrome/browser/ash/crostini/crosvm_metrics.h" +#include "chrome/browser/ash/dbus/ash_dbus_helper.h" #include "chrome/browser/ash/dbus/chrome_features_service_provider.h" #include "chrome/browser/ash/dbus/component_updater_service_provider.h" #include "chrome/browser/ash/dbus/cryptohome_key_delegate_service_provider.h" -#include "chrome/browser/ash/dbus/dbus_helper.h" #include "chrome/browser/ash/dbus/dlp_files_policy_service_provider.h" #include "chrome/browser/ash/dbus/drive_file_stream_service_provider.h" #include "chrome/browser/ash/dbus/encrypted_reporting_service_provider.h"
diff --git a/chrome/browser/chromeos/input_method/component_extension_ime_manager_delegate_impl.cc b/chrome/browser/chromeos/input_method/component_extension_ime_manager_delegate_impl.cc index 67986cb0..8d5997b 100644 --- a/chrome/browser/chromeos/input_method/component_extension_ime_manager_delegate_impl.cc +++ b/chrome/browser/chromeos/input_method/component_extension_ime_manager_delegate_impl.cc
@@ -19,7 +19,6 @@ #include "base/system/sys_info.h" #include "base/task/post_task.h" #include "base/task/thread_pool.h" -#include "base/trace_event/trace_event.h" #include "build/branding_buildflags.h" #include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/extensions/extension_service.h" @@ -110,7 +109,6 @@ const std::string& extension_id, const std::string& manifest, const base::FilePath& file_path) { - TRACE_EVENT1("ime", "DoLoadExtension", "ext_id", extension_id); extensions::ExtensionRegistry* extension_registry = extensions::ExtensionRegistry::Get(profile); DCHECK(extension_registry); @@ -156,7 +154,18 @@ const base::FilePath* file_path, bool result) { if (result) { - DoLoadExtension(profile, *extension_id, *manifest, *file_path); + std::string manifest_str = *manifest; +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + // Load Mojo-only background page for ChromeOS IME extension when feature + // 'ImeMojoDecoder' is enabled. See http://b/181170189 for more details. + // TODO(http://b/170278753): Remove this once NaCl decoder is removed. + if ((*extension_id == extension_ime_util::kXkbExtensionId) && + base::FeatureList::IsEnabled(chromeos::features::kImeMojoDecoder)) { + base::ReplaceFirstSubstringAfterOffset( + &manifest_str, 0, "background.html", "background_mojo.html"); + } +#endif + DoLoadExtension(profile, *extension_id, manifest_str, *file_path); } else { LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS()) << "IME extension file path does not exist: " << file_path->value(); @@ -185,26 +194,6 @@ const std::string& extension_id, const std::string& manifest, const base::FilePath& file_path) { - TRACE_EVENT0("ime", "ComponentExtensionIMEManagerDelegateImpl::Load"); - std::string* manifest_cp = new std::string(manifest); -#if BUILDFLAG(GOOGLE_CHROME_BRANDING) - // Skip checking the path of the Chrome OS IME component extension when it's - // Google Chrome brand, since it is bundled resource on Chrome OS image. This - // will improve the IME extension load latency a lot. - // See http://b/192032670 for more details. - if (extension_id == extension_ime_util::kXkbExtensionId) { - // Update manifest content inplace to load Mojo background page for ChromeOS - // IME extension when the feature 'ImeMojoDecoder' is enabled. - // See http://b/181170189 for more details. - // TODO(http://b/170278753): Remove this once NaCl decoder is removed. - if (base::FeatureList::IsEnabled(chromeos::features::kImeMojoDecoder)) { - base::ReplaceFirstSubstringAfterOffset(manifest_cp, 0, "background.html", - "background_mojo.html"); - } - DoLoadExtension(profile, extension_id, *manifest_cp, file_path); - return; - } -#endif // Check the existence of file path to avoid unnecessary extension loading // and InputMethodEngine creation, so that the virtual keyboard web content // url won't be override by IME component extensions. @@ -216,7 +205,8 @@ base::BindOnce(&CheckFilePath, base::Unretained(copied_file_path)), base::BindOnce(&OnFilePathChecked, base::Unretained(profile), base::Owned(new std::string(extension_id)), - base::Owned(manifest_cp), base::Owned(copied_file_path))); + base::Owned(new std::string(manifest)), + base::Owned(copied_file_path))); } bool ComponentExtensionIMEManagerDelegateImpl::IsInLoginLayoutAllowlist(
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc index 0f6168b..0ca55730 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
@@ -26,7 +26,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/system/sys_info.h" #include "base/time/time.h" -#include "base/trace_event/trace_event.h" #include "chrome/browser/ash/login/session/user_session_manager.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part_chromeos.h" @@ -1162,11 +1161,8 @@ // image. If specified component extension IME no longer exists, falling back // to an existing IME. DCHECK(state); - TRACE_EVENT0("ime", - "InputMethodManagerImpl::LoadNecessaryComponentExtensions"); std::vector<std::string> unfiltered_input_method_ids; unfiltered_input_method_ids.swap(state->active_input_method_ids); - std::set<std::string> ext_loaded; for (const auto& unfiltered_input_method_id : unfiltered_input_method_ids) { if (!extension_ime_util::IsComponentExtensionIME( unfiltered_input_method_id)) { @@ -1176,7 +1172,7 @@ unfiltered_input_method_id)) { if (enable_extension_loading_) { component_extension_ime_manager_->LoadComponentExtensionIME( - state->profile, unfiltered_input_method_id, &ext_loaded); + state->profile, unfiltered_input_method_id); } state->active_input_method_ids.push_back(unfiltered_input_method_id);
diff --git a/chrome/browser/chromeos/input_method/ui/candidate_view.cc b/chrome/browser/chromeos/input_method/ui/candidate_view.cc index cca6f35..6af89b7 100644 --- a/chrome/browser/chromeos/input_method/ui/candidate_view.cc +++ b/chrome/browser/chromeos/input_method/ui/candidate_view.cc
@@ -48,47 +48,83 @@ BEGIN_METADATA(VerticalCandidateLabel, views::Label) END_METADATA -// Creates the shortcut label, and returns it (never returns nullptr). -// The label text is not set in this function. -std::unique_ptr<views::Label> CreateShortcutLabel( - ui::CandidateWindow::Orientation orientation, - const ui::NativeTheme& theme) { - auto shortcut_label = std::make_unique<views::Label>(); +// The label text is not set in this class. +class ShortcutLabel : public views::Label { + public: + METADATA_HEADER(ShortcutLabel); + explicit ShortcutLabel(ui::CandidateWindow::Orientation orientation) + : orientation_(orientation) { + // TODO(tapted): Get this FontList from views::style. + if (orientation == ui::CandidateWindow::VERTICAL) { + SetFontList(font_list().Derive(kFontSizeDelta, gfx::Font::NORMAL, + gfx::Font::Weight::BOLD)); + } else { + SetFontList(font_list().DeriveWithSizeDelta(kFontSizeDelta)); + } + // TODO(satorux): Maybe we need to use language specific fonts for + // candidate_label, like Chinese font for Chinese input method? - // TODO(tapted): Get this FontList from views::style. - if (orientation == ui::CandidateWindow::VERTICAL) { - shortcut_label->SetFontList(shortcut_label->font_list().Derive( - kFontSizeDelta, gfx::Font::NORMAL, gfx::Font::Weight::BOLD)); - } else { - shortcut_label->SetFontList( - shortcut_label->font_list().DeriveWithSizeDelta(kFontSizeDelta)); + // Setup paddings. + const gfx::Insets kVerticalShortcutLabelInsets(1, 6, 1, 6); + const gfx::Insets kHorizontalShortcutLabelInsets(1, 3, 1, 0); + const gfx::Insets insets = (orientation == ui::CandidateWindow::VERTICAL + ? kVerticalShortcutLabelInsets + : kHorizontalShortcutLabelInsets); + SetBorder(views::CreateEmptyBorder(insets.top(), insets.left(), + insets.bottom(), insets.right())); + + SetElideBehavior(gfx::NO_ELIDE); } - // TODO(satorux): Maybe we need to use language specific fonts for - // candidate_label, like Chinese font for Chinese input method? + ShortcutLabel(const ShortcutLabel&) = delete; + ShortcutLabel& operator=(const ShortcutLabel&) = delete; + ~ShortcutLabel() override = default; - // Setup paddings. - const gfx::Insets kVerticalShortcutLabelInsets(1, 6, 1, 6); - const gfx::Insets kHorizontalShortcutLabelInsets(1, 3, 1, 0); - const gfx::Insets insets = (orientation == ui::CandidateWindow::VERTICAL - ? kVerticalShortcutLabelInsets - : kHorizontalShortcutLabelInsets); - shortcut_label->SetBorder(views::CreateEmptyBorder( - insets.top(), insets.left(), insets.bottom(), insets.right())); - - // Add decoration based on the orientation. - if (orientation == ui::CandidateWindow::VERTICAL) { - // Set the background color. - SkColor blackish = color_utils::AlphaBlend( - SK_ColorBLACK, - theme.GetSystemColor(ui::NativeTheme::kColorId_WindowBackground), - 0.25f); - shortcut_label->SetBackground( - views::CreateSolidBackground(SkColorSetA(blackish, 0xE0))); + // views::Label: + void OnThemeChanged() override { + Label::OnThemeChanged(); + // Add decoration based on the orientation. + if (orientation_ == ui::CandidateWindow::VERTICAL) { + // Set the background color. + SkColor blackish = color_utils::AlphaBlend( + SK_ColorBLACK, + GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_WindowBackground), + 0.25f); + SetBackground(views::CreateSolidBackground(SkColorSetA(blackish, 0xE0))); + } } - shortcut_label->SetElideBehavior(gfx::NO_ELIDE); - return shortcut_label; -} + private: + const ui::CandidateWindow::Orientation orientation_; +}; + +BEGIN_METADATA(ShortcutLabel, views::Label) +END_METADATA + +// The label text is not set in this class. +class AnnotationLabel : public views::Label { + public: + METADATA_HEADER(AnnotationLabel); + AnnotationLabel() { + // Change the font size and color. + SetFontList(font_list().DeriveWithSizeDelta(kFontSizeDelta)); + SetHorizontalAlignment(gfx::ALIGN_LEFT); + SetElideBehavior(gfx::NO_ELIDE); + } + AnnotationLabel(const AnnotationLabel&) = delete; + AnnotationLabel& operator=(const AnnotationLabel&) = delete; + ~AnnotationLabel() override = default; + + // views::Label: + void OnThemeChanged() override { + Label::OnThemeChanged(); + SetEnabledColor(GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_LabelSecondaryColor)); + } +}; + +BEGIN_METADATA(AnnotationLabel, views::Label) +END_METADATA // Creates the candidate label, and returns it (never returns nullptr). // The label text is not set in this function. @@ -111,24 +147,6 @@ return candidate_label; } -// Creates the annotation label, and return it (never returns nullptr). -// The label text is not set in this function. -std::unique_ptr<views::Label> CreateAnnotationLabel( - ui::CandidateWindow::Orientation orientation, - const ui::NativeTheme& theme) { - auto annotation_label = std::make_unique<views::Label>(); - - // Change the font size and color. - annotation_label->SetFontList( - annotation_label->font_list().DeriveWithSizeDelta(kFontSizeDelta)); - annotation_label->SetEnabledColor( - theme.GetSystemColor(ui::NativeTheme::kColorId_LabelSecondaryColor)); - annotation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - annotation_label->SetElideBehavior(gfx::NO_ELIDE); - - return annotation_label; -} - } // namespace CandidateView::CandidateView(PressedCallback callback, @@ -136,17 +154,12 @@ : views::Button(std::move(callback)), orientation_(orientation) { SetBorder(views::CreateEmptyBorder(1, 1, 1, 1)); - const ui::NativeTheme& theme = *GetNativeTheme(); - shortcut_label_ = AddChildView(CreateShortcutLabel(orientation, theme)); + shortcut_label_ = AddChildView(std::make_unique<ShortcutLabel>(orientation)); candidate_label_ = AddChildView(CreateCandidateLabel(orientation)); - annotation_label_ = AddChildView(CreateAnnotationLabel(orientation, theme)); + annotation_label_ = AddChildView(std::make_unique<AnnotationLabel>()); - if (orientation == ui::CandidateWindow::VERTICAL) { - auto infolist_icon = std::make_unique<views::View>(); - infolist_icon->SetBackground(views::CreateSolidBackground( - theme.GetSystemColor(ui::NativeTheme::kColorId_FocusedBorderColor))); - infolist_icon_ = AddChildView(std::move(infolist_icon)); - } + if (orientation == ui::CandidateWindow::VERTICAL) + infolist_icon_ = AddChildView(std::make_unique<views::View>()); SetFocusBehavior(views::View::FocusBehavior::ACCESSIBLE_ONLY); } @@ -300,6 +313,15 @@ total_candidates_); } +void CandidateView::OnThemeChanged() { + Button::OnThemeChanged(); + if (infolist_icon_) { + infolist_icon_->SetBackground( + views::CreateSolidBackground(GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_FocusedBorderColor))); + } +} + BEGIN_METADATA(CandidateView, views::Button) END_METADATA
diff --git a/chrome/browser/chromeos/input_method/ui/candidate_view.h b/chrome/browser/chromeos/input_method/ui/candidate_view.h index f330871b..72a40448 100644 --- a/chrome/browser/chromeos/input_method/ui/candidate_view.h +++ b/chrome/browser/chromeos/input_method/ui/candidate_view.h
@@ -53,6 +53,7 @@ void Layout() override; gfx::Size CalculatePreferredSize() const override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; + void OnThemeChanged() override; // The orientation of the candidate view. ui::CandidateWindow::Orientation orientation_;
diff --git a/chrome/browser/chromeos/input_method/ui/candidate_window_view.cc b/chrome/browser/chromeos/input_method/ui/candidate_window_view.cc index 8db9e14..3a333fe 100644 --- a/chrome/browser/chromeos/input_method/ui/candidate_window_view.cc +++ b/chrome/browser/chromeos/input_method/ui/candidate_window_view.cc
@@ -106,16 +106,22 @@ SetLayoutManager(std::make_unique<views::FillLayout>()); AddChildView(label_); + } + + InformationTextArea(const InformationTextArea&) = delete; + InformationTextArea& operator=(const InformationTextArea&) = delete; + + // views::View: + void OnThemeChanged() override { + View::OnThemeChanged(); SetBackground(views::CreateSolidBackground( color_utils::AlphaBlend(SK_ColorBLACK, GetNativeTheme()->GetSystemColor( ui::NativeTheme::kColorId_WindowBackground), 0.0625f))); + UpdateBorder(); } - InformationTextArea(const InformationTextArea&) = delete; - InformationTextArea& operator=(const InformationTextArea&) = delete; - // Sets the text alignment. void SetAlignment(gfx::HorizontalAlignment alignment) { label_->SetHorizontalAlignment(alignment); @@ -126,8 +132,15 @@ // Sets the border thickness for top/bottom. void SetBorderFromPosition(BorderPosition position) { + position_ = position; + UpdateBorder(); + } + + void UpdateBorder() { + if (!position_ || !GetWidget()) + return; SetBorder(views::CreateSolidSidedBorder( - (position == TOP) ? 1 : 0, 0, (position == BOTTOM) ? 1 : 0, 0, + (position_ == TOP) ? 1 : 0, 0, (position_ == BOTTOM) ? 1 : 0, 0, GetNativeTheme()->GetSystemColor( ui::NativeTheme::kColorId_MenuBorderColor))); } @@ -142,6 +155,7 @@ private: views::Label* label_; int min_width_; + absl::optional<BorderPosition> position_; }; BEGIN_METADATA(InformationTextArea, views::View) @@ -169,10 +183,6 @@ // with what CandidateWindowView expects. set_use_round_corners(false); - SetBorder(views::CreateSolidBorder( - 1, GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_MenuBorderColor))); - SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical)); auxiliary_text_ = new InformationTextArea(gfx::ALIGN_RIGHT, 0); @@ -214,6 +224,13 @@ return widget; } +void CandidateWindowView::OnThemeChanged() { + BubbleDialogDelegateView::OnThemeChanged(); + SetBorder(views::CreateSolidBorder( + 1, GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_MenuBorderColor))); +} + void CandidateWindowView::UpdateVisibility() { if (candidate_area_->GetVisible() || auxiliary_text_->GetVisible() || preedit_->GetVisible()) {
diff --git a/chrome/browser/chromeos/input_method/ui/candidate_window_view.h b/chrome/browser/chromeos/input_method/ui/candidate_window_view.h index 9064a180..527a90e 100644 --- a/chrome/browser/chromeos/input_method/ui/candidate_window_view.h +++ b/chrome/browser/chromeos/input_method/ui/candidate_window_view.h
@@ -39,6 +39,9 @@ ~CandidateWindowView() override; views::Widget* InitWidget(); + // views::BubbleDialogDelegateView: + void OnThemeChanged() override; + // Adds the given observer. The ownership is not transferred. void AddObserver(Observer* observer) { observers_.AddObserver(observer); }
diff --git a/chrome/browser/chromeos/policy/fuzzer/policy_fuzzer.cc b/chrome/browser/chromeos/policy/fuzzer/policy_fuzzer.cc index fff83ee9..5eb493a9 100644 --- a/chrome/browser/chromeos/policy/fuzzer/policy_fuzzer.cc +++ b/chrome/browser/chromeos/policy/fuzzer/policy_fuzzer.cc
@@ -15,7 +15,7 @@ #include "base/path_service.h" #include "base/test/task_environment.h" #include "build/build_config.h" -#include "chrome/browser/ash/dbus/dbus_helper.h" +#include "chrome/browser/ash/dbus/ash_dbus_helper.h" #include "chrome/browser/ash/settings/device_settings_provider.h" #include "chrome/browser/ash/settings/device_settings_service.h" #include "chrome/browser/chromeos/policy/fuzzer/policy_fuzzer.pb.h"
diff --git a/chrome/browser/chromeos/policy/status_collector/affiliated_session_service.cc b/chrome/browser/chromeos/policy/status_collector/affiliated_session_service.cc deleted file mode 100644 index 5162988d..0000000 --- a/chrome/browser/chromeos/policy/status_collector/affiliated_session_service.cc +++ /dev/null
@@ -1,104 +0,0 @@ -// 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. - -#include "chrome/browser/chromeos/policy/status_collector/affiliated_session_service.h" - -#include "base/logging.h" -#include "chrome/browser/ash/profiles/profile_helper.h" - -namespace policy { - -namespace { - -constexpr base::TimeDelta kMinimumSuspendDuration = - base::TimeDelta::FromMinutes(1); - -bool IsPrimaryAndAffiliated(Profile* profile) { - user_manager::User* user = - chromeos::ProfileHelper::Get()->GetUserByProfile(profile); - bool is_primary = chromeos::ProfileHelper::Get()->IsPrimaryProfile(profile); - bool is_affiliated = user && user->IsAffiliated(); - if (!is_primary || !is_affiliated) { - VLOG(1) << "The profile for the primary user is not associated with an " - "affiliated user."; - } - return is_primary && is_affiliated; -} - -} // namespace - -AffiliatedSessionService::AffiliatedSessionService(base::Clock* clock) - : clock_(clock), session_manager_(session_manager::SessionManager::Get()) { - if (session_manager_) { - // To alleviate tight coupling in unit tests to DeviceStatusCollector. - session_manager_observation_.Observe(session_manager_); - is_session_locked_ = session_manager_->IsScreenLocked(); - } - power_manager_observation_.Observe(chromeos::PowerManagerClient::Get()); -} - -AffiliatedSessionService::~AffiliatedSessionService() = default; - -void AffiliatedSessionService::AddObserver( - AffiliatedSessionService::Observer* observer) { - observers_.AddObserver(observer); -} - -void AffiliatedSessionService::RemoveObserver( - AffiliatedSessionService::Observer* observer) { - observers_.RemoveObserver(observer); -} - -void AffiliatedSessionService::OnSessionStateChanged() { - bool is_session_locked = session_manager_->IsScreenLocked(); - if (is_session_locked_ == is_session_locked) { - return; - } - is_session_locked_ = is_session_locked; - - if (is_session_locked_) { - for (auto& observer : observers_) { - observer.OnLocked(); - } - } else { - for (auto& observer : observers_) { - observer.OnUnlocked(); - } - } -} - -void AffiliatedSessionService::OnUserProfileLoaded( - const AccountId& account_id) { - Profile* profile = - chromeos::ProfileHelper::Get()->GetProfileByAccountId(account_id); - if (!IsPrimaryAndAffiliated(profile)) { - return; - } - profile_observations_.AddObservation(profile); - for (auto& observer : observers_) { - observer.OnAffiliatedLogin(profile); - } -} - -void AffiliatedSessionService::OnProfileWillBeDestroyed(Profile* profile) { - is_session_locked_ = false; - if (!IsPrimaryAndAffiliated(profile)) { - return; - } - for (auto& observer : observers_) { - observer.OnAffiliatedLogout(profile); - } - profile_observations_.RemoveObservation(profile); -} - -void AffiliatedSessionService::SuspendDone(base::TimeDelta sleep_duration) { - if (sleep_duration < kMinimumSuspendDuration) { - return; - } - for (auto& observer : observers_) { - observer.OnResumeActive(clock_->Now() - sleep_duration); - } -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/status_collector/affiliated_session_service.h b/chrome/browser/chromeos/policy/status_collector/affiliated_session_service.h deleted file mode 100644 index ca2b1b2..0000000 --- a/chrome/browser/chromeos/policy/status_collector/affiliated_session_service.h +++ /dev/null
@@ -1,88 +0,0 @@ -// 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. - -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_AFFILIATED_SESSION_SERVICE_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_AFFILIATED_SESSION_SERVICE_H_ - -#include "base/observer_list.h" -#include "base/observer_list_types.h" -#include "base/scoped_multi_source_observation.h" -#include "base/scoped_observation.h" -#include "base/time/clock.h" -#include "base/time/default_clock.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_observer.h" -#include "chromeos/dbus/power/power_manager_client.h" -#include "components/account_id/account_id.h" -#include "components/session_manager/core/session_manager.h" -#include "components/session_manager/core/session_manager_observer.h" - -namespace policy { - -class AffiliatedSessionService : public session_manager::SessionManagerObserver, - public ProfileObserver, - public chromeos::PowerManagerClient::Observer { - public: - class Observer : public base::CheckedObserver { - public: - // Occurs when an affiliated primary user has logged in. - virtual void OnAffiliatedLogin(Profile* profile) {} - - // Occurs when an affiliated primary user has logged out. - virtual void OnAffiliatedLogout(Profile* profile) {} - - // Occurs when the active user has locked the user session. - virtual void OnLocked() {} - - // Occurs when the active user has unlocked the user session. - virtual void OnUnlocked() {} - - // Occurs when the device recovers from a suspend state, where - // |suspend_time| is the time when the suspend state - // first occurred. Short duration suspends are not reported. - virtual void OnResumeActive(base::Time suspend_time) {} - }; - - explicit AffiliatedSessionService( - base::Clock* clock = base::DefaultClock::GetInstance()); - AffiliatedSessionService(const AffiliatedSessionService&) = delete; - AffiliatedSessionService& operator=(const AffiliatedSessionService&) = delete; - ~AffiliatedSessionService() override; - - void AddObserver(Observer* observer); - - void RemoveObserver(Observer* observer); - - // session_manager::SessionManagerObserver::Observer - void OnSessionStateChanged() override; - void OnUserProfileLoaded(const AccountId& account_id) override; - - // ProfileObserver - void OnProfileWillBeDestroyed(Profile* profile) override; - - // chromeos::PowerManagerClient::Observer - void SuspendDone(base::TimeDelta sleep_duration) override; - - private: - bool is_session_locked_; - - base::Clock* clock_; - - base::ObserverList<Observer> observers_; - - session_manager::SessionManager* const session_manager_; - - base::ScopedMultiSourceObservation<Profile, ProfileObserver> - profile_observations_{this}; - base::ScopedObservation<session_manager::SessionManager, - session_manager::SessionManagerObserver> - session_manager_observation_{this}; - base::ScopedObservation<chromeos::PowerManagerClient, - chromeos::PowerManagerClient::Observer> - power_manager_observation_{this}; -}; - -} // namespace policy - -#endif // CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_AFFILIATED_SESSION_SERVICE_H_
diff --git a/chrome/browser/chromeos/policy/status_collector/app_info_generator.cc b/chrome/browser/chromeos/policy/status_collector/app_info_generator.cc index ae71d95..0bacacc3 100644 --- a/chrome/browser/chromeos/policy/status_collector/app_info_generator.cc +++ b/chrome/browser/chromeos/policy/status_collector/app_info_generator.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/chromeos/policy/status_collector/app_info_generator.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" +#include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/web_app_provider_factory.h" #include "chrome/browser/web_applications/web_app_registrar.h" @@ -19,6 +20,18 @@ namespace { +bool IsPrimaryAndAffiliated(Profile* profile) { + user_manager::User* user = + chromeos::ProfileHelper::Get()->GetUserByProfile(profile); + bool is_primary = chromeos::ProfileHelper::Get()->IsPrimaryProfile(profile); + bool is_affiliated = user && user->IsAffiliated(); + if (!is_primary || !is_affiliated) { + VLOG(1) << "The profile for the primary user is not associated with an " + "affiliated user."; + } + return is_primary && is_affiliated; +} + em::AppInfo::Status ExtractStatus(const apps::mojom::Readiness readiness) { switch (readiness) { case apps::mojom::Readiness::kReady: @@ -77,10 +90,15 @@ AppInfoGenerator::AppInfoProvider::~AppInfoProvider() = default; AppInfoGenerator::AppInfoGenerator( + ManagedSessionService* managed_session_service, base::TimeDelta max_stored_past_activity_interval, base::Clock* clock) : max_stored_past_activity_interval_(max_stored_past_activity_interval), - clock_(*clock) {} + clock_(*clock) { + if (managed_session_service) { + managed_session_observation_.Observe(managed_session_service); + } +} AppInfoGenerator::AppInstances::AppInstances(const base::Time start_time_) : start_time(start_time_) {} @@ -152,7 +170,11 @@ SetIdleDurationsToOpen(); } -void AppInfoGenerator::OnAffiliatedLogin(Profile* profile) { +void AppInfoGenerator::OnLogin(Profile* profile) { + if (!IsPrimaryAndAffiliated(profile)) { + return; + } + if (!apps::AppServiceProxyFactory::IsAppServiceAvailableForProfile(profile)) { VLOG(1) << "No apps available. Will not track usage."; return; @@ -167,7 +189,11 @@ } } -void AppInfoGenerator::OnAffiliatedLogout(Profile* profile) { +void AppInfoGenerator::OnLogout(Profile* profile) { + if (!IsPrimaryAndAffiliated(profile)) { + return; + } + if (provider_) { if (should_report_) { provider_->app_service_proxy.InstanceRegistry().RemoveObserver(this);
diff --git a/chrome/browser/chromeos/policy/status_collector/app_info_generator.h b/chrome/browser/chromeos/policy/status_collector/app_info_generator.h index c315a1b..89d0b601 100644 --- a/chrome/browser/chromeos/policy/status_collector/app_info_generator.h +++ b/chrome/browser/chromeos/policy/status_collector/app_info_generator.h
@@ -13,7 +13,7 @@ #include "base/time/default_clock.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/chromeos/policy/status_collector/activity_storage.h" -#include "chrome/browser/chromeos/policy/status_collector/affiliated_session_service.h" +#include "chrome/browser/chromeos/policy/status_collector/managed_session_service.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "components/prefs/pref_registry_simple.h" #include "components/services/app_service/public/cpp/instance.h" @@ -30,11 +30,12 @@ // A class that is responsible for collecting application inventory and usage // information. class AppInfoGenerator : public apps::InstanceRegistry::Observer, - public AffiliatedSessionService::Observer { + public ManagedSessionService::Observer { public: using Result = absl::optional<std::vector<enterprise_management::AppInfo>>; explicit AppInfoGenerator( + ManagedSessionService* managed_session_service, base::TimeDelta max_stored_past_activity_interval, base::Clock* clock = base::DefaultClock::GetInstance()); AppInfoGenerator(const AppInfoGenerator&) = delete; @@ -59,9 +60,9 @@ // up until the current time, so it may be reported. void OnWillReport(); - // AffiliatedSessionManager::Observer - void OnAffiliatedLogin(Profile* profile) override; - void OnAffiliatedLogout(Profile* profile) override; + // ManagedSessionService::Observer + void OnLogin(Profile* profile) override; + void OnLogout(Profile* profile) override; void OnLocked() override; void OnUnlocked() override; void OnResumeActive(base::Time suspend_time) override; @@ -122,6 +123,10 @@ base::TimeDelta max_stored_past_activity_interval_; const base::Clock& clock_; + + base::ScopedObservation<ManagedSessionService, + ManagedSessionService::Observer> + managed_session_observation_{this}; }; } // namespace policy
diff --git a/chrome/browser/chromeos/policy/status_collector/app_info_generator_unittest.cc b/chrome/browser/chromeos/policy/status_collector/app_info_generator_unittest.cc index 5b646ea..cb504b0e 100644 --- a/chrome/browser/chromeos/policy/status_collector/app_info_generator_unittest.cc +++ b/chrome/browser/chromeos/policy/status_collector/app_info_generator_unittest.cc
@@ -166,11 +166,24 @@ GetInstanceRegistry().OnInstances(deltas); } + std::unique_ptr<TestingProfile> CreateProfile(const AccountId& account_id, + bool is_affiliated = true) { + TestingProfile::Builder profile_builder; + profile_builder.SetProfileName(account_id.GetUserEmail()); + auto profile = profile_builder.Build(); + user_manager_->AddUserWithAffiliationAndTypeAndProfile( + account_id, is_affiliated, user_manager::UserType::USER_TYPE_REGULAR, + profile.get()); + return profile; + } + void SetUp() override { auto user_manager = std::make_unique<ash::FakeChromeUserManager>(); + user_manager_ = user_manager.get(); user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>( std::move(user_manager)); - profile_ = std::make_unique<TestingProfile>(); + account_id_ = AccountId::FromUserEmail("affiliated@managed.com"); + profile_ = CreateProfile(account_id_); test_clock().SetNow(MakeLocalTime("25-MAR-2020 1:30am")); web_app::WebAppProviderFactory::GetInstance()->SetTestingFactoryAndUse( @@ -206,13 +219,13 @@ std::unique_ptr<AppInfoGenerator> GetGenerator( base::TimeDelta max_stored_past_activity_interval = base::TimeDelta::FromDays(0)) { - return std::make_unique<AppInfoGenerator>(max_stored_past_activity_interval, - &test_clock()); + return std::make_unique<AppInfoGenerator>( + nullptr, max_stored_past_activity_interval, &test_clock()); } std::unique_ptr<AppInfoGenerator> GetReadyGenerator() { auto generator = GetGenerator(); - generator->OnAffiliatedLogin(profile()); + generator->OnLogin(profile()); generator->OnReportingChanged(true); return generator; } @@ -239,6 +252,10 @@ Profile* profile() { return profile_.get(); } + ash::FakeChromeUserManager* user_manager() { return user_manager_; } + + AccountId account_id() { return account_id_; } + static auto EqActivity(const base::Time& start_time, const base::Time& end_time) { return AllOf( @@ -265,8 +282,10 @@ apps::ScopedOmitPluginVmAppsForTesting scoped_omit_plugin_vm_apps_for_testing_; content::BrowserTaskEnvironment task_environment_; + AccountId account_id_; std::unique_ptr<TestingProfile> profile_; web_app::WebAppRegistrarMutable* app_registrar_; + ash::FakeChromeUserManager* user_manager_; std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_; TestingPrefServiceSimple pref_service_; @@ -283,6 +302,7 @@ PushApp("c", "ThirdApp", apps::mojom::Readiness::kUninstalledByUser, "", apps::mojom::AppType::kCrostini); + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); auto result = generator->Generate(); @@ -297,6 +317,7 @@ } TEST_F(AppInfoGeneratorTest, GenerateWebApp) { + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); PushApp("c", "App", apps::mojom::Readiness::kUninstalledByUser, "", apps::mojom::AppType::kWeb); @@ -321,6 +342,7 @@ } TEST_F(AppInfoGeneratorTest, MultipleInstances) { + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); @@ -347,18 +369,54 @@ } TEST_F(AppInfoGeneratorTest, ShouldNotReport) { + user_manager()->LoginUser(account_id(), true); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); auto generator = GetGenerator(); generator->OnReportingChanged(false); - generator->OnAffiliatedLogin(profile()); + generator->OnLogin(profile()); + auto result = generator->Generate(); + + EXPECT_FALSE(result.has_value()); +} + +TEST_F(AppInfoGeneratorTest, UnaffiliatedUser) { + auto unaffiliated_account_id = + AccountId::FromUserEmail("unaffiliated@unmanaged.com"); + auto unaffiliated_profile = + CreateProfile(unaffiliated_account_id, /* is_affiliated= */ false); + user_manager()->LoginUser(unaffiliated_account_id, true); + PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", + apps::mojom::AppType::kArc); + + auto generator = GetGenerator(); + generator->OnReportingChanged(true); + generator->OnLogin(unaffiliated_profile.get()); + auto result = generator->Generate(); + + EXPECT_FALSE(result.has_value()); +} + +TEST_F(AppInfoGeneratorTest, SecondaryUser) { + user_manager()->LoginUser(account_id(), true); + auto secondary_account_id = AccountId::FromUserEmail("secondary@managed.com"); + auto secondary_profile = + CreateProfile(secondary_account_id, /* is_affiliated= */ true); + user_manager()->LoginUser(secondary_account_id, true); + PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", + apps::mojom::AppType::kArc); + + auto generator = GetGenerator(); + generator->OnReportingChanged(true); + generator->OnLogin(secondary_profile.get()); auto result = generator->Generate(); EXPECT_FALSE(result.has_value()); } TEST_F(AppInfoGeneratorTest, OnReportedSuccessfully) { + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); @@ -388,6 +446,7 @@ } TEST_F(AppInfoGeneratorTest, OnWillReport) { + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); @@ -426,12 +485,13 @@ } TEST_F(AppInfoGeneratorTest, OnLogoutOnLogin) { + user_manager()->LoginUser(account_id(), true); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); auto generator = GetGenerator(); generator->OnReportingChanged(true); - generator->OnAffiliatedLogin(profile()); - generator->OnAffiliatedLogout(profile()); + generator->OnLogin(profile()); + generator->OnLogout(profile()); Instance app_instance("a"); test_clock().SetNow(MakeLocalTime("29-MAR-2020 1:30pm")); PushAppInstance(app_instance, apps::InstanceState::kStarted); @@ -443,7 +503,7 @@ EXPECT_FALSE(result.has_value()); - generator->OnAffiliatedLogin(profile()); + generator->OnLogin(profile()); test_clock().SetNow(MakeLocalTime("30-MAR-2020 2:30pm")); PushAppInstance(app_instance, apps::InstanceState::kStarted); @@ -462,6 +522,7 @@ } TEST_F(AppInfoGeneratorTest, OnLocked) { + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); @@ -484,6 +545,7 @@ } TEST_F(AppInfoGeneratorTest, OnUnlocked) { + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); @@ -512,6 +574,7 @@ } TEST_F(AppInfoGeneratorTest, OnResumeActive) { + user_manager()->LoginUser(account_id(), true); auto generator = GetReadyGenerator(); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); @@ -540,6 +603,7 @@ } TEST_F(AppInfoGeneratorTest, OnLoginRemoveOldUsage) { + user_manager()->LoginUser(account_id(), true); PushApp("a", "FirstApp", apps::mojom::Readiness::kDisabledByPolicy, "1.1", apps::mojom::AppType::kArc); PushApp("b", "SecondApp", apps::mojom::Readiness::kReady, "1.2", @@ -548,7 +612,7 @@ 1); // Exclude all past usage except for UTC today and yesterday. auto generator = GetGenerator(max_days_past); generator->OnReportingChanged(true); - generator->OnAffiliatedLogin(profile()); + generator->OnLogin(profile()); Instance app_instance1("a"); test_clock().SetNow(MakeLocalTime("28-MAR-2020 1:30am")); @@ -561,9 +625,9 @@ test_clock().SetNow(MakeLocalTime("29-MAR-2020 3:30am")); PushAppInstance(app_instance2, apps::InstanceState::kDestroyed); - generator->OnAffiliatedLogout(profile()); + generator->OnLogout(profile()); test_clock().SetNow(MakeLocalTime("30-MAR-2020 11:00am")); - generator->OnAffiliatedLogin(profile()); + generator->OnLogin(profile()); auto result = generator->Generate();
diff --git a/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc b/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc index 127983a4..3d8f2a4 100644 --- a/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc +++ b/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc
@@ -1443,7 +1443,9 @@ graphics_status_fetcher_(graphics_status_fetcher), crash_report_info_fetcher_(crash_report_info_fetcher), power_manager_(chromeos::PowerManagerClient::Get()), - app_info_generator_(kMaxStoredPastActivityInterval, clock_) { + app_info_generator_(&managed_session_service_, + kMaxStoredPastActivityInterval, + clock_) { // protected fields of `StatusCollector`. max_stored_past_activity_interval_ = kMaxStoredPastActivityInterval; max_stored_future_activity_interval_ = kMaxStoredFutureActivityInterval; @@ -1547,8 +1549,7 @@ stats_reporting_pref_subscription_ = cros_settings_->AddSettingsObserver( chromeos::kStatsReportingPref, callback); - affiliated_session_service_.AddObserver(&app_info_generator_); - + // TODO(b/191986061):: consider using ScopedObservation instead. power_manager_->AddObserver(this); // Fetch the current values of the policies. @@ -1603,7 +1604,6 @@ DeviceStatusCollector::~DeviceStatusCollector() { power_manager_->RemoveObserver(this); - affiliated_session_service_.RemoveObserver(&app_info_generator_); } // static
diff --git a/chrome/browser/chromeos/policy/status_collector/device_status_collector.h b/chrome/browser/chromeos/policy/status_collector/device_status_collector.h index b64d0cd7..7816073 100644 --- a/chrome/browser/chromeos/policy/status_collector/device_status_collector.h +++ b/chrome/browser/chromeos/policy/status_collector/device_status_collector.h
@@ -211,8 +211,8 @@ static void RegisterPrefs(PrefRegistrySimple* registry); - AffiliatedSessionService* GetAffiliatedSessionServiceForTesting() { - return &affiliated_session_service_; + ManagedSessionService* GetManagedSessionServiceForTesting() { + return &managed_session_service_; } // How often to poll to see if the user is idle. @@ -480,7 +480,7 @@ base::CallbackListSubscription app_info_subscription_; base::CallbackListSubscription stats_reporting_pref_subscription_; - AffiliatedSessionService affiliated_session_service_; + ManagedSessionService managed_session_service_; AppInfoGenerator app_info_generator_;
diff --git a/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc index 01ba596..a8e183d8 100644 --- a/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc +++ b/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc
@@ -216,7 +216,7 @@ constexpr uint32_t kFakeTotalMemory = 1287312; constexpr uint32_t kFakeFreeMemory = 981239; constexpr uint32_t kFakeAvailableMemory = 98719321; -constexpr uint32_t kFakePageFaults = 896123761; +constexpr uint64_t kFakePageFaults = 896123761; // Backlight test values: constexpr char kFakeBacklightPath[] = "/sys/class/backlight/fake_backlight"; constexpr uint32_t kFakeMaxBrightness = 769; @@ -947,7 +947,7 @@ options->crash_report_info_fetcher = base::BindRepeating(&GetEmptyCrashReportInfo); options->app_info_generator = std::make_unique<policy::AppInfoGenerator>( - base::TimeDelta::FromDays(0)); + nullptr, base::TimeDelta::FromDays(0)); return options; } @@ -3608,8 +3608,8 @@ MockRegularUserWithAffiliation(account_id, true); scoped_testing_cros_settings_.device_settings()->SetBoolean( chromeos::kReportDeviceAppInfo, true); - status_collector_->GetAffiliatedSessionServiceForTesting() - ->OnUserProfileLoaded(account_id); + status_collector_->GetManagedSessionServiceForTesting()->OnUserProfileLoaded( + account_id); auto* app_proxy = apps::AppServiceProxyFactory::GetForProfile(testing_profile_.get()); auto app1 = apps::mojom::App::New();
diff --git a/chrome/browser/chromeos/policy/status_collector/managed_session_service.cc b/chrome/browser/chromeos/policy/status_collector/managed_session_service.cc new file mode 100644 index 0000000..35184f3 --- /dev/null +++ b/chrome/browser/chromeos/policy/status_collector/managed_session_service.cc
@@ -0,0 +1,110 @@ +// 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. + +#include "chrome/browser/chromeos/policy/status_collector/managed_session_service.h" + +#include "base/logging.h" +#include "chrome/browser/ash/login/existing_user_controller.h" +#include "chrome/browser/ash/profiles/profile_helper.h" +#include "components/user_manager/user_manager.h" + +namespace policy { + +namespace { + +constexpr base::TimeDelta kMinimumSuspendDuration = + base::TimeDelta::FromMinutes(1); + +} // namespace + +ManagedSessionService::ManagedSessionService(base::Clock* clock) + : clock_(clock), session_manager_(session_manager::SessionManager::Get()) { + if (session_manager_) { + // To alleviate tight coupling in unit tests to DeviceStatusCollector. + session_manager_observation_.Observe(session_manager_); + is_session_locked_ = session_manager_->IsScreenLocked(); + } + if (user_manager::UserManager::IsInitialized()) { + authenticator_observation_.Observe(ash::UserSessionManager::GetInstance()); + } + power_manager_observation_.Observe(chromeos::PowerManagerClient::Get()); +} + +ManagedSessionService::~ManagedSessionService() { + if (ash::ExistingUserController::current_controller()) { + ash::ExistingUserController::current_controller() + ->RemoveLoginStatusConsumer(this); + } +} + +void ManagedSessionService::AddObserver( + ManagedSessionService::Observer* observer) { + observers_.AddObserver(observer); +} + +void ManagedSessionService::RemoveObserver( + ManagedSessionService::Observer* observer) { + observers_.RemoveObserver(observer); +} + +void ManagedSessionService::OnSessionStateChanged() { + bool is_session_locked = session_manager_->IsScreenLocked(); + if (is_session_locked_ == is_session_locked) { + return; + } + is_session_locked_ = is_session_locked; + + if (is_session_locked_) { + for (auto& observer : observers_) { + observer.OnLocked(); + } + } else { + for (auto& observer : observers_) { + observer.OnUnlocked(); + } + } +} + +void ManagedSessionService::OnUserProfileLoaded(const AccountId& account_id) { + Profile* profile = + chromeos::ProfileHelper::Get()->GetProfileByAccountId(account_id); + profile_observations_.AddObservation(profile); + for (auto& observer : observers_) { + observer.OnLogin(profile); + } +} + +void ManagedSessionService::OnProfileWillBeDestroyed(Profile* profile) { + is_session_locked_ = false; + for (auto& observer : observers_) { + observer.OnLogout(profile); + } + profile_observations_.RemoveObservation(profile); +} + +void ManagedSessionService::SuspendDone(base::TimeDelta sleep_duration) { + if (sleep_duration < kMinimumSuspendDuration) { + return; + } + for (auto& observer : observers_) { + observer.OnResumeActive(clock_->Now() - sleep_duration); + } +} + +void ManagedSessionService::OnAuthAttemptStarted() { + if (ash::ExistingUserController::current_controller()) { + ash::ExistingUserController::current_controller() + ->RemoveLoginStatusConsumer(this); + ash::ExistingUserController::current_controller()->AddLoginStatusConsumer( + this); + } +} + +void ManagedSessionService::OnAuthFailure(const chromeos::AuthFailure& error) { + for (auto& observer : observers_) { + observer.OnLoginFailure(error); + } +} + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/status_collector/managed_session_service.h b/chrome/browser/chromeos/policy/status_collector/managed_session_service.h new file mode 100644 index 0000000..52f6d4bb --- /dev/null +++ b/chrome/browser/chromeos/policy/status_collector/managed_session_service.h
@@ -0,0 +1,107 @@ +// 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. + +#ifndef CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_MANAGED_SESSION_SERVICE_H_ +#define CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_MANAGED_SESSION_SERVICE_H_ + +#include "base/observer_list.h" +#include "base/observer_list_types.h" +#include "base/scoped_multi_source_observation.h" +#include "base/scoped_observation.h" +#include "base/time/clock.h" +#include "base/time/default_clock.h" +#include "chrome/browser/ash/login/session/user_session_manager.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_observer.h" +#include "chromeos/dbus/power/power_manager_client.h" +#include "chromeos/login/auth/auth_status_consumer.h" +#include "components/account_id/account_id.h" +#include "components/session_manager/core/session_manager.h" +#include "components/session_manager/core/session_manager_observer.h" + +namespace policy { + +class ManagedSessionService : public session_manager::SessionManagerObserver, + public ProfileObserver, + public chromeos::PowerManagerClient::Observer, + public chromeos::AuthStatusConsumer, + public ash::UserAuthenticatorObserver { + public: + class Observer : public base::CheckedObserver { + public: + // Occurs when a user's login attempt fails. + virtual void OnLoginFailure(const chromeos::AuthFailure& error) {} + + // Occurs when a user has logged in. + virtual void OnLogin(Profile* profile) {} + + // Occurs when a user has logged out. + virtual void OnLogout(Profile* profile) {} + + // Occurs when the active user has locked the user session. + virtual void OnLocked() {} + + // Occurs when the active user has unlocked the user session. + virtual void OnUnlocked() {} + + // Occurs when the device recovers from a suspend state, where + // |suspend_time| is the time when the suspend state + // first occurred. Short duration suspends are not reported. + virtual void OnResumeActive(base::Time suspend_time) {} + }; + + explicit ManagedSessionService( + base::Clock* clock = base::DefaultClock::GetInstance()); + ManagedSessionService(const ManagedSessionService&) = delete; + ManagedSessionService& operator=(const ManagedSessionService&) = delete; + ~ManagedSessionService() override; + + void AddObserver(Observer* observer); + + void RemoveObserver(Observer* observer); + + // session_manager::SessionManagerObserver::Observer + void OnSessionStateChanged() override; + void OnUserProfileLoaded(const AccountId& account_id) override; + + // ProfileObserver + void OnProfileWillBeDestroyed(Profile* profile) override; + + // chromeos::PowerManagerClient::Observer + void SuspendDone(base::TimeDelta sleep_duration) override; + + void OnAuthSuccess(const ash::UserContext& user_context) override {} + + void OnAuthFailure(const chromeos::AuthFailure& error) override; + + void OnAuthAttemptStarted() override; + + private: + bool is_session_locked_; + + base::Clock* clock_; + + base::ObserverList<Observer> observers_; + + session_manager::SessionManager* const session_manager_; + + base::ScopedMultiSourceObservation<Profile, ProfileObserver> + profile_observations_{this}; + base::ScopedObservation<session_manager::SessionManager, + session_manager::SessionManagerObserver> + session_manager_observation_{this}; + base::ScopedObservation<chromeos::PowerManagerClient, + chromeos::PowerManagerClient::Observer> + power_manager_observation_{this}; + base::ScopedObservation< + ash::UserSessionManager, + ash::UserAuthenticatorObserver, + &ash::UserSessionManager::AddUserAuthenticatorObserver, + &ash::UserSessionManager::RemoveUserAuthenticatorObserver> + authenticator_observation_{this}; +}; + +} // namespace policy + +#endif // CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_MANAGED_SESSION_SERVICE_H_
diff --git a/chrome/browser/chromeos/policy/status_collector/affiliated_session_service_unittest.cc b/chrome/browser/chromeos/policy/status_collector/managed_session_service_unittest.cc similarity index 73% rename from chrome/browser/chromeos/policy/status_collector/affiliated_session_service_unittest.cc rename to chrome/browser/chromeos/policy/status_collector/managed_session_service_unittest.cc index cffd115..da195126 100644 --- a/chrome/browser/chromeos/policy/status_collector/affiliated_session_service_unittest.cc +++ b/chrome/browser/chromeos/policy/status_collector/managed_session_service_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/status_collector/affiliated_session_service.h" +#include "chrome/browser/chromeos/policy/status_collector/managed_session_service.h" #include "base/test/simple_test_clock.h" #include "chrome/browser/ash/login/users/chrome_user_manager.h" @@ -17,9 +17,9 @@ namespace policy { -class AffiliatedSessionServiceTest +class ManagedSessionServiceTest : public ::testing::Test, - public policy::AffiliatedSessionService::Observer { + public policy::ManagedSessionService::Observer { protected: using SessionState = session_manager::SessionState; @@ -30,12 +30,12 @@ user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>( std::move(user_manager)); - affiliated_session_service_ = - std::make_unique<AffiliatedSessionService>(&test_clock_); + managed_session_service_ = + std::make_unique<ManagedSessionService>(&test_clock_); } void TearDown() override { - affiliated_session_service_.reset(); + managed_session_service_.reset(); chromeos::PowerManagerClient::Shutdown(); } @@ -54,8 +54,8 @@ return profile; } - AffiliatedSessionService* affiliated_session_service() { - return affiliated_session_service_.get(); + ManagedSessionService* managed_session_service() { + return managed_session_service_.get(); } session_manager::SessionManager* session_manager() { @@ -68,14 +68,19 @@ base::SimpleTestClock* test_clock() { return &test_clock_; } - void OnAffiliatedLogin(Profile* profile) override { logged_in_ = profile; } - void OnAffiliatedLogout(Profile* profile) override { logged_out_ = profile; } + void OnLoginFailure(const chromeos::AuthFailure& error) override { + auth_failure_ = error; + } + void OnLogin(Profile* profile) override { logged_in_ = profile; } + void OnLogout(Profile* profile) override { logged_out_ = profile; } void OnLocked() override { locked_ = true; } void OnUnlocked() override { unlocked_ = true; } void OnResumeActive(base::Time time) override { suspend_time_ = std::make_unique<base::Time>(time); } + chromeos::AuthFailure auth_failure_ = + chromeos::AuthFailure::AuthFailureNone(); Profile* logged_in_ = nullptr; Profile* logged_out_ = nullptr; bool locked_ = false; @@ -92,11 +97,11 @@ base::SimpleTestClock test_clock_; - std::unique_ptr<AffiliatedSessionService> affiliated_session_service_; + std::unique_ptr<ManagedSessionService> managed_session_service_; }; -TEST_F(AffiliatedSessionServiceTest, OnSessionStateChanged) { - affiliated_session_service()->AddObserver(this); +TEST_F(ManagedSessionServiceTest, OnSessionStateChanged) { + managed_session_service()->AddObserver(this); session_manager()->SetSessionState(SessionState::LOCKED); session_manager()->SetSessionState(SessionState::ACTIVE); @@ -129,49 +134,49 @@ EXPECT_TRUE(unlocked_); } -TEST_F(AffiliatedSessionServiceTest, OnUserProfileLoadedAffiliatedAndPrimary) { +TEST_F(ManagedSessionServiceTest, OnUserProfileLoadedAffiliatedAndPrimary) { AccountId affiliated_account_id = AccountId::FromUserEmail("user0@managed.com"); std::unique_ptr<TestingProfile> affiliated_profile = CreateProfile( affiliated_account_id, true /* affiliated */, true /* login */); - affiliated_session_service()->AddObserver(this); + managed_session_service()->AddObserver(this); session_manager()->NotifyUserProfileLoaded(affiliated_account_id); EXPECT_TRUE(affiliated_profile->IsSameOrParent(logged_in_)); } -TEST_F(AffiliatedSessionServiceTest, OnUserProfileLoadedAffiliated) { +TEST_F(ManagedSessionServiceTest, OnUserProfileLoadedAffiliated) { AccountId secondary_account_id = AccountId::FromUserEmail("user3@managed.com"); std::unique_ptr<TestingProfile> secondary_profile = CreateProfile( secondary_account_id, true /* affiliated */, false /* login */); - affiliated_session_service()->AddObserver(this); + managed_session_service()->AddObserver(this); session_manager()->NotifyUserProfileLoaded(secondary_account_id); - EXPECT_EQ(logged_in_, nullptr); + EXPECT_TRUE(secondary_profile->IsSameOrParent(logged_in_)); } -TEST_F(AffiliatedSessionServiceTest, OnUserProfileLoadedPrimary) { +TEST_F(ManagedSessionServiceTest, OnUserProfileLoadedPrimary) { AccountId unaffiliated_account_id = AccountId::FromUserEmail("user2@managed.com"); std::unique_ptr<TestingProfile> unaffiliated_profile = CreateProfile( unaffiliated_account_id, false /* affiliated */, true /* login */); - affiliated_session_service()->AddObserver(this); + managed_session_service()->AddObserver(this); session_manager()->NotifyUserProfileLoaded(unaffiliated_account_id); - EXPECT_EQ(logged_in_, nullptr); + EXPECT_TRUE(unaffiliated_profile->IsSameOrParent(logged_in_)); } -TEST_F(AffiliatedSessionServiceTest, +TEST_F(ManagedSessionServiceTest, OnProfileWillBeDestroyedAffiliatedAndPrimary) { AccountId affiliated_account_id = AccountId::FromUserEmail("user0@managed.com"); std::unique_ptr<TestingProfile> affiliated_profile = CreateProfile( affiliated_account_id, true /* affiliated */, true /* login */); - affiliated_session_service()->AddObserver(this); + managed_session_service()->AddObserver(this); session_manager()->NotifyUserProfileLoaded(affiliated_account_id); affiliated_profile->MaybeSendDestroyedNotification(); @@ -179,34 +184,34 @@ EXPECT_TRUE(affiliated_profile->IsSameOrParent(logged_out_)); } -TEST_F(AffiliatedSessionServiceTest, OnProfileWillBeDestroyedAffiliated) { +TEST_F(ManagedSessionServiceTest, OnProfileWillBeDestroyedAffiliated) { AccountId secondary_account_id = AccountId::FromUserEmail("user3@managed.com"); std::unique_ptr<TestingProfile> secondary_profile = CreateProfile( secondary_account_id, true /* affiliated */, false /* login */); - affiliated_session_service()->AddObserver(this); + managed_session_service()->AddObserver(this); session_manager()->NotifyUserProfileLoaded(secondary_account_id); secondary_profile->MaybeSendDestroyedNotification(); - EXPECT_EQ(logged_out_, nullptr); + EXPECT_TRUE(secondary_profile->IsSameOrParent(logged_in_)); } -TEST_F(AffiliatedSessionServiceTest, OnProfileWillBeDestroyedPrimary) { +TEST_F(ManagedSessionServiceTest, OnProfileWillBeDestroyedPrimary) { AccountId unaffiliated_account_id = AccountId::FromUserEmail("user2@managed.com"); std::unique_ptr<TestingProfile> unaffiliated_profile = CreateProfile( unaffiliated_account_id, false /* affiliated */, true /* login */); - affiliated_session_service()->AddObserver(this); + managed_session_service()->AddObserver(this); session_manager()->NotifyUserProfileLoaded(unaffiliated_account_id); unaffiliated_profile->MaybeSendDestroyedNotification(); - EXPECT_EQ(logged_out_, nullptr); + EXPECT_TRUE(unaffiliated_profile->IsSameOrParent(logged_in_)); } -TEST_F(AffiliatedSessionServiceTest, SuspendDone) { - affiliated_session_service()->AddObserver(this); +TEST_F(ManagedSessionServiceTest, SuspendDone) { + managed_session_service()->AddObserver(this); test_clock()->SetNow(base::Time::Now()); base::TimeDelta sleep_duration = base::TimeDelta::FromHours(2); @@ -215,13 +220,13 @@ EXPECT_EQ(*suspend_time_, test_clock()->Now() - sleep_duration); } -TEST_F(AffiliatedSessionServiceTest, RemoveObserver) { +TEST_F(ManagedSessionServiceTest, RemoveObserver) { AccountId account_id = AccountId::FromUserEmail("user0@managed.com"); std::unique_ptr<TestingProfile> profile = CreateProfile(account_id, true /* affiliated */, true /* login */); - affiliated_session_service()->AddObserver(this); + managed_session_service()->AddObserver(this); - affiliated_session_service()->RemoveObserver(this); + managed_session_service()->RemoveObserver(this); session_manager()->SetSessionState(SessionState::LOCKED); session_manager()->SetSessionState(SessionState::ACTIVE); @@ -236,4 +241,14 @@ EXPECT_FALSE(profile->IsSameOrParent(logged_out_)); } +TEST_F(ManagedSessionServiceTest, LoginFailure) { + managed_session_service()->AddObserver(this); + + managed_session_service()->OnAuthFailure(chromeos::AuthFailure( + chromeos::AuthFailure::FailureReason::OWNER_REQUIRED)); + + EXPECT_EQ(auth_failure_.reason(), + chromeos::AuthFailure::FailureReason::OWNER_REQUIRED); +} + } // namespace policy
diff --git a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/ImplicitPriceDropSubscriptionsManager.java b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/ImplicitPriceDropSubscriptionsManager.java index 83d8389..d9e5bfe 100644 --- a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/ImplicitPriceDropSubscriptionsManager.java +++ b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/ImplicitPriceDropSubscriptionsManager.java
@@ -147,8 +147,8 @@ private boolean isStaleTab(Tab tab) { long tabLastOpenTime = System.currentTimeMillis() - CriticalPersistedTabData.from(tab).getTimestampMillis(); - return tabLastOpenTime <= TimeUnit.SECONDS.toMillis( - ShoppingPersistedTabData.STALE_TAB_THRESHOLD_SECONDS.getValue()) + return tabLastOpenTime + <= TimeUnit.SECONDS.toMillis(ShoppingPersistedTabData.getStaleTabThresholdSeconds()) && tabLastOpenTime >= TimeUnit.SECONDS.toMillis(CommerceSubscriptionsServiceConfig .STALE_TAB_LOWER_BOUND_SECONDS.getValue());
diff --git a/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/ImplicitPriceDropSubscriptionsManagerUnitTest.java b/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/ImplicitPriceDropSubscriptionsManagerUnitTest.java index 26dcc59..aedc7ef 100644 --- a/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/ImplicitPriceDropSubscriptionsManagerUnitTest.java +++ b/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/ImplicitPriceDropSubscriptionsManagerUnitTest.java
@@ -116,8 +116,7 @@ doReturn(OFFER1_ID).when(mShoppingPersistedTabData1).getMainOfferId(); doReturn(OFFER2_ID).when(mShoppingPersistedTabData2).getMainOfferId(); long fakeTimestamp = System.currentTimeMillis() - - TimeUnit.SECONDS.toMillis( - ShoppingPersistedTabData.STALE_TAB_THRESHOLD_SECONDS.getValue()) + - TimeUnit.SECONDS.toMillis(ShoppingPersistedTabData.getStaleTabThresholdSeconds()) + TimeUnit.DAYS.toMillis(7); doReturn(fakeTimestamp).when(mCriticalPersistedTabData1).getTimestampMillis(); doReturn(fakeTimestamp).when(mCriticalPersistedTabData2).getTimestampMillis(); @@ -214,8 +213,7 @@ @Test public void testInitialSubscription_TabTooOld() { doReturn(System.currentTimeMillis() - - TimeUnit.SECONDS.toMillis( - ShoppingPersistedTabData.STALE_TAB_THRESHOLD_SECONDS.getValue()) + - TimeUnit.SECONDS.toMillis(ShoppingPersistedTabData.getStaleTabThresholdSeconds()) - TimeUnit.DAYS.toMillis(7)) .when(mCriticalPersistedTabData1) .getTimestampMillis();
diff --git a/chrome/browser/devtools/protocol/window_manager_handler.cc b/chrome/browser/devtools/protocol/window_manager_handler.cc index 2c1df6b..a5da6ea 100644 --- a/chrome/browser/devtools/protocol/window_manager_handler.cc +++ b/chrome/browser/devtools/protocol/window_manager_handler.cc
@@ -17,14 +17,16 @@ protocol::Response WindowManagerHandler::EnterOverviewMode() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - bool success = ash::Shell::Get()->overview_controller()->StartOverview(); + bool success = ash::Shell::Get()->overview_controller()->StartOverview( + ash::OverviewStartAction::kDevTools); return success ? protocol::Response::Success() : protocol::Response::ServerError("Overview failed"); } protocol::Response WindowManagerHandler::ExitOverviewMode() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - bool success = ash::Shell::Get()->overview_controller()->EndOverview(); + bool success = ash::Shell::Get()->overview_controller()->EndOverview( + ash::OverviewEndAction::kDevTools); return success ? protocol::Response::Success() : protocol::Response::ServerError("Overview failed"); }
diff --git a/chrome/browser/download/simple_download_manager_coordinator_factory.h b/chrome/browser/download/simple_download_manager_coordinator_factory.h index bead09e..6bb06a3 100644 --- a/chrome/browser/download/simple_download_manager_coordinator_factory.h +++ b/chrome/browser/download/simple_download_manager_coordinator_factory.h
@@ -8,16 +8,12 @@ #include <memory> #include "base/macros.h" +#include "base/no_destructor.h" #include "components/keyed_service/core/simple_keyed_service_factory.h" class KeyedService; class SimpleFactoryKey; -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - namespace download { class SimpleDownloadManagerCoordinator; } // namespace download
diff --git a/chrome/browser/extensions/activity_log/activity_actions.cc b/chrome/browser/extensions/activity_log/activity_actions.cc index df83aa93..399915d0 100644 --- a/chrome/browser/extensions/activity_log/activity_actions.cc +++ b/chrome/browser/extensions/activity_log/activity_actions.cc
@@ -68,7 +68,7 @@ auto clone = base::MakeRefCounted<Action>( extension_id(), time(), action_type(), api_name(), action_id()); if (args()) - clone->set_args(base::WrapUnique(args()->DeepCopy())); + clone->set_args(args()->CreateDeepCopy()); clone->set_page_url(page_url()); clone->set_page_title(page_title()); clone->set_page_incognito(page_incognito());
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc index b8c17c17..cdd5609 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -2421,7 +2421,7 @@ " \"incognito\": false," " \"bytesReceived\": 0.0," " \"fileSize\": 0.0," - " \"mime\": \"\"," + " \"mime\": \"text/plain\"," " \"paused\": false," " \"url\": \"%s\"}]", download_url.c_str()))); @@ -2560,7 +2560,7 @@ item, download::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT, base::StringPrintf("[{\"danger\": \"safe\"," " \"incognito\": false," - " \"mime\": \"\"," + " \"mime\": \"text/plain\"," " \"paused\": false," " \"id\": %d," " \"url\": \"%s\"}]", @@ -2601,7 +2601,7 @@ item, download::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT, base::StringPrintf("[{\"danger\": \"safe\"," " \"incognito\": false," - " \"mime\": \"\"," + " \"mime\": \"text/plain\"," " \"paused\": false," " \"id\": %d," " \"url\": \"%s\"}]",
diff --git a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc index 5179a26..93cd9dfd 100644 --- a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc +++ b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc
@@ -304,10 +304,10 @@ #if defined(OS_MAC) // We need this on mac so we don't loose 2x representations from browser icon // in transformations gfx::ImageSkia -> NSImage -> gfx::ImageSkia. - std::vector<ui::ScaleFactor> supported_scale_factors; + std::vector<ui::ResourceScaleFactor> supported_scale_factors; supported_scale_factors.push_back(ui::SCALE_FACTOR_100P); supported_scale_factors.push_back(ui::SCALE_FACTOR_200P); - ui::SetSupportedScaleFactors(supported_scale_factors); + ui::SetSupportedResourceScaleFactors(supported_scale_factors); #endif // We should not be creating icons asynchronously, so we don't need an
diff --git a/chrome/browser/extensions/api/notifications/notifications_api.cc b/chrome/browser/extensions/api/notifications/notifications_api.cc index 3e5eece..7822dc72 100644 --- a/chrome/browser/extensions/api/notifications/notifications_api.cc +++ b/chrome/browser/extensions/api/notifications/notifications_api.cc
@@ -220,8 +220,8 @@ NotificationBitmapSizes bitmap_sizes = GetNotificationBitmapSizes(); - float image_scale = - ui::GetScaleForScaleFactor(ui::GetSupportedScaleFactors().back()); + float image_scale = ui::GetScaleForResourceScaleFactor( + ui::GetSupportedResourceScaleFactors().back()); // Extract required fields: type, title, message, and icon. message_center::NotificationType type = @@ -373,8 +373,8 @@ #endif NotificationBitmapSizes bitmap_sizes = GetNotificationBitmapSizes(); - float image_scale = - ui::GetScaleForScaleFactor(ui::GetSupportedScaleFactors().back()); + float image_scale = ui::GetScaleForResourceScaleFactor( + ui::GetSupportedResourceScaleFactors().back()); // Update optional fields if provided. if (options->type != api::notifications::TEMPLATE_TYPE_NONE)
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.cc b/chrome/browser/extensions/api/tabs/tabs_event_router.cc index 3f121134..fd2f9dd 100644 --- a/chrome/browser/extensions/api/tabs/tabs_event_router.cc +++ b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
@@ -472,8 +472,7 @@ Profile* profile = tab_strip_model->profile(); DispatchEvent(profile, events::TABS_ON_HIGHLIGHT_CHANGED, api::tabs::OnHighlightChanged::kEventName, - std::unique_ptr<base::ListValue>(args->DeepCopy()), - EventRouter::USER_GESTURE_UNKNOWN); + args->CreateDeepCopy(), EventRouter::USER_GESTURE_UNKNOWN); DispatchEvent(profile, events::TABS_ON_HIGHLIGHTED, api::tabs::OnHighlighted::kEventName, std::move(args), EventRouter::USER_GESTURE_UNKNOWN);
diff --git a/chrome/browser/extensions/chrome_content_verifier_delegate.cc b/chrome/browser/extensions/chrome_content_verifier_delegate.cc index e7eb2db..e0a7b87 100644 --- a/chrome/browser/extensions/chrome_content_verifier_delegate.cc +++ b/chrome/browser/extensions/chrome_content_verifier_delegate.cc
@@ -51,10 +51,9 @@ absl::optional<ChromeContentVerifierDelegate::VerifyInfo::Mode>& GetModeForTesting() { - static base::NoDestructor< - absl::optional<ChromeContentVerifierDelegate::VerifyInfo::Mode>> + static absl::optional<ChromeContentVerifierDelegate::VerifyInfo::Mode> testing_mode; - return *testing_mode; + return testing_mode; } const char kContentVerificationExperimentName[] =
diff --git a/chrome/browser/extensions/extension_icon_manager_unittest.cc b/chrome/browser/extensions/extension_icon_manager_unittest.cc index 77baff7..e3035d0e 100644 --- a/chrome/browser/extensions/extension_icon_manager_unittest.cc +++ b/chrome/browser/extensions/extension_icon_manager_unittest.cc
@@ -217,7 +217,7 @@ ASSERT_TRUE(extension); constexpr int kMaxIconSizeInManifest = 32; - std::vector<std::vector<ui::ScaleFactor>> supported_scales = { + std::vector<std::vector<ui::ResourceScaleFactor>> supported_scales = { // Base case. {ui::SCALE_FACTOR_100P}, // Two scale factors. @@ -235,8 +235,9 @@ // the logic in this test work, we need to set the scale factor to one of // the "supported" scales. ScopedSetDeviceScaleFactor scoped_dsf( - ui::GetScaleForScaleFactor(supported_scales[i][0])); - ui::test::ScopedSetSupportedScaleFactors scoped(supported_scales[i]); + ui::GetScaleForResourceScaleFactor(supported_scales[i][0])); + ui::test::ScopedSetSupportedResourceScaleFactors scoped( + supported_scales[i]); ExtensionIconManager icon_manager; icon_manager.set_observer(this); @@ -248,7 +249,8 @@ // icon. bool should_fall_back_to_default = true; for (auto supported_scale : supported_scales[i]) { - if (gfx::kFaviconSize * ui::GetScaleForScaleFactor(supported_scale) <= + if (gfx::kFaviconSize * + ui::GetScaleForResourceScaleFactor(supported_scale) <= kMaxIconSizeInManifest) { should_fall_back_to_default = false; break; @@ -263,8 +265,9 @@ for (int scale_factor_iter = ui::SCALE_FACTOR_NONE + 1; scale_factor_iter < ui::NUM_SCALE_FACTORS; ++scale_factor_iter) { - auto scale_factor = static_cast<ui::ScaleFactor>(scale_factor_iter); - float scale = ui::GetScaleForScaleFactor(scale_factor); + auto scale_factor = + static_cast<ui::ResourceScaleFactor>(scale_factor_iter); + float scale = ui::GetScaleForResourceScaleFactor(scale_factor); SCOPED_TRACE(testing::Message() << "Scale: " << scale); const bool has_representation = image_skia.HasRepresentation(scale);
diff --git a/chrome/browser/extensions/extension_web_ui.cc b/chrome/browser/extensions/extension_web_ui.cc index f23292d2..fa5dc9b 100644 --- a/chrome/browser/extensions/extension_web_ui.cc +++ b/chrome/browser/extensions/extension_web_ui.cc
@@ -592,7 +592,8 @@ pixel_size, ExtensionIconSet::MATCH_BIGGER); - ui::ScaleFactor resource_scale_factor = ui::GetSupportedScaleFactor(scale); + ui::ResourceScaleFactor resource_scale_factor = + ui::GetSupportedResourceScaleFactor(scale); if (!icon_resource.empty()) { info_list.push_back(extensions::ImageLoader::ImageRepresentation( icon_resource, @@ -609,10 +610,11 @@ gfx::ImageSkia placeholder_skia(placeholder_image.AsImageSkia()); // Ensure the ImageSkia has representation at all scales we would use for // favicons. - std::vector<ui::ScaleFactor> scale_factors = ui::GetSupportedScaleFactors(); + std::vector<ui::ResourceScaleFactor> scale_factors = + ui::GetSupportedResourceScaleFactors(); for (const auto& scale_factor : scale_factors) { placeholder_skia.GetRepresentation( - ui::GetScaleForScaleFactor(scale_factor)); + ui::GetScaleForResourceScaleFactor(scale_factor)); } RunFaviconCallbackAsync(std::move(callback), gfx::Image(placeholder_skia)); } else {
diff --git a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source_unittest.cc b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source_unittest.cc index 225bf2e..196e521c 100644 --- a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source_unittest.cc +++ b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source_unittest.cc
@@ -6,6 +6,7 @@ #include "base/run_loop.h" #include "base/test/bind.h" +#include "build/branding_buildflags.h" #include "build/build_config.h" #include "chrome/common/channel_info.h" #include "chrome/test/base/browser_with_test_window_test.h" @@ -16,6 +17,10 @@ #include "base/mac/mac_util.h" #endif +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && !defined(OS_CHROMEOS) +#include "chrome/test/base/scoped_channel_override.h" +#endif + namespace system_logs { namespace { @@ -42,6 +47,20 @@ response->at("CHROME VERSION")); } +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && !defined(OS_CHROMEOS) +TEST_F(ChromeInternalLogSourceTest, VersionTagContainsExtendedLabel) { + chrome::ScopedChannelOverride channel_override( + chrome::ScopedChannelOverride::Channel::kExtendedStable); + + ASSERT_TRUE(chrome::IsExtendedStableChannel()); + auto response = GetChromeInternalLogs(); + EXPECT_PRED_FORMAT2( + testing::IsSubstring, + chrome::GetVersionString(chrome::WithExtendedStable(true)), + response->at("CHROME VERSION")); +} +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) && !defined(OS_CHROMEOS) + #if defined(OS_MAC) TEST_F(ChromeInternalLogSourceTest, CpuTypePresentAndValid) { auto response = GetChromeInternalLogs();
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index b508ca8..9ed4ef9 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1976,6 +1976,11 @@ "expiry_milestone": 80 }, { + "name": "enable-holding-space-in-progress-downloads-integration", + "owners": [ "//ash/public/cpp/holding_space/OWNERS" ], + "expiry_milestone": 95 + }, + { "name": "enable-hostname-setting", "owners": [ "jhawkins" ], "expiry_milestone": 92 @@ -2202,9 +2207,14 @@ "expiry_milestone": 91 }, { - "name": "enable-ntp-memory-enhancement", - "owners": [ "adamta", "sczs" ], - "expiry_milestone": 96 + "name": "enable-ntp-memory-enhancement", + "owners": [ "adamta", "sczs" ], + "expiry_milestone": 96 + }, + { + "name": "enable-oauth-ipp", + "owners": [ "batrapranav", "pawliczek" ], + "expiry_milestone": 99 }, { "name": "enable-offline-previews", @@ -5127,6 +5137,11 @@ "expiry_milestone": 90 }, { + "name": "tab-groups-save", + "owners": [ "chrome-desktop-ui-sea@google.com", "cyan" ], + "expiry_milestone": 95 + }, + { "name": "tab-hover-card-images", "owners": [ "dfried", "corising", "//chrome/browser/ui/views/tabs/OWNERS" ], "expiry_milestone": 96
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 834cbaaf..743a8f60 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -2515,6 +2515,10 @@ "Causes a 'New' badge to appear on the entry point for creating a tab " "group in the tab context menu."; +const char kTabGroupsSaveName[] = "Tab Groups Save"; +const char kTabGroupsSaveDescription[] = + "Enables users to explicitly save and recall tab groups."; + const char kTabHoverCardImagesName[] = "Tab Hover Card Images"; const char kTabHoverCardImagesDescription[] = "Shows a preview image in tab hover cards, if tab hover cards are enabled."; @@ -4522,6 +4526,11 @@ const char kEnableNetworkingInDiagnosticsAppDescription[] = "Enable networking cards in the Diagnostics App"; +const char kEnableOAuthIppName[] = + "Enable OAuth when printing via the IPP protocol"; +const char kEnableOAuthIppDescription[] = + "Enable OAuth when printing via the IPP protocol"; + const char kEnableSuggestedFilesName[] = "Enable Suggested Files"; const char kEnableSuggestedFilesDescription[] = "Enable Suggested Files feature in Launcher, which will show file " @@ -4682,6 +4691,12 @@ "Hides media notifications for ARC apps. Requires " "#enable-media-session-notifications to be enabled."; +const char kHoldingSpaceInProgressDownloadsIntegrationName[] = + "Enable showing in-progress downloads in Tote."; +const char kHoldingSpaceInProgressDownloadsIntegrationDescription[] = + "Show in-progress download functionality in Tote to increase productivity " + "by giving users one place to go to monitor and access their downloads."; + const char kImeAssistAutocorrectName[] = "Enable assistive autocorrect"; const char kImeAssistAutocorrectDescription[] = "Enable assistive auto-correct features for native IME";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index a92d8bc..f82b18e 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1444,6 +1444,9 @@ extern const char kTabGroupsNewBadgePromoName[]; extern const char kTabGroupsNewBadgePromoDescription[]; +extern const char kTabGroupsSaveName[]; +extern const char kTabGroupsSaveDescription[]; + extern const char kTabHoverCardImagesName[]; extern const char kTabHoverCardImagesDescription[]; @@ -2598,6 +2601,9 @@ extern const char kEnableNetworkingInDiagnosticsAppName[]; extern const char kEnableNetworkingInDiagnosticsAppDescription[]; +extern const char kEnableOAuthIppName[]; +extern const char kEnableOAuthIppDescription[]; + extern const char kEnableSuggestedFilesName[]; extern const char kEnableSuggestedFilesDescription[]; @@ -2692,6 +2698,9 @@ extern const char kHideArcMediaNotificationsName[]; extern const char kHideArcMediaNotificationsDescription[]; +extern const char kHoldingSpaceInProgressDownloadsIntegrationName[]; +extern const char kHoldingSpaceInProgressDownloadsIntegrationDescription[]; + extern const char kImeAssistAutocorrectName[]; extern const char kImeAssistAutocorrectDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index e32c4f3..dbc4fb3a 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -268,7 +268,6 @@ &kVoiceButtonInTopToolbar, &kVrBrowsingFeedback, &kWebOtpCrossDeviceSimpleString, - &kPrefetchNotificationSchedulingIntegration, &content_creation::kWebNotesStylizeEnabled, &features::kDnsOverHttps, ¬ifications::features::kUseChimeAndroidSdk, @@ -739,10 +738,6 @@ "UpdateNotificationSchedulingIntegration", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kPrefetchNotificationSchedulingIntegration{ - "PrefetchNotificationSchedulingIntegration", - base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kUpdateNotificationScheduleServiceImmediateShowOption{ "UpdateNotificationScheduleServiceImmediateShowOption", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index df73f6b..47d31558 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -154,7 +154,6 @@ extern const base::Feature kVoiceButtonInTopToolbar; extern const base::Feature kVrBrowsingFeedback; extern const base::Feature kWebOtpCrossDeviceSimpleString; -extern const base::Feature kPrefetchNotificationSchedulingIntegration; } // namespace android } // namespace chrome
diff --git a/chrome/browser/media/webrtc/desktop_media_picker_manager.h b/chrome/browser/media/webrtc/desktop_media_picker_manager.h index 3919941..b51b51f 100644 --- a/chrome/browser/media/webrtc/desktop_media_picker_manager.h +++ b/chrome/browser/media/webrtc/desktop_media_picker_manager.h
@@ -6,13 +6,9 @@ #define CHROME_BROWSER_MEDIA_WEBRTC_DESKTOP_MEDIA_PICKER_MANAGER_H_ #include "base/macros.h" +#include "base/no_destructor.h" #include "base/observer_list.h" -namespace base { -template <typename T> -class NoDestructor; -} - // A singleton that acts as a rendezvous for dialog observers to register and // the dialog managers/delegates to post their activities. // TODO(crbug/953495): Merge this into DesktopMediaPickerFactoryImpl.
diff --git a/chrome/browser/metrics/perf/windowed_incognito_observer.h b/chrome/browser/metrics/perf/windowed_incognito_observer.h index 4dbcd10f..cea83ddc 100644 --- a/chrome/browser/metrics/perf/windowed_incognito_observer.h +++ b/chrome/browser/metrics/perf/windowed_incognito_observer.h
@@ -6,17 +6,13 @@ #define CHROME_BROWSER_METRICS_PERF_WINDOWED_INCOGNITO_OBSERVER_H_ #include "base/macros.h" +#include "base/no_destructor.h" #include "base/sequence_checker.h" #include "base/synchronization/lock.h" #include "chrome/browser/ui/browser_list_observer.h" class Browser; -namespace base { -template <class T> -class NoDestructor; -} // namespace base - namespace metrics { class WindowedIncognitoMonitor;
diff --git a/chrome/browser/nearby_sharing/certificates/test_util.cc b/chrome/browser/nearby_sharing/certificates/test_util.cc index def351d..c99e370 100644 --- a/chrome/browser/nearby_sharing/certificates/test_util.cc +++ b/chrome/browser/nearby_sharing/certificates/test_util.cc
@@ -181,15 +181,15 @@ } base::Time GetNearbyShareTestNotBefore() { - static const base::NoDestructor<base::Time> not_before( - base::Time::FromJavaTime(kTestNotBeforeMillis)); - return *not_before; + static const base::Time not_before = + base::Time::FromJavaTime(kTestNotBeforeMillis); + return not_before; } base::TimeDelta GetNearbyShareTestValidityOffset() { - static const base::NoDestructor<base::TimeDelta> offset( - base::TimeDelta::FromMilliseconds(kTestValidityOffsetMillis)); - return *offset; + static const base::TimeDelta offset = + base::TimeDelta::FromMilliseconds(kTestValidityOffsetMillis); + return offset; } const nearbyshare::proto::EncryptedMetadata& GetNearbyShareTestMetadata() {
diff --git a/chrome/browser/nearby_sharing/client/nearby_share_client_impl.cc b/chrome/browser/nearby_sharing/client/nearby_share_client_impl.cc index 26b8e09..92c27c9 100644 --- a/chrome/browser/nearby_sharing/client/nearby_share_client_impl.cc +++ b/chrome/browser/nearby_sharing/client/nearby_share_client_impl.cc
@@ -10,7 +10,6 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/memory/ptr_util.h" -#include "base/no_destructor.h" #include "base/strings/string_number_conversions.h" #include "chrome/browser/nearby_sharing/client/nearby_share_api_call_flow_impl.h" #include "chrome/browser/nearby_sharing/client/nearby_share_http_notifier.h" @@ -95,10 +94,10 @@ // TODO(crbug.com/1103471): Update "chrome_policy" when a Nearby Share // enterprise policy is created. const net::PartialNetworkTrafficAnnotationTag& GetUpdateDeviceAnnotation() { - static const base::NoDestructor<net::PartialNetworkTrafficAnnotationTag> - annotation(net::DefinePartialNetworkTrafficAnnotation( - "nearby_share_update_device", "oauth2_api_call_flow", - R"( + static const net::PartialNetworkTrafficAnnotationTag annotation = + net::DefinePartialNetworkTrafficAnnotation("nearby_share_update_device", + "oauth2_api_call_flow", + R"( semantics { sender: "Nearby Share" description: @@ -137,17 +136,17 @@ SigninAllowed: false } } - })")); - return *annotation; + })"); + return annotation; } // TODO(crbug.com/1103471): Update "chrome_policy" when a Nearby Share // enterprise policy is created. const net::PartialNetworkTrafficAnnotationTag& GetContactsAnnotation() { - static const base::NoDestructor<net::PartialNetworkTrafficAnnotationTag> - annotation(net::DefinePartialNetworkTrafficAnnotation( - "nearby_share_contacts", "oauth2_api_call_flow", - R"( + static const net::PartialNetworkTrafficAnnotationTag annotation = + net::DefinePartialNetworkTrafficAnnotation("nearby_share_contacts", + "oauth2_api_call_flow", + R"( semantics { sender: "Nearby Share" description: @@ -173,16 +172,16 @@ SigninAllowed: false } } - })")); - return *annotation; + })"); + return annotation; } // TODO(crbug.com/1103471): Update "chrome_policy" when a Nearby Share // enterprise policy is created. const net::PartialNetworkTrafficAnnotationTag& GetListPublicCertificatesAnnotation() { - static const base::NoDestructor<net::PartialNetworkTrafficAnnotationTag> - annotation(net::DefinePartialNetworkTrafficAnnotation( + static const net::PartialNetworkTrafficAnnotationTag annotation = + net::DefinePartialNetworkTrafficAnnotation( "nearby_share_list_public_certificates", "oauth2_api_call_flow", R"( semantics { @@ -213,8 +212,8 @@ SigninAllowed: false } } - })")); - return *annotation; + })"); + return annotation; } } // namespace
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_factory.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_factory.cc index f921c05..3d3018d 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_factory.cc +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_factory.cc
@@ -9,7 +9,6 @@ #include "base/feature_list.h" #include "base/memory/singleton.h" -#include "base/no_destructor.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/chromeos/nearby/nearby_process_manager_factory.h" @@ -34,8 +33,8 @@ constexpr char kServiceName[] = "NearbySharingService"; absl::optional<bool>& IsSupportedTesting() { - static base::NoDestructor<absl::optional<bool>> is_supported; - return *is_supported; + static absl::optional<bool> is_supported; + return is_supported; } } // namespace
diff --git a/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc b/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc index 5198b699..cea656a 100644 --- a/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc +++ b/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc
@@ -18,7 +18,6 @@ #include "chrome/browser/ntp_tiles/chrome_custom_links_manager_factory.h" #include "chrome/browser/ntp_tiles/chrome_popular_sites_factory.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/search/suggestions/suggestions_service_factory.h" #include "chrome/common/buildflags.h" #include "components/history/core/browser/top_sites.h" #include "components/image_fetcher/core/image_fetcher_impl.h" @@ -38,8 +37,6 @@ #include "chrome/browser/supervised_user/supervised_user_url_filter.h" #endif -using suggestions::SuggestionsServiceFactory; - #if BUILDFLAG(ENABLE_SUPERVISED_USERS) namespace { @@ -119,7 +116,6 @@ auto most_visited_sites = std::make_unique<ntp_tiles::MostVisitedSites>( profile->GetPrefs(), TopSitesFactory::GetForProfile(profile), - SuggestionsServiceFactory::GetForProfile(profile), #if defined(OS_ANDROID) ChromePopularSitesFactory::NewForProfile(profile), #else
diff --git a/chrome/browser/payments/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestIntegrationTest.java b/chrome/browser/payments/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestIntegrationTest.java index 29542630..574defe 100644 --- a/chrome/browser/payments/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestIntegrationTest.java +++ b/chrome/browser/payments/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestIntegrationTest.java
@@ -91,6 +91,10 @@ ShadowPaymentFeatureList.setFeatureEnabled( PaymentFeatureList.WEB_PAYMENTS_SINGLE_APP_UI_SKIP, true); + ShadowPaymentFeatureList.setFeatureEnabled( + PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION, true); + ShadowPaymentFeatureList.setFeatureEnabled( + PaymentFeatureList.WEB_PAYMENTS_EXPERIMENTAL_FEATURES, true); PaymentRequestService.resetShowingPaymentRequestForTest(); PaymentAppService.getInstance().resetForTest();
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_origin_prober.cc b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_origin_prober.cc index 5c8cb6b..8c4c5b9 100644 --- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_origin_prober.cc +++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_origin_prober.cc
@@ -6,7 +6,6 @@ #include "base/bind.h" #include "base/feature_list.h" -#include "base/no_destructor.h" #include "base/strings/string_util.h" #include "base/task/post_task.h" #include "chrome/browser/availability/availability_prober.h" @@ -224,13 +223,13 @@ }; CanaryCheckDelegate* GetCanaryCheckDelegate() { - static base::NoDestructor<CanaryCheckDelegate> delegate; - return delegate.get(); + static CanaryCheckDelegate delegate; + return &delegate; } OriginProbeDelegate* GetOriginProbeDelegate() { - static base::NoDestructor<OriginProbeDelegate> delegate; - return delegate.get(); + static OriginProbeDelegate delegate; + return &delegate; } // Allows probing to start after a delay so that browser start isn't slowed.
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc index cbe686c..7f35eb1 100644 --- a/chrome/browser/printing/print_job.cc +++ b/chrome/browser/printing/print_job.cc
@@ -43,7 +43,7 @@ namespace { -// Helper function to ensure |job| is valid until at least |callback| returns. +// Helper function to ensure `job` is valid until at least `callback` returns. void HoldRefCallback(scoped_refptr<PrintJob> job, base::OnceClosure callback) { std::move(callback).Run(); } @@ -138,18 +138,19 @@ document()->DebugDumpData(print_data.get(), FILE_PATH_LITERAL(".pdf")); const PrintSettings& settings = document()->settings(); - if (settings.printer_is_textonly()) { + if (settings.printer_language_is_textonly()) { StartPdfToTextConversion(print_data, page_size); - } else if (settings.printer_is_ps2() || settings.printer_is_ps3()) { + } else if (settings.printer_language_is_ps2() || + settings.printer_language_is_ps3()) { StartPdfToPostScriptConversion(print_data, content_area, physical_offsets, - settings.printer_is_ps2()); + settings.printer_language_is_ps2()); } else { StartPdfToEmfConversion(print_data, page_size, content_area); } // Indicate that the PDF is fully rendered and we no longer need the renderer // and web contents, so the print job does not need to be cancelled if they - // die. This is needed on Windows because the PrintedDocument will not be + // die. This is needed on Windows because the `PrintedDocument` will not be // considered complete until PDF conversion finishes. document()->SetConvertingPdf(); } @@ -179,7 +180,7 @@ return; } - // Real work is done in PrintJobWorker::StartPrinting(). + // Real work is done in `PrintJobWorker::StartPrinting()`. worker_->PostTask( FROM_HERE, base::BindOnce(&HoldRefCallback, base::WrapRefCounted(this), base::BindOnce(&PrintJobWorker::StartPrinting, @@ -231,7 +232,7 @@ // InvokeLater since it would take too much time. worker_->Cancel(); } - // Make sure a Cancel() is broadcast. + // Make sure a `Cancel()` is broadcast. auto details = base::MakeRefCounted<JobEventDetails>(JobEventDetails::FAILED, 0, nullptr); content::NotificationService::current()->Notify( @@ -349,11 +350,11 @@ // seems to work with the fix for this bug applied. const PrintSettings& settings = document()->settings(); bool print_text_with_gdi = - settings.print_text_with_gdi() && !settings.printer_is_xps() && + settings.print_text_with_gdi() && !settings.printer_language_is_xps() && base::FeatureList::IsEnabled(::features::kGdiTextPrinting); // TODO(thestig): Figure out why crbug.com/1083911 occurred, which is likely - // because |web_contents| was null. As a result, this section has many more + // because `web_contents` was null. As a result, this section has many more // pointer checks to avoid crashing. content::WebContents* web_contents = worker_->GetWebContents(); content::BrowserContext* context = @@ -516,7 +517,7 @@ break; } case JobEventDetails::DOC_DONE: { - // This will call Stop() and broadcast a JOB_DONE message. + // This will call `Stop()` and broadcast a `JOB_DONE` message. content::GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(&PrintJob::OnDocumentDone, this)); break; @@ -541,7 +542,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); // Be sure to live long enough. The instance could be destroyed by the - // JOB_DONE broadcast. + // `JOB_DONE` broadcast. scoped_refptr<PrintJob> handle(this); // Stop the worker thread.
diff --git a/chrome/browser/printing/print_view_manager_unittest.cc b/chrome/browser/printing/print_view_manager_unittest.cc index 1e236cc..000c2ce 100644 --- a/chrome/browser/printing/print_view_manager_unittest.cc +++ b/chrome/browser/printing/print_view_manager_unittest.cc
@@ -26,6 +26,10 @@ #include "mojo/public/cpp/bindings/associated_remote.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#if defined(OS_WIN) +#include "printing/mojom/print.mojom.h" +#endif + namespace printing { using PrintViewManagerTest = BrowserWithTestWindowTest; @@ -34,16 +38,18 @@ public: explicit TestPrintViewManager(content::WebContents* web_contents) : PrintViewManagerBase(web_contents) {} + TestPrintViewManager(const TestPrintViewManager&) = delete; + TestPrintViewManager& operator=(const TestPrintViewManager&) = delete; ~TestPrintViewManager() override { - // Set this null here. Otherwise, the PrintViewManagerBase destructor will - // try to de-register for notifications that were not registered for in - // CreateNewPrintJob(). + // Set this null here. Otherwise, the `PrintViewManagerBase` destructor + // will try to de-register for notifications that were not registered for + // in `CreateNewPrintJob()`. print_job_ = nullptr; } - // Mostly copied from PrintViewManager::PrintPreviewNow(). We can't override - // PrintViewManager since it is a user data class. + // Mostly copied from `PrintViewManager::PrintPreviewNow()`. We can't + // override `PrintViewManager` since it is a user data class. bool PrintPreviewNow(content::RenderFrameHost* rfh, bool has_selection) { // Don't print / print preview crashed tabs. if (IsCrashed()) @@ -66,7 +72,7 @@ } #if defined(OS_WIN) - PrintSettings::PrinterType type() { return test_job()->type(); } + mojom::PrinterLanguageType type() { return test_job()->type(); } #endif // Ends the run loop. @@ -84,7 +90,7 @@ } protected: - // Override to create a TestPrintJob instead of a real one. + // Override to create a `TestPrintJob` instead of a real one. bool CreateNewPrintJob(std::unique_ptr<PrinterQuery> query) override { print_job_ = base::MakeRefCounted<TestPrintJob>(); print_job_->Initialize(std::move(query), RenderSourceName(), @@ -115,8 +121,6 @@ } base::RunLoop* run_loop_ = nullptr; - - DISALLOW_COPY_AND_ASSIGN(TestPrintViewManager); }; TEST_F(PrintViewManagerTest, PrintSubFrameAndDestroy) { @@ -142,14 +146,15 @@ } #if defined(OS_WIN) -// Verifies that StartPdfToPostScriptConversion is called with the correct +// Verifies that `StartPdfToPostScriptConversion` is called with the correct // printable area offsets. See crbug.com/821485. TEST_F(PrintViewManagerTest, PostScriptHasCorrectOffsets) { scoped_refptr<TestPrintQueriesQueue> queue = base::MakeRefCounted<TestPrintQueriesQueue>(); // Setup PostScript printer with printable area offsets of 0.1in. - queue->SetupPrinterType(PrintSettings::PrinterType::TYPE_POSTSCRIPT_LEVEL2); + queue->SetupPrinterLanguageType( + mojom::PrinterLanguageType::kPostscriptLevel2); int offset_in_pixels = static_cast<int>(kTestPrinterDpi * 0.1f); queue->SetupPrinterOffsets(offset_in_pixels, offset_in_pixels); g_browser_process->print_job_manager()->SetQueueForTest(queue); @@ -181,7 +186,7 @@ EXPECT_EQ(gfx::Point(60, 60), print_view_manager->physical_offsets()); EXPECT_EQ(gfx::Rect(0, 0, 5100, 6600), print_view_manager->content_area()); - EXPECT_EQ(PrintSettings::PrinterType::TYPE_POSTSCRIPT_LEVEL2, + EXPECT_EQ(mojom::PrinterLanguageType::kPostscriptLevel2, print_view_manager->type()); } #endif
diff --git a/chrome/browser/printing/test_print_job.cc b/chrome/browser/printing/test_print_job.cc index 022bcc33..2b6ee7e 100644 --- a/chrome/browser/printing/test_print_job.cc +++ b/chrome/browser/printing/test_print_job.cc
@@ -14,6 +14,10 @@ #include "printing/printed_document.h" #include "ui/gfx/geometry/size.h" +#if defined(OS_WIN) +#include "printing/mojom/print.mojom.h" +#endif + namespace printing { void TestPrintJob::Initialize(std::unique_ptr<PrinterQuery> query, @@ -54,7 +58,7 @@ const gfx::Rect& content_area) { page_size_ = page_size; content_area_ = content_area; - type_ = PrintSettings::PrinterType::TYPE_NONE; + type_ = mojom::PrinterLanguageType::kNone; } void TestPrintJob::StartPdfToPostScriptConversion( @@ -64,15 +68,15 @@ bool ps_level2) { content_area_ = content_area; physical_offsets_ = physical_offsets; - type_ = ps_level2 ? PrintSettings::PrinterType::TYPE_POSTSCRIPT_LEVEL2 - : PrintSettings::PrinterType::TYPE_POSTSCRIPT_LEVEL3; + type_ = ps_level2 ? mojom::PrinterLanguageType::kPostscriptLevel2 + : mojom::PrinterLanguageType::kPostscriptLevel3; } void TestPrintJob::StartPdfToTextConversion( scoped_refptr<base::RefCountedMemory> bytes, const gfx::Size& page_size) { page_size_ = page_size; - type_ = PrintSettings::PrinterType::TYPE_TEXTONLY; + type_ = mojom::PrinterLanguageType::kTextOnly; } #endif // defined(OS_WIN)
diff --git a/chrome/browser/printing/test_print_job.h b/chrome/browser/printing/test_print_job.h index c1fa0d2..491e65d 100644 --- a/chrome/browser/printing/test_print_job.h +++ b/chrome/browser/printing/test_print_job.h
@@ -13,41 +13,45 @@ #include "chrome/browser/printing/print_job.h" #include "printing/print_settings.h" +#if defined(OS_WIN) +#include "printing/mojom/print.mojom.h" +#endif + namespace printing { class PrinterQuery; class TestPrintJob : public PrintJob { public: - // Create a empty PrintJob. When initializing with this constructor, - // post-constructor initialization must be done with Initialize(). + // Create an empty `PrintJob`. When initializing with this constructor, + // post-constructor initialization must be done with `Initialize()`. TestPrintJob() = default; - // Getters for values stored by TestPrintJob in Start...Converter functions. + // Getters for values stored by `TestPrintJob` in Start...Converter functions. const gfx::Size& page_size() const { return page_size_; } const gfx::Rect& content_area() const { return content_area_; } const gfx::Point& physical_offsets() const { return physical_offsets_; } #if defined(OS_WIN) - PrintSettings::PrinterType type() const { return type_; } + mojom::PrinterLanguageType type() const { return type_; } #endif - // content::NotificationObserver implementation. Deliberately empty. + // `content::NotificationObserver` implementation. Deliberately empty. void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) override {} - // All remaining functions are PrintJob implementation. + // All remaining functions are `PrintJob` implementation. void Initialize(std::unique_ptr<PrinterQuery> query, const std::u16string& name, uint32_t page_count) override; - // Sets |job_pending_| to true. + // Sets `job_pending_` to true. void StartPrinting() override; - // Sets |job_pending_| to false and deletes the worker. + // Sets `job_pending_` to false and deletes the worker. void Stop() override; - // Sets |job_pending_| to false and deletes the worker. + // Sets `job_pending_` to false and deletes the worker. void Cancel() override; // Intentional no-op, returns true. @@ -77,7 +81,7 @@ gfx::Rect content_area_; gfx::Point physical_offsets_; #if defined(OS_WIN) - PrintSettings::PrinterType type_; + mojom::PrinterLanguageType type_; #endif };
diff --git a/chrome/browser/printing/test_printer_query.cc b/chrome/browser/printing/test_printer_query.cc index 82572a5..028bd4c 100644 --- a/chrome/browser/printing/test_printer_query.cc +++ b/chrome/browser/printing/test_printer_query.cc
@@ -15,6 +15,10 @@ #include "printing/print_settings_conversion.h" #include "printing/units.h" +#if defined(OS_WIN) +#include "printing/mojom/print.mojom.h" +#endif + namespace printing { std::unique_ptr<PrinterQuery> TestPrintQueriesQueue::CreatePrinterQuery( @@ -23,7 +27,7 @@ auto test_query = std::make_unique<TestPrinterQuery>(render_process_id, render_frame_id); #if defined(OS_WIN) - test_query->SetPrinterType(printer_type_); + test_query->SetPrinterLanguageType(printer_language_type_); #endif test_query->SetPrintableAreaOffsets(printable_offset_x_, printable_offset_y_); @@ -36,8 +40,9 @@ } #if defined(OS_WIN) -void TestPrintQueriesQueue::SetupPrinterType(PrintSettings::PrinterType type) { - printer_type_ = type; +void TestPrintQueriesQueue::SetupPrinterLanguageType( + mojom::PrinterLanguageType type) { + printer_language_type_ = type; } #endif @@ -50,7 +55,7 @@ base::OnceClosure callback) { DCHECK(offsets_); #if defined(OS_WIN) - DCHECK(printer_type_); + DCHECK(printer_language_type_); #endif std::unique_ptr<PrintSettings> settings = PrintSettingsFromJobSettings(new_settings); @@ -71,15 +76,15 @@ paper_rect.Inset(offsets_->x(), offsets_->y()); settings->SetPrinterPrintableArea(paper_size, paper_rect, true); #if defined(OS_WIN) - settings->set_printer_type(*printer_type_); + settings->set_printer_language_type(*printer_language_type_); #endif GetSettingsDone(std::move(callback), std::move(settings), result); } #if defined(OS_WIN) -void TestPrinterQuery::SetPrinterType(PrintSettings::PrinterType type) { - printer_type_ = type; +void TestPrinterQuery::SetPrinterLanguageType(mojom::PrinterLanguageType type) { + printer_language_type_ = type; } #endif
diff --git a/chrome/browser/printing/test_printer_query.h b/chrome/browser/printing/test_printer_query.h index 88ca62b..5199a20 100644 --- a/chrome/browser/printing/test_printer_query.h +++ b/chrome/browser/printing/test_printer_query.h
@@ -14,61 +14,69 @@ #include "chrome/browser/printing/print_job_manager.h" #include "chrome/browser/printing/printer_query.h" +#if defined(OS_WIN) +#include "printing/mojom/print.mojom.h" +#endif + namespace printing { class TestPrintQueriesQueue : public PrintQueriesQueue { public: TestPrintQueriesQueue() = default; + TestPrintQueriesQueue(const TestPrintQueriesQueue&) = delete; + TestPrintQueriesQueue& operator=(const TestPrintQueriesQueue&) = delete; - // Creates a TestPrinterQuery. Sets up the printer query with the printer - // settings indicated by |printable_offset_x_|, |printable_offset_y_|, and - // |printer_type_|. + // Creates a `TestPrinterQuery`. Sets up the printer query with the printer + // settings indicated by `printable_offset_x_`, `printable_offset_y_`, and + // `print_driver_type_`. std::unique_ptr<PrinterQuery> CreatePrinterQuery( int render_process_id, int render_frame_id) override; - // Sets the printer's printable area offsets to |offset_x| and |offset_y|, + // Sets the printer's printable area offsets to `offset_x` and `offset_y`, // which should be in pixels. Used to fill in printer settings that would - // normally be filled in by the backend |PrintingContext|. + // normally be filled in by the backend `PrintingContext`. void SetupPrinterOffsets(int offset_x, int offset_y); #if defined(OS_WIN) - // Sets the printer type to |type|. Used to fill in printer settings that - // would normally be filled in by the backend |PrintingContext|. - void SetupPrinterType(PrintSettings::PrinterType type); + // Sets the printer type to `type`. Used to fill in printer settings that + // would normally be filled in by the backend `PrintingContext`. + void SetupPrinterLanguageType(mojom::PrinterLanguageType type); #endif private: ~TestPrintQueriesQueue() override {} #if defined(OS_WIN) - PrintSettings::PrinterType printer_type_; + mojom::PrinterLanguageType printer_language_type_; #endif int printable_offset_x_; int printable_offset_y_; - - DISALLOW_COPY_AND_ASSIGN(TestPrintQueriesQueue); }; class TestPrinterQuery : public PrinterQuery { public: - // Can only be called on the IO thread, since this inherits from PrinterQuery. + // Can only be called on the IO thread, since this inherits from + // `PrinterQuery`. TestPrinterQuery(int render_process_id, int render_frame_id); + TestPrinterQuery(const TestPrinterQuery&) = delete; + TestPrinterQuery& operator=(const TestPrinterQuery&) = delete; ~TestPrinterQuery() override; - // Updates the current settings with |new_settings| dictionary values. Also - // fills in the settings with values from |offsets_| and |printer_type_| that - // would normally be filled in by the PrintingContext. + // Updates the current settings with `new_settings` dictionary values. Also + // fills in the settings with values from `offsets_` and `printer_type_` that + // would normally be filled in by the `PrintingContext`. void SetSettings(base::Value new_settings, base::OnceClosure callback) override; #if defined(OS_WIN) - // Sets |printer_type_| to |type|. Should be called before SetSettings(). - void SetPrinterType(PrintSettings::PrinterType type); + // Sets `printer_language_type_` to `type`. Should be called before + // `SetSettings()`. + void SetPrinterLanguageType(mojom::PrinterLanguageType type); #endif - // Sets printer offsets to |offset_x| and |offset_y|, which should be in DPI. - // Should be called before SetSettings(). + // Sets printer offsets to `offset_x` and `offset_y`, which should be in DPI. + // Should be called before `SetSettings()`. void SetPrintableAreaOffsets(int offset_x, int offset_y); // Intentional no-op. @@ -77,10 +85,8 @@ private: absl::optional<gfx::Point> offsets_; #if defined(OS_WIN) - absl::optional<PrintSettings::PrinterType> printer_type_; + absl::optional<mojom::PrinterLanguageType> printer_language_type_; #endif - - DISALLOW_COPY_AND_ASSIGN(TestPrinterQuery); }; } // namespace printing
diff --git a/chrome/browser/privacy_budget/BUILD.gn b/chrome/browser/privacy_budget/BUILD.gn index 74f90314..7aed98b 100644 --- a/chrome/browser/privacy_budget/BUILD.gn +++ b/chrome/browser/privacy_budget/BUILD.gn
@@ -6,6 +6,7 @@ sources = [ "encountered_surface_tracker.h", "identifiability_study_state.h", + "mesa_distribution.h", "privacy_budget_metrics_provider.h", "privacy_budget_prefs.h", "privacy_budget_ukm_entry_filter.h", @@ -51,6 +52,7 @@ "encountered_surface_tracker_unittest.cc", "identifiability_study_state_unittest.cc", "inspectable_identifiability_study_state.h", + "mesa_distribution_unittest.cc", "privacy_budget_metrics_provider_unittest.cc", "privacy_budget_ukm_entry_filter_unittest.cc", ]
diff --git a/chrome/browser/privacy_budget/identifiability_study_state.h b/chrome/browser/privacy_budget/identifiability_study_state.h index 583997c..79b051be 100644 --- a/chrome/browser/privacy_budget/identifiability_study_state.h +++ b/chrome/browser/privacy_budget/identifiability_study_state.h
@@ -12,6 +12,7 @@ #include "chrome/browser/privacy_budget/encountered_surface_tracker.h" #include "chrome/browser/privacy_budget/privacy_budget_prefs.h" #include "chrome/common/privacy_budget/privacy_budget_settings_provider.h" +#include "chrome/common/privacy_budget/types.h" #include "components/prefs/pref_service.h" #include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h" #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" @@ -108,10 +109,6 @@ private: friend class test_utils::InspectableIdentifiabilityStudyState; - using IdentifiableSurfaceSet = - PrivacyBudgetSettingsProvider::IdentifiableSurfaceSet; - using IdentifiableSurfaceTypeSet = - PrivacyBudgetSettingsProvider::IdentifiableSurfaceTypeSet; using SurfaceSelectionRateMap = base::flat_map<blink::IdentifiableSurface, int,
diff --git a/chrome/browser/privacy_budget/identifiability_study_state_unittest.cc b/chrome/browser/privacy_budget/identifiability_study_state_unittest.cc index 731bd00c..a5fabcf 100644 --- a/chrome/browser/privacy_budget/identifiability_study_state_unittest.cc +++ b/chrome/browser/privacy_budget/identifiability_study_state_unittest.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/privacy_budget/privacy_budget_prefs.h" #include "chrome/common/privacy_budget/privacy_budget_features.h" #include "chrome/common/privacy_budget/scoped_privacy_budget_config.h" +#include "chrome/common/privacy_budget/types.h" #include "components/prefs/pref_service.h" #include "components/prefs/testing_pref_service.h" #include "testing/gtest/include/gtest/gtest.h" @@ -52,12 +53,6 @@ return base::JoinString(list_as_strings, ","); } -// Make names short -using IdentifiableSurfaceSet = - test_utils::InspectableIdentifiabilityStudyState::IdentifiableSurfaceSet; -using IdentifiableSurfaceTypeSet = test_utils:: - InspectableIdentifiabilityStudyState::IdentifiableSurfaceTypeSet; - } // namespace class IdentifiabilityStudyStateTest : public ::testing::Test {
diff --git a/chrome/browser/privacy_budget/inspectable_identifiability_study_state.h b/chrome/browser/privacy_budget/inspectable_identifiability_study_state.h index 8ef2525..b94506d 100644 --- a/chrome/browser/privacy_budget/inspectable_identifiability_study_state.h +++ b/chrome/browser/privacy_budget/inspectable_identifiability_study_state.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_PRIVACY_BUDGET_INSPECTABLE_IDENTIFIABILITY_STUDY_STATE_H_ #include "chrome/browser/privacy_budget/identifiability_study_state.h" +#include "chrome/common/privacy_budget/types.h" namespace test_utils { @@ -13,9 +14,6 @@ // internals. Use this as a last resort. class InspectableIdentifiabilityStudyState : public IdentifiabilityStudyState { public: - using IdentifiabilityStudyState::IdentifiableSurfaceSet; - using IdentifiabilityStudyState::IdentifiableSurfaceTypeSet; - explicit InspectableIdentifiabilityStudyState(PrefService* pref_service) : IdentifiabilityStudyState(pref_service) {}
diff --git a/chrome/browser/privacy_budget/mesa_distribution.h b/chrome/browser/privacy_budget/mesa_distribution.h new file mode 100644 index 0000000..5b9ca44 --- /dev/null +++ b/chrome/browser/privacy_budget/mesa_distribution.h
@@ -0,0 +1,114 @@ +// 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. + +#ifndef CHROME_BROWSER_PRIVACY_BUDGET_MESA_DISTRIBUTION_H_ +#define CHROME_BROWSER_PRIVACY_BUDGET_MESA_DISTRIBUTION_H_ + +#include <random> +#include <set> +#include <type_traits> + +#include "base/containers/contains.h" + +// Generates a set of integers drawn from a mesa shaped probability distribution +// with replacement. +// +// The PDF is: +// +// ⎧ 0 ... if x < 0 +// ⎪ +// ⎪ λ ... if 0 <= x < T +// P(x) = ⎨ +// ⎪ λ (1 - γ)⁽ˣ⁻ᵀ⁾ ... otherwise +// ⎪ +// ⎩ +// where ... +// +// T = Value at which the PDF switches from a uniform to a geometric +// distribution. Referred to in code as the `pivot_point`. +// +// τ = Ratio of probability between linear region of the PDF. I.e. if τ = 0.9, +// then 90% of the probability space is in the linear region. The ratio is +// referred to in code as `dist_ratio`. +// +// τ +// λ = ─── +// T +// +// λ τ +// γ = ───── = ─────────── +// 1 - τ T * (1 - τ) +// +// In otherwords, the PDF is uniform up to T with a probability of λ, and then +// switches to a geometric distribution with parameter λ that extends to +// infinity. +// +// It looks like this in the form of a graph which should make a little bit more +// sense. +// +// P(x) ▲ +// │ +// probability λ│┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┬, +// density │ uniform ┊ L geometric +// │ distribution ┊ "._ distribution +// │ ┊ `--..______ +// └────────────────┴──────────────────▶ x +// 0 T +// +// Why this odd combination of disjoint probability distributions? +// +// Such a distribution is useful when you want to select some set of elements +// uniformly up to a threshold, but want to allow for a tail distribution that +// extends arbitrarily past that range. +// +// The τ parameter establishes the balance between the linear region and the +// geometric region, while T establishes the scale. Typically we set τ to +// something close to 0.9 or so such that 0.1 of the probability space is +// reserved for the long tail. +// +// Parameters: +// pivot_point: T as described above. Arbitrary range. +// dist_ratio : τ as described above. Must be in (0,1). +template <typename ResultType, + std::enable_if_t<std::is_integral<ResultType>::value, int> = 0> +class MesaDistribution { + public: + MesaDistribution(ResultType pivot_point, double dist_ratio) + : pivot_point_(pivot_point), + uniform_distribution_(0, std::ceil(pivot_point / dist_ratio)), + geometric_distribution_(dist_ratio / + (pivot_point * (1.0l - dist_ratio))) {} + ~MesaDistribution() = default; + + // Draws a single value from the distribution. + // + // `Generator` must satisfy `UniformRandomBitGenerator`. + // https://en.cppreference.com/w/cpp/named_req/UniformRandomBitGenerator + template <class Generator> + ResultType Get(Generator& g) { + ResultType v = uniform_distribution_(g); + if (v >= pivot_point_) + return pivot_point_ + geometric_distribution_(g); + return v; + } + + // RandomNumberDistribution. + // https://en.cppreference.com/w/cpp/named_req/RandomNumberDistribution + // + // `Generator` must satisfy `UniformRandomBitGenerator`. + // https://en.cppreference.com/w/cpp/named_req/UniformRandomBitGenerator + template <class Generator> + ResultType operator()(Generator g) { + return Get(g); + } + + ResultType pivot_point() const { return pivot_point_; } + + private: + const ResultType pivot_point_; + std::uniform_int_distribution<ResultType> uniform_distribution_; + std::geometric_distribution<ResultType> geometric_distribution_; +}; + +#endif // CHROME_BROWSER_PRIVACY_BUDGET_MESA_DISTRIBUTION_H_
diff --git a/chrome/browser/privacy_budget/mesa_distribution_unittest.cc b/chrome/browser/privacy_budget/mesa_distribution_unittest.cc new file mode 100644 index 0000000..820df06e --- /dev/null +++ b/chrome/browser/privacy_budget/mesa_distribution_unittest.cc
@@ -0,0 +1,101 @@ +// 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. + +#include "chrome/browser/privacy_budget/mesa_distribution.h" +#include <math.h> + +#include <array> +#include <limits> +#include <random> +#include <set> + +#include "base/rand_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { +constexpr auto kSeed = 3; +constexpr auto kPivotPoint = 300; +constexpr auto kDistRatio = 0.9l; +} // namespace + +TEST(MesaDistributionTest, Get) { + MesaDistribution<int> mesa(kPivotPoint, kDistRatio); + std::mt19937 g(kSeed); + auto v1 = mesa.Get(g); + g.seed(kSeed); + auto v2 = mesa.Get(g); + EXPECT_EQ(v1, v2); +} + +// This test asserts that the MesaDistribution produces a near ideal +// distribution of offset selections. +// +// We do this by drawing a very large number of samples from MesaDistribution in +// the presence of a fairly good PRNG and verifying that the resulting +// probability distribution is within a close margin of the ideal distribution. +// +// In order to pass the test, the simulation must result in an aggregate +// probability distribution that's within ε of the ideal distribution. +// +// The PRNG is MT19937 with a fixed seed. +TEST(MesaDistributionTest, SpreadTest_MaybeSlow) { + constexpr auto kTrials = 10'000'000lu; + + // We truncate the distribution at kMaxOffset, or else we'd need to keep + // occurrence counts for over a very large range. + // + // Truncation changes the probability distribution as a side-effect. Observed + // probability density increases by a factor of 1 / CDF(kMaxOffset) where CDF + // is the cumulative distribution function for Mesa. However beyond + // 2 * kPivotPoint the CDF is incalculably close to 1. + constexpr auto kMaxOffset = kPivotPoint * 3; + + // Lambda corresponds to λ in the description in mesa_distribution.h + // explaining the distribution. It's the probability density within the linear + // region of the distribution. + const auto kLambda = kDistRatio / kPivotPoint; + + // Gamma corresponds to γ in the description in mesa_distribution.h. It's the + // parameter to the Geometric distribution in the tail region. + const auto kGamma = kLambda / (1 - kDistRatio); + + // kEpsilon is the maximum absolute error in probability per element. We + // expect the experiment below to produce values within 5% of the linear + // region density. + const double kEpsilon = kLambda * 0.05 /* ±5% envelope */; + + // occurrence[i] := the number of times we've seen `i`. + std::array<double, kMaxOffset + 1> occurrences = {0.0}; + + // The distribution under test: + MesaDistribution<int> mesa(kPivotPoint, kDistRatio); + + std::mt19937 random_bit_generator(kSeed); + + for (auto i = 0u; i < kTrials; ++i) { + auto v = mesa.Get(random_bit_generator); + if (v > kMaxOffset) + continue; + ++occurrences[v]; + } + + // `occurrences` is a histogram of seen values. This loop converts it to + // a probability. + for (double& occurrence : occurrences) + occurrence /= kTrials; + + // Offsets from 0 thru `kPivotPoint - 1` (inclusive) should have the same + // probability. I.e. uniform. + for (int i = 0; i < kPivotPoint; ++i) { + ASSERT_NEAR(occurrences[i], kLambda, kEpsilon) << "at offset" << i; + } + + // Offsets from `kPivotPoint` thru infinity should follow a geometric + // distribution. We compare the observed probabilities with the Geometric PDF. + double expected_pdf = kLambda; + for (int i = kPivotPoint; i <= kMaxOffset; ++i) { + ASSERT_NEAR(occurrences[i], expected_pdf, kEpsilon) << "at offset" << i; + expected_pdf *= 1.0l - kGamma; + } +}
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 5699573..c220381 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -71,7 +71,6 @@ #include "chrome/browser/profiles/guest_signin_observer_factory.h" #include "chrome/browser/profiles/renderer_updater_factory.h" #include "chrome/browser/safe_browsing/certificate_reporting_service_factory.h" -#include "chrome/browser/search/suggestions/suggestions_service_factory.h" #include "chrome/browser/search_engines/template_url_fetcher_factory.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/send_tab_to_self/send_tab_to_self_client_service_factory.h" @@ -470,7 +469,6 @@ #if !defined(OS_ANDROID) StorageNotificationServiceFactory::GetInstance(); #endif - suggestions::SuggestionsServiceFactory::GetInstance(); #if BUILDFLAG(ENABLE_SUPERVISED_USERS) SupervisedUserServiceFactory::GetInstance(); #endif
diff --git a/chrome/browser/resources/pdf/controller.js b/chrome/browser/resources/pdf/controller.js index c5eed00..95dca320 100644 --- a/chrome/browser/resources/pdf/controller.js +++ b/chrome/browser/resources/pdf/controller.js
@@ -466,7 +466,7 @@ async load(fileName, data) { const url = URL.createObjectURL(new Blob([data])); this.plugin_.removeAttribute('headers'); - this.plugin_.setAttribute('stream-url', url); + this.plugin_.setAttribute('src', url); this.plugin_.setAttribute('has-edits', ''); this.plugin_.style.display = 'block'; try {
diff --git a/chrome/browser/resources/pdf/pdf_viewer_base.js b/chrome/browser/resources/pdf/pdf_viewer_base.js index 4c1b28c..23a3520 100644 --- a/chrome/browser/resources/pdf/pdf_viewer_base.js +++ b/chrome/browser/resources/pdf/pdf_viewer_base.js
@@ -160,10 +160,10 @@ * @private */ createPlugin_(isPrintPreview) { - // Create the plugin object dynamically so we can set its src. The plugin - // element is sized to fill the entire window and is set to be fixed - // positioning, acting as a viewport. The plugin renders into this viewport - // according to the scroll position of the window. + // Create the plugin object dynamically. The plugin element is sized to + // fill the entire window and is set to be fixed positioning, acting as a + // viewport. The plugin renders into this viewport according to the scroll + // position of the window. const plugin = /** @type {!HTMLEmbedElement} */ (document.createElement('embed')); @@ -174,9 +174,8 @@ plugin.id = 'plugin'; plugin.type = 'application/x-google-chrome-pdf'; - plugin.setAttribute('src', this.originalUrl); - plugin.setAttribute( - 'stream-url', this.browserApi.getStreamInfo().streamUrl); + plugin.setAttribute('original-url', this.originalUrl); + plugin.setAttribute('src', this.browserApi.getStreamInfo().streamUrl); let headers = ''; for (const header in this.browserApi.getStreamInfo().responseHeaders) { headers += header + ': ' +
diff --git a/chrome/browser/resources/tab_search/infinite_list.js b/chrome/browser/resources/tab_search/infinite_list.js index 4910483..b46a5ca9 100644 --- a/chrome/browser/resources/tab_search/infinite_list.js +++ b/chrome/browser/resources/tab_search/infinite_list.js
@@ -252,7 +252,16 @@ * @private */ getDomItem_(index) { - return this.instances_[index].children[0]; + const instance = this.instances_[index]; + if (instance === undefined) { + // TODO(crbug.com/1225247): Remove this after we root cause the issue. + console.error(`Unexpected call to non-existing instance index: ${ + index}. Instance count: ${this.instances_.length}. Item count: ${ + this.items.length}`); + return undefined; + } + + return instance.children[0]; } /** @@ -327,6 +336,9 @@ const selectedItemIndex = this.$.selector.selected; if (selectedItemIndex !== undefined) { const selectedItem = this.getSelectableDomItem_(selectedItemIndex); + if (selectedItem === undefined) { + return false; + } const deepActiveElement = getDeepActiveElement(); return selectedItem === deepActiveElement ||
diff --git a/chrome/browser/search/drive/drive_service.cc b/chrome/browser/search/drive/drive_service.cc index fb7c18a..22a1b11 100644 --- a/chrome/browser/search/drive/drive_service.cc +++ b/chrome/browser/search/drive/drive_service.cc
@@ -44,7 +44,10 @@ "platform_type": "%s", "scenario_type": "CHROME_NTP_FILES", "language_code": "%s", - "request_type": "LIVE_REQUEST" + "request_type": "LIVE_REQUEST", + "client_tags": { + "name": "%s" + } }, "max_suggestions": 3, "type_detail_fields": "drive_item.title,drive_item.mimeType" @@ -247,7 +250,11 @@ kTrafficAnnotation); url_loader_->SetRetryOptions(0, network::SimpleURLLoader::RETRY_NEVER); url_loader_->AttachStringForUpload( - base::StringPrintf(kRequestBody, kPlatform, application_locale_.c_str()), + base::StringPrintf(kRequestBody, kPlatform, application_locale_.c_str(), + base::GetFieldTrialParamValueByFeature( + ntp_features::kNtpDriveModule, + ntp_features::kNtpDriveModuleExperimentGroupParam) + .c_str()), "application/json"); url_loader_->DownloadToString( url_loader_factory_.get(),
diff --git a/chrome/browser/search/drive/drive_service_unittest.cc b/chrome/browser/search/drive/drive_service_unittest.cc index 373999a..2bb24913 100644 --- a/chrome/browser/search/drive/drive_service_unittest.cc +++ b/chrome/browser/search/drive/drive_service_unittest.cc
@@ -355,6 +355,31 @@ base::PersistentHash("drive"))); } +TEST_F(DriveServiceTest, AddsClientTagIfRequested) { + // Make sure we are not in the dismissed time window. + prefs_.SetTime(DriveService::kLastDismissedTimePrefName, base::Time::Now()); + task_environment_.AdvanceClock(DriveService::kDismissDuration); + + // Set client tag. + base::test::ScopedFeatureList features; + features.InitAndEnableFeatureWithParameters( + ntp_features::kNtpDriveModule, + {{ntp_features::kNtpDriveModuleExperimentGroupParam, "foo"}}); + + service_->GetDriveFiles(DriveService::GetFilesCallback()); + identity_test_env.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( + "foo_token", base::Time()); + EXPECT_EQ(1, test_url_loader_factory_.NumPending()); + std::string request_body(test_url_loader_factory_.pending_requests() + ->at(0) + .request.request_body->elements() + ->at(0) + .As<network::DataElementBytes>() + .AsStringPiece()); + auto body_value = base::JSONReader::Read(request_body); + EXPECT_EQ("foo", *body_value->FindStringPath("client_info.client_tags.name")); +} + TEST_F(DriveServiceTest, PassesNoDataIfDismissed) { bool passed_no_data = false; base::MockCallback<DriveService::GetFilesCallback> callback;
diff --git a/chrome/browser/search/instant_service_factory.cc b/chrome/browser/search/instant_service_factory.cc index 905b26b..038da6c 100644 --- a/chrome/browser/search/instant_service_factory.cc +++ b/chrome/browser/search/instant_service_factory.cc
@@ -4,12 +4,9 @@ #include "chrome/browser/search/instant_service_factory.h" -#include "chrome/browser/history/top_sites_factory.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search/instant_service.h" -#include "chrome/browser/search/suggestions/suggestions_service_factory.h" -#include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/themes/theme_service_factory.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/search/search.h" @@ -31,10 +28,7 @@ : BrowserContextKeyedServiceFactory( "InstantService", BrowserContextDependencyManager::GetInstance()) { - DependsOn(suggestions::SuggestionsServiceFactory::GetInstance()); - DependsOn(TemplateURLServiceFactory::GetInstance()); DependsOn(ThemeServiceFactory::GetInstance()); - DependsOn(TopSitesFactory::GetInstance()); } InstantServiceFactory::~InstantServiceFactory() = default;
diff --git a/chrome/browser/search/suggestions/OWNERS b/chrome/browser/search/suggestions/OWNERS deleted file mode 100644 index 919d244..0000000 --- a/chrome/browser/search/suggestions/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -file://components/suggestions/OWNERS
diff --git a/chrome/browser/search/suggestions/suggestions_service_factory.cc b/chrome/browser/search/suggestions/suggestions_service_factory.cc deleted file mode 100644 index caa8de5..0000000 --- a/chrome/browser/search/suggestions/suggestions_service_factory.cc +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright 2014 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. - -#include "chrome/browser/search/suggestions/suggestions_service_factory.h" - -#include <memory> -#include <utility> - -#include "base/task/post_task.h" -#include "base/time/default_tick_clock.h" -#include "chrome/browser/profiles/incognito_helpers.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/browser/sync/sync_service_factory.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/pref_registry/pref_registry_syncable.h" -#include "components/prefs/pref_service.h" -#include "components/signin/public/identity_manager/identity_manager.h" -#include "components/suggestions/blocklist_store.h" -#include "components/suggestions/proto/suggestions.pb.h" -#include "components/suggestions/suggestions_service_impl.h" -#include "components/suggestions/suggestions_store.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/storage_partition.h" - -using content::BrowserThread; - -namespace suggestions { - -// static -SuggestionsService* SuggestionsServiceFactory::GetForProfile(Profile* profile) { - return static_cast<SuggestionsService*>( - GetInstance()->GetServiceForBrowserContext(profile, true)); -} - -// static -SuggestionsServiceFactory* SuggestionsServiceFactory::GetInstance() { - return base::Singleton<SuggestionsServiceFactory>::get(); -} - -SuggestionsServiceFactory::SuggestionsServiceFactory() - : BrowserContextKeyedServiceFactory( - "SuggestionsService", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(IdentityManagerFactory::GetInstance()); - DependsOn(SyncServiceFactory::GetInstance()); -} - -SuggestionsServiceFactory::~SuggestionsServiceFactory() {} - -KeyedService* SuggestionsServiceFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - Profile* profile = static_cast<Profile*>(context); - - signin::IdentityManager* identity_manager = - IdentityManagerFactory::GetForProfile(profile); - syncer::SyncService* sync_service = - SyncServiceFactory::GetForProfile(profile); - - std::unique_ptr<SuggestionsStore> suggestions_store( - new SuggestionsStore(profile->GetPrefs())); - std::unique_ptr<BlocklistStore> blocklist_store( - new BlocklistStore(profile->GetPrefs())); - - return new SuggestionsServiceImpl( - identity_manager, sync_service, - profile->GetDefaultStoragePartition() - ->GetURLLoaderFactoryForBrowserProcess(), - std::move(suggestions_store), std::move(blocklist_store), - base::DefaultTickClock::GetInstance()); -} - -void SuggestionsServiceFactory::RegisterProfilePrefs( - user_prefs::PrefRegistrySyncable* registry) { - SuggestionsServiceImpl::RegisterProfilePrefs(registry); -} - -} // namespace suggestions
diff --git a/chrome/browser/search/suggestions/suggestions_service_factory.h b/chrome/browser/search/suggestions/suggestions_service_factory.h deleted file mode 100644 index 18b4364..0000000 --- a/chrome/browser/search/suggestions/suggestions_service_factory.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2014 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. - -#ifndef CHROME_BROWSER_SEARCH_SUGGESTIONS_SUGGESTIONS_SERVICE_FACTORY_H_ -#define CHROME_BROWSER_SEARCH_SUGGESTIONS_SUGGESTIONS_SERVICE_FACTORY_H_ - -#include "base/macros.h" -#include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -class Profile; - -namespace suggestions { - -class SuggestionsService; - -// Singleton that owns all SuggestionsServices and associates them with -// Profiles. -class SuggestionsServiceFactory : public BrowserContextKeyedServiceFactory { - public: - // Returns the SuggestionsService for |profile|. - static suggestions::SuggestionsService* GetForProfile(Profile* profile); - - static SuggestionsServiceFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits<SuggestionsServiceFactory>; - - SuggestionsServiceFactory(); - ~SuggestionsServiceFactory() override; - - // Overrides from BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* profile) const override; - void RegisterProfilePrefs( - user_prefs::PrefRegistrySyncable* registry) override; - - DISALLOW_COPY_AND_ASSIGN(SuggestionsServiceFactory); -}; - -} // namespace suggestions - -#endif // CHROME_BROWSER_SEARCH_SUGGESTIONS_SUGGESTIONS_SERVICE_FACTORY_H_
diff --git a/chrome/browser/search/suggestions/suggestions_ui.cc b/chrome/browser/search/suggestions/suggestions_ui.cc deleted file mode 100644 index f459d4e..0000000 --- a/chrome/browser/search/suggestions/suggestions_ui.cc +++ /dev/null
@@ -1,76 +0,0 @@ -// Copyright 2016 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. - -#include "chrome/browser/search/suggestions/suggestions_ui.h" - -#include <map> -#include <memory> -#include <string> - -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/search/suggestions/suggestions_service_factory.h" -#include "chrome/common/url_constants.h" -#include "components/suggestions/webui/suggestions_source.h" -#include "content/public/browser/url_data_source.h" - -namespace suggestions { - -namespace { - -// Glues a SuggestionsSource instance to //chrome. -class SuggestionsSourceWrapper : public content::URLDataSource { - public: - explicit SuggestionsSourceWrapper(SuggestionsService* suggestions_service); - ~SuggestionsSourceWrapper() override; - - // content::URLDataSource implementation. - std::string GetSource() override; - void StartDataRequest( - const GURL& url, - const content::WebContents::Getter& wc_getter, - content::URLDataSource::GotDataCallback callback) override; - std::string GetMimeType(const std::string& path) override; - - private: - SuggestionsSource suggestions_source_; - - DISALLOW_COPY_AND_ASSIGN(SuggestionsSourceWrapper); -}; - -SuggestionsSourceWrapper::SuggestionsSourceWrapper( - SuggestionsService* suggestions_service) - : suggestions_source_(suggestions_service, - chrome::kChromeUISuggestionsURL) {} - -SuggestionsSourceWrapper::~SuggestionsSourceWrapper() {} - -std::string SuggestionsSourceWrapper::GetSource() { - return chrome::kChromeUISuggestionsHost; -} - -void SuggestionsSourceWrapper::StartDataRequest( - const GURL& url, - const content::WebContents::Getter& wc_getter, - content::URLDataSource::GotDataCallback callback) { - suggestions_source_.StartDataRequest( - content::URLDataSource::URLToRequestPath(url), std::move(callback)); -} - -std::string SuggestionsSourceWrapper::GetMimeType(const std::string& path) { - return "text/html"; -} - -} // namespace - -SuggestionsUI::SuggestionsUI(content::WebUI* web_ui) - : content::WebUIController(web_ui) { - Profile* profile = Profile::FromWebUI(web_ui); - content::URLDataSource::Add( - profile, std::make_unique<SuggestionsSourceWrapper>( - SuggestionsServiceFactory::GetForProfile(profile))); -} - -SuggestionsUI::~SuggestionsUI() {} - -} // namespace suggestions
diff --git a/chrome/browser/search/suggestions/suggestions_ui.h b/chrome/browser/search/suggestions/suggestions_ui.h deleted file mode 100644 index feb7c51..0000000 --- a/chrome/browser/search/suggestions/suggestions_ui.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2016 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. - -#ifndef CHROME_BROWSER_SEARCH_SUGGESTIONS_SUGGESTIONS_UI_H_ -#define CHROME_BROWSER_SEARCH_SUGGESTIONS_SUGGESTIONS_UI_H_ - -#include "base/macros.h" -#include "content/public/browser/web_ui_controller.h" - -namespace content { -class WebUI; -} - -namespace suggestions { - -// The WebUIController for chrome://suggestions. Renders a webpage to list -// SuggestionsService data. -class SuggestionsUI : public content::WebUIController { - public: - explicit SuggestionsUI(content::WebUI* web_ui); - ~SuggestionsUI() override; - - private: - DISALLOW_COPY_AND_ASSIGN(SuggestionsUI); -}; - -} // namespace suggestions - -#endif // CHROME_BROWSER_SEARCH_SUGGESTIONS_SUGGESTIONS_UI_H_
diff --git a/chrome/browser/signin/chrome_signin_helper.cc b/chrome/browser/signin/chrome_signin_helper.cc index ecc11a0..ce2b1f3 100644 --- a/chrome/browser/signin/chrome_signin_helper.cc +++ b/chrome/browser/signin/chrome_signin_helper.cc
@@ -260,7 +260,7 @@ // 2. Displaying a reauthentication window if (!manage_accounts_params.email.empty()) { - // TODO(https://crbug.com/1177728): enable this for lacros. + // TODO(https://crbug.com/1226055): enable this for lacros. #if BUILDFLAG(IS_CHROMEOS_ASH) // Do not display the re-authentication dialog if this event was triggered // by supervision being enabled for an account. In this situation, a
diff --git a/chrome/browser/speech/cros_speech_recognition_service_factory.h b/chrome/browser/speech/cros_speech_recognition_service_factory.h index 5c58caf5..fa7908e 100644 --- a/chrome/browser/speech/cros_speech_recognition_service_factory.h +++ b/chrome/browser/speech/cros_speech_recognition_service_factory.h
@@ -5,15 +5,11 @@ #ifndef CHROME_BROWSER_SPEECH_CROS_SPEECH_RECOGNITION_SERVICE_FACTORY_H_ #define CHROME_BROWSER_SPEECH_CROS_SPEECH_RECOGNITION_SERVICE_FACTORY_H_ +#include "base/no_destructor.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" class Profile; -namespace base { -template <class T> -class NoDestructor; -} // namespace base - namespace speech { class SpeechRecognitionService; } // namespace speech
diff --git a/chrome/browser/speech/speech_recognition_client_browser_interface_factory.h b/chrome/browser/speech/speech_recognition_client_browser_interface_factory.h index b7b31e1..f3856b6 100644 --- a/chrome/browser/speech/speech_recognition_client_browser_interface_factory.h +++ b/chrome/browser/speech/speech_recognition_client_browser_interface_factory.h
@@ -5,15 +5,11 @@ #ifndef CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_CLIENT_BROWSER_INTERFACE_FACTORY_H_ #define CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_CLIENT_BROWSER_INTERFACE_FACTORY_H_ +#include "base/no_destructor.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" class Profile; -namespace base { -template <class T> -class NoDestructor; -} // namespace base - namespace speech { class SpeechRecognitionClientBrowserInterface; } // namespace speech
diff --git a/chrome/browser/speech/speech_recognition_service_factory.h b/chrome/browser/speech/speech_recognition_service_factory.h index 6c45c04..6ef7270 100644 --- a/chrome/browser/speech/speech_recognition_service_factory.h +++ b/chrome/browser/speech/speech_recognition_service_factory.h
@@ -5,15 +5,11 @@ #ifndef CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_SERVICE_FACTORY_H_ #define CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_SERVICE_FACTORY_H_ +#include "base/no_destructor.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" class Profile; -namespace base { -template <class T> -class NoDestructor; -} // namespace base - namespace speech { class SpeechRecognitionService; } // namespace speech
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java index b8eef03..f96d27e3 100644 --- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java +++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java
@@ -11,13 +11,12 @@ import com.google.protobuf.InvalidProtocolBufferException; import org.chromium.base.Callback; +import org.chromium.base.FeatureList; import org.chromium.base.Log; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.supplier.Supplier; -import org.chromium.chrome.browser.flags.BooleanCachedFieldTrialParameter; import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.flags.IntCachedFieldTrialParameter; import org.chromium.chrome.browser.optimization_guide.OptimizationGuideBridgeFactory; import org.chromium.chrome.browser.page_annotations.BuyableProductPageAnnotation; import org.chromium.chrome.browser.page_annotations.PageAnnotation; @@ -66,28 +65,12 @@ private static final long TWO_UNITS = 2 * MICROS_TO_UNITS; private static final long TEN_UNITS = 10 * MICROS_TO_UNITS; private static final int MINIMUM_DROP_PERCENTAGE = 10; - private static final long ONE_WEEK_MS = TimeUnit.DAYS.toMillis(7); + private static final int ONE_WEEK_MS = (int) TimeUnit.DAYS.toMillis(7); @VisibleForTesting public static final long ONE_HOUR_MS = TimeUnit.HOURS.toMillis(1); - private static final long NINETY_DAYS_SECONDS = TimeUnit.DAYS.toSeconds(90); - - public static final IntCachedFieldTrialParameter STALE_TAB_THRESHOLD_SECONDS = - new IntCachedFieldTrialParameter(ChromeFeatureList.COMMERCE_PRICE_TRACKING, - STALE_TAB_THRESHOLD_SECONDS_PARAM, (int) NINETY_DAYS_SECONDS); - - public static final IntCachedFieldTrialParameter TIME_TO_LIVE_MS = - new IntCachedFieldTrialParameter(ChromeFeatureList.COMMERCE_PRICE_TRACKING, - TIME_TO_LIVE_MS_PARAM, (int) ONE_HOUR_MS); - - public static final IntCachedFieldTrialParameter DISPLAY_TIME_MS = - new IntCachedFieldTrialParameter(ChromeFeatureList.COMMERCE_PRICE_TRACKING, - DISPLAY_TIME_MS_PARAM, (int) ONE_WEEK_MS); - - public static final BooleanCachedFieldTrialParameter PRICE_TRACKING_WITH_OPTIMIZATION_GUIDE = - new BooleanCachedFieldTrialParameter(ChromeFeatureList.COMMERCE_PRICE_TRACKING, - PRICE_TRACKING_WITH_OPTIMIZATION_GUIDE_PARAM, false); + private static final int NINETY_DAYS_SECONDS = (int) TimeUnit.DAYS.toSeconds(90); @VisibleForTesting public static final long NO_TRANSITIONS_OCCURRED = -1; @@ -99,6 +82,8 @@ protected static PageAnnotationsServiceFactory sPageAnnotationsServiceFactory = new PageAnnotationsServiceFactory(); + private static boolean sPriceTrackingWithOptimizationGuideForTesting; + public long mLastPriceChangeTimeMs = NO_TRANSITIONS_OCCURRED; private PriceDropData mPriceDropData = new PriceDropData(); @@ -127,7 +112,7 @@ private static final OptimizationGuideBridgeFactory sOptimizationGuideBridgeFactory; static { List<HintsProto.OptimizationType> optimizationTypes; - if (PRICE_TRACKING_WITH_OPTIMIZATION_GUIDE.getValue()) { + if (isPriceTrackingWithOptimizationGuideEnabled()) { optimizationTypes = Arrays.asList(HintsProto.OptimizationType.SHOPPING_PAGE_PREDICTOR, HintsProto.OptimizationType.PRICE_TRACKING); @@ -301,7 +286,7 @@ @Override public void onDidFinishNavigation(Tab tab, NavigationHandle navigationHandle) { - if (ShoppingPersistedTabData.PRICE_TRACKING_WITH_OPTIMIZATION_GUIDE.getValue()) { + if (isPriceTrackingWithOptimizationGuideEnabled()) { prefetchOnNewNavigation(tab, navigationHandle); } } @@ -331,7 +316,7 @@ (supplierCallback) -> { if (getTimeSinceTabLastOpenedMs(tab) - > TimeUnit.SECONDS.toMillis(STALE_TAB_THRESHOLD_SECONDS.getValue())) { + > TimeUnit.SECONDS.toMillis(getStaleTabThresholdSeconds())) { supplierCallback.onResult(null); return; } @@ -342,7 +327,7 @@ return; } - if (PRICE_TRACKING_WITH_OPTIMIZATION_GUIDE.getValue()) { + if (isPriceTrackingWithOptimizationGuideEnabled()) { OptimizationGuideBridgeFactoryHolder.sOptimizationGuideBridgeFactory .create() .canApplyOptimization(tab.getUrl(), @@ -681,7 +666,7 @@ private boolean isPriceChangeStale() { return mLastPriceChangeTimeMs != NO_TRANSITIONS_OCCURRED - && System.currentTimeMillis() - mLastPriceChangeTimeMs > DISPLAY_TIME_MS.getValue(); + && System.currentTimeMillis() - mLastPriceChangeTimeMs > getDisplayTimeMs(); } private boolean isQualifyingPriceDrop() { @@ -774,7 +759,12 @@ @Override public long getTimeToLiveMs() { - return TIME_TO_LIVE_MS.getValue(); + if (FeatureList.isInitialized()) { + return ChromeFeatureList.getFieldTrialParamByFeatureAsInt( + ChromeFeatureList.COMMERCE_PRICE_TRACKING, TIME_TO_LIVE_MS_PARAM, + (int) ONE_HOUR_MS); + } + return (int) ONE_HOUR_MS; } @VisibleForTesting @@ -793,6 +783,47 @@ super.destroy(); } + /** + * @return the threshold in seconds at which a {@link Tab} is considered stale + * (and we no longer acquire shopping data for stale tabs). + */ + public static int getStaleTabThresholdSeconds() { + if (FeatureList.isInitialized()) { + return ChromeFeatureList.getFieldTrialParamByFeatureAsInt( + ChromeFeatureList.COMMERCE_PRICE_TRACKING, STALE_TAB_THRESHOLD_SECONDS_PARAM, + NINETY_DAYS_SECONDS); + } + return NINETY_DAYS_SECONDS; + } + + /** + * @return true is acquiring pricing data using OptimizationGuide is enabled. + */ + public static boolean isPriceTrackingWithOptimizationGuideEnabled() { + if (sPriceTrackingWithOptimizationGuideForTesting) { + return true; + } + if (FeatureList.isInitialized()) { + return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( + ChromeFeatureList.COMMERCE_PRICE_TRACKING, + PRICE_TRACKING_WITH_OPTIMIZATION_GUIDE_PARAM, false); + } + return false; + } + + @VisibleForTesting + public static void enablePriceTrackingWithOptimizationGuideForTesting() { + sPriceTrackingWithOptimizationGuideForTesting = true; + } + + private static int getDisplayTimeMs() { + if (FeatureList.isInitialized()) { + return ChromeFeatureList.getFieldTrialParamByFeatureAsInt( + ChromeFeatureList.COMMERCE_PRICE_TRACKING, DISPLAY_TIME_MS_PARAM, ONE_WEEK_MS); + } + return ONE_WEEK_MS; + } + private static long getTimeSinceTabLastOpenedMs(Tab tab) { return System.currentTimeMillis() - CriticalPersistedTabData.from(tab).getTimestampMillis(); }
diff --git a/chrome/browser/transition_manager/full_browser_transition_manager.h b/chrome/browser/transition_manager/full_browser_transition_manager.h index d60b2d9..8e10624 100644 --- a/chrome/browser/transition_manager/full_browser_transition_manager.h +++ b/chrome/browser/transition_manager/full_browser_transition_manager.h
@@ -11,14 +11,10 @@ #include "base/callback.h" #include "base/component_export.h" #include "base/macros.h" +#include "base/no_destructor.h" #include "base/sequence_checker.h" #include "components/keyed_service/core/simple_factory_key.h" -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - class Profile; // FullBrowserTransitionManager allows SimpleKeyedServices to hook into the
diff --git a/chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder_tab_tracker_unittest.cc b/chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder_tab_tracker_unittest.cc index 45aee46..2f10de4 100644 --- a/chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder_tab_tracker_unittest.cc +++ b/chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder_tab_tracker_unittest.cc
@@ -4,6 +4,7 @@ #include "ash/public/cpp/app_list/app_list_switches.h" #include "base/command_line.h" +#include "base/no_destructor.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/ui/ash/assistant/assistant_browsertest.cc b/chrome/browser/ui/ash/assistant/assistant_browsertest.cc index b38701fd..09386388 100644 --- a/chrome/browser/ui/ash/assistant/assistant_browsertest.cc +++ b/chrome/browser/ui/ash/assistant/assistant_browsertest.cc
@@ -5,6 +5,7 @@ #include "ash/components/audio/cras_audio_handler.h" #include "base/run_loop.h" #include "base/test/bind.h" +#include "base/test/scoped_feature_list.h" #include "base/test/scoped_run_loop_timeout.h" #include "base/time/time.h" #include "chrome/browser/ui/ash/assistant/assistant_test_mixin.h"
diff --git a/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc b/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc index 7b1a626..c846151 100644 --- a/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc +++ b/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc
@@ -17,6 +17,7 @@ #include "base/strings/string_util.h" #include "base/test/bind.h" #include "base/test/icu_test_util.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/ui/ash/assistant/assistant_test_mixin.h" #include "chrome/browser/ui/ash/assistant/test_support/test_util.h" #include "chrome/test/base/mixin_based_in_process_browser_test.h" @@ -189,7 +190,11 @@ class AssistantTimersBrowserTest : public MixinBasedInProcessBrowserTest { public: - AssistantTimersBrowserTest() = default; + AssistantTimersBrowserTest() { + // TODO(b/190633242): enable sandbox in browser tests. + feature_list_.InitAndDisableFeature( + chromeos::assistant::features::kEnableLibAssistantSandbox); + } AssistantTimersBrowserTest(const AssistantTimersBrowserTest&) = delete; AssistantTimersBrowserTest& operator=(const AssistantTimersBrowserTest&) = @@ -205,6 +210,7 @@ AssistantTestMixin* tester() { return &tester_; } private: + base::test::ScopedFeatureList feature_list_; base::test::ScopedRestoreICUDefaultLocale locale_{"en_US"}; AssistantTestMixin tester_{&mixin_host_, this, embedded_test_server(), kMode, kVersion};
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_downloads_delegate.cc b/chrome/browser/ui/ash/holding_space/holding_space_downloads_delegate.cc index 2feee31..e5a727a 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_downloads_delegate.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_downloads_delegate.cc
@@ -83,22 +83,7 @@ // Returns the number of bytes received for the underlying `download_item_`. int64_t GetReceivedBytes() const { - int64_t received_bytes = download_item_->GetReceivedBytes(); - - if (IsInProgress(download_item_)) { - // If the underlying `download_item_` is still in-progress, ensure that - // `received_bytes` < `total_bytes`. This may not actually be the case if, - // for example, all bytes have been received but the `download_item_` is - // still in the process of completing. Failure to account for this - // scenario would cause the associated `holding_space_item_` to be marked - // complete prematurely and potentially be removed from the model due to - // failed backing file validity checks. - const absl::optional<int64_t> total_bytes = GetTotalBytes(); - if (total_bytes.has_value()) - received_bytes = std::min(received_bytes, total_bytes.value() - 1); - } - - return received_bytes; + return download_item_->GetReceivedBytes(); } // Returns the file path associated with the underlying `download_item_`. @@ -118,7 +103,8 @@ HoldingSpaceProgress GetProgress() const { if (IsComplete(download_item_)) return HoldingSpaceProgress(); - return HoldingSpaceProgress(GetReceivedBytes(), GetTotalBytes()); + return HoldingSpaceProgress(GetReceivedBytes(), GetTotalBytes(), + /*complete=*/false); } // Returns the number of total bytes for the underlying `download_item`.
diff --git a/chrome/browser/ui/ash/network/network_state_notifier.cc b/chrome/browser/ui/ash/network/network_state_notifier.cc index 9d22361..6ffa118 100644 --- a/chrome/browser/ui/ash/network/network_state_notifier.cc +++ b/chrome/browser/ui/ash/network/network_state_notifier.cc
@@ -197,6 +197,29 @@ RemoveConnectNotification(); } +void NetworkStateNotifier::NetworkConnectionStateChanged( + const chromeos::NetworkState* network) { + if (!network->IsConnectedState() || + connect_error_notification_network_guid_.empty() || + connect_error_notification_network_guid_ != network->guid()) { + return; + } + RemoveConnectNotification(); +} + +void NetworkStateNotifier::NetworkIdentifierTransitioned( + const std::string& old_service_path, + const std::string& new_service_path, + const std::string& old_guid, + const std::string& new_guid) { + if (old_guid == new_guid || + old_guid != connect_error_notification_network_guid_) { + return; + } + + connect_error_notification_network_guid_ = new_guid; +} + void NetworkStateNotifier::ConnectSucceeded(const std::string& service_path) { RemoveConnectNotification(); } @@ -426,6 +449,7 @@ void NetworkStateNotifier::RemoveConnectNotification() { SystemNotificationHelper::GetInstance()->Close(kNetworkConnectNotificationId); + connect_error_notification_network_guid_.clear(); } void NetworkStateNotifier::OnConnectErrorGetProperties( @@ -560,6 +584,7 @@ weak_ptr_factory_.GetWeakPtr(), guid); } + connect_error_notification_network_guid_ = guid; ShowErrorNotification( NetworkPathId(service_path), kNetworkConnectNotificationId, network_type, l10n_util::GetStringUTF16(IDS_NETWORK_CONNECTION_ERROR_TITLE), error_msg,
diff --git a/chrome/browser/ui/ash/network/network_state_notifier.h b/chrome/browser/ui/ash/network/network_state_notifier.h index 97273ad485..0db251bc 100644 --- a/chrome/browser/ui/ash/network/network_state_notifier.h +++ b/chrome/browser/ui/ash/network/network_state_notifier.h
@@ -81,6 +81,12 @@ void ActiveNetworksChanged( const std::vector<const NetworkState*>& active_networks) override; void NetworkPropertiesUpdated(const NetworkState* network) override; + void NetworkConnectionStateChanged( + const chromeos::NetworkState* network) override; + void NetworkIdentifierTransitioned(const std::string& old_service_path, + const std::string& new_service_path, + const std::string& old_guid, + const std::string& new_guid) override; void OnConnectErrorGetProperties( const std::string& error_name, @@ -124,6 +130,10 @@ // Set to the GUID of the active non VPN network if any, otherwise empty. std::string active_non_vpn_network_guid_; + // Set to the GUID of the current network which spawned a connection error + // notification if any, otherwise empty. + std::string connect_error_notification_network_guid_; + // Tracks GUIDs of activating cellular networks for activation notification. std::set<std::string> cellular_activating_guids_;
diff --git a/chrome/browser/ui/ash/network/network_state_notifier_unittest.cc b/chrome/browser/ui/ash/network/network_state_notifier_unittest.cc index 55132f6..dec35d8 100644 --- a/chrome/browser/ui/ash/network/network_state_notifier_unittest.cc +++ b/chrome/browser/ui/ash/network/network_state_notifier_unittest.cc
@@ -43,6 +43,8 @@ const char16_t kCellular1NetworkName16[] = u"cellular1"; const char kTestEsimProfileName[] = "test_profile_name"; const char16_t kTestEsimProfileName16[] = u"test_profile_name"; +const char kCellularEsimServicePath[] = "/service/cellular_esim1"; +const char kCellularDevicePath[] = "/device/cellular1"; class NetworkConnectTestDelegate : public NetworkConnect::Delegate { public: @@ -140,6 +142,20 @@ kAddProfileWithService); base::RunLoop().RunUntilIdle(); } + + void SetCellularDeviceLocked(bool is_locked) { + ShillDeviceClient::TestInterface* device_test = + network_handler_test_helper_->device_test(); + + std::string lock_pin = is_locked ? shill::kSIMLockPin : ""; + base::Value sim_lock_status(base::Value::Type::DICTIONARY); + sim_lock_status.SetKey(shill::kSIMLockTypeProperty, base::Value(lock_pin)); + device_test->SetDeviceProperty( + kCellularDevicePath, shill::kSIMLockStatusProperty, + std::move(sim_lock_status), /*notify_changed=*/true); + base::RunLoop().RunUntilIdle(); + } + void SetupDefaultShillState() { ShillDeviceClient::TestInterface* device_test = network_handler_test_helper_->device_test(); @@ -164,7 +180,6 @@ kWiFi1ServicePath, shill::kPassphraseProperty, base::Value("failure")); // Set up Cellular device, and add a single locked network. - const char kCellularDevicePath[] = "/device/cellular1"; const char kCellular1ServicePath[] = "/service/cellular1"; const char kCellular1Iccid[] = "iccid"; device_test->AddDevice(kCellularDevicePath, shill::kTypeCellular, @@ -264,6 +279,22 @@ l10n_util::GetStringFUTF16( IDS_NETWORK_CONNECTION_ERROR_MESSAGE, kTestEsimProfileName16, l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SIM_CARD_LOCKED))); + + ShillServiceClient::TestInterface* service_test = + ShillServiceClient::Get()->GetTestInterface(); + service_test->SetServiceProperty( + kCellularEsimServicePath, shill::kConnectableProperty, base::Value(true)); + + // Set device locked status to false, this will allow for network connection + // to succeed. + SetCellularDeviceLocked(/*is_locked=*/false); + NetworkConnect::Get()->ConnectToNetworkId("esim_guidiccid"); + base::RunLoop().RunUntilIdle(); + + // Notification is removed. + notification = tester.GetNotification( + NetworkStateNotifier::kNetworkConnectNotificationId); + EXPECT_FALSE(notification); } } // namespace chromeos
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.cc b/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.cc index efaf4a8..afbdef485 100644 --- a/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.cc +++ b/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.cc
@@ -92,15 +92,10 @@ public: METADATA_HEADER(SharesheetImagePreview); explicit SharesheetImagePreview(size_t file_count) { - const int border_radius = - views::LayoutProvider::Get()->GetCornerRadiusMetric( - views::Emphasis::kMedium); SetBackground(views::CreateRoundedRectBackground( - kImagePreviewPlaceholderBackgroundColor, border_radius)); - SetBorder(views::CreateRoundedRectBorder( - /* thickness */ 1, border_radius, - GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_UnfocusedBorderColor))); + kImagePreviewPlaceholderBackgroundColor, + views::LayoutProvider::Get()->GetCornerRadiusMetric( + views::Emphasis::kMedium))); SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical, /* inside_border_insets */ gfx::Insets(), @@ -185,6 +180,16 @@ was_pressed_ = true; } + void OnThemeChanged() override { + View::OnThemeChanged(); + SetBorder(views::CreateRoundedRectBorder( + /*thickness=*/1, + views::LayoutProvider::Get()->GetCornerRadiusMetric( + views::Emphasis::kMedium), + GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_UnfocusedBorderColor))); + } + void AddRowToImageContainerView() { auto* row = AddChildView(std::make_unique<views::View>()); row->SetLayoutManager(std::make_unique<views::BoxLayout>(
diff --git a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_shelf_controller.cc b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_shelf_controller.cc index 6f31f5f4..f5fa5b9c 100644 --- a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_shelf_controller.cc +++ b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_shelf_controller.cc
@@ -170,6 +170,28 @@ observed_windows_.AddObservation(window); if (arc_tracker_) arc_tracker_->AddCandidateWindow(window); + + // When the visibility of the window changes and if it is not already on a + // shelf then it is added to a shelf by `ASAWSC::OnWindowVisibilityChanged()` + // but when the window is created as a minimized window there is no change in + // visible state and it is not added to the shelf. Hence, when a widget has a + // `initial_show_state_` as ui::SHOW_STATE_MINIMIZED, it should add itself to + // a shelf during initialization. The below code is applicable only for Lacros + // browser app. + auto shelf_id = GetShelfId(window); + if (!shelf_id.IsNull() && + GetAppType(shelf_id.app_id) == apps::mojom::AppType::kStandaloneBrowser && + widget->IsMinimized()) { + // Update |state|. The app must be started, and running state. If visible, + // set it as |kVisible|, otherwise, clear the visible bit. + apps::InstanceState state = + app_service_instance_helper_->CalculateVisibilityState( + window, /*visible=*/false); + app_service_instance_helper_->OnInstances(GetAppId(shelf_id.app_id), window, + shelf_id.launch_id, state); + + RegisterWindow(window, shelf_id); + } } void AppServiceAppWindowShelfController::OnWindowPropertyChanged(
diff --git a/chrome/browser/ui/aura/accessibility/automation_manager_aura.h b/chrome/browser/ui/aura/accessibility/automation_manager_aura.h index 44b7f8e0..17669a84 100644 --- a/chrome/browser/ui/aura/accessibility/automation_manager_aura.h +++ b/chrome/browser/ui/aura/accessibility/automation_manager_aura.h
@@ -13,6 +13,7 @@ #include <vector> #include "base/macros.h" +#include "base/no_destructor.h" #include "base/scoped_observation.h" #include "extensions/browser/api/automation_internal/automation_event_router.h" #include "ui/accessibility/ax_action_handler.h" @@ -21,11 +22,6 @@ #include "ui/views/accessibility/ax_event_observer.h" #include "ui/views/accessibility/ax_tree_source_views.h" -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - namespace extensions { class AutomationEventRouterInterface; } // namespace extensions
diff --git a/chrome/browser/ui/search/ntp_user_data_logger.cc b/chrome/browser/ui/search/ntp_user_data_logger.cc index 72f8cda..80eb35c 100644 --- a/chrome/browser/ui/search/ntp_user_data_logger.cc +++ b/chrome/browser/ui/search/ntp_user_data_logger.cc
@@ -461,16 +461,12 @@ return; } - bool has_server_side_suggestions = false; int tiles_count = 0; for (const absl::optional<ntp_tiles::NTPTileImpression>& impression : logged_impressions_) { if (!impression.has_value()) { break; } - if (impression->source == ntp_tiles::TileSource::SUGGESTIONS_SERVICE) { - has_server_side_suggestions = true; - } ntp_tiles::metrics::RecordTileImpression(*impression); ++tiles_count; } @@ -480,13 +476,7 @@ << "number of tiles: " << tiles_count; UMA_HISTOGRAM_LOAD_TIME("NewTabPage.LoadTime", load_time); - - // Split between ML (aka SuggestionsService) and MV (aka TopSites). - if (has_server_side_suggestions) { - UMA_HISTOGRAM_LOAD_TIME("NewTabPage.LoadTime.MostLikely", load_time); - } else { - UMA_HISTOGRAM_LOAD_TIME("NewTabPage.LoadTime.MostVisited", load_time); - } + UMA_HISTOGRAM_LOAD_TIME("NewTabPage.LoadTime.MostVisited", load_time); // Note: This could be inaccurate if the default search engine was changed // since the page load started. That's unlikely enough to not warrant special
diff --git a/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc b/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc index b242a9d4..4e613e9 100644 --- a/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc +++ b/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc
@@ -101,7 +101,7 @@ for (int i = 0; i < ntp_tiles::kMaxNumTiles; ++i) { logger.LogMostVisitedImpression(MakeNTPTileImpression( - i, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, + i, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, TileVisualType::ICON_REAL)); } logger.LogMostVisitedLoaded(delta, /*using_most_visited=*/true, @@ -121,9 +121,6 @@ base::HistogramTester histogram_tester; - logger.LogMostVisitedImpression(MakeNTPTileImpression( - 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, - TileVisualType::ICON_REAL)); logger.LogMostVisitedImpression( MakeNTPTileImpression(1, TileSource::TOP_SITES, TileTitleSource::INFERRED, TileVisualType::ICON_DEFAULT)); @@ -134,22 +131,15 @@ histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression"), IsEmpty()); EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.server"), - IsEmpty()); - EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.client"), IsEmpty()); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType"), IsEmpty()); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.client"), IsEmpty()); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.server"), - IsEmpty()); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle"), IsEmpty()); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.client"), IsEmpty()); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.server"), - IsEmpty()); } TEST_F(NTPUserDataLoggerTest, ShouldRecordImpressions) { @@ -158,18 +148,18 @@ base::HistogramTester histogram_tester; // Impressions increment the associated bins. - logger.LogMostVisitedImpression(MakeNTPTileImpression( - 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, - TileVisualType::ICON_REAL)); - logger.LogMostVisitedImpression(MakeNTPTileImpression( - 1, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, - TileVisualType::ICON_DEFAULT)); - logger.LogMostVisitedImpression(MakeNTPTileImpression( - 2, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, - TileVisualType::ICON_REAL)); - logger.LogMostVisitedImpression(MakeNTPTileImpression( - 3, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, - TileVisualType::ICON_REAL)); + logger.LogMostVisitedImpression( + MakeNTPTileImpression(0, TileSource::TOP_SITES, TileTitleSource::INFERRED, + TileVisualType::ICON_REAL)); + logger.LogMostVisitedImpression( + MakeNTPTileImpression(1, TileSource::TOP_SITES, TileTitleSource::INFERRED, + TileVisualType::ICON_DEFAULT)); + logger.LogMostVisitedImpression( + MakeNTPTileImpression(2, TileSource::TOP_SITES, TileTitleSource::INFERRED, + TileVisualType::ICON_REAL)); + logger.LogMostVisitedImpression( + MakeNTPTileImpression(3, TileSource::TOP_SITES, TileTitleSource::INFERRED, + TileVisualType::ICON_REAL)); logger.LogMostVisitedImpression(MakeNTPTileImpression( 4, TileSource::TOP_SITES, TileTitleSource::TITLE_TAG, TileVisualType::ICON_REAL)); @@ -192,11 +182,9 @@ ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), Bucket(3, 1), Bucket(4, 1), Bucket(5, 1), Bucket(6, 1), Bucket(7, 1))); EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.server"), - ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), Bucket(3, 1))); - EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.client"), - ElementsAre(Bucket(4, 1), Bucket(5, 1))); + ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), Bucket(3, 1), + Bucket(4, 1), Bucket(5, 1))); EXPECT_THAT(histogram_tester.GetAllSamples( "NewTabPage.SuggestionsImpression.popular_fetched"), ElementsAre(Bucket(6, 1))); @@ -206,11 +194,9 @@ EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType"), ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 7), Bucket(ntp_tiles::TileVisualType::ICON_DEFAULT, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.server"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 3), - Bucket(ntp_tiles::TileVisualType::ICON_DEFAULT, 1))); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.client"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 2))); + ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 5), + Bucket(ntp_tiles::TileVisualType::ICON_DEFAULT, 1))); EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.TileType.popular_fetched"), ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 1))); @@ -222,11 +208,10 @@ Bucket(kMetaTagTitleSource, 1), Bucket(kTitleTagTitleSource, 2), Bucket(kInferredTitleSource, 4))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.server"), - ElementsAre(Bucket(kInferredTitleSource, 4))); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.client"), ElementsAre(Bucket(kManifestTitleSource, 1), - Bucket(kTitleTagTitleSource, 1))); + Bucket(kTitleTagTitleSource, 1), + Bucket(kInferredTitleSource, 4))); EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.TileTitle.popular_fetched"), ElementsAre(Bucket(kTitleTagTitleSource, 1))); @@ -241,29 +226,29 @@ base::HistogramTester histogram_tester; // Impressions increment the associated bins. - logger.LogMostVisitedImpression(MakeNTPTileImpression( - 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, - TileVisualType::ICON_REAL)); - logger.LogMostVisitedImpression(MakeNTPTileImpression( - 1, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, - TileVisualType::ICON_DEFAULT)); - logger.LogMostVisitedImpression(MakeNTPTileImpression( - 2, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, - TileVisualType::ICON_REAL)); - logger.LogMostVisitedImpression(MakeNTPTileImpression( - 3, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, - TileVisualType::ICON_REAL)); + logger.LogMostVisitedImpression( + MakeNTPTileImpression(0, TileSource::TOP_SITES, TileTitleSource::INFERRED, + TileVisualType::ICON_REAL)); + logger.LogMostVisitedImpression( + MakeNTPTileImpression(1, TileSource::TOP_SITES, TileTitleSource::INFERRED, + TileVisualType::ICON_DEFAULT)); + logger.LogMostVisitedImpression( + MakeNTPTileImpression(2, TileSource::TOP_SITES, TileTitleSource::INFERRED, + TileVisualType::ICON_REAL)); + logger.LogMostVisitedImpression( + MakeNTPTileImpression(3, TileSource::TOP_SITES, TileTitleSource::INFERRED, + TileVisualType::ICON_REAL)); // Repeated impressions for the same bins are ignored. - logger.LogMostVisitedImpression(MakeNTPTileImpression( - 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, - TileVisualType::ICON_DEFAULT)); + logger.LogMostVisitedImpression( + MakeNTPTileImpression(0, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, + TileVisualType::ICON_DEFAULT)); logger.LogMostVisitedImpression( MakeNTPTileImpression(1, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, TileVisualType::ICON_DEFAULT)); - logger.LogMostVisitedImpression(MakeNTPTileImpression( - 2, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, - TileVisualType::ICON_REAL)); + logger.LogMostVisitedImpression( + MakeNTPTileImpression(2, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, + TileVisualType::ICON_REAL)); logger.LogMostVisitedImpression( MakeNTPTileImpression(3, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, TileVisualType::ICON_REAL)); @@ -276,25 +261,18 @@ histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression"), ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), Bucket(3, 1))); EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.server"), - ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), Bucket(3, 1))); - EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.client"), - IsEmpty()); + ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), Bucket(3, 1))); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType"), ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 3), Bucket(ntp_tiles::TileVisualType::ICON_DEFAULT, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.server"), + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.client"), ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 3), Bucket(ntp_tiles::TileVisualType::ICON_DEFAULT, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.client"), - IsEmpty()); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle"), ElementsAre(Bucket(kInferredTitleSource, 4))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.server"), - ElementsAre(Bucket(kInferredTitleSource, 4))); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.client"), - IsEmpty()); + ElementsAre(Bucket(kInferredTitleSource, 4))); } TEST_F(NTPUserDataLoggerTest, ShouldNotRecordImpressionsForBinsBeyondMax) { @@ -305,7 +283,7 @@ // Impressions increment the associated bins. for (int bin = 0; bin < ntp_tiles::kMaxNumTiles; bin++) { logger.LogMostVisitedImpression(MakeNTPTileImpression( - bin, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, + bin, TileSource::TOP_SITES, TileTitleSource::INFERRED, TileVisualType::ICON_REAL)); } @@ -327,27 +305,20 @@ histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression"), ContainerEq(expectedImpressions)); EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.server"), - ContainerEq(expectedImpressions)); - EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.client"), - IsEmpty()); + ContainerEq(expectedImpressions)); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType"), ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, ntp_tiles::kMaxNumTiles))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.server"), + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.client"), ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, ntp_tiles::kMaxNumTiles))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.client"), - IsEmpty()); EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.TileTitle"), ElementsAre(Bucket(kInferredTitleSource, ntp_tiles::kMaxNumTiles))); EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTitle.server"), + histogram_tester.GetAllSamples("NewTabPage.TileTitle.client"), ElementsAre(Bucket(kInferredTitleSource, ntp_tiles::kMaxNumTiles))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.client"), - IsEmpty()); } TEST_F(NTPUserDataLoggerTest, ShouldRecordNavigations) { @@ -357,49 +328,39 @@ base::HistogramTester histogram_tester; logger.LogMostVisitedNavigation(MakeNTPTileImpression( - 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, + 0, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, TileVisualType::ICON_REAL)); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited"), ElementsAre(Bucket(0, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), - ElementsAre(Bucket(0, 1))); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), - IsEmpty()); + ElementsAre(Bucket(0, 1))); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 1))); EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 1))); - EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), - IsEmpty()); + ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 1))); } { base::HistogramTester histogram_tester; logger.LogMostVisitedNavigation(MakeNTPTileImpression( - 1, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, + 1, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, TileVisualType::ICON_DEFAULT)); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited"), ElementsAre(Bucket(1, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), - ElementsAre(Bucket(1, 1))); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), - IsEmpty()); + ElementsAre(Bucket(1, 1))); EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_DEFAULT, 1))); EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_DEFAULT, 1))); - EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), - IsEmpty()); + ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_DEFAULT, 1))); } { @@ -411,8 +372,6 @@ EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited"), ElementsAre(Bucket(2, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), - IsEmpty()); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), ElementsAre(Bucket(2, 1))); @@ -420,9 +379,6 @@ histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_DEFAULT, 1))); EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), - IsEmpty()); - EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_DEFAULT, 1))); } @@ -436,8 +392,6 @@ EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited"), ElementsAre(Bucket(3, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), - IsEmpty()); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), IsEmpty()); EXPECT_THAT(histogram_tester.GetAllSamples( @@ -447,9 +401,6 @@ EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 1))); EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), - IsEmpty()); - EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), IsEmpty()); EXPECT_THAT(histogram_tester.GetAllSamples( @@ -459,9 +410,6 @@ EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked"), ElementsAre(Bucket(kMetaTagTitleSource, 1))); EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked.server"), - IsEmpty()); - EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked.client"), IsEmpty()); EXPECT_THAT(histogram_tester.GetAllSamples( @@ -474,13 +422,13 @@ // Navigations always increase. logger.LogMostVisitedNavigation(MakeNTPTileImpression( - 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, + 0, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, TileVisualType::ICON_REAL)); logger.LogMostVisitedNavigation(MakeNTPTileImpression( 1, TileSource::TOP_SITES, TileTitleSource::TITLE_TAG, TileVisualType::ICON_REAL)); logger.LogMostVisitedNavigation(MakeNTPTileImpression( - 2, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, + 2, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, TileVisualType::ICON_REAL)); logger.LogMostVisitedNavigation( MakeNTPTileImpression(3, TileSource::POPULAR, TileTitleSource::MANIFEST, @@ -489,10 +437,8 @@ EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.MostVisited"), ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), Bucket(3, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), - ElementsAre(Bucket(0, 1), Bucket(2, 1))); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), - ElementsAre(Bucket(1, 1))); + ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1))); EXPECT_THAT(histogram_tester.GetAllSamples( "NewTabPage.MostVisited.popular_fetched"), ElementsAre(Bucket(3, 1))); @@ -500,11 +446,8 @@ EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 4))); EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 2))); - EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 1))); + ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 3))); EXPECT_THAT(histogram_tester.GetAllSamples( "NewTabPage.TileTypeClicked.popular_fetched"), ElementsAre(Bucket(ntp_tiles::TileVisualType::ICON_REAL, 1))); @@ -514,11 +457,9 @@ Bucket(kManifestTitleSource, 1), Bucket(kTitleTagTitleSource, 1))); EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked.server"), - ElementsAre(Bucket(kUnknownTitleSource, 2))); - EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked.client"), - ElementsAre(Bucket(kTitleTagTitleSource, 1))); + ElementsAre(Bucket(kUnknownTitleSource, 2), + Bucket(kTitleTagTitleSource, 1))); EXPECT_THAT(histogram_tester.GetAllSamples( "NewTabPage.TileTitleClicked.popular_fetched"), ElementsAre(Bucket(kManifestTitleSource, 1))); @@ -560,33 +501,6 @@ delta_tiles_loaded, 1); } -TEST_F(NTPUserDataLoggerTest, ShouldRecordMostLikelyLoadTime) { - base::HistogramTester histogram_tester; - - TestNTPUserDataLogger logger(GURL("chrome://newtab/")); - - // Log a SUGGESTIONS_SERVICE impression, so the times will end up in - // .MostLikely. - logger.LogMostVisitedImpression(MakeNTPTileImpression( - 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, - TileVisualType::ICON_REAL)); - - base::TimeDelta delta_tiles_loaded = base::TimeDelta::FromMilliseconds(500); - logger.LogMostVisitedLoaded(delta_tiles_loaded, /*using_most_visited=*/true, - /*is_visible=*/true); - - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.LoadTime"), SizeIs(1)); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.LoadTime.MostVisited"), - IsEmpty()); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.LoadTime.MostLikely"), - SizeIs(1)); - - histogram_tester.ExpectTimeBucketCount("NewTabPage.LoadTime", - delta_tiles_loaded, 1); - histogram_tester.ExpectTimeBucketCount("NewTabPage.LoadTime.MostLikely", - delta_tiles_loaded, 1); -} - TEST_F(NTPUserDataLoggerTest, ShouldRecordLoadTimeRemoteNTPOther) { base::HistogramTester histogram_tester; @@ -628,7 +542,7 @@ constexpr base::TimeDelta kBucketTolerance = base::TimeDelta::FromSeconds(20); logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, + 0, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, TileVisualType::ICON_REAL, favicon_base::IconType::kInvalid, base::Time::Now() - kSuggestionAge, GURL())); @@ -636,7 +550,7 @@ /*is_visible=*/true); EXPECT_THAT(histogram_tester.GetAllSamples( - "NewTabPage.SuggestionsImpressionAge.server"), + "NewTabPage.SuggestionsImpressionAge.client"), ElementsAre(IsBucketBetween( (kSuggestionAge - kBucketTolerance).InSeconds(), (kSuggestionAge + kBucketTolerance).InSeconds(),
diff --git a/chrome/browser/ui/search/search_ipc_router_unittest.cc b/chrome/browser/ui/search/search_ipc_router_unittest.cc index 19718a2a..f8f1428 100644 --- a/chrome/browser/ui/search/search_ipc_router_unittest.cc +++ b/chrome/browser/ui/search/search_ipc_router_unittest.cc
@@ -347,9 +347,9 @@ TEST_F(SearchIPCRouterTest, ProcessLogMostVisitedImpressionMsg) { const ntp_tiles::NTPTileImpression impression( - 3, ntp_tiles::TileSource::SUGGESTIONS_SERVICE, - ntp_tiles::TileTitleSource::UNKNOWN, ntp_tiles::TileVisualType::ICON_REAL, - favicon_base::IconType::kInvalid, base::Time(), GURL()); + 3, ntp_tiles::TileSource::TOP_SITES, ntp_tiles::TileTitleSource::UNKNOWN, + ntp_tiles::TileVisualType::ICON_REAL, favicon_base::IconType::kInvalid, + base::Time(), GURL()); NavigateAndCommitActiveTab(GURL("chrome-search://foo/baz")); SetupMockDelegateAndPolicy(); MockSearchIPCRouterPolicy* policy = GetSearchIPCRouterPolicy(); @@ -364,9 +364,9 @@ TEST_F(SearchIPCRouterTest, ProcessLogMostVisitedNavigationMsg) { const ntp_tiles::NTPTileImpression impression( - 3, ntp_tiles::TileSource::SUGGESTIONS_SERVICE, - ntp_tiles::TileTitleSource::UNKNOWN, ntp_tiles::TileVisualType::ICON_REAL, - favicon_base::IconType::kInvalid, base::Time(), GURL()); + 3, ntp_tiles::TileSource::TOP_SITES, ntp_tiles::TileTitleSource::UNKNOWN, + ntp_tiles::TileVisualType::ICON_REAL, favicon_base::IconType::kInvalid, + base::Time(), GURL()); NavigateAndCommitActiveTab(GURL("chrome-search://foo/baz")); SetupMockDelegateAndPolicy(); MockSearchIPCRouterPolicy* policy = GetSearchIPCRouterPolicy();
diff --git a/chrome/browser/ui/tab_contents/tab_contents_iterator.cc b/chrome/browser/ui/tab_contents/tab_contents_iterator.cc index 6132096..d1857216 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_iterator.cc +++ b/chrome/browser/ui/tab_contents/tab_contents_iterator.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" #include "base/check.h" -#include "base/no_destructor.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -54,6 +53,6 @@ } const AllTabContentsesList& AllTabContentses() { - static const base::NoDestructor<AllTabContentsesList> all_tabs; - return *all_tabs; + static const AllTabContentsesList all_tabs; + return all_tabs; }
diff --git a/chrome/browser/ui/thumbnails/thumbnail_stats_tracker.h b/chrome/browser/ui/thumbnails/thumbnail_stats_tracker.h index 044a3b0..8ec6cce 100644 --- a/chrome/browser/ui/thumbnails/thumbnail_stats_tracker.h +++ b/chrome/browser/ui/thumbnails/thumbnail_stats_tracker.h
@@ -7,14 +7,10 @@ #include <set> +#include "base/no_destructor.h" #include "base/time/time.h" #include "base/timer/timer.h" -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - class ThumbnailImage; // Records memory metrics across all thumbnails in a browser process.
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc index 0b4ea70..0bbc1e82 100644 --- a/chrome/browser/ui/ui_features.cc +++ b/chrome/browser/ui/ui_features.cc
@@ -128,6 +128,11 @@ const base::Feature kTabGroupsNewBadgePromo{"TabGroupsNewBadgePromo", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables users to explicitly save and recall tab groups. +// https://crbug.com/1223929 +const base::Feature kTabGroupsSave{"TabGroupsSave", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables preview images in tab-hover cards. // https://crbug.com/928954 const base::Feature kTabHoverCardImages{"TabHoverCardImages",
diff --git a/chrome/browser/ui/ui_features.h b/chrome/browser/ui/ui_features.h index ec5881f7..a5562fc 100644 --- a/chrome/browser/ui/ui_features.h +++ b/chrome/browser/ui/ui_features.h
@@ -82,6 +82,8 @@ extern const base::Feature kTabGroupsNewBadgePromo; +extern const base::Feature kTabGroupsSave; + extern const base::Feature kTabHoverCardImages; extern const char kTabHoverCardImagesNotReadyDelayParameterName[]; extern const char kTabHoverCardImagesLoadingDelayParameterName[];
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc index 83255c7..46a0c2e5 100644 --- a/chrome/browser/ui/views/download/download_item_view.cc +++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -139,6 +139,9 @@ // The analysis service tag for data loss prevention. const char kDlpTag[] = "dlp"; +// The analysis service tag for malware. +const char kMalwareTag[] = "malware"; + // A stub subclass of Button that has no visuals. class TransparentButton : public views::Button { public: @@ -820,16 +823,26 @@ prompt_to_scan = danger_type == download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING; - prompt_to_review = - (danger_type == - download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING || - danger_type == - download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_BLOCK) && - enterprise_connectors::ConnectorsServiceFactory::GetForBrowserContext( - model_->profile()) - ->HasCustomInfoToDisplay( - enterprise_connectors::AnalysisConnector::FILE_DOWNLOADED, - kDlpTag); + if (danger_type == + download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING || + danger_type == download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_BLOCK) { + prompt_to_review = + enterprise_connectors::ConnectorsServiceFactory::GetForBrowserContext( + model_->profile()) + ->HasCustomInfoToDisplay( + enterprise_connectors::AnalysisConnector::FILE_DOWNLOADED, + kDlpTag); + } else if (danger_type == download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE || + danger_type == download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL || + danger_type == + download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT) { + prompt_to_review = + enterprise_connectors::ConnectorsServiceFactory::GetForBrowserContext( + model_->profile()) + ->HasCustomInfoToDisplay( + enterprise_connectors::AnalysisConnector::FILE_DOWNLOADED, + kMalwareTag); + } prompt_to_discard = !prompt_to_review && !prompt_to_scan && @@ -1243,6 +1256,14 @@ WARNING; } + const char* tag = + (danger_type == + download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING || + danger_type == + download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_BLOCK + ? kDlpTag + : kMalwareTag); + auto* connectors_service = enterprise_connectors::ConnectorsServiceFactory::GetForBrowserContext( model_->profile()); @@ -1251,14 +1272,12 @@ std::u16string custom_message = connectors_service ->GetCustomMessage( - enterprise_connectors::AnalysisConnector::FILE_DOWNLOADED, - kDlpTag) + enterprise_connectors::AnalysisConnector::FILE_DOWNLOADED, tag) .value_or(u""); GURL learn_more_url = connectors_service ->GetLearnMoreUrl( - enterprise_connectors::AnalysisConnector::FILE_DOWNLOADED, - kDlpTag) + enterprise_connectors::AnalysisConnector::FILE_DOWNLOADED, tag) .value_or(GURL()); // This dialog opens itself, and is thereafter owned by constrained window
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc index f82e4e3..18897624 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
@@ -137,11 +137,13 @@ } void StartOverview() { - ash::Shell::Get()->overview_controller()->StartOverview(); + ash::Shell::Get()->overview_controller()->StartOverview( + ash::OverviewStartAction::kTests); } void EndOverview() { - ash::Shell::Get()->overview_controller()->EndOverview(); + ash::Shell::Get()->overview_controller()->EndOverview( + ash::OverviewEndAction::kTests); } bool IsShelfVisible() {
diff --git a/chrome/browser/ui/views/frame/webui_tab_strip_field_trial.cc b/chrome/browser/ui/views/frame/webui_tab_strip_field_trial.cc index d9143d9..a6045dc 100644 --- a/chrome/browser/ui/views/frame/webui_tab_strip_field_trial.cc +++ b/chrome/browser/ui/views/frame/webui_tab_strip_field_trial.cc
@@ -6,7 +6,6 @@ #include "base/feature_list.h" #include "base/logging.h" -#include "base/no_destructor.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" @@ -51,7 +50,7 @@ // static void WebUITabStripFieldTrial::RegisterFieldTrialIfNecessary() { - static base::NoDestructor<WebUITabStripFieldTrial> instance; + static WebUITabStripFieldTrial instance; } WebUITabStripFieldTrial::WebUITabStripFieldTrial() {
diff --git a/chrome/browser/ui/views/frame/webui_tab_strip_field_trial.h b/chrome/browser/ui/views/frame/webui_tab_strip_field_trial.h index 7342d59..1884c953 100644 --- a/chrome/browser/ui/views/frame/webui_tab_strip_field_trial.h +++ b/chrome/browser/ui/views/frame/webui_tab_strip_field_trial.h
@@ -5,10 +5,7 @@ #ifndef CHROME_BROWSER_UI_VIEWS_FRAME_WEBUI_TAB_STRIP_FIELD_TRIAL_H_ #define CHROME_BROWSER_UI_VIEWS_FRAME_WEBUI_TAB_STRIP_FIELD_TRIAL_H_ -namespace base { -template <typename T> -class NoDestructor; -} +#include "base/no_destructor.h" // Manages a synthetic field trial for the WebUI tab strip. The feature // flag itself is controlled by an external field trial. This synthetic
diff --git a/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc b/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc index 857126bd..f21ea451 100644 --- a/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc +++ b/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc
@@ -263,7 +263,6 @@ // "chrome://signin-dice-web-intercept", "chrome://signin-internals", "chrome://site-engagement", - "chrome://suggestions", // TODO(crbug.com/1099564): Navigating to chrome://sync-confirmation and // quickly navigating away cause DCHECK failure. // "chrome://sync-confirmation",
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index c47da6f6..c466e88 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -23,7 +23,6 @@ #include "chrome/browser/media/media_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/search/suggestions/suggestions_ui.h" #include "chrome/browser/ui/chrome_select_file_policy.h" #include "chrome/browser/ui/webui/about_ui.h" #include "chrome/browser/ui/webui/autofill_and_password_manager_internals/autofill_internals_ui.h" @@ -630,8 +629,6 @@ return &NewWebUI<safe_browsing::SafeBrowsingUI>; if (url.host_piece() == chrome::kChromeUISignInInternalsHost) return &NewWebUI<SignInInternalsUI>; - if (url.host_piece() == chrome::kChromeUISuggestionsHost) - return &NewWebUI<suggestions::SuggestionsUI>; if (url.host_piece() == chrome::kChromeUISupervisedUserPassphrasePageHost) return &NewWebUI<ConstrainedWebDialogUI>; if (url.host_piece() == chrome::kChromeUISyncInternalsHost)
diff --git a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_metrics_recorder.cc b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_metrics_recorder.cc index d9412ba..13c687f 100644 --- a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_metrics_recorder.cc +++ b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_metrics_recorder.cc
@@ -12,8 +12,8 @@ // static AddSupervisionMetricsRecorder* AddSupervisionMetricsRecorder::GetInstance() { - static base::NoDestructor<AddSupervisionMetricsRecorder> instance_; - return instance_.get(); + static AddSupervisionMetricsRecorder instance_; + return &instance_; } void AddSupervisionMetricsRecorder::RecordAddSupervisionEnrollment(
diff --git a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_metrics_recorder.h b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_metrics_recorder.h index 540c314..1e20c1e 100644 --- a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_metrics_recorder.h +++ b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_metrics_recorder.h
@@ -6,7 +6,6 @@ #define CHROME_BROWSER_UI_WEBUI_CHROMEOS_ADD_SUPERVISION_ADD_SUPERVISION_METRICS_RECORDER_H_ #include "base/macros.h" -#include "base/no_destructor.h" #include "base/time/time.h" namespace base { @@ -47,8 +46,6 @@ void SetClockForTesting(const base::TickClock* tick_clock); private: - friend class base::NoDestructor<AddSupervisionMetricsRecorder>; - AddSupervisionMetricsRecorder(); // Records UMA metric of how long the user spends in the Add Supervision
diff --git a/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc b/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc index d23b3545..1ad3803 100644 --- a/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc +++ b/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
@@ -14,7 +14,6 @@ #include "chrome/browser/history/top_sites_factory.h" #include "chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/search/suggestions/suggestions_service_factory.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/common/url_constants.h" #include "components/grit/dev_ui_components_resources.h" @@ -79,7 +78,6 @@ ntp_tiles::TileSource source) { switch (source) { case ntp_tiles::TileSource::TOP_SITES: - case ntp_tiles::TileSource::SUGGESTIONS_SERVICE: case ntp_tiles::TileSource::ALLOWLIST: case ntp_tiles::TileSource::HOMEPAGE: return true;
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc index 8cae117..b77f5ff 100644 --- a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
@@ -245,7 +245,7 @@ std::unique_ptr<base::ListValue>* printers_out, const base::ListValue& printers) { ++(*call_count); - printers_out->reset(printers.DeepCopy()); + *printers_out = printers.CreateDeepCopy(); } // Used as a callback to StartGetPrinters in tests.
diff --git a/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos_unittest.cc b/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos_unittest.cc index 1dd8c674..dfdd73a 100644 --- a/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos_unittest.cc
@@ -32,7 +32,7 @@ std::unique_ptr<base::ListValue>& printers_out, const base::ListValue& printers) { ++call_count; - printers_out.reset(printers.DeepCopy()); + printers_out = printers.CreateDeepCopy(); } // Used as a callback to `StartGetPrinters` in tests.
diff --git a/chrome/browser/ui/webui/print_preview/local_printer_handler_default_unittest.cc b/chrome/browser/ui/webui/print_preview/local_printer_handler_default_unittest.cc index f7f5904..ce2753e 100644 --- a/chrome/browser/ui/webui/print_preview/local_printer_handler_default_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/local_printer_handler_default_unittest.cc
@@ -43,7 +43,7 @@ std::unique_ptr<base::ListValue>& printers_out, const base::ListValue& printers) { ++call_count; - printers_out.reset(printers.DeepCopy()); + printers_out = printers.CreateDeepCopy(); } // Used as a callback to `StartGetPrinters` in tests.
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_chromeos.h b/chrome/browser/upgrade_detector/upgrade_detector_chromeos.h index 99062fa..b4cc9e73 100644 --- a/chrome/browser/upgrade_detector/upgrade_detector_chromeos.h +++ b/chrome/browser/upgrade_detector/upgrade_detector_chromeos.h
@@ -7,6 +7,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/no_destructor.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "chrome/browser/upgrade_detector/build_state_observer.h" @@ -17,8 +18,6 @@ class PrefRegistrySimple; namespace base { class Clock; -template <typename T> -class NoDestructor; class TickClock; } // namespace base
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_impl.h b/chrome/browser/upgrade_detector/upgrade_detector_impl.h index 25ad785..73a7934 100644 --- a/chrome/browser/upgrade_detector/upgrade_detector_impl.h +++ b/chrome/browser/upgrade_detector/upgrade_detector_impl.h
@@ -8,6 +8,7 @@ #include <array> #include "base/macros.h" +#include "base/no_destructor.h" #include "base/sequence_checker.h" #include "base/timer/timer.h" #include "base/version.h" @@ -19,8 +20,6 @@ namespace base { class Clock; -template <typename T> -class NoDestructor; class TickClock; } // namespace base
diff --git a/chrome/browser/web_applications/components/install_bounce_metric.cc b/chrome/browser/web_applications/components/install_bounce_metric.cc index fa0a73d..20b47f6 100644 --- a/chrome/browser/web_applications/components/install_bounce_metric.cc +++ b/chrome/browser/web_applications/components/install_bounce_metric.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/web_applications/components/install_bounce_metric.h" #include "base/metrics/histogram_macros.h" -#include "base/no_destructor.h" #include "base/strings/string_number_conversions.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_registry_simple.h" @@ -16,8 +15,8 @@ namespace { absl::optional<base::Time>& GetTimeOverride() { - static base::NoDestructor<absl::optional<base::Time>> g_time_override; - return *g_time_override; + static absl::optional<base::Time> time_override; + return time_override; } base::Time GetTime() {
diff --git a/chrome/common/channel_info_mac.mm b/chrome/common/channel_info_mac.mm index cef77b676..6696a10f 100644 --- a/chrome/common/channel_info_mac.mm +++ b/chrome/common/channel_info_mac.mm
@@ -95,7 +95,7 @@ bool SideBySideCapable() { #if BUILDFLAG(GOOGLE_CHROME_BRANDING) - static const base::NoDestructor<bool> capable([] { + static const bool capable = [] { // Use the main Chrome application bundle and not the framework bundle. // Keystone keys don't live in the framework. NSBundle* bundle = base::mac::OuterBundle(); @@ -117,8 +117,8 @@ // beta/dev/canary Chrome is separate, and it can run side-by-side to the // stable Chrome. return [bundle objectForInfoDictionaryKey:@"CrProductDirName"] != nil; - }()); - return *capable; + }(); + return capable; #else return true; #endif
diff --git a/chrome/common/privacy_budget/BUILD.gn b/chrome/common/privacy_budget/BUILD.gn index 8190119..0d22dbf 100644 --- a/chrome/common/privacy_budget/BUILD.gn +++ b/chrome/common/privacy_budget/BUILD.gn
@@ -11,6 +11,7 @@ "privacy_budget_features.h", "privacy_budget_settings_provider.cc", "privacy_budget_settings_provider.h", + "types.h", ] public_deps = [
diff --git a/chrome/common/privacy_budget/container_ops.h b/chrome/common/privacy_budget/container_ops.h index 29ac502..6449586 100644 --- a/chrome/common/privacy_budget/container_ops.h +++ b/chrome/common/privacy_budget/container_ops.h
@@ -15,8 +15,8 @@ #include "base/strings/string_piece.h" namespace internal { -// Note that these implementations aren't meant for to be used outside of the -// narrow usage within this directory. +// Note that these implementations aren't meant to be used outside of the narrow +// usage within this directory. // Moves a random subset of |num| elements from |from| to |to|. The type |T| // must satisfy |UnorderedAssociativeContainer|. @@ -47,7 +47,7 @@ to_be_moved.reserve(from->size()); std::copy_if(from->begin(), from->end(), std::inserter(to_be_moved, to_be_moved.end()), predicate); - for (const auto& v : to_be_moved) + for (const auto v : to_be_moved) from->erase(v); to->insert(to_be_moved.begin(), to_be_moved.end()); return !to_be_moved.empty();
diff --git a/chrome/common/privacy_budget/container_ops_unittest.cc b/chrome/common/privacy_budget/container_ops_unittest.cc index f524505..4d43c12 100644 --- a/chrome/common/privacy_budget/container_ops_unittest.cc +++ b/chrome/common/privacy_budget/container_ops_unittest.cc
@@ -2,17 +2,32 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <initializer_list> +#include <iterator> #include <set> #include "base/containers/cxx20_erase.h" +#include "base/containers/flat_set.h" +#include "base/notreached.h" +#include "base/ranges/algorithm.h" #include "chrome/common/privacy_budget/container_ops.h" +#include "chrome/common/privacy_budget/types.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" namespace internal { namespace { -typedef ::testing::Types<std::unordered_set<int>, std::set<int>> ContainerTypes; +typedef ::testing::Types<IdentifiableSurfaceSet> ContainerTypes; + +IdentifiableSurfaceSet TestCaseFrom(std::initializer_list<int> ints) { + IdentifiableSurfaceSet::container_type surfaces; + base::ranges::transform(ints, std::back_inserter(surfaces), [](const auto v) { + return blink::IdentifiableSurface::FromMetricHash(v); + }); + return IdentifiableSurfaceSet(surfaces); +} } // namespace @@ -22,8 +37,8 @@ TYPED_TEST_SUITE_P(ContainerOpsTest); TYPED_TEST_P(ContainerOpsTest, TestExtractRandomSubset) { - TypeParam from = {1, 2, 3, 4}; - TypeParam to = {5}; + TypeParam from = TestCaseFrom({1, 2, 3, 4}); + TypeParam to = TestCaseFrom({5}); EXPECT_TRUE(ExtractRandomSubset(&from, &to, 1)); EXPECT_EQ(3u, from.size()); @@ -31,15 +46,15 @@ } TYPED_TEST_P(ContainerOpsTest, TestExtractRandomSubset_Zero) { - TypeParam from = {1, 2, 3, 4}; - TypeParam to = {5}; + TypeParam from = TestCaseFrom({1, 2, 3, 4}); + TypeParam to = TestCaseFrom({5}); EXPECT_FALSE(ExtractRandomSubset(&from, &to, 0)); - EXPECT_EQ(from, (TypeParam{1, 2, 3, 4})); + EXPECT_EQ(from, TestCaseFrom({1, 2, 3, 4})); } TYPED_TEST_P(ContainerOpsTest, TestExtractRandomSubset_Empty) { - TypeParam to = {5}; + TypeParam to = TestCaseFrom({5}); // Moving from an empty set. TypeParam from_two; @@ -47,8 +62,9 @@ } TYPED_TEST_P(ContainerOpsTest, TestExtractRandomSubset_Overflow) { - TypeParam from = {1, 2, 3, 4}; - TypeParam to = {5}; + TypeParam from = TestCaseFrom({1, 2, 3, 4}); + TypeParam to = TestCaseFrom({5}); + // Overflow. EXPECT_TRUE(ExtractRandomSubset(&from, &to, 100)); EXPECT_EQ(0u, from.size()); @@ -56,8 +72,9 @@ } TYPED_TEST_P(ContainerOpsTest, TestExtractRandomSubset_Merge) { - TypeParam from = {1, 2, 3, 4}; - TypeParam to = {1, 2, 3, 4, 5}; + TypeParam from = TestCaseFrom({1, 2, 3, 4}); + TypeParam to = TestCaseFrom({1, 2, 3, 4, 5}); + // Moved element disappears because |from| is a subset of |to|. Assuming the // underlying set implementation is correct (we'd be in pretty bad shape if // that were not true) verifies that the element being moved is one we expect. @@ -67,9 +84,9 @@ } TYPED_TEST_P(ContainerOpsTest, TestIntersects) { - TypeParam a = {1, 2, 3, 4}; - TypeParam b = {4, 5, 6, 7}; - TypeParam c = {10, 11}; + TypeParam a = TestCaseFrom({1, 2, 3, 4}); + TypeParam b = TestCaseFrom({4, 5, 6, 7}); + TypeParam c = TestCaseFrom({10, 11}); TypeParam d; EXPECT_TRUE(Intersects(a, b)); @@ -79,27 +96,28 @@ } TYPED_TEST_P(ContainerOpsTest, TestExtractIf_Basic) { - TypeParam from = {1, 2, 3, 4, 5, 6}; + TypeParam from = TestCaseFrom({1, 2, 3, 4, 5, 6}); TypeParam to; // Extracts only when predicate is true. - EXPECT_TRUE(ExtractIf(&from, &to, [](const auto& v) { return v % 2 == 0; })); - EXPECT_EQ(from, (TypeParam{1, 3, 5})); - EXPECT_EQ(to, (TypeParam{2, 4, 6})); + EXPECT_TRUE(ExtractIf( + &from, &to, [](const auto& v) { return v.ToUkmMetricHash() % 2 == 0; })); + EXPECT_EQ(from, TestCaseFrom({1, 3, 5})); + EXPECT_EQ(to, TestCaseFrom({2, 4, 6})); } TYPED_TEST_P(ContainerOpsTest, TestExtractIf_AlwaysFalse) { - TypeParam from = {1, 3, 5}; + TypeParam from = TestCaseFrom({1, 3, 5}); TypeParam to; // Noop if predicate is always false. EXPECT_FALSE(ExtractIf(&from, &to, [](const auto& v) { return false; })); - EXPECT_EQ(from, (TypeParam{1, 3, 5})); + EXPECT_EQ(from, TestCaseFrom({1, 3, 5})); EXPECT_TRUE(to.empty()); } TYPED_TEST_P(ContainerOpsTest, TestExtractIf_AlwaysTrue) { - TypeParam from = {1, 2, 3, 4, 5, 6}; + TypeParam from = TestCaseFrom({1, 2, 3, 4, 5, 6}); TypeParam to; // Just because. Isn't testing anything new. @@ -110,7 +128,7 @@ TYPED_TEST_P(ContainerOpsTest, TestExtractIf_EmptySource) { TypeParam from; - TypeParam to = {1, 2, 3, 4, 5, 6}; + TypeParam to = TestCaseFrom({1, 2, 3, 4, 5, 6}); // Noop if |from| is empty. EXPECT_FALSE(ExtractIf(&from, &to, [](const auto& v) { return true; })); @@ -119,29 +137,29 @@ } TYPED_TEST_P(ContainerOpsTest, TestSubtractLeftFromRight_WithIntersection) { - TypeParam a = {1, 2, 3, 4, 5, 6, 7}; - TypeParam b = {2, 3, 4}; + TypeParam a = TestCaseFrom({1, 2, 3, 4, 5, 6, 7}); + TypeParam b = TestCaseFrom({2, 3, 4}); EXPECT_TRUE(SubtractLeftFromRight(b, &a)); - EXPECT_EQ(a, (TypeParam{1, 5, 6, 7})); + EXPECT_EQ(a, (TestCaseFrom({1, 5, 6, 7}))); } TYPED_TEST_P(ContainerOpsTest, TestSubtractLeftFromRight_NoIntersection) { - TypeParam a = {1, 5, 6, 7}; - TypeParam c = {10}; + TypeParam a = TestCaseFrom({1, 5, 6, 7}); + TypeParam c = TestCaseFrom({10}); // Nothing happens if there's no intersection. EXPECT_FALSE(SubtractLeftFromRight(c, &a)); - EXPECT_EQ(a, (TypeParam{1, 5, 6, 7})); + EXPECT_EQ(a, TestCaseFrom({1, 5, 6, 7})); } TYPED_TEST_P(ContainerOpsTest, TestSubtractLeftFromRight_LeftEmpty) { - TypeParam a = {1, 5, 6, 7}; + TypeParam a = TestCaseFrom({1, 5, 6, 7}); TypeParam d; // Nothing happens when the left side is empty. EXPECT_FALSE(SubtractLeftFromRight(d, &a)); - EXPECT_EQ(a, (TypeParam{1, 5, 6, 7})); + EXPECT_EQ(a, TestCaseFrom({1, 5, 6, 7})); } REGISTER_TYPED_TEST_SUITE_P(ContainerOpsTest,
diff --git a/chrome/common/privacy_budget/field_trial_param_conversions.cc b/chrome/common/privacy_budget/field_trial_param_conversions.cc index 80859cbe..bc0143d 100644 --- a/chrome/common/privacy_budget/field_trial_param_conversions.cc +++ b/chrome/common/privacy_budget/field_trial_param_conversions.cc
@@ -4,7 +4,15 @@ #include "chrome/common/privacy_budget/field_trial_param_conversions.h" +#include <algorithm> #include <utility> +#include "base/ranges/algorithm.h" +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" + +namespace privacy_budget_internal { bool DecodeIdentifiabilityType(const base::StringPiece s, blink::IdentifiableSurface* out) { @@ -26,6 +34,25 @@ return true; } +bool DecodeIdentifiabilityType(const base::StringPiece s, int* out) { + return base::StringToInt(s, out); +} + +bool DecodeIdentifiabilityType(const base::StringPiece s, unsigned int* out) { + return base::StringToUint(s, out); +} + +bool DecodeIdentifiabilityType(const base::StringPiece s, double* out) { + return base::StringToDouble(s, out); +} + +bool DecodeIdentifiabilityType(const base::StringPiece s, + std::vector<blink::IdentifiableSurface>* out) { + *out = DecodeIdentifiabilityFieldTrialParam< + std::vector<blink::IdentifiableSurface>, ';'>(s); + return !out->empty(); +} + std::string EncodeIdentifiabilityType(const blink::IdentifiableSurface& s) { return base::NumberToString(s.ToUkmMetricHash()); } @@ -37,12 +64,23 @@ std::string EncodeIdentifiabilityType( const std::pair<const blink::IdentifiableSurface, int>& v) { - return EncodeIdentifiabilityType(v.first) + ";" + - base::NumberToString(v.second); + return base::StrCat({EncodeIdentifiabilityType(v.first), ";", + base::NumberToString(v.second)}); +} + +std::string EncodeIdentifiabilityType(const unsigned int& v) { + return base::NumberToString(v); } std::string EncodeIdentifiabilityType( - const std::pair<const blink::IdentifiableSurface::Type, int>& v) { - return EncodeIdentifiabilityType(v.first) + ";" + - base::NumberToString(v.second); + const std::vector<blink::IdentifiableSurface>& value) { + std::vector<std::string> parts; + base::ranges::transform( + value, std::back_inserter(parts), + [](const blink::IdentifiableSurface v) -> std::string { + return EncodeIdentifiabilityType(v); + }); + return base::JoinString(parts, ";"); } + +} // namespace privacy_budget_internal
diff --git a/chrome/common/privacy_budget/field_trial_param_conversions.h b/chrome/common/privacy_budget/field_trial_param_conversions.h index 3c99297..f967aa34 100644 --- a/chrome/common/privacy_budget/field_trial_param_conversions.h +++ b/chrome/common/privacy_budget/field_trial_param_conversions.h
@@ -5,101 +5,107 @@ #ifndef CHROME_COMMON_PRIVACY_BUDGET_FIELD_TRIAL_PARAM_CONVERSIONS_H_ #define CHROME_COMMON_PRIVACY_BUDGET_FIELD_TRIAL_PARAM_CONVERSIONS_H_ +#include <iterator> #include <type_traits> +#include <vector> -#include "base/notreached.h" +#include "base/ranges/algorithm.h" +#include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" -#include "chrome/common/privacy_budget/privacy_budget_features.h" #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" // The Encode/Decode families of functions are meant to be used to encode // various types so that they can be specified via field trial configurations // and Prefs. +namespace privacy_budget_internal { + +// DecodeIdentifiabilityType() overloads should not be called directly. Instead +// use either DecodeIdentifiabilityFieldTrialParam() or +// EncodeIdentifiabilityFieldTrialParam(). +// +// DecodeIdentifiabilityType(StringPiece s,V* v) decodes a element of type +// V serialized as a string and referred to via StringPiece s and stores it in +// *v. bool DecodeIdentifiabilityType(const base::StringPiece, blink::IdentifiableSurface*); - bool DecodeIdentifiabilityType(const base::StringPiece, blink::IdentifiableSurface::Type*); +bool DecodeIdentifiabilityType(const base::StringPiece, int*); +bool DecodeIdentifiabilityType(const base::StringPiece, unsigned int*); +bool DecodeIdentifiabilityType(const base::StringPiece, double*); +bool DecodeIdentifiabilityType(const base::StringPiece, + std::vector<blink::IdentifiableSurface>*); -// This explosion of DecodeIdentifiabilityTypePair specializations is a great -// example of why you don't want to go down the path of templates if you could -// ever avoid it. -// -// The variability here is that unordered_map uses pair<K,V> as its value_type -// while map uses pair<const K, V>. Per spec, unordered_map should also use the -// latter, but alas, that is not the case. -// -// Adding to the confusion, pair<const K, V> is non-movable and non-copyable. So -// it can't be returned via a trivial *out parameter. Amazing. -template <typename U, - typename V = typename U::value_type, - typename P = typename std::remove_const<typename V::first_type>::type> -std::pair<V, bool> DecodeIdentifiabilityTypePair(base::StringPiece s) { +// V is a std::pair<P,R> where P and R are types known to +// DecodeIdentifiabilityType(). +template < + typename V, + typename P = typename std::remove_const<typename V::first_type>::type, + typename R = typename std::remove_const<typename V::second_type>::type> +bool DecodeIdentifiabilityType(base::StringPiece s, V* result) { auto pieces = base::SplitStringPiece(s, ";", base::WhitespaceHandling::TRIM_WHITESPACE, base::SplitResult::SPLIT_WANT_NONEMPTY); if (pieces.size() != 2) - return {V(), false}; - P type_id; - int rate; - if (!DecodeIdentifiabilityType(pieces[0], &type_id) || - !base::StringToInt(pieces[1], &rate)) - return {V(), false}; - if (rate < 0 || rate > features::kMaxIdentifiabilityStudySurfaceSelectionRate) - return {V(), false}; - return {V(type_id, rate), true}; -} - -template < - typename U, - typename S = std::enable_if_t< - std::is_same<typename U::key_type, typename U::value_type>::value>> -std::pair<typename U::value_type, bool> DecodeIdentifiabilityTypePair( - base::StringPiece s) { - using P = typename U::value_type; - P value; - if (!DecodeIdentifiabilityType(s, &value)) - return {P(), false}; - return {value, true}; + return false; + P first; + R second; + if (!DecodeIdentifiabilityType(pieces[0], &first) || + !DecodeIdentifiabilityType(pieces[1], &second)) + return false; + ::new (result) V(std::move(first), std::move(second)); + return true; } std::string EncodeIdentifiabilityType(const blink::IdentifiableSurface&); - std::string EncodeIdentifiabilityType(const blink::IdentifiableSurface::Type&); - +std::string EncodeIdentifiabilityType(const unsigned int&); +template <typename T, typename U> +std::string EncodeIdentifiabilityType(const std::pair<T, U>& v) { + return base::StrCat({EncodeIdentifiabilityType(v.first), ";", + base::NumberToString(v.second)}); +} std::string EncodeIdentifiabilityType( - const std::pair<const blink::IdentifiableSurface, int>&); + const std::vector<blink::IdentifiableSurface>& value); -std::string EncodeIdentifiabilityType( - const std::pair<const blink::IdentifiableSurface::Type, int>&); +template <typename T> +struct NoOpFilter { + bool operator()(T t) { return true; } +}; -std::string EncodeIdentifiabilityType( - const std::pair<blink::IdentifiableSurface, int>&); +// Instantiate with a type and inherit from std::true_type in order to sort the +// encoded elements of a container. The ordering is undefined but stable across +// versions of Chrome. +template <typename T> +struct SortWhenSerializing : std::false_type {}; -std::string EncodeIdentifiabilityType( - const std::pair<blink::IdentifiableSurface::Type, int>&); +} // namespace privacy_budget_internal // Decodes a field trial parameter containing a list of values. The result is // returned in the form of a container type that must be specified at // instantiation. There should be a valid DecodeIdentifiabilityType // specialization for the container's value type. template <typename T, - std::pair<typename T::value_type, bool> Decoder( - const base::StringPiece) = DecodeIdentifiabilityTypePair<T>> + char Separator = ',', + typename V = typename T::value_type, + bool ElementDecoder(const base::StringPiece, V*) = + &privacy_budget_internal::DecodeIdentifiabilityType> T DecodeIdentifiabilityFieldTrialParam(base::StringPiece encoded_value) { T result; - auto hashes = base::SplitStringPiece( - encoded_value, ",", base::WhitespaceHandling::TRIM_WHITESPACE, - base::SplitResult::SPLIT_WANT_NONEMPTY); - for (const auto& hash : hashes) { - auto decoded = Decoder(hash); - if (!decoded.second) + auto pieces = + base::SplitStringPiece(encoded_value, std::string(1, Separator), + base::WhitespaceHandling::TRIM_WHITESPACE, + base::SplitResult::SPLIT_WANT_NONEMPTY); + auto inserter = std::inserter(result, result.end()); + for (const auto& piece : pieces) { + V v; + if (!ElementDecoder(piece, &v)) continue; - result.insert(decoded.first); + inserter = v; } return result; } @@ -109,13 +115,18 @@ // value_type must have a corresponding EncodeIdentifiabilityType // specialization. template <typename T, - std::string Encoder(const typename T::value_type&) = - EncodeIdentifiabilityType> + std::string ElementEncoder(const typename T::value_type&) = + privacy_budget_internal::EncodeIdentifiabilityType> std::string EncodeIdentifiabilityFieldTrialParam(const T& source) { - std::vector<std::string> result; - std::transform(source.begin(), source.end(), std::back_inserter(result), - [](auto& v) { return Encoder(v); }); - return base::JoinString(result, ","); + std::vector<std::string> encoded_elements; + std::transform(source.begin(), source.end(), + std::back_inserter(encoded_elements), + [](auto& v) { return ElementEncoder(v); }); + if (privacy_budget_internal::SortWhenSerializing< + typename std::remove_cv<T>::type>::value) { + base::ranges::sort(encoded_elements); + } + return base::JoinString(encoded_elements, ","); } #endif // CHROME_COMMON_PRIVACY_BUDGET_FIELD_TRIAL_PARAM_CONVERSIONS_H_
diff --git a/chrome/common/privacy_budget/field_trial_param_conversions_unittest.cc b/chrome/common/privacy_budget/field_trial_param_conversions_unittest.cc index 88a15f5..0d7e9f59 100644 --- a/chrome/common/privacy_budget/field_trial_param_conversions_unittest.cc +++ b/chrome/common/privacy_budget/field_trial_param_conversions_unittest.cc
@@ -4,60 +4,224 @@ #include "chrome/common/privacy_budget/field_trial_param_conversions.h" +#include <cstddef> +#include <cstdint> +#include <limits> +#include <string> +#include <vector> + +#include "chrome/common/privacy_budget/types.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" -TEST(FieldTrialParamConversionsTest, Surface) { - auto original_surface = blink::IdentifiableSurface::FromMetricHash(100); - EXPECT_EQ(std::string("100"), EncodeIdentifiabilityType(original_surface)); +namespace privacy_budget_internal { - original_surface = blink::IdentifiableSurface::FromTypeAndToken( - blink::IdentifiableSurface::Type::kWebFeature, 1); - std::string encoded = EncodeIdentifiabilityType(original_surface); - EXPECT_EQ(std::string("257"), encoded); +namespace { + +// 100 +constexpr auto kSurface1 = blink::IdentifiableSurface::FromMetricHash(100); + +// 257 +constexpr auto kSurface2 = blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kWebFeature, + 1); + +// 36028797018963968 +constexpr auto kSurface3 = + blink::IdentifiableSurface::FromMetricHash(UINT64_C(1) << 55); + +// 1 +constexpr auto kType1 = blink::IdentifiableSurface::Type::kWebFeature; + +// 9 +constexpr auto kType2 = + blink::IdentifiableSurface::Type::kMediaRecorder_IsTypeSupported; + +} // namespace + +TEST(FieldTrialParamConversionsTest, EncodeDecodeSingleSurface) { + EXPECT_EQ(std::string("100"), EncodeIdentifiabilityType(kSurface1)); auto decoded_surface = blink::IdentifiableSurface(); - EXPECT_TRUE(DecodeIdentifiabilityType(encoded, &decoded_surface)); - EXPECT_EQ(original_surface, decoded_surface); + EXPECT_TRUE(DecodeIdentifiabilityType("257", &decoded_surface)); + EXPECT_EQ(kSurface2, decoded_surface); + + EXPECT_FALSE(DecodeIdentifiabilityType("", &decoded_surface)); } -TEST(FieldTrialParamConversionsTest, Type) { - auto original_type = blink::IdentifiableSurface::Type::kWebFeature; - std::string encoded = EncodeIdentifiabilityType(original_type); - EXPECT_EQ(std::string("1"), encoded); +TEST(FieldTrialParamConversionsTest, EncodeDecodeSingleType) { + EXPECT_EQ(std::string("1"), EncodeIdentifiabilityType(kType1)); auto foo = blink::IdentifiableSurface::Type::kReservedInternal; - EXPECT_TRUE(DecodeIdentifiabilityType(encoded, &foo)); - EXPECT_EQ(original_type, foo); + EXPECT_TRUE(DecodeIdentifiabilityType("1", &foo)); + EXPECT_EQ(kType1, foo); + + EXPECT_FALSE(DecodeIdentifiabilityType("", &foo)); } -TEST(FieldTrialParamConversionsTest, FieldTrialParam_Surface) { - std::map<blink::IdentifiableSurface, int> original_map; - original_map[blink::IdentifiableSurface::FromMetricHash(100)] = 5; - original_map[blink::IdentifiableSurface::FromMetricHash(UINT64_C(1) << 55)] = - 5; +TEST(FieldTrialParamConversionsTest, SurfaceToIntMap) { + const std::map<blink::IdentifiableSurface, unsigned int> original_map = { + {kSurface1, 5}, {kSurface3, 5}}; auto encoded = EncodeIdentifiabilityFieldTrialParam(original_map); EXPECT_EQ(std::string("100;5,36028797018963968;5"), encoded); auto decoded_map = DecodeIdentifiabilityFieldTrialParam< - std::map<blink::IdentifiableSurface, int>>(encoded); + std::map<blink::IdentifiableSurface, unsigned int>>(encoded); EXPECT_EQ(original_map, decoded_map); } -TEST(FieldTrialParamConversionsTest, FieldTrialParam_Type) { - std::map<blink::IdentifiableSurface::Type, int> original_map; - original_map[blink::IdentifiableSurface::Type::kReservedInternal] = 6; - original_map[blink::IdentifiableSurface::Type::kWebFeature] = 5; +TEST(FieldTrialParamConversionsTest, IdentifiableSurfaceList) { + const IdentifiableSurfaceList kSurfaceList = {kSurface1, kSurface2, + kSurface3}; + + auto encoded_surface_list = + EncodeIdentifiabilityFieldTrialParam(kSurfaceList); + EXPECT_EQ(std::string("100,257,36028797018963968"), encoded_surface_list); + + auto decoded_surface_list = + DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceList>( + encoded_surface_list); + EXPECT_EQ(kSurfaceList, decoded_surface_list); +} + +TEST(FieldTrialParamConversionsTest, IdentifiableSurfaceTypeList) { + const IdentifiableSurfaceTypeList kTypeList = {kType1, kType2}; + + auto encoded_type_list = EncodeIdentifiabilityFieldTrialParam(kTypeList); + EXPECT_EQ(std::string("1,9"), encoded_type_list); + + auto decoded_type_list = + DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceTypeList>( + encoded_type_list); + EXPECT_EQ(kTypeList, decoded_type_list); +} + +TEST(FieldTrialParamConversionsTest, IdentifiableSurfaceSet) { + const IdentifiableSurfaceSet kSurfaceSet = {kSurface1, kSurface2, kSurface3}; + + auto encoded_surface_set = EncodeIdentifiabilityFieldTrialParam(kSurfaceSet); + EXPECT_EQ(std::string("100,257,36028797018963968"), encoded_surface_set); + + auto decoded_surface_set = + DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceSet>( + encoded_surface_set); + EXPECT_EQ(kSurfaceSet, decoded_surface_set); +} + +TEST(FieldTrialParamConversionsTest, IdentifiableSurfaceTypeSet) { + const IdentifiableSurfaceTypeSet kTypeSet = {kType1, kType2}; + + auto encoded_type_set = EncodeIdentifiabilityFieldTrialParam(kTypeSet); + EXPECT_EQ(std::string("1,9"), encoded_type_set); + + auto decoded_type_set = + DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceTypeSet>( + encoded_type_set); + EXPECT_EQ(kTypeSet, decoded_type_set); +} + +TEST(FieldTrialParamConversionsTest, IdentifiableSurfaceSampleRateMap) { + IdentifiableSurfaceSampleRateMap original_map = {{kSurface1, 5}, + {kSurface2, 6}}; auto encoded = EncodeIdentifiabilityFieldTrialParam(original_map); - EXPECT_EQ(std::string("0;6,1;5"), encoded); + EXPECT_EQ(std::string("100;5,257;6"), encoded); - auto decoded_map = DecodeIdentifiabilityFieldTrialParam< - std::map<blink::IdentifiableSurface::Type, int>>(encoded); + auto decoded_map = + DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceSampleRateMap>( + encoded); EXPECT_EQ(original_map, decoded_map); } -TEST(FieldTrialParamConversionsTest, DecodeBadSurface) { +TEST(FieldTrialParamConversionsTest, IdentifiableSurfaceTypeSampleRateMap) { + const IdentifiableSurfaceTypeSampleRateMap original_map = {{kType1, 6}, + {kType2, 7}}; + + auto encoded = EncodeIdentifiabilityFieldTrialParam(original_map); + EXPECT_EQ(std::string("1;6,9;7"), encoded); + + auto decoded_map = DecodeIdentifiabilityFieldTrialParam< + IdentifiableSurfaceTypeSampleRateMap>(encoded); + EXPECT_EQ(original_map, decoded_map); + + // Extraneous bad values should be silently skipped. + auto decoded_with_noise = DecodeIdentifiabilityFieldTrialParam< + IdentifiableSurfaceTypeSampleRateMap>("1;6,2;3;4,9;7,10"); + EXPECT_EQ(original_map, decoded_with_noise); +} + +TEST(FieldTrialParamConversionsTest, IdentifiableSurfaceCostMap) { + const IdentifiableSurfaceCostMap original_map = { + {kSurface1, 0.5}, {kSurface2, 0.25}, {kSurface3, 0.4}}; + + auto encoded = + EncodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceCostMap>( + original_map); + EXPECT_EQ(std::string("100;0.5,257;0.25,36028797018963968;0.4"), encoded); + + auto decoded = + DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceCostMap>( + "100;0.5,257;0.25,36028797018963968;0.4"); + EXPECT_EQ(original_map, decoded); +} + +TEST(FieldTrialParamConversionsTest, IdentifiableSurfaceTypeCostMap) { + const IdentifiableSurfaceTypeCostMap original_map = {{kType1, 0.5}, + {kType2, 0.25}}; + + auto encoded = + EncodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceTypeCostMap>( + original_map); + EXPECT_EQ(std::string("1;0.5,9;0.25"), encoded); + + auto decoded = + DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceTypeCostMap>( + "1;0.5,9;0.25"); + EXPECT_EQ(original_map, decoded); +} + +TEST(FieldTrialParamConversionsTest, SurfaceSetEquivalentClassesList) { + const SurfaceSetEquivalentClassesList original_classes = { + {kSurface1, kSurface2, kSurface3}, {kSurface3, kSurface2, kSurface1}}; + auto encoded = + EncodeIdentifiabilityFieldTrialParam<SurfaceSetEquivalentClassesList>( + original_classes); + EXPECT_EQ(std::string("100;257;36028797018963968,36028797018963968;257;100"), + encoded); + auto decoded = + DecodeIdentifiabilityFieldTrialParam<SurfaceSetEquivalentClassesList>( + encoded); + EXPECT_EQ(original_classes, decoded); +} + +TEST(FieldTrialParamConversionsTest, IdentifiableSurfaceGroupList) { + const IdentifiableSurfaceGroupList original_classes = { + {kSurface1, kSurface2, kSurface3}, {kSurface3, kSurface2, kSurface1}}; + auto encoded = + EncodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceGroupList>( + original_classes); + EXPECT_EQ(std::string("100;257;36028797018963968,36028797018963968;257;100"), + encoded); + auto decoded = + DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceGroupList>( + encoded); + EXPECT_EQ(original_classes, decoded); +} + +TEST(FieldTrialParamConversionsTest, VectorOfSizeT) { + const std::vector<unsigned int> kNumbers = {1, 3, 1000, + std::numeric_limits<int>::max()}; + auto encoded = EncodeIdentifiabilityFieldTrialParam(kNumbers); + EXPECT_EQ(std::string("1,3,1000,2147483647"), encoded); + + auto decoded = + DecodeIdentifiabilityFieldTrialParam<std::vector<unsigned int>>( + "4, 1000, 23"); + EXPECT_EQ(std::vector<unsigned int>({4, 1000, 23}), decoded); +} + +TEST(FieldTrialParamConversionsTest, DecodeBadValues) { auto decoded_surface = blink::IdentifiableSurface(); EXPECT_FALSE(DecodeIdentifiabilityType("foo", &decoded_surface)); EXPECT_FALSE(DecodeIdentifiabilityType("-100", &decoded_surface)); @@ -65,9 +229,11 @@ &decoded_surface)); } -TEST(FieldTrialParamConversionsTest, DecodeBadType) { +TEST(FieldTrialParamConversionsTest, DecodeBadTypes) { auto decoded_type = blink::IdentifiableSurface::Type::kReservedInternal; EXPECT_FALSE(DecodeIdentifiabilityType("foo", &decoded_type)); EXPECT_FALSE(DecodeIdentifiabilityType("-100", &decoded_type)); EXPECT_FALSE(DecodeIdentifiabilityType("256", &decoded_type)); } + +} // namespace privacy_budget_internal
diff --git a/chrome/common/privacy_budget/privacy_budget_settings_provider.h b/chrome/common/privacy_budget/privacy_budget_settings_provider.h index 81d597d..375cfae 100644 --- a/chrome/common/privacy_budget/privacy_budget_settings_provider.h +++ b/chrome/common/privacy_budget/privacy_budget_settings_provider.h
@@ -5,10 +5,8 @@ #ifndef CHROME_COMMON_PRIVACY_BUDGET_PRIVACY_BUDGET_SETTINGS_PROVIDER_H_ #define CHROME_COMMON_PRIVACY_BUDGET_PRIVACY_BUDGET_SETTINGS_PROVIDER_H_ -#include <memory> -#include <unordered_set> - #include "base/containers/flat_map.h" +#include "chrome/common/privacy_budget/types.h" #include "third_party/blink/public/common/privacy_budget/identifiability_study_settings_provider.h" #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" @@ -34,12 +32,6 @@ class PrivacyBudgetSettingsProvider final : public blink::IdentifiabilityStudySettingsProvider { public: - using IdentifiableSurfaceSet = - std::unordered_set<blink::IdentifiableSurface, - blink::IdentifiableSurfaceHash>; - using IdentifiableSurfaceTypeSet = - std::unordered_set<blink::IdentifiableSurface::Type>; - PrivacyBudgetSettingsProvider(); PrivacyBudgetSettingsProvider(const PrivacyBudgetSettingsProvider&); PrivacyBudgetSettingsProvider(PrivacyBudgetSettingsProvider&&);
diff --git a/chrome/common/privacy_budget/types.h b/chrome/common/privacy_budget/types.h new file mode 100644 index 0000000..c89732d --- /dev/null +++ b/chrome/common/privacy_budget/types.h
@@ -0,0 +1,98 @@ +// Copyright 2021 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. + +#ifndef CHROME_COMMON_PRIVACY_BUDGET_TYPES_H_ +#define CHROME_COMMON_PRIVACY_BUDGET_TYPES_H_ + +#include <type_traits> +#include <vector> + +#include "base/containers/flat_map.h" +#include "base/containers/flat_set.h" +#include "chrome/common/privacy_budget/field_trial_param_conversions.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" + +// Common container and map types. In order to verify successful encoding and +// decoding, each of these must be tested in +// field_trial_param_conversions_unittest.cc. +// +// In all cases, the choice of container assumes that: +// 1. Size is relatively low: Use of a contiguous container helps with data +// locality. +// 2. Mutations are uncommon: A contiguous container is usually expensive to +// mutate, but fast lookups and locality make up for it. +// +// If other characteristics are desired, then we should consider other container +// types. Please test encoding/decoding when using new container types. + +using IdentifiableSurfaceSet = base::flat_set<blink::IdentifiableSurface>; + +using IdentifiableSurfaceTypeSet = + base::flat_set<blink::IdentifiableSurface::Type>; + +using IdentifiableSurfaceList = std::vector<blink::IdentifiableSurface>; + +using IdentifiableSurfaceTypeList = + std::vector<blink::IdentifiableSurface::Type>; + +// Sampling rates are represented as the denominator of a quotient 1/R. I.e. +// A sampling rate of 1 in 100 is represented using the integer 100. +using IdentifiableSurfaceSampleRateMap = + base::flat_map<blink::IdentifiableSurface, unsigned int>; + +// Sampling rates are represented as the denominator of a quotient 1/R. I.e. +// A sampling rate of 1 in 100 is represented using the integer 100. +using IdentifiableSurfaceTypeSampleRateMap = + base::flat_map<blink::IdentifiableSurface::Type, unsigned int>; + +// Costs are represented as a ratio relative to the "median" identifiability of +// a single API. This odd choice is due to backwards compatibility where prior +// versions of the study controlled client exposure via placing a limit on the +// _number_ of surfaces sampled. +// +// Relative costs are in the logarithmic domain. Explained below. +// +// Let's say there's a surface 𝐀 whose value can be used to uniformly divide the +// audience in to four segments. In terms of Shannon entropy one might say that +// the information content of surface 𝐀 is log₂4 bits. Now if there's another +// surface 𝐁 whose relative cost is 0.5, then 𝐁 would have a Shannon entropy of +// 0.5×log₂4 bits. In other words 𝐁 has the information content equivalent to +// what's needed to uniformly divide an audience into √4=2 equal parts. +// +// In general, if the median identifiability is 𝐦, and the relative +// identifiability of a surface is 𝐫, then the identifiability of that surface +// is mʳ. +using PrivacyBudgetCost = double; + +using IdentifiableSurfaceCostMap = + base::flat_map<blink::IdentifiableSurface, PrivacyBudgetCost>; + +using IdentifiableSurfaceTypeCostMap = + base::flat_map<blink::IdentifiableSurface::Type, PrivacyBudgetCost>; + +// See SurfaceSetEquivalence for details on how equivalence classes work. +// SurfaceSetEquivalentClassesList contains a list of equivalence classes. Each +// class is encoded as a list of surfaces. +// +// **The first element in the list is considered to be the representative +// surface for that class. +// +// Obv an equivalence set which contains just zero or one members is +// nonsensical. For the purpose of ecoding/decoding such instances are ignored. +using SurfaceSetEquivalentClassesList = std::vector<IdentifiableSurfaceList>; + +// Similar to the SurfaceSetEquivalentClassesList, but is semantically different +// in that the ordering doesn't matter. There's no assumption that the first +// element of each list is special in any meaningful way. +using IdentifiableSurfaceGroupList = std::vector<IdentifiableSurfaceList>; + +namespace privacy_budget_internal { + +template <> +struct SortWhenSerializing<IdentifiableSurfaceSet> : std::true_type {}; +template <> +struct SortWhenSerializing<IdentifiableSurfaceTypeSet> : std::true_type {}; + +} // namespace privacy_budget_internal +#endif // CHROME_COMMON_PRIVACY_BUDGET_TYPES_H_
diff --git a/chrome/common/profiler/thread_profiler.cc b/chrome/common/profiler/thread_profiler.cc index ca98c2a..05b83820 100644 --- a/chrome/common/profiler/thread_profiler.cc +++ b/chrome/common/profiler/thread_profiler.cc
@@ -282,8 +282,7 @@ void ThreadProfiler::StartOnChildThread(CallStackProfileParams::Thread thread) { // The profiler object is stored in a SequenceLocalStorageSlot on child // threads to give it the same lifetime as the threads. - static base::NoDestructor< - base::SequenceLocalStorageSlot<std::unique_ptr<ThreadProfiler>>> + static base::SequenceLocalStorageSlot<std::unique_ptr<ThreadProfiler>> child_thread_profiler_sequence_local_storage; if (!ThreadProfilerConfiguration::Get() @@ -291,7 +290,7 @@ return; } - child_thread_profiler_sequence_local_storage->emplace( + child_thread_profiler_sequence_local_storage.emplace( new ThreadProfiler(thread, base::ThreadTaskRunnerHandle::Get())); }
diff --git a/chrome/common/profiler/thread_profiler_configuration.h b/chrome/common/profiler/thread_profiler_configuration.h index 27f56c5..e67d413 100644 --- a/chrome/common/profiler/thread_profiler_configuration.h +++ b/chrome/common/profiler/thread_profiler_configuration.h
@@ -8,6 +8,7 @@ #include <initializer_list> #include <string> +#include "base/no_destructor.h" #include "base/profiler/stack_sampling_profiler.h" #include "components/metrics/call_stack_profile_params.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -15,8 +16,6 @@ namespace base { class CommandLine; -template <typename> -class NoDestructor; } // namespace base class ThreadProfilerPlatformConfiguration;
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 95b6bb7..31d58aa 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1041,9 +1041,20 @@ break; } -#if BUILDFLAG(ENABLE_PDF_UNSEASONED) if (info.name == ASCIIToUTF16(ChromeContentClient::kPDFInternalPluginName)) { + // For a PDF plugin, `params.url` holds the plugin's stream url. If + // `params` contains an 'original-url' attribute, reset `params.url` + // with its original URL value so that it can be used to determine + // the plugin's origin. + for (size_t i = 0; i < params.attribute_names.size(); ++i) { + if (params.attribute_names[i] == "original-url") { + params.url = GURL(params.attribute_values[i].Utf16()); + break; + } + } + +#if BUILDFLAG(ENABLE_PDF_UNSEASONED) // Create unseasoned PDF plugin directly, for development purposes. // TODO(crbug.com/1123621): Implement a more permanent solution once // the new PDF viewer process model is approved and in place. @@ -1054,12 +1065,11 @@ #if BUILDFLAG(ENABLE_PRINTING) print_client = std::make_unique<ChromePdfViewWebPluginPrintClient>(render_frame); -#endif +#endif // BUILDFLAG(ENABLE_PRINTING) return new chrome_pdf::PdfViewWebPlugin( std::move(pdf_service_remote), std::move(print_client), params); - } #endif // BUILDFLAG(ENABLE_PDF_UNSEASONED) - + } return render_frame->CreatePlugin(info, params); } case chrome::mojom::PluginStatus::kDisabled: {
diff --git a/chrome/renderer/extensions/notifications_native_handler.cc b/chrome/renderer/extensions/notifications_native_handler.cc index ba5500b..aa1e815f 100644 --- a/chrome/renderer/extensions/notifications_native_handler.cc +++ b/chrome/renderer/extensions/notifications_native_handler.cc
@@ -31,8 +31,8 @@ const v8::FunctionCallbackInfo<v8::Value>& args) { NotificationBitmapSizes bitmap_sizes = GetNotificationBitmapSizes(); - float scale_factor = - ui::GetScaleForScaleFactor(ui::GetSupportedScaleFactors().back()); + float scale_factor = ui::GetScaleForResourceScaleFactor( + ui::GetSupportedResourceScaleFactors().back()); v8::Isolate* isolate = GetIsolate(); v8::HandleScope handle_scope(isolate);
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index c2c7159..5ee912d 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -5217,6 +5217,8 @@ "//v8", ] + public_deps = [] + if (enable_paint_preview) { deps += [ "//chrome/browser/paint_preview:services" ] } @@ -6954,6 +6956,9 @@ if (is_win) { sources += [ "../browser/ui/webui/print_preview/pdf_printer_handler_win_unittest.cc" ] + + # Needed by test_print_job.h, test_printer_query.h. + public_deps += [ "//printing/mojom" ] } if (is_mac) {
diff --git a/chrome/test/chromedriver/capabilities.cc b/chrome/test/chromedriver/capabilities.cc index 1cb7e18..be1ccfd 100644 --- a/chrome/test/chromedriver/capabilities.cc +++ b/chrome/test/chromedriver/capabilities.cc
@@ -519,13 +519,11 @@ Status ParseDevToolsEventsLoggingPrefs(const base::Value& option, Capabilities* capabilities) { - const base::ListValue* devtools_events_logging_prefs = nullptr; - if (!option.GetAsList(&devtools_events_logging_prefs)) + if (!option.is_list()) return Status(kInvalidArgument, "must be a list"); - if (devtools_events_logging_prefs->empty()) + if (option.GetList().empty()) return Status(kInvalidArgument, "list must contain values"); - capabilities->devtools_events_logging_prefs.reset( - devtools_events_logging_prefs->DeepCopy()); + capabilities->devtools_events_logging_prefs = option.Clone(); return Status(kOk); }
diff --git a/chrome/test/chromedriver/capabilities.h b/chrome/test/chromedriver/capabilities.h index 271444f..4dd2f54 100644 --- a/chrome/test/chromedriver/capabilities.h +++ b/chrome/test/chromedriver/capabilities.h
@@ -15,6 +15,7 @@ #include "base/command_line.h" #include "base/files/file_path.h" +#include "base/values.h" #include "chrome/test/chromedriver/chrome/device_metrics.h" #include "chrome/test/chromedriver/chrome/devtools_http_client.h" #include "chrome/test/chromedriver/chrome/log.h" @@ -23,8 +24,6 @@ namespace base { class CommandLine; -class DictionaryValue; -class ListValue; } class Status; @@ -177,7 +176,7 @@ PerfLoggingPrefs perf_logging_prefs; - std::unique_ptr<base::ListValue> devtools_events_logging_prefs; + base::Value devtools_events_logging_prefs; std::unique_ptr<base::DictionaryValue> prefs;
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc index 88e058a..a17d76c7 100644 --- a/chrome/test/chromedriver/chrome/web_view_impl.cc +++ b/chrome/test/chromedriver/chrome/web_view_impl.cc
@@ -810,7 +810,7 @@ base::ListValue* cookies_tmp; if (!result->GetList("cookies", &cookies_tmp)) return Status(kUnknownError, "DevTools didn't return cookies"); - cookies->reset(cookies_tmp->DeepCopy()); + *cookies = cookies_tmp->CreateDeepCopy(); return Status(kOk); }
diff --git a/chrome/test/chromedriver/devtools_events_logger.cc b/chrome/test/chromedriver/devtools_events_logger.cc index e068147..6962b41f 100644 --- a/chrome/test/chromedriver/devtools_events_logger.cc +++ b/chrome/test/chromedriver/devtools_events_logger.cc
@@ -9,15 +9,13 @@ #include "chrome/test/chromedriver/chrome/devtools_client.h" #include "chrome/test/chromedriver/chrome/devtools_client_impl.h" -DevToolsEventsLogger::DevToolsEventsLogger(Log* log, - const base::ListValue* prefs) - : log_(log), - prefs_(prefs) {} +DevToolsEventsLogger::DevToolsEventsLogger(Log* log, const base::Value& prefs) + : log_(log), prefs_(prefs) {} inline DevToolsEventsLogger::~DevToolsEventsLogger() {} Status DevToolsEventsLogger::OnConnected(DevToolsClient* client) { - for (const auto& entry : prefs_->GetList()) { + for (const auto& entry : prefs_.GetList()) { std::string event; entry.GetAsString(&event); events_.insert(event);
diff --git a/chrome/test/chromedriver/devtools_events_logger.h b/chrome/test/chromedriver/devtools_events_logger.h index 570e7e56..496f289 100644 --- a/chrome/test/chromedriver/devtools_events_logger.h +++ b/chrome/test/chromedriver/devtools_events_logger.h
@@ -25,7 +25,7 @@ class DevToolsEventsLogger : public DevToolsEventListener { public: // Creates a |DevToolsEventsLogger| with specific preferences. - DevToolsEventsLogger(Log* log, const base::ListValue* prefs); + DevToolsEventsLogger(Log* log, const base::Value& prefs); ~DevToolsEventsLogger() override; @@ -38,7 +38,7 @@ private: Log* log_; // The log where to create entries. - const base::ListValue* prefs_; + const base::Value& prefs_; std::unordered_set<std::string> events_; DISALLOW_COPY_AND_ASSIGN(DevToolsEventsLogger);
diff --git a/chrome/test/chromedriver/logging.cc b/chrome/test/chromedriver/logging.cc index 79e6f9c2..a4f2f19 100644 --- a/chrome/test/chromedriver/logging.cc +++ b/chrome/test/chromedriver/logging.cc
@@ -388,10 +388,8 @@ } } else if (type == WebDriverLog::kDevToolsType) { logs.push_back(std::make_unique<WebDriverLog>(type, Log::kAll)); - devtools_listeners.push_back( - std::make_unique<DevToolsEventsLogger>( - logs.back().get(), - capabilities.devtools_events_logging_prefs.get())); + devtools_listeners.push_back(std::make_unique<DevToolsEventsLogger>( + logs.back().get(), capabilities.devtools_events_logging_prefs)); } else if (type == WebDriverLog::kBrowserType) { browser_log_level = level; } else if (type != WebDriverLog::kDriverType) {
diff --git a/chrome/test/chromedriver/util_unittest.cc b/chrome/test/chromedriver/util_unittest.cc index 79ae394..976f07b2 100644 --- a/chrome/test/chromedriver/util_unittest.cc +++ b/chrome/test/chromedriver/util_unittest.cc
@@ -292,10 +292,10 @@ base::ListValue lv2; lv2.AppendString("2"); - std::unique_ptr<base::ListValue> params(lv1.DeepCopy()); + base::Value params = lv1.Clone(); base::DictionaryValue dict; - dict.SetList(key, std::move(params)); + dict.SetPath(key, std::move(params)); const base::ListValue* res = &lv2; bool has_value; bool has_dict = GetOptionalList(&dict, key, &res, &has_value);
diff --git a/chrome/test/data/pdf/basic_test.js b/chrome/test/data/pdf/basic_test.js index 3cc35497..5cd05ec 100644 --- a/chrome/test/data/pdf/basic_test.js +++ b/chrome/test/data/pdf/basic_test.js
@@ -32,7 +32,7 @@ chrome.test.assertEq('embed', plugin.localName); chrome.test.assertTrue( - plugin.getAttribute('src').indexOf('/pdf/test.pdf') !== -1); + plugin.getAttribute('original-url').indexOf('/pdf/test.pdf') !== -1); chrome.test.succeed(); },
diff --git a/chrome/test/data/pdf/redirects_fail_test.js b/chrome/test/data/pdf/redirects_fail_test.js index 5f78818..82df54c 100644 --- a/chrome/test/data/pdf/redirects_fail_test.js +++ b/chrome/test/data/pdf/redirects_fail_test.js
@@ -16,8 +16,8 @@ } }, false); - plugin.setAttribute('src', url); - plugin.setAttribute('stream-url', streamUrl); + plugin.setAttribute('original-url', url); + plugin.setAttribute('src', streamUrl); plugin.setAttribute('full-frame', ''); plugin.setAttribute('headers', headers); document.body.appendChild(plugin);
diff --git a/chrome/test/data/xr/e2e_test_files/html/webxr_test_basic_all_ar_features.html b/chrome/test/data/xr/e2e_test_files/html/webxr_test_basic_all_ar_features.html new file mode 100644 index 0000000..bf7db17 --- /dev/null +++ b/chrome/test/data/xr/e2e_test_files/html/webxr_test_basic_all_ar_features.html
@@ -0,0 +1,66 @@ +<!-- +Tests that AR session is stable for specified amount of time when all features +are enabled. +--> +<html> + <head> + <link rel="stylesheet" type="text/css" href="../resources/webxr_e2e.css"> + <meta name="timeout" content="long"> <!-- this is a long-running test! --> + </head> + <body> + <canvas id="webgl-canvas"></canvas> + <script src="../../../../../../third_party/blink/web_tests/resources/testharness.js"></script> + <script src="../resources/webxr_e2e.js"></script> + <script>var shouldAutoCreateNonImmersiveSession = false;</script> + <script src="../resources/webxr_boilerplate.js"></script> + <script> + immersiveArSessionInit.requiredFeatures = [ + 'anchors', 'camera-access', 'depth-sensing', 'hit-test', 'light-estimation', 'plane-detection', + ]; + + // Depth sensing needs to be configured: + immersiveArSessionInit.depthSensing = { + usagePreference: ['cpu-optimized'], + dataFormatPreference: ['luminance-alpha'], + }; + + setup({single_test: true}); + + function disableCameraAccess() { + const indexToRemove = immersiveArSessionInit.requiredFeatures.indexOf("camera-access"); + if(indexToRemove != -1) { + immersiveArSessionInit.requiredFeatures.splice(indexToRemove, 1); + } + } + + function stepStartTest(durationInSeconds) { + + updateSingleTestProgressMessage("state: starting test, will run for: " + durationInSeconds + "s"); + + let firstFrameTime = null; + let frame_num = 0; + + onARFrameCallback = (session, frame, t) => { + if (firstFrameTime == null) { + updateSingleTestProgressMessage("state: first frame received, timestamp: " + t); + firstFrameTime = t; + } + + const timePassedInMs = t - firstFrameTime; + + frame_num++; + if (frame_num % 120) { + updateSingleTestProgressMessage("state: waiting for tests to finish, time passed (ms): " + timePassedInMs + ", desired duration (s): " + durationInSeconds); + } + + if (timePassedInMs > durationInSeconds * 1000) { + updateSingleTestProgressMessage("state: test completed"); + + onARFrameCallback = null; + done(); + } + }; + } + </script> + </body> +</html>
diff --git a/chrome/test/data/xr/e2e_test_files/resources/webxr_boilerplate.js b/chrome/test/data/xr/e2e_test_files/resources/webxr_boilerplate.js index f17c2da..8ff4238 100644 --- a/chrome/test/data/xr/e2e_test_files/resources/webxr_boilerplate.js +++ b/chrome/test/data/xr/e2e_test_files/resources/webxr_boilerplate.js
@@ -220,7 +220,7 @@ break; case sessionTypes.AR: if (onARFrameCallback) { - onARFrameCallback(session, frame); + onARFrameCallback(session, frame, t); } break; default:
diff --git a/chrome/updater/crash_client.h b/chrome/updater/crash_client.h index f96ee05..173f1f4 100644 --- a/chrome/updater/crash_client.h +++ b/chrome/updater/crash_client.h
@@ -8,13 +8,9 @@ #include <memory> #include <string> +#include "base/no_destructor.h" #include "base/sequence_checker.h" -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - namespace crashpad { class CrashReportDatabase; } // namespace crashpad
diff --git a/chrome/updater/policy/dm_policy_manager.cc b/chrome/updater/policy/dm_policy_manager.cc index dcb23966..c786299 100644 --- a/chrome/updater/policy/dm_policy_manager.cc +++ b/chrome/updater/policy/dm_policy_manager.cc
@@ -57,7 +57,7 @@ DMPolicyManager::~DMPolicyManager() = default; bool DMPolicyManager::IsManaged() const { - return true; + return base::IsMachineExternallyManaged(); } std::string DMPolicyManager::source() const {
diff --git a/chrome/updater/policy/dm_policy_manager_unittest.cc b/chrome/updater/policy/dm_policy_manager_unittest.cc index 1999b0d..4e04e1c 100644 --- a/chrome/updater/policy/dm_policy_manager_unittest.cc +++ b/chrome/updater/policy/dm_policy_manager_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/updater/policy/dm_policy_manager.h" +#include "base/enterprise_util.h" #include "build/build_config.h" #include "chrome/updater/constants.h" #include "chrome/updater/unittest_util.h" @@ -107,7 +108,7 @@ auto policy_manager(std::make_unique<DMPolicyManager>(omaha_settings)); - EXPECT_TRUE(policy_manager->IsManaged()); + EXPECT_EQ(policy_manager->IsManaged(), base::IsMachineExternallyManaged()); EXPECT_EQ(policy_manager->source(), "DeviceManagement"); int last_check_period_minutes = 0; @@ -181,7 +182,7 @@ auto policy_manager(std::make_unique<DMPolicyManager>(omaha_settings)); - EXPECT_TRUE(policy_manager->IsManaged()); + EXPECT_EQ(policy_manager->IsManaged(), base::IsMachineExternallyManaged()); EXPECT_EQ(policy_manager->source(), "DeviceManagement"); int last_check_period_minutes = 0; @@ -271,7 +272,7 @@ auto policy_manager(std::make_unique<DMPolicyManager>(omaha_settings)); - EXPECT_TRUE(policy_manager->IsManaged()); + EXPECT_EQ(policy_manager->IsManaged(), base::IsMachineExternallyManaged()); EXPECT_EQ(policy_manager->source(), "DeviceManagement"); int last_check_period_minutes = 0;
diff --git a/chrome/updater/policy/mac/managed_preference_policy_manager_impl.mm b/chrome/updater/policy/mac/managed_preference_policy_manager_impl.mm index 20803cb..38e2795 100644 --- a/chrome/updater/policy/mac/managed_preference_policy_manager_impl.mm +++ b/chrome/updater/policy/mac/managed_preference_policy_manager_impl.mm
@@ -4,6 +4,7 @@ #import "chrome/updater/policy/mac/managed_preference_policy_manager_impl.h" +#include "base/enterprise_util.h" #include "base/mac/scoped_nsobject.h" #include "chrome/updater/constants.h" #include "chrome/updater/policy/manager.h" @@ -216,7 +217,7 @@ - (instancetype)initWithDictionary:(CRUUpdatePolicyDictionary*)policies { if (([super init])) { - _managed = (policies.count > 0); + _managed = policies.count > 0 && base::IsMachineExternallyManaged(); // Always create a global policy instance for default values. _globalPolicy.reset([[CRUManagedPreferenceGlobalPolicySettings alloc]
diff --git a/chrome/updater/policy/mac/managed_preference_policy_manager_impl_unittest.mm b/chrome/updater/policy/mac/managed_preference_policy_manager_impl_unittest.mm index 34639989..816692a7 100644 --- a/chrome/updater/policy/mac/managed_preference_policy_manager_impl_unittest.mm +++ b/chrome/updater/policy/mac/managed_preference_policy_manager_impl_unittest.mm
@@ -4,6 +4,7 @@ #include "chrome/updater/policy/mac/managed_preference_policy_manager_impl.h" +#include "base/enterprise_util.h" #include "base/mac/scoped_nsobject.h" #include "chrome/updater/constants.h" #include "testing/gtest/include/gtest/gtest.h" @@ -33,7 +34,7 @@ [[CRUManagedPreferencePolicyManager alloc] initWithDictionary:policyDict]); EXPECT_NSEQ([policyManager source], @"ManagedPreference"); - EXPECT_TRUE([policyManager managed]); + EXPECT_EQ([policyManager managed], base::IsMachineExternallyManaged()); // Verify global level policies. EXPECT_EQ([policyManager lastCheckPeriodMinutes], kPolicyNotSet); @@ -77,7 +78,7 @@ [[CRUManagedPreferencePolicyManager alloc] initWithDictionary:policyDict]); EXPECT_NSEQ([policyManager source], @"ManagedPreference"); - EXPECT_TRUE([policyManager managed]); + EXPECT_EQ([policyManager managed], base::IsMachineExternallyManaged()); // Verify global level policies are set to default. EXPECT_EQ([policyManager lastCheckPeriodMinutes], kPolicyNotSet); @@ -116,7 +117,7 @@ [[CRUManagedPreferencePolicyManager alloc] initWithDictionary:policyDict]); EXPECT_NSEQ([policyManager source], @"ManagedPreference"); - EXPECT_TRUE([policyManager managed]); + EXPECT_EQ([policyManager managed], base::IsMachineExternallyManaged()); // Verify global level policies. EXPECT_EQ([policyManager lastCheckPeriodMinutes], kPolicyNotSet);
diff --git a/chrome/updater/policy/win/group_policy_manager.cc b/chrome/updater/policy/win/group_policy_manager.cc index a69fb8b0..488ebb3 100644 --- a/chrome/updater/policy/win/group_policy_manager.cc +++ b/chrome/updater/policy/win/group_policy_manager.cc
@@ -9,11 +9,11 @@ #include <userenv.h> +#include "base/enterprise_util.h" #include "base/scoped_generic.h" #include "base/strings/sys_string_conversions.h" #include "base/values.h" #include "base/win/registry.h" -#include "base/win/win_util.h" #include "chrome/updater/policy/manager.h" #include "chrome/updater/win/win_constants.h" @@ -81,7 +81,7 @@ GroupPolicyManager::~GroupPolicyManager() = default; bool GroupPolicyManager::IsManaged() const { - return policies_.DictSize() > 0 && base::win::IsEnrolledToDomain(); + return policies_.DictSize() > 0 && base::IsMachineExternallyManaged(); } std::string GroupPolicyManager::source() const { @@ -203,7 +203,7 @@ void GroupPolicyManager::LoadAllPolicies() { scoped_hpolicy policy_lock; - if (base::win::IsEnrolledToDomain()) { + if (base::IsMachineExternallyManaged()) { // GPO rules mandate a call to EnterCriticalPolicySection() before reading // policies (and a matching LeaveCriticalPolicySection() call after read). // Acquire the lock for domain-joined machines because group policies are
diff --git a/chrome/updater/service_factory_win.cc b/chrome/updater/service_factory_win.cc index 304dd85..1ded800a 100644 --- a/chrome/updater/service_factory_win.cc +++ b/chrome/updater/service_factory_win.cc
@@ -4,7 +4,6 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "base/no_destructor.h" #include "chrome/updater/updater_scope.h" #include "chrome/updater/win/update_service_internal_proxy.h" #include "chrome/updater/win/update_service_proxy.h" @@ -22,8 +21,8 @@ } static const WRLModuleInitializer& Get() { - static const base::NoDestructor<WRLModuleInitializer> module; - return *module; + static const WRLModuleInitializer module; + return module; } };
diff --git a/chromecast/browser/cast_content_browser_client_receiver_bindings.cc b/chromecast/browser/cast_content_browser_client_receiver_bindings.cc index f97f4c8..a748722 100644 --- a/chromecast/browser/cast_content_browser_client_receiver_bindings.cc +++ b/chromecast/browser/cast_content_browser_client_receiver_bindings.cc
@@ -10,7 +10,6 @@ #include "base/bind.h" #include "base/logging.h" -#include "base/no_destructor.h" #include "base/threading/sequence_local_storage_slot.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" @@ -171,10 +170,8 @@ mojo_media_client->SetVideoGeometrySetterService( video_geometry_setter_service_.get()); - static base::NoDestructor< - base::SequenceLocalStorageSlot<::media::MediaService>> - service; - service->emplace(std::move(mojo_media_client), std::move(receiver)); + static base::SequenceLocalStorageSlot<::media::MediaService> service; + service.emplace(std::move(mojo_media_client), std::move(receiver)); } void CastContentBrowserClient::CreateVideoGeometrySetterServiceOnMediaThread() {
diff --git a/chromecast/browser/system_connector.cc b/chromecast/browser/system_connector.cc index f104af4..8b117d8 100644 --- a/chromecast/browser/system_connector.cc +++ b/chromecast/browser/system_connector.cc
@@ -5,7 +5,6 @@ #include "chromecast/browser/system_connector.h" #include "base/check_op.h" -#include "base/no_destructor.h" #include "base/threading/sequence_local_storage_slot.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -18,10 +17,8 @@ base::SequenceLocalStorageSlot<service_manager::Connector>& GetConnectorStorage() { - static base::NoDestructor< - base::SequenceLocalStorageSlot<service_manager::Connector>> - storage; - return *storage; + static base::SequenceLocalStorageSlot<service_manager::Connector> storage; + return storage; } void BindReceiverOnMainThread(
diff --git a/chromecast/browser/ui/aura/accessibility/automation_manager_aura.h b/chromecast/browser/ui/aura/accessibility/automation_manager_aura.h index 88aa909d..2c44f86 100644 --- a/chromecast/browser/ui/aura/accessibility/automation_manager_aura.h +++ b/chromecast/browser/ui/aura/accessibility/automation_manager_aura.h
@@ -13,6 +13,7 @@ #include <vector> #include "base/macros.h" +#include "base/no_destructor.h" #include "chromecast/browser/ui/aura/accessibility/ax_tree_source_aura.h" #include "ui/accessibility/ax_action_handler.h" #include "ui/accessibility/ax_tree_serializer.h" @@ -22,11 +23,6 @@ class AXRootObjWrapper; -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - namespace extensions { class AutomationEventRouterInterface; }
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 290f703..0ef0bbb 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -911,6 +911,12 @@ <message name="IDS_DIAGNOSTICS_NO_ETHERNET" desc="The label for the text displayed when a dongle is connected to a device but an Ethernet connection is not detected."> No Ethernet connection detected </message> + <message name="IDS_DIAGNOSTICS_OVERVIEW" desc="The label for the overview navigation panel item."> + Overview + </message> + <message name="IDS_DIAGNOSTICS_CONNECTIVITY" desc="The label for the connectivity navigation panel item."> + Connectivity + </message> <message name="IDS_ECHE_APP_DEFAULT_DEVICE_NAME" desc="The default device name used to display on Android endpoint of Eche app."> <ph name="GIVEN_NAME">$1<ex>Josh</ex></ph>'s <ph name="DEVICE_TYPE">$2<ex>Chromebook</ex></ph>
diff --git a/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_CONNECTIVITY.png.sha1 b/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_CONNECTIVITY.png.sha1 new file mode 100644 index 0000000..5a01d53 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_CONNECTIVITY.png.sha1
@@ -0,0 +1 @@ +cc40055130fdba6aec5141fbb40958a2f5e2fae4 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_OVERVIEW.png.sha1 b/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_OVERVIEW.png.sha1 new file mode 100644 index 0000000..5a01d53 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_OVERVIEW.png.sha1
@@ -0,0 +1 @@ +cc40055130fdba6aec5141fbb40958a2f5e2fae4 \ No newline at end of file
diff --git a/chromeos/components/cdm_factory_daemon/output_protection_impl.cc b/chromeos/components/cdm_factory_daemon/output_protection_impl.cc index 51b5e23d..02fe6b38 100644 --- a/chromeos/components/cdm_factory_daemon/output_protection_impl.cc +++ b/chromeos/components/cdm_factory_daemon/output_protection_impl.cc
@@ -16,7 +16,6 @@ #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "ui/display/manager/display_configurator.h" #include "ui/display/manager/display_manager.h" -#include "ui/display/screen.h" #include "ui/display/types/display_constants.h" namespace chromeos { @@ -115,12 +114,6 @@ display::ContentProtectionManager::ClientId client_id) override { content_protection_manager_->UnregisterClient(client_id); } - void AddObserver(display::DisplayObserver* observer) override { - display::Screen::GetScreen()->AddObserver(observer); - } - void RemoveObserver(display::DisplayObserver* observer) override { - display::Screen::GetScreen()->RemoveObserver(observer); - } const std::vector<display::DisplaySnapshot*>& cached_displays() const override { return display_configurator_->cached_displays(); @@ -174,10 +167,8 @@ OutputProtectionImpl::~OutputProtectionImpl() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (client_id_) { - delegate_->RemoveObserver(this); + if (client_id_) delegate_->UnregisterClient(client_id_); - } } void OutputProtectionImpl::QueryStatus(QueryStatusCallback callback) { @@ -247,7 +238,7 @@ // are on that thread (i.e. don't do it in the constructor). client_id_ = delegate_->RegisterClient(); DCHECK(client_id_); - delegate_->AddObserver(this); + display_observer_.emplace(this); display_id_list_ = GetDisplayIdsFromSnapshots(delegate_->cached_displays()); }
diff --git a/chromeos/components/cdm_factory_daemon/output_protection_impl.h b/chromeos/components/cdm_factory_daemon/output_protection_impl.h index 451bbe4c..24632aa 100644 --- a/chromeos/components/cdm_factory_daemon/output_protection_impl.h +++ b/chromeos/components/cdm_factory_daemon/output_protection_impl.h
@@ -47,10 +47,6 @@ virtual void UnregisterClient( display::ContentProtectionManager::ClientId client_id) = 0; - // Delegate to ash::screen::GetScreen(). - virtual void AddObserver(display::DisplayObserver* observer) = 0; - virtual void RemoveObserver(display::DisplayObserver* observer) = 0; - // Delegate to display::DisplayConfigurator. virtual const std::vector<display::DisplaySnapshot*>& cached_displays() const = 0; @@ -113,6 +109,8 @@ std::unique_ptr<DisplaySystemDelegate> delegate_; display::ContentProtectionManager::ClientId client_id_; + absl::optional<display::ScopedOptionalDisplayObserver> display_observer_; + std::vector<int64_t> display_id_list_; uint32_t desired_protection_mask_{0};
diff --git a/chromeos/components/cdm_factory_daemon/output_protection_impl_unittest.cc b/chromeos/components/cdm_factory_daemon/output_protection_impl_unittest.cc index c347e31..d102b9c 100644 --- a/chromeos/components/cdm_factory_daemon/output_protection_impl_unittest.cc +++ b/chromeos/components/cdm_factory_daemon/output_protection_impl_unittest.cc
@@ -51,8 +51,6 @@ MOCK_METHOD(void, UnregisterClient, (display::ContentProtectionManager::ClientId)); - MOCK_METHOD(void, AddObserver, (display::DisplayObserver*)); - MOCK_METHOD(void, RemoveObserver, (display::DisplayObserver*)); MOCK_METHOD(const std::vector<display::DisplaySnapshot*>&, cached_displays, (), @@ -89,7 +87,6 @@ EXPECT_CALL(*delegate_, RegisterClient()) .WillOnce(Return(absl::optional<uint64_t>(kFakeClientId))); - EXPECT_CALL(*delegate_, AddObserver(_)); } void UpdateDisplays(size_t count) { @@ -102,7 +99,6 @@ ~OutputProtectionImplTest() override { EXPECT_CALL(*delegate_, UnregisterClient(_)); - EXPECT_CALL(*delegate_, RemoveObserver(_)); output_protection_mojo_.reset(); base::RunLoop().RunUntilIdle(); }
diff --git a/components/BUILD.gn b/components/BUILD.gn index 3d10666..ba1ad24 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -84,7 +84,6 @@ "//components/content_settings/core/common:unit_tests", "//components/crash/core/common:unit_tests", "//components/crx_file:unit_tests", - "//components/desks_storage:unit_tests", "//components/device_event_log:unit_tests", "//components/dom_distiller/core:unit_tests", "//components/download:unit_tests", @@ -461,6 +460,7 @@ deps += [ "//components/arc:unit_tests", "//components/arc/mojom:unit_tests", + "//components/desks_storage:unit_tests", "//components/guest_os:unit_tests", "//components/metrics/structured:unit_tests", "//components/ownership:unit_tests",
diff --git a/components/autofill_assistant/browser/autofill_assistant_onboarding_fetcher.cc b/components/autofill_assistant/browser/autofill_assistant_onboarding_fetcher.cc index aee9564..9deafb43 100644 --- a/components/autofill_assistant/browser/autofill_assistant_onboarding_fetcher.cc +++ b/components/autofill_assistant/browser/autofill_assistant_onboarding_fetcher.cc
@@ -8,7 +8,6 @@ #include "base/containers/flat_map.h" #include "base/json/json_reader.h" #include "base/metrics/histogram_functions.h" -#include "base/no_destructor.h" #include "base/strings/string_util.h" #include "components/autofill_assistant/browser/features.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -81,7 +80,7 @@ void AutofillAssistantOnboardingFetcher::StartFetch(const std::string& locale, int timeout_ms) { - static const base::NoDestructor<base::TimeDelta> kFetchTimeout( + static const base::TimeDelta kFetchTimeout( base::TimeDelta::FromMilliseconds(timeout_ms)); if (url_loader_) { return; @@ -96,7 +95,7 @@ kTrafficAnnotationDefinition); url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request), traffic_annotation); - url_loader_->SetTimeoutDuration(*kFetchTimeout); + url_loader_->SetTimeoutDuration(kFetchTimeout); url_loader_->DownloadToString( url_loader_factory_.get(), base::BindOnce(&AutofillAssistantOnboardingFetcher::OnFetchComplete,
diff --git a/components/browser_sync/BUILD.gn b/components/browser_sync/BUILD.gn index 291f1fa..c92f09d 100644 --- a/components/browser_sync/BUILD.gn +++ b/components/browser_sync/BUILD.gn
@@ -25,7 +25,6 @@ "//build:chromeos_buildflags", "//components/autofill/core/browser", "//components/autofill/core/common", - "//components/desks_storage", "//components/history/core/browser", "//components/history/core/common", "//components/password_manager/core/browser", @@ -42,7 +41,10 @@ ] if (is_chromeos_ash) { - deps += [ "//ash/constants" ] + deps += [ + "//ash/constants", + "//components/desks_storage", + ] } }
diff --git a/components/browser_ui/styles/android/java/res/values-night/styles.xml b/components/browser_ui/styles/android/java/res/values-night/styles.xml index bdf87785..0ff8180 100644 --- a/components/browser_ui/styles/android/java/res/values-night/styles.xml +++ b/components/browser_ui/styles/android/java/res/values-night/styles.xml
@@ -16,6 +16,7 @@ <item name="android:colorBackground">@color/modern_grey_900</item> <item name="colorSurface">@color/modern_grey_900</item> <item name="colorOnBackground">@color/modern_white</item> + <item name="colorOnPrimary">@color/modern_blue_800</item> <item name="colorOnSurface">@color/modern_grey_100</item> <item name="colorOnSurfaceVariant">@color/white_alpha_70</item> <item name="colorOnSurfaceInverse">@color/modern_grey_800</item>
diff --git a/components/browser_ui/styles/android/java/res/values/styles.xml b/components/browser_ui/styles/android/java/res/values/styles.xml index 39a8887f..b1b28c5 100644 --- a/components/browser_ui/styles/android/java/res/values/styles.xml +++ b/components/browser_ui/styles/android/java/res/values/styles.xml
@@ -201,6 +201,7 @@ <item name="colorSurface">@color/modern_white</item> <item name="colorSurfaceVariant">@color/neutral_variant_100</item> <item name="colorOnBackground">@color/modern_grey_900</item> + <item name="colorOnPrimary">@color/modern_white</item> <item name="colorOnSurface">@color/modern_grey_900</item> <item name="colorOnSurfaceVariant">@color/modern_grey_700</item> <item name="colorOnSurfaceInverse">@color/modern_white</item>
diff --git a/components/component_updater/installer_policies/origin_trials_component_installer.cc b/components/component_updater/installer_policies/origin_trials_component_installer.cc index e24a05af..b74c94f 100644 --- a/components/component_updater/installer_policies/origin_trials_component_installer.cc +++ b/components/component_updater/installer_policies/origin_trials_component_installer.cc
@@ -72,7 +72,7 @@ bool OriginTrialsComponentInstallerPolicy:: SupportsGroupPolicyEnabledComponentUpdates() const { - return false; + return true; } bool OriginTrialsComponentInstallerPolicy::RequiresNetworkEncryption() const {
diff --git a/components/crash/content/app/breakpad_win.cc b/components/crash/content/app/breakpad_win.cc index 4c79b7e..0502be7 100644 --- a/components/crash/content/app/breakpad_win.cc +++ b/components/crash/content/app/breakpad_win.cc
@@ -156,12 +156,11 @@ } } - static base::NoDestructor<google_breakpad::CustomClientInfo> - custom_client_info; - custom_client_info->entries = &custom_entries->front(); - custom_client_info->count = custom_entries->size(); + static google_breakpad::CustomClientInfo custom_client_info; + custom_client_info.entries = &custom_entries->front(); + custom_client_info.count = custom_entries->size(); - return custom_client_info.get(); + return &custom_client_info; } } // namespace
diff --git a/components/cronet/stale_host_resolver.cc b/components/cronet/stale_host_resolver.cc index ad56a6c..2dd046a 100644 --- a/components/cronet/stale_host_resolver.cc +++ b/components/cronet/stale_host_resolver.cc
@@ -4,6 +4,7 @@ #include "components/cronet/stale_host_resolver.h" +#include <memory> #include <string> #include <utility> #include <vector> @@ -19,9 +20,12 @@ #include "net/base/network_isolation_key.h" #include "net/dns/context_host_resolver.h" #include "net/dns/dns_util.h" +#include "net/dns/host_resolver.h" #include "net/dns/host_resolver_source.h" #include "net/dns/public/resolve_error_info.h" #include "net/log/net_log_with_source.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/scheme_host_port.h" namespace cronet { @@ -328,6 +332,17 @@ std::unique_ptr<net::HostResolver::ResolveHostRequest> StaleHostResolver::CreateRequest( + url::SchemeHostPort host, + net::NetworkIsolationKey network_isolation_key, + net::NetLogWithSource net_log, + absl::optional<ResolveHostParameters> optional_parameters) { + // TODO(crbug.com/1206799): Propagate scheme. + return CreateRequest(net::HostPortPair::FromSchemeHostPort(host), + network_isolation_key, net_log, optional_parameters); +} + +std::unique_ptr<net::HostResolver::ResolveHostRequest> +StaleHostResolver::CreateRequest( const net::HostPortPair& host, const net::NetworkIsolationKey& network_isolation_key, const net::NetLogWithSource& net_log,
diff --git a/components/cronet/stale_host_resolver.h b/components/cronet/stale_host_resolver.h index 335cbc3..57b88e5 100644 --- a/components/cronet/stale_host_resolver.h +++ b/components/cronet/stale_host_resolver.h
@@ -11,7 +11,11 @@ #include "base/memory/weak_ptr.h" #include "base/time/default_tick_clock.h" #include "net/base/completion_once_callback.h" +#include "net/base/network_isolation_key.h" #include "net/dns/host_resolver.h" +#include "net/log/net_log_with_source.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/scheme_host_port.h" namespace base { class TickClock; @@ -79,6 +83,11 @@ // If stale data is returned, the StaleHostResolver allows the underlying // request to continue in order to repopulate the cache. std::unique_ptr<ResolveHostRequest> CreateRequest( + url::SchemeHostPort host, + net::NetworkIsolationKey network_isolation_key, + net::NetLogWithSource net_log, + absl::optional<ResolveHostParameters> optional_parameters) override; + std::unique_ptr<ResolveHostRequest> CreateRequest( const net::HostPortPair& host, const net::NetworkIsolationKey& network_isolation_key, const net::NetLogWithSource& net_log,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc index 45b4b76..affe5cd 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
@@ -395,8 +395,7 @@ void DataReductionProxyCompressionStats::InitListPref(const char* pref) { std::unique_ptr<base::ListValue> pref_value = - std::unique_ptr<base::ListValue>( - pref_service_->GetList(pref)->DeepCopy()); + pref_service_->GetList(pref)->CreateDeepCopy(); list_pref_map_[pref] = std::move(pref_value); }
diff --git a/components/desks_storage/BUILD.gn b/components/desks_storage/BUILD.gn index 8d918d27..3a6203c 100644 --- a/components/desks_storage/BUILD.gn +++ b/components/desks_storage/BUILD.gn
@@ -13,6 +13,8 @@ "core/desk_sync_bridge.h", "core/desk_template.cc", "core/desk_template.h", + "core/local_desk_data_manager.cc", + "core/local_desk_data_manager.h", ] deps = [ "//base", @@ -28,7 +30,10 @@ source_set("unit_tests") { testonly = true - sources = [ "core/desk_sync_bridge_unittest.cc" ] + sources = [ + "core/desk_sync_bridge_unittest.cc", + "core/local_desks_data_manager_unittests.cc", + ] deps = [ ":desks_storage", "//base",
diff --git a/components/desks_storage/core/desk_template.h b/components/desks_storage/core/desk_template.h index e13b29f4..69096db 100644 --- a/components/desks_storage/core/desk_template.h +++ b/components/desks_storage/core/desk_template.h
@@ -18,6 +18,9 @@ // A desk template being saved. The UUID is a unique identifier for a // template. This class is a temporary placeholder. This could be replaced // by future ash::DeskTemplate when it is ready. +// +// NOTE: This definition will be deleted in an upcoming CL to be replaced by +// ash::DeskTemplate. class DeskTemplate { public: // Creates a DeskTemplate from the protobuf format.
diff --git a/components/desks_storage/core/local_desk_data_manager.cc b/components/desks_storage/core/local_desk_data_manager.cc new file mode 100644 index 0000000..799e030 --- /dev/null +++ b/components/desks_storage/core/local_desk_data_manager.cc
@@ -0,0 +1,262 @@ +// Copyright 2021 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. + +#include "components/desks_storage/core/local_desk_data_manager.h" + +#include "base/files/dir_reader_posix.h" +#include "base/files/file_util.h" +#include "base/task/post_task.h" +#include "base/task/thread_pool.h" +#include "base/threading/scoped_blocking_call.h" +#include "components/desks_storage/core/desk_model.h" +#include "components/desks_storage/core/desk_template.h" +#include "components/sync/protocol/workspace_desk_specifics.pb.h" + +namespace desks_storage { + +namespace { + +constexpr char kFileExtension[] = ".template"; + +// WriteTemplateToFile is a method that takes a base::FilePath +// |path_to_template| and a DeskTemplate unique pointer |entry| +// and writes the entry out in its serialized form to the path +// represented by |path_to_template|. +// +// WARNING: This private helper function utilizes blocking calls +// and assumes that it is being called from a thread which can accept +// such calls, please don't call this function from the main thread. +bool WriteTemplateFile(const base::FilePath& path_to_template, + std::unique_ptr<DeskTemplate> entry) { + std::string proto_string; + bool string_conversion_success = + entry->AsSyncProto().SerializeToString(&proto_string); + + if (!string_conversion_success) + return false; + + base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, + base::BlockingType::MAY_BLOCK); + bool write_success = base::WriteFile(path_to_template, proto_string); + + if (!write_success) + return false; + + return true; +} + +// AppendTemplateUUID appends a std::string |entry| to a std::vector of uuids. +// in order to be appended |entry| must contain .template within the string. +// This method populates the std::vector as a side effect and has a void return +// type hence |out_uuids|. +void AppendTemplateUUID(const std::string& entry, + std::vector<std::string>* out_uuids) { + const size_t extension_at = entry.find(kFileExtension); + + if (extension_at == std::string::npos) + return; + + out_uuids->push_back(entry.substr(0, extension_at)); +} + +// returns the fully qualified path to a template file given the file path to +// the desk template directory. +base::FilePath GetFullyQualifiedPath(base::FilePath file_path, + std::string uuid) { + std::string filename(uuid); + filename.append(kFileExtension); + return base::FilePath( + file_path.Append(base::FilePath::StringPieceType(filename.c_str()))); +} + +struct GetAllUuidsResult { + DeskModel::GetAllUuidsStatus status; + std::vector<std::string> uuids; +}; + +// This method gets all UUIDs available in the template directory. This +// is a task that is posted to the local storage object's task runner. +GetAllUuidsResult GetAllUuidsTask(const base::FilePath local_template_path) { + base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, + base::BlockingType::MAY_BLOCK); + base::DirReaderPosix dir_reader(local_template_path.AsUTF8Unsafe().c_str()); + if (!dir_reader.IsValid()) { + return {DeskModel::GetAllUuidsStatus::kFailure, {}}; + } + + std::vector<std::string> uuids; + while (dir_reader.Next()) { + if (dir_reader.name() == nullptr) + continue; + + AppendTemplateUUID(std::string(dir_reader.name()), &uuids); + } + + return {DeskModel::GetAllUuidsStatus::kOk, std::move(uuids)}; +} + +// Handles GetAllUuidsTask and calls the callback with the result. +void HandleGetAllUuidsTask(DeskModel::GetAllUuidsCallback callback, + GetAllUuidsResult result) { + std::move(callback).Run(result.status, std::move(result.uuids)); +} + +// Adds or updates an entry. This is a task that is posted to base::ThreadPool +// in order to complete io operations. +DeskModel::AddOrUpdateEntryStatus AddOrUpdateEntryTask( + const base::FilePath local_template_path, + std::unique_ptr<DeskTemplate> new_entry) { + const base::FilePath fully_qualified_path = + GetFullyQualifiedPath(local_template_path, new_entry->uuid()); + + if (WriteTemplateFile(fully_qualified_path, std::move(new_entry))) + return DeskModel::AddOrUpdateEntryStatus::kOk; + else + return DeskModel::AddOrUpdateEntryStatus::kFailure; +} + +struct GetEntryByUuidResult { + DeskModel::GetEntryByUuidStatus status; + std::unique_ptr<DeskTemplate> desk_template; +}; + +// This method Handles getting the task of getting an entry by it's Uuid. Unlike +// the other statuses this function returns the DeskTemplate pointer instead of +// a status. This is because this method has to instantiate the DeskTemplate +// itself in order to use the DeskTemplate::FromProto factory method. +GetEntryByUuidResult GetEntryByUuidTask( + const base::FilePath local_template_path, + const std::string& uuid) { + const base::FilePath fully_qualified_path = + GetFullyQualifiedPath(local_template_path, uuid); + + base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, + base::BlockingType::MAY_BLOCK); + if (!base::PathExists(fully_qualified_path)) + return {DeskModel::GetEntryByUuidStatus::kNotFound, nullptr}; + + std::string proto_string; + bool read_success = + base::ReadFileToString(fully_qualified_path, &proto_string); + + if (!read_success) + return {DeskModel::GetEntryByUuidStatus::kFailure, nullptr}; + + sync_pb::WorkspaceDeskSpecifics desk_proto; + bool parse_success = desk_proto.ParseFromString(proto_string); + + if (!parse_success) + return {DeskModel::GetEntryByUuidStatus::kFailure, nullptr}; + + return {DeskModel::GetEntryByUuidStatus::kOk, + DeskTemplate::FromProto(desk_proto)}; +} + +// Handles replies from |GetEntryByUuidTask| and calls callback. +void HandleGetEntryByUuidTask(DeskModel::GetEntryByUuidCallback callback, + GetEntryByUuidResult result) { + std::move(callback).Run(result.status, std::move(result.desk_template)); +} + +// This task deletes a single entry keyed by its |uuid|. +DeskModel::DeleteEntryStatus DeleteSingleEntryTask( + const base::FilePath local_file_path, + const std::string& uuid) { + const base::FilePath fully_qualified_path = + GetFullyQualifiedPath(local_file_path, uuid); + + base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, + base::BlockingType::MAY_BLOCK); + if (base::DeleteFile(fully_qualified_path)) + return DeskModel::DeleteEntryStatus::kOk; + + return DeskModel::DeleteEntryStatus::kFailure; +} + +// Deletes all entries. +DeskModel::DeleteEntryStatus DeleteAllEntriesTask( + const base::FilePath local_file_path) { + base::DirReaderPosix dir_reader(local_file_path.AsUTF8Unsafe().c_str()); + + if (!dir_reader.IsValid()) + return DeskModel::DeleteEntryStatus::kFailure; + + DeskModel::DeleteEntryStatus overall_delete_successes = + DeskModel::DeleteEntryStatus::kOk; + while (dir_reader.Next()) { + if (dir_reader.name() == nullptr) + continue; + + std::string filename(dir_reader.name()); + size_t extension_at = filename.find(kFileExtension); + + if (extension_at == std::string::npos) + continue; + + base::FilePath fully_qualified_path(local_file_path.Append(filename)); + base::ScopedBlockingCall scoped_blocking_call( + FROM_HERE, base::BlockingType::MAY_BLOCK); + bool delete_success = base::DeleteFile(fully_qualified_path); + if ((overall_delete_successes == DeskModel::DeleteEntryStatus::kOk) && + !delete_success) + overall_delete_successes = DeskModel::DeleteEntryStatus::kFailure; + } + + return overall_delete_successes; +} + +} // namespace + +LocalDeskDataManager::LocalDeskDataManager(const base::FilePath& path) + : task_runner_(base::ThreadPool::CreateSequencedTaskRunner( + {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})), + local_path_(path) {} + +LocalDeskDataManager::~LocalDeskDataManager() = default; + +void LocalDeskDataManager::AddOrUpdateEntry( + std::unique_ptr<DeskTemplate> new_entry, + DeskModel::AddOrUpdateEntryCallback callback) { + task_runner_->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&AddOrUpdateEntryTask, base::FilePath(local_path_), + std::move(new_entry)), + std::move(callback)); +} + +void LocalDeskDataManager::GetAllUuids( + DeskModel::GetAllUuidsCallback callback) { + task_runner_->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&GetAllUuidsTask, base::FilePath(local_path_)), + base::BindOnce(&HandleGetAllUuidsTask, std::move(callback))); +} + +void LocalDeskDataManager::GetEntryByUUID( + const std::string& uuid, + DeskModel::GetEntryByUuidCallback callback) { + task_runner_->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&GetEntryByUuidTask, base::FilePath(local_path_), uuid), + base::BindOnce(&HandleGetEntryByUuidTask, std::move(callback))); +} + +void LocalDeskDataManager::DeleteEntry( + const std::string& uuid, + DeskModel::DeleteEntryCallback callback) { + task_runner_->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&DeleteSingleEntryTask, base::FilePath(local_path_), uuid), + std::move(callback)); +} + +void LocalDeskDataManager::DeleteAllEntries( + DeskModel::DeleteEntryCallback callback) { + task_runner_->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&DeleteAllEntriesTask, base::FilePath(local_path_)), + std::move(callback)); +} + +} // namespace desks_storage \ No newline at end of file
diff --git a/components/desks_storage/core/local_desk_data_manager.h b/components/desks_storage/core/local_desk_data_manager.h new file mode 100644 index 0000000..e6429b05 --- /dev/null +++ b/components/desks_storage/core/local_desk_data_manager.h
@@ -0,0 +1,51 @@ +// Copyright 2021 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. + +#ifndef COMPONENTS_DESKS_STORAGE_CORE_LOCAL_DESK_DATA_MANAGER_H_ +#define COMPONENTS_DESKS_STORAGE_CORE_LOCAL_DESK_DATA_MANAGER_H_ + +#include <memory> + +#include "base/files/file_path.h" +#include "base/memory/ref_counted.h" +#include "base/memory/ref_counted_delete_on_sequence.h" +#include "base/memory/weak_ptr.h" +#include "base/sequenced_task_runner_helpers.h" +#include "components/desks_storage/core/desk_model.h" + +namespace desks_storage { + +class DeskTemplate; + +// The LocalDeskDataManager is the local storage implementation of +// the DeskModel interface and handles storage operations for local +// desk templates. +class LocalDeskDataManager : public DeskModel { + public: + explicit LocalDeskDataManager(const base::FilePath& path); + + LocalDeskDataManager(const LocalDeskDataManager&) = delete; + LocalDeskDataManager& operator=(const LocalDeskDataManager&) = delete; + ~LocalDeskDataManager() override; + + // DeskModel: + void GetAllUuids(GetAllUuidsCallback callback) override; + void DeleteAllEntries(DeleteEntryCallback callback) override; + void GetEntryByUUID(const std::string& uuid, + GetEntryByUuidCallback callback) override; + void AddOrUpdateEntry(std::unique_ptr<DeskTemplate> new_entry, + AddOrUpdateEntryCallback callback) override; + void DeleteEntry(const std::string& uuid, + DeleteEntryCallback callback) override; + + private: + scoped_refptr<base::SequencedTaskRunner> task_runner_; + // This file path points to the user data directory's subdirectory: + // "/path/to/user/data/dir/templates" + const base::FilePath local_path_; +}; + +} // namespace desks_storage + +#endif // COMPONENTS_DESKS_STORAGE_CORE_LOCAL_DESK_DATA_MANAGER_H_
diff --git a/components/desks_storage/core/local_desks_data_manager_unittests.cc b/components/desks_storage/core/local_desks_data_manager_unittests.cc new file mode 100644 index 0000000..aecf5b94 --- /dev/null +++ b/components/desks_storage/core/local_desks_data_manager_unittests.cc
@@ -0,0 +1,241 @@ +// Copyright 2021 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. + +#include "components/desks_storage/core/local_desk_data_manager.h" + +#include <string> + +#include "base/files/file_path.h" +#include "base/files/scoped_temp_dir.h" +#include "base/run_loop.h" +#include "base/task/post_task.h" +#include "base/test/bind.h" +#include "base/test/task_environment.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "build/build_config.h" +#include "components/desks_storage/core/desk_template.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace desks_storage { + +namespace { + +// Search |uuid_list| for |uuid_query| returns true if found false if not. +// +// we don't know what order the dir_reader will read the files back to us so +// instead of relying on the operation returning the uuids in order we can +// simply run a linear search for each of the uuids we expect to find. +// +// we don't use std::find here because we want to run each member through +// the string compare method. +bool FindUuidInUuidList(const std::string& uuid_query, + const std::vector<std::string>& uuid_list) { + for (const std::string& uuid : uuid_list) { + if (uuid.compare(uuid_query) == 0) + return true; + } + + return false; +} + +// Verifies that the status passed into it is kOk +void VerifyEntryAddedCorrectly(DeskModel::AddOrUpdateEntryStatus status) { + EXPECT_EQ(status, DeskModel::AddOrUpdateEntryStatus::kOk); +} + +} // namespace + +class LocalDeskDataManagerTest : public testing::Test { + public: + LocalDeskDataManagerTest() + : sample_desk_template_one_( + std::make_unique<DeskTemplate>(std::string("01"), + std::string("desk_01"), + base::Time())), + sample_desk_template_two_( + std::make_unique<DeskTemplate>(std::string("02"), + std::string("desk_02"), + base::Time())), + sample_desk_template_three_( + std::make_unique<DeskTemplate>(std::string("03"), + std::string("desk_03"), + base::Time())), + modified_sample_desk_template_one_( + std::make_unique<DeskTemplate>(std::string("01"), + std::string("desk_01_mod"), + base::Time())) {} + + LocalDeskDataManagerTest(const LocalDeskDataManagerTest&) = delete; + LocalDeskDataManagerTest& operator=(const LocalDeskDataManagerTest&) = delete; + + ~LocalDeskDataManagerTest() override = default; + + void SetUp() override { + EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); + testing::Test::SetUp(); + } + + base::ScopedTempDir temp_dir_; + std::unique_ptr<DeskTemplate> sample_desk_template_one_; + std::unique_ptr<DeskTemplate> sample_desk_template_two_; + std::unique_ptr<DeskTemplate> sample_desk_template_three_; + std::unique_ptr<DeskTemplate> modified_sample_desk_template_one_; +}; + +TEST_F(LocalDeskDataManagerTest, CanAddEntry) { + base::test::TaskEnvironment task_environment( + base::test::TaskEnvironment::MainThreadType::IO); + + LocalDeskDataManager data_manager(temp_dir_.GetPath()); + + data_manager.AddOrUpdateEntry(std::move(sample_desk_template_one_), + base::BindOnce(&VerifyEntryAddedCorrectly)); +} + +TEST_F(LocalDeskDataManagerTest, CanGetAllUuids) { + base::test::TaskEnvironment task_environment( + base::test::TaskEnvironment::MainThreadType::IO); + + LocalDeskDataManager data_manager(temp_dir_.GetPath()); + + data_manager.AddOrUpdateEntry(std::move(sample_desk_template_one_), + base::BindOnce(&VerifyEntryAddedCorrectly)); + + data_manager.AddOrUpdateEntry(std::move(sample_desk_template_two_), + base::BindOnce(&VerifyEntryAddedCorrectly)); + + data_manager.AddOrUpdateEntry(std::move(sample_desk_template_three_), + base::BindOnce(&VerifyEntryAddedCorrectly)); + + // Because we're using a SequencedTaskRunner we can assume that all of the + // previous tasks have been completed by the time we actually attempt to + // read the UUIDs. + data_manager.GetAllUuids( + base::BindLambdaForTesting([](DeskModel::GetAllUuidsStatus status, + const std::vector<std::string>& uuids) { + EXPECT_EQ(status, DeskModel::GetAllUuidsStatus::kOk); + EXPECT_EQ(uuids.size(), static_cast<unsigned long>(3)); + EXPECT_TRUE(FindUuidInUuidList(std::string("01"), uuids)); + EXPECT_TRUE(FindUuidInUuidList(std::string("02"), uuids)); + EXPECT_TRUE(FindUuidInUuidList(std::string("03"), uuids)); + + // Sanity check for the search function. + EXPECT_FALSE(FindUuidInUuidList(std::string("04"), uuids)); + })); +} + +TEST_F(LocalDeskDataManagerTest, CanGetEntryByUuid) { + base::test::TaskEnvironment task_environment( + base::test::TaskEnvironment::MainThreadType::IO); + + LocalDeskDataManager data_manager(temp_dir_.GetPath()); + + data_manager.AddOrUpdateEntry(std::move(sample_desk_template_one_), + base::BindOnce(&VerifyEntryAddedCorrectly)); + + data_manager.GetEntryByUUID( + std::string("01"), + base::BindLambdaForTesting( + [](DeskModel::GetEntryByUuidStatus status, + std::unique_ptr<DeskTemplate> result_template) { + EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kOk, status); + + EXPECT_EQ(result_template->uuid(), std::string("01")); + EXPECT_EQ(result_template->name(), std::string("desk_01")); + EXPECT_EQ(result_template->created_time(), base::Time()); + })); +} + +TEST_F(LocalDeskDataManagerTest, GetEntryByUuidFailsIfEntryDoesntExist) { + base::test::TaskEnvironment task_environment( + base::test::TaskEnvironment::MainThreadType::IO); + + LocalDeskDataManager data_manager(temp_dir_.GetPath()); + + data_manager.GetEntryByUUID( + std::string("01"), + base::BindLambdaForTesting([](DeskModel::GetEntryByUuidStatus status, + std::unique_ptr<DeskTemplate> _) { + EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kNotFound, status); + })); +} + +TEST_F(LocalDeskDataManagerTest, CanUpdateEntry) { + base::test::TaskEnvironment task_environment( + base::test::TaskEnvironment::MainThreadType::IO); + + LocalDeskDataManager data_manager(temp_dir_.GetPath()); + + data_manager.AddOrUpdateEntry(std::move(sample_desk_template_one_), + base::BindOnce(&VerifyEntryAddedCorrectly)); + + data_manager.AddOrUpdateEntry(std::move(modified_sample_desk_template_one_), + base::BindOnce(&VerifyEntryAddedCorrectly)); + + data_manager.GetEntryByUUID( + std::string("01"), + base::BindLambdaForTesting( + [](DeskModel::GetEntryByUuidStatus status, + std::unique_ptr<DeskTemplate> result_template) { + EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kOk, status); + + EXPECT_EQ(result_template->uuid(), std::string("01")); + EXPECT_EQ(result_template->name(), std::string("desk_01_mod")); + EXPECT_EQ(result_template->created_time(), base::Time()); + })); +} + +TEST_F(LocalDeskDataManagerTest, CanDeleteEntry) { + base::test::TaskEnvironment task_environment( + base::test::TaskEnvironment::MainThreadType::IO); + + LocalDeskDataManager data_manager(temp_dir_.GetPath()); + + data_manager.AddOrUpdateEntry(std::move(sample_desk_template_one_), + base::BindOnce(&VerifyEntryAddedCorrectly)); + + data_manager.DeleteEntry( + std::string("01"), + base::BindLambdaForTesting([](DeskModel::DeleteEntryStatus status) { + EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kOk); + })); + + data_manager.GetAllUuids( + base::BindLambdaForTesting([](DeskModel::GetAllUuidsStatus status, + const std::vector<std::string>& uuids) { + EXPECT_EQ(status, DeskModel::GetAllUuidsStatus::kOk); + EXPECT_EQ(uuids.size(), 0ul); + })); +} + +TEST_F(LocalDeskDataManagerTest, CanDeleteAllEntries) { + base::test::TaskEnvironment task_environment( + base::test::TaskEnvironment::MainThreadType::IO); + + LocalDeskDataManager data_manager(temp_dir_.GetPath()); + + data_manager.AddOrUpdateEntry(std::move(sample_desk_template_one_), + base::BindOnce(&VerifyEntryAddedCorrectly)); + + data_manager.AddOrUpdateEntry(std::move(sample_desk_template_two_), + base::BindOnce(&VerifyEntryAddedCorrectly)); + + data_manager.AddOrUpdateEntry(std::move(sample_desk_template_three_), + base::BindOnce(&VerifyEntryAddedCorrectly)); + + data_manager.DeleteAllEntries( + base::BindLambdaForTesting([](DeskModel::DeleteEntryStatus status) { + EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kOk); + })); + + data_manager.GetAllUuids( + base::BindLambdaForTesting([](DeskModel::GetAllUuidsStatus status, + const std::vector<std::string>& uuids) { + EXPECT_EQ(status, DeskModel::GetAllUuidsStatus::kOk); + EXPECT_EQ(uuids.size(), 0ul); + })); +} + +} // namespace desks_storage
diff --git a/components/download/internal/common/resource_downloader.cc b/components/download/internal/common/resource_downloader.cc index fe8a1a6..5abe9d6d 100644 --- a/components/download/internal/common/resource_downloader.cc +++ b/components/download/internal/common/resource_downloader.cc
@@ -180,7 +180,8 @@ url_loader_factory_->CreateLoaderAndStart( url_loader_.BindNewPipeAndPassReceiver(), 0, // request_id - network::mojom::kURLLoadOptionSendSSLInfoWithResponse, + network::mojom::kURLLoadOptionSendSSLInfoWithResponse | + network::mojom::kURLLoadOptionSniffMimeType, *(resource_request_.get()), std::move(url_loader_client_remote), net::MutableNetworkTrafficAnnotationTag( download_url_parameters->GetNetworkTrafficAnnotation()));
diff --git a/components/exo/client_controlled_shell_surface_unittest.cc b/components/exo/client_controlled_shell_surface_unittest.cc index 0553e8a..09ceeee 100644 --- a/components/exo/client_controlled_shell_surface_unittest.cc +++ b/components/exo/client_controlled_shell_surface_unittest.cc
@@ -1295,7 +1295,7 @@ // Drag the window long enough (pass one fourth of the screen vertical // height) to snap the window to splitscreen. - shell->overview_controller()->EndOverview(); + shell->overview_controller()->EndOverview(ash::OverviewEndAction::kTests); SendGestureEvents(window, gfx::Point(0, 210)); EXPECT_EQ(ash::WindowState::Get(window)->GetStateType(), WindowStateType::kPrimarySnapped);
diff --git a/components/feed/core/proto/BUILD.gn b/components/feed/core/proto/BUILD.gn index cf2c20d..5c847c6 100644 --- a/components/feed/core/proto/BUILD.gn +++ b/components/feed/core/proto/BUILD.gn
@@ -24,6 +24,7 @@ "v2/wire/client_info.proto", "v2/wire/consistency_token.proto", "v2/wire/content_id.proto", + "v2/wire/content_lifetime.proto", "v2/wire/data_operation.proto", "v2/wire/device.proto", "v2/wire/diagnostic_info.proto",
diff --git a/components/feed/core/proto/v2/wire/content_lifetime.proto b/components/feed/core/proto/v2/wire/content_lifetime.proto new file mode 100644 index 0000000..4d5cade82 --- /dev/null +++ b/components/feed/core/proto/v2/wire/content_lifetime.proto
@@ -0,0 +1,14 @@ +// Copyright 2021 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. + +syntax = "proto2"; + +package feedwire; + +option optimize_for = LITE_RUNTIME; + +message ContentLifetime { + optional int64 stale_age_ms = 1; + optional int64 invalid_age_ms = 2; +}
diff --git a/components/feed/core/proto/v2/wire/feed_response.proto b/components/feed/core/proto/v2/wire/feed_response.proto index 575d463..c3324d4 100644 --- a/components/feed/core/proto/v2/wire/feed_response.proto +++ b/components/feed/core/proto/v2/wire/feed_response.proto
@@ -7,6 +7,7 @@ package feedwire; import "components/feed/core/proto/v2/wire/chrome_feed_response_metadata.proto"; +import "components/feed/core/proto/v2/wire/content_lifetime.proto"; import "components/feed/core/proto/v2/wire/data_operation.proto"; import "components/feed/core/proto/v2/wire/eventid.proto"; import "components/feed/core/proto/v2/wire/server_experiment_data.proto"; @@ -22,5 +23,6 @@ optional EventIdMessage event_id = 2; optional bool pinned_content_fulfilled = 4; optional ServerExperimentData server_experiment_data = 5; + optional ContentLifetime content_lifetime = 6; optional ChromeFeedResponseMetadata chrome_feed_response_metadata = 326233599; }
diff --git a/components/feed/core/v2/feed_network.h b/components/feed/core/v2/feed_network.h index 322a080..bb005c2 100644 --- a/components/feed/core/v2/feed_network.h +++ b/components/feed/core/v2/feed_network.h
@@ -77,7 +77,7 @@ using Response = feedwire::webfeed::ListWebFeedsResponse; static constexpr NetworkRequestType kRequestType = NetworkRequestType::kListWebFeeds; - static base::StringPiece Method() { return "GET"; } + static base::StringPiece Method() { return "POST"; } static base::StringPiece RequestPath(const Request&) { return "v1/webFeeds"; } }; @@ -86,7 +86,7 @@ using Response = feedwire::webfeed::ListRecommendedWebFeedsResponse; static constexpr NetworkRequestType kRequestType = NetworkRequestType::kListRecommendedWebFeeds; - static base::StringPiece Method() { return "GET"; } + static base::StringPiece Method() { return "POST"; } static base::StringPiece RequestPath(const Request&) { return "v1/recommendedWebFeeds"; }
diff --git a/components/infobars/core/infobar_delegate.cc b/components/infobars/core/infobar_delegate.cc index 96a25a9..352970f3 100644 --- a/components/infobars/core/infobar_delegate.cc +++ b/components/infobars/core/infobar_delegate.cc
@@ -4,7 +4,6 @@ #include "components/infobars/core/infobar_delegate.h" -#include "base/no_destructor.h" #include "build/build_config.h" #include "components/infobars/core/infobar.h" #include "components/infobars/core/infobar_manager.h" @@ -33,8 +32,8 @@ } const gfx::VectorIcon& InfoBarDelegate::GetVectorIcon() const { - static base::NoDestructor<gfx::VectorIcon> empty_icon; - return *empty_icon; + static gfx::VectorIcon empty_icon; + return empty_icon; } gfx::Image InfoBarDelegate::GetIcon() const {
diff --git a/components/keyed_service/content/browser_context_dependency_manager.h b/components/keyed_service/content/browser_context_dependency_manager.h index e521103..98d4ab9 100644 --- a/components/keyed_service/content/browser_context_dependency_manager.h +++ b/components/keyed_service/content/browser_context_dependency_manager.h
@@ -9,14 +9,10 @@ #include "base/callback_list.h" #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/no_destructor.h" #include "components/keyed_service/core/dependency_manager.h" #include "components/keyed_service/core/keyed_service_export.h" -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - namespace content { class BrowserContext; }
diff --git a/components/leveldb_proto/internal/shared_proto_database.cc b/components/leveldb_proto/internal/shared_proto_database.cc index 416fe74..810d69a2 100644 --- a/components/leveldb_proto/internal/shared_proto_database.cc +++ b/components/leveldb_proto/internal/shared_proto_database.cc
@@ -10,6 +10,7 @@ #include "base/callback_helpers.h" #include "base/memory/ptr_util.h" #include "base/sequenced_task_runner.h" +#include "base/synchronization/lock.h" #include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "components/leveldb_proto/internal/leveldb_database.h" @@ -478,6 +479,7 @@ delete_obsolete_task_.Reset(base::BindOnce( &SharedProtoDatabase::DestroyObsoleteSharedProtoDatabaseClients, this, std::move(keep_shared_db_alive))); + base::AutoLock lock(delete_obsolete_delay_lock_); task_runner_->PostDelayedTask(FROM_HERE, delete_obsolete_task_.callback(), delete_obsolete_delay_); } @@ -605,6 +607,12 @@ std::move(db_wrapper), std::move(done)); } +void SharedProtoDatabase::SetDeleteObsoleteDelayForTesting( + base::TimeDelta delay) { + base::AutoLock lock(delete_obsolete_delay_lock_); + delete_obsolete_delay_ = delay; +} + LevelDB* SharedProtoDatabase::GetLevelDBForTesting() const { return db_.get(); }
diff --git a/components/leveldb_proto/internal/shared_proto_database.h b/components/leveldb_proto/internal/shared_proto_database.h index 67b6adc..d155e79 100644 --- a/components/leveldb_proto/internal/shared_proto_database.h +++ b/components/leveldb_proto/internal/shared_proto_database.h
@@ -15,6 +15,7 @@ #include "base/containers/queue.h" #include "base/memory/ref_counted.h" #include "base/sequence_checker.h" +#include "base/synchronization/lock.h" #include "components/leveldb_proto/internal/proto/shared_db_metadata.pb.h" #include "components/leveldb_proto/internal/shared_proto_database_client.h" #include "components/leveldb_proto/public/proto_database.h" @@ -159,9 +160,7 @@ LevelDB* GetLevelDBForTesting() const; - void set_delete_obsolete_delay_for_testing(base::TimeDelta delay) { - delete_obsolete_delay_ = delay; - } + void SetDeleteObsoleteDelayForTesting(base::TimeDelta delay); scoped_refptr<base::SequencedTaskRunner> database_task_runner_for_testing() const { @@ -192,6 +191,7 @@ bool create_if_missing_ = false; base::TimeDelta delete_obsolete_delay_ = base::TimeDelta::FromSeconds(120); + base::Lock delete_obsolete_delay_lock_; base::CancelableOnceClosure delete_obsolete_task_; DISALLOW_COPY_AND_ASSIGN(SharedProtoDatabase);
diff --git a/components/leveldb_proto/internal/shared_proto_database_unittest.cc b/components/leveldb_proto/internal/shared_proto_database_unittest.cc index 79ec500..82e006a 100644 --- a/components/leveldb_proto/internal/shared_proto_database_unittest.cc +++ b/components/leveldb_proto/internal/shared_proto_database_unittest.cc
@@ -254,7 +254,7 @@ } TEST_F(SharedProtoDatabaseTest, DeleteObsoleteClients) { - db()->set_delete_obsolete_delay_for_testing(base::TimeDelta()); + db()->SetDeleteObsoleteDelayForTesting(base::TimeDelta()); EXPECT_CALL(*db(), DestroyObsoleteSharedProtoDatabaseClients(_)).Times(1); base::RunLoop run_init_loop; InitDB(true /* create_if_missing */, "TestDatabaseUMA",
diff --git a/components/leveldb_proto/public/proto_database_provider.cc b/components/leveldb_proto/public/proto_database_provider.cc index 9a5caaa9..9ba0bd2 100644 --- a/components/leveldb_proto/public/proto_database_provider.cc +++ b/components/leveldb_proto/public/proto_database_provider.cc
@@ -56,7 +56,7 @@ base::TimeDelta delay) { base::AutoLock lock(get_db_lock_); if (db_) - db_->set_delete_obsolete_delay_for_testing(delay); // IN-TEST + db_->SetDeleteObsoleteDelayForTesting(delay); // IN-TEST } } // namespace leveldb_proto
diff --git a/components/leveldb_proto/public/proto_database_provider.h b/components/leveldb_proto/public/proto_database_provider.h index 97626b3..8036009 100644 --- a/components/leveldb_proto/public/proto_database_provider.h +++ b/components/leveldb_proto/public/proto_database_provider.h
@@ -63,6 +63,7 @@ virtual ~ProtoDatabaseProvider(); + // This method is thread safe. void SetSharedDBDeleteObsoleteDelayForTesting(base::TimeDelta delay); private:
diff --git a/components/metrics/entropy_state.cc b/components/metrics/entropy_state.cc index 4995f51..3833ed8f 100644 --- a/components/metrics/entropy_state.cc +++ b/components/metrics/entropy_state.cc
@@ -6,7 +6,6 @@ #include "base/command_line.h" #include "base/metrics/histogram_functions.h" -#include "base/no_destructor.h" #include "base/rand_util.h" #include "base/strings/string_number_conversions.h" #include "components/metrics/metrics_pref_names.h" @@ -23,14 +22,15 @@ const int kMaxLowEntropySize = 8000; // Generates a new non-identifying entropy source used to seed persistent -// activities. Using a NoDestructor so that the new low entropy source value -// will only be generated on first access. And thus, even though we may write -// the new low entropy source value to prefs multiple times, it stays the same +// activities. Make it static so that the new low entropy source value will +// only be generated on first access. And thus, even though we may write the +// new low entropy source value to prefs multiple times, it stays the same // value. int GenerateLowEntropySource() { - static const base::NoDestructor<int> low_entropy_source( - [] { return base::RandInt(0, kMaxLowEntropySize - 1); }()); - return *low_entropy_source; + static const int low_entropy_source = + base::RandInt(0, kMaxLowEntropySize - 1); + ; + return low_entropy_source; } // Generates a new non-identifying low entropy source using the same method @@ -38,9 +38,10 @@ // used for statistical validation, and *not* for randomization or experiment // assignment. int GeneratePseudoLowEntropySource() { - static const base::NoDestructor<int> pseudo_low_entropy_source( - [] { return base::RandInt(0, kMaxLowEntropySize - 1); }()); - return *pseudo_low_entropy_source; + static const int pseudo_low_entropy_source = + base::RandInt(0, kMaxLowEntropySize - 1); + ; + return pseudo_low_entropy_source; } } // namespace
diff --git a/components/mirroring/service/video_capture_client.cc b/components/mirroring/service/video_capture_client.cc index 85902fa..437dfe2 100644 --- a/components/mirroring/service/video_capture_client.cc +++ b/components/mirroring/service/video_capture_client.cc
@@ -5,7 +5,6 @@ #include "components/mirroring/service/video_capture_client.h" #include "base/bind.h" -#include "base/no_destructor.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "media/base/bind_to_current_loop.h" @@ -21,16 +20,16 @@ // Required by mojom::VideoCaptureHost interface. Can be any nonzero value. const base::UnguessableToken& DeviceId() { - static const base::NoDestructor<base::UnguessableToken> device_id( + static const base::UnguessableToken device_id( base::UnguessableToken::Deserialize(1, 1)); - return *device_id; + return device_id; } // Required by mojom::VideoCaptureHost interface. Can be any nonzero value. const base::UnguessableToken& SessionId() { - static const base::NoDestructor<base::UnguessableToken> session_id( + static const base::UnguessableToken session_id( base::UnguessableToken::Deserialize(1, 1)); - return *session_id; + return session_id; } } // namespace
diff --git a/components/ntp_tiles/BUILD.gn b/components/ntp_tiles/BUILD.gn index 8e20403..42c9bdb 100644 --- a/components/ntp_tiles/BUILD.gn +++ b/components/ntp_tiles/BUILD.gn
@@ -48,7 +48,6 @@ public_deps = [ "//base", "//components/history/core/browser", - "//components/suggestions", ] deps = [ "//build:branding_buildflags",
diff --git a/components/ntp_tiles/DEPS b/components/ntp_tiles/DEPS index 6b856fa..b1142d5 100644 --- a/components/ntp_tiles/DEPS +++ b/components/ntp_tiles/DEPS
@@ -11,7 +11,6 @@ "+components/search_engines", "+components/search", "+components/strings/grit/components_strings.h", - "+components/suggestions", "+components/sync_preferences", "+components/url_formatter", "+components/variations",
diff --git a/components/ntp_tiles/custom_links_store.cc b/components/ntp_tiles/custom_links_store.cc index 799e3c60..f6cbb1d 100644 --- a/components/ntp_tiles/custom_links_store.cc +++ b/components/ntp_tiles/custom_links_store.cc
@@ -14,7 +14,6 @@ #include "components/ntp_tiles/pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" -#include "components/suggestions/suggestions_pref_names.h" namespace ntp_tiles {
diff --git a/components/ntp_tiles/features.cc b/components/ntp_tiles/features.cc index e3840f31..4ce3356 100644 --- a/components/ntp_tiles/features.cc +++ b/components/ntp_tiles/features.cc
@@ -21,7 +21,4 @@ const base::Feature kUsePopularSitesSuggestions{ "UsePopularSitesSuggestions", base::FEATURE_ENABLED_BY_DEFAULT}; -const base::Feature kDisplaySuggestionsServiceTiles{ - "DisplaySuggestionsServiceTiles", base::FEATURE_DISABLED_BY_DEFAULT}; - } // namespace ntp_tiles
diff --git a/components/ntp_tiles/features.h b/components/ntp_tiles/features.h index 628ed7c..d9e819607 100644 --- a/components/ntp_tiles/features.h +++ b/components/ntp_tiles/features.h
@@ -26,10 +26,6 @@ // If this feature is enabled, we enable popular sites in the suggestions UI. extern const base::Feature kUsePopularSitesSuggestions; -// If this feature is enabled, we use the remote service to populate suggestions -// tiles. -extern const base::Feature kDisplaySuggestionsServiceTiles; - } // namespace ntp_tiles #endif // COMPONENTS_NTP_TILES_FEATURES_H_
diff --git a/components/ntp_tiles/metrics.cc b/components/ntp_tiles/metrics.cc index e145379..198de53 100644 --- a/components/ntp_tiles/metrics.cc +++ b/components/ntp_tiles/metrics.cc
@@ -22,7 +22,6 @@ // Identifiers for the various tile sources. const char kHistogramClientName[] = "client"; -const char kHistogramServerName[] = "server"; const char kHistogramPopularName[] = "popular_fetched"; const char kHistogramBakedInName[] = "popular_baked_in"; const char kHistogramAllowlistName[] = "allowlist"; @@ -51,8 +50,6 @@ return kHistogramPopularName; case TileSource::ALLOWLIST: return kHistogramAllowlistName; - case TileSource::SUGGESTIONS_SERVICE: - return kHistogramServerName; case TileSource::HOMEPAGE: return kHistogramHomepageName; case TileSource::CUSTOM_LINKS:
diff --git a/components/ntp_tiles/metrics_unittest.cc b/components/ntp_tiles/metrics_unittest.cc index 5018f4e..ab860ef 100644 --- a/components/ntp_tiles/metrics_unittest.cc +++ b/components/ntp_tiles/metrics_unittest.cc
@@ -112,12 +112,12 @@ .Build()); RecordTileImpression(Builder() .WithIndex(5) - .WithSource(TileSource::SUGGESTIONS_SERVICE) + .WithSource(TileSource::POPULAR) .WithVisualType(ICON_REAL) .Build()); RecordTileImpression(Builder() .WithIndex(6) - .WithSource(TileSource::SUGGESTIONS_SERVICE) + .WithSource(TileSource::POPULAR) .WithVisualType(ICON_DEFAULT) .Build()); RecordTileImpression(Builder() @@ -137,10 +137,6 @@ base::Bucket(/*min=*/6, /*count=*/1), base::Bucket(/*min=*/7, /*count=*/1))); EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.server"), - ElementsAre(base::Bucket(/*min=*/5, /*count=*/1), - base::Bucket(/*min=*/6, /*count=*/1))); - EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.client"), ElementsAre(base::Bucket(/*min=*/0, /*count=*/1), base::Bucket(/*min=*/1, /*count=*/1), @@ -149,21 +145,21 @@ base::Bucket(/*min=*/4, /*count=*/1))); EXPECT_THAT(histogram_tester.GetAllSamples( "NewTabPage.SuggestionsImpression.popular_fetched"), - ElementsAre(base::Bucket(/*min=*/7, /*count=*/1))); + ElementsAre(base::Bucket(/*min=*/5, /*count=*/1), + base::Bucket(/*min=*/6, /*count=*/1), + base::Bucket(/*min=*/7, /*count=*/1))); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType"), ElementsAre(base::Bucket(/*min=*/ICON_REAL, /*count=*/4), base::Bucket(/*min=*/ICON_COLOR, /*count=*/3), base::Bucket(/*min=*/ICON_DEFAULT, /*count=*/1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.server"), - ElementsAre(base::Bucket(/*min=*/ICON_REAL, /*count=*/1), - base::Bucket(/*min=*/ICON_DEFAULT, /*count=*/1))); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.client"), ElementsAre(base::Bucket(/*min=*/ICON_REAL, /*count=*/3), base::Bucket(/*min=*/ICON_COLOR, /*count=*/2))); EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.TileType.popular_fetched"), - ElementsAre(base::Bucket(/*min=*/ICON_COLOR, - /*count=*/1))); + ElementsAre(base::Bucket(/*min=*/ICON_REAL, /*count=*/1), + base::Bucket(/*min=*/ICON_COLOR, /*count=*/1), + base::Bucket(/*min=*/ICON_DEFAULT, /*count=*/1))); EXPECT_THAT(histogram_tester.GetAllSamples( "NewTabPage.SuggestionsImpression.IconsReal"), ElementsAre(base::Bucket(/*min=*/0, /*count=*/1), @@ -187,7 +183,7 @@ .WithTitleSource(TileTitleSource::UNKNOWN) .Build()); RecordTileImpression(Builder() - .WithSource(TileSource::SUGGESTIONS_SERVICE) + .WithSource(TileSource::TOP_SITES) .WithTitleSource(TileTitleSource::INFERRED) .Build()); RecordTileImpression(Builder() @@ -208,9 +204,8 @@ .Build()); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.client"), - ElementsAre(base::Bucket(kUnknownTitleSource, /*count=*/1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.server"), - ElementsAre(base::Bucket(kInferredTitleSource, /*count=*/1))); + ElementsAre(base::Bucket(kUnknownTitleSource, /*count=*/1), + base::Bucket(kInferredTitleSource, /*count=*/1))); EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.TileTitle.popular_fetched"), ElementsAre(base::Bucket(kManifestTitleSource, /*count=*/1), @@ -233,7 +228,7 @@ base::HistogramTester histogram_tester; RecordTileImpression( Builder() - .WithSource(TileSource::SUGGESTIONS_SERVICE) + .WithSource(TileSource::TOP_SITES) .WithDataGenerationTime(base::Time::Now() - kSuggestionAge) .Build()); @@ -244,7 +239,7 @@ (kSuggestionAge + kBucketTolerance).InSeconds(), /*count=*/1))); EXPECT_THAT(histogram_tester.GetAllSamples( - "NewTabPage.SuggestionsImpressionAge.server"), + "NewTabPage.SuggestionsImpressionAge.client"), ElementsAre(IsBucketBetween( (kSuggestionAge - kBucketTolerance).InSeconds(), (kSuggestionAge + kBucketTolerance).InSeconds(), @@ -286,8 +281,6 @@ ElementsAre(base::Bucket(/*min=*/3, /*count=*/1))); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), ElementsAre(base::Bucket(/*min=*/3, /*count=*/1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), - IsEmpty()); EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.MostVisited.popular_fetched"), IsEmpty()); @@ -315,8 +308,6 @@ ElementsAre(base::Bucket(/*min=*/3, /*count=*/1))); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), ElementsAre(base::Bucket(/*min=*/3, /*count=*/1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), - IsEmpty()); EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.MostVisited.popular_fetched"), IsEmpty()); @@ -339,8 +330,8 @@ .WithTitleSource(TileTitleSource::UNKNOWN) .Build()); RecordTileClick(Builder() - .WithSource(TileSource::SUGGESTIONS_SERVICE) - .WithTitleSource(TileTitleSource::UNKNOWN) + .WithSource(TileSource::TOP_SITES) + .WithTitleSource(TileTitleSource::TITLE_TAG) .Build()); RecordTileClick(Builder() .WithSource(TileSource::POPULAR) @@ -361,10 +352,8 @@ EXPECT_THAT( histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked.client"), - ElementsAre(base::Bucket(kUnknownTitleSource, /*count=*/1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked.server"), - ElementsAre(base::Bucket(kUnknownTitleSource, /*count=*/1))); + ElementsAre(base::Bucket(kUnknownTitleSource, /*count=*/1), + base::Bucket(kTitleTagTitleSource, /*count=*/1))); EXPECT_THAT(histogram_tester.GetAllSamples( "NewTabPage.TileTitleClicked.popular_fetched"), ElementsAre(base::Bucket(kManifestTitleSource, /*count=*/1), @@ -374,10 +363,10 @@ ElementsAre(base::Bucket(kMetaTagTitleSource, /*count=*/1), base::Bucket(kTitleTagTitleSource, /*count=*/1))); EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked"), - ElementsAre(base::Bucket(kUnknownTitleSource, /*count=*/2), + ElementsAre(base::Bucket(kUnknownTitleSource, /*count=*/1), base::Bucket(kManifestTitleSource, /*count=*/1), base::Bucket(kMetaTagTitleSource, /*count=*/1), - base::Bucket(kTitleTagTitleSource, /*count=*/2))); + base::Bucket(kTitleTagTitleSource, /*count=*/3))); } TEST(RecordTileClickTest, ShouldRecordClickAge) { @@ -386,7 +375,7 @@ base::HistogramTester histogram_tester; RecordTileClick( Builder() - .WithSource(TileSource::SUGGESTIONS_SERVICE) + .WithSource(TileSource::TOP_SITES) .WithDataGenerationTime(base::Time::Now() - kSuggestionAge) .Build()); @@ -396,7 +385,7 @@ (kSuggestionAge + kBucketTolerance).InSeconds(), /*count=*/1))); EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.MostVisitedAge.server"), + histogram_tester.GetAllSamples("NewTabPage.MostVisitedAge.client"), ElementsAre( IsBucketBetween((kSuggestionAge - kBucketTolerance).InSeconds(), (kSuggestionAge + kBucketTolerance).InSeconds(),
diff --git a/components/ntp_tiles/most_visited_sites.cc b/components/ntp_tiles/most_visited_sites.cc index 3a57af9..21e3180 100644 --- a/components/ntp_tiles/most_visited_sites.cc +++ b/components/ntp_tiles/most_visited_sites.cc
@@ -29,9 +29,6 @@ #include "components/search/ntp_features.h" using history::TopSites; -using suggestions::ChromeSuggestion; -using suggestions::SuggestionsProfile; -using suggestions::SuggestionsService; namespace ntp_tiles { @@ -120,14 +117,12 @@ MostVisitedSites::MostVisitedSites( PrefService* prefs, scoped_refptr<history::TopSites> top_sites, - SuggestionsService* suggestions, std::unique_ptr<PopularSites> popular_sites, std::unique_ptr<CustomLinksManager> custom_links, std::unique_ptr<IconCacher> icon_cacher, std::unique_ptr<MostVisitedSitesSupervisor> supervisor) : prefs_(prefs), top_sites_(top_sites), - suggestions_service_(suggestions), popular_sites_(std::move(popular_sites)), custom_links_(std::move(custom_links)), icon_cacher_(std::move(icon_cacher)), @@ -139,7 +134,6 @@ // top_sites_ can be null in tests. // TODO(sfiera): have iOS use a dummy TopSites in its tests. - DCHECK(suggestions_service_); if (supervisor_) supervisor_->SetObserver(this); } @@ -168,8 +162,6 @@ switch (source) { case TileSource::TOP_SITES: return top_sites_ != nullptr; - case TileSource::SUGGESTIONS_SERVICE: - return suggestions_service_ != nullptr; case TileSource::POPULAR_BAKED_IN: case TileSource::POPULAR: return popular_sites_ != nullptr; @@ -228,14 +220,10 @@ custom_links_->RegisterCallbackForOnChanged(base::BindRepeating( &MostVisitedSites::OnCustomLinksChanged, base::Unretained(this))); } - - suggestions_subscription_ = suggestions_service_->AddCallback( - base::BindRepeating(&MostVisitedSites::OnSuggestionsProfileChanged, - base::Unretained(this))); } - // Immediately build the current set of tiles, getting suggestions from the - // SuggestionsService's cache or, if that is empty, sites from TopSites. + // Immediately build the current set of tiles, getting suggestions from + // TopSites. BuildCurrentTiles(); // Also start a request for fresh suggestions. Refresh(); @@ -249,12 +237,8 @@ if (top_sites_) { // TopSites updates itself after a delay. To ensure up-to-date results, // force an update now. - // TODO(mastiz): Is seems unnecessary to refresh TopSites if we will end up - // using server-side suggestions. top_sites_->SyncWithHistory(); } - - suggestions_service_->FetchSuggestionsData(); } void MostVisitedSites::RefreshTiles() { @@ -424,23 +408,11 @@ else top_sites_->RemoveBlockedUrl(url); } - - // Only blocklist in the server-side suggestions service if it's active. - if (mv_source_ == TileSource::SUGGESTIONS_SERVICE) { - if (add_url) - suggestions_service_->BlocklistURL(url); - else - suggestions_service_->UndoBlocklistURL(url); - } } void MostVisitedSites::ClearBlockedUrls() { if (top_sites_) top_sites_->ClearBlockedUrls(); - - // Only update the server-side blocklist if it's active. - if (mv_source_ == TileSource::SUGGESTIONS_SERVICE) - suggestions_service_->ClearBlocklist(); } void MostVisitedSites::OnBlockedSitesChanged() { @@ -484,10 +456,9 @@ void MostVisitedSites::OnMostVisitedURLsAvailable( const history::MostVisitedURLList& visited_list) { - // Ignore the event if tiles are provided by the Suggestions Service or custom - // links, which take precedence. - if (IsCustomLinksInitialized() || - mv_source_ == TileSource::SUGGESTIONS_SERVICE) { + // Ignore the event if tiles are provided by custom links, which take + // precedence. + if (IsCustomLinksInitialized()) { return; } @@ -518,76 +489,14 @@ InitiateNotificationForNewTiles(std::move(tiles)); } -void MostVisitedSites::OnSuggestionsProfileChanged( - const SuggestionsProfile& suggestions_profile) { - // Ignore the event if tiles are provided by custom links, which take - // precedence. - if (IsCustomLinksInitialized() || - (suggestions_profile.suggestions_size() == 0 && - mv_source_ != TileSource::SUGGESTIONS_SERVICE)) { - return; - } - - BuildCurrentTilesGivenSuggestionsProfile(suggestions_profile); -} - void MostVisitedSites::BuildCurrentTiles() { if (IsCustomLinksInitialized()) { BuildCustomLinks(custom_links_->GetLinks()); return; } - BuildCurrentTilesGivenSuggestionsProfile( - suggestions_service_->GetSuggestionsDataFromCache().value_or( - SuggestionsProfile())); -} - -void MostVisitedSites::BuildCurrentTilesGivenSuggestionsProfile( - const suggestions::SuggestionsProfile& suggestions_profile) { - size_t num_tiles = suggestions_profile.suggestions_size(); - // With no server suggestions, fall back to local TopSites. - if (num_tiles == 0 || - !base::FeatureList::IsEnabled(kDisplaySuggestionsServiceTiles)) { - mv_source_ = TileSource::TOP_SITES; - InitiateTopSitesQuery(); - return; - } - if (GetMaxNumSites() < num_tiles) - num_tiles = GetMaxNumSites(); - - const base::Time profile_timestamp = - base::Time::UnixEpoch() + - base::TimeDelta::FromMicroseconds(suggestions_profile.timestamp()); - - NTPTilesVector tiles; - for (size_t i = 0; i < num_tiles; ++i) { - const ChromeSuggestion& suggestion_pb = suggestions_profile.suggestions(i); - GURL url(suggestion_pb.url()); - if (supervisor_ && supervisor_->IsBlocked(url)) - continue; - - NTPTile tile; - tile.title = - custom_links_ - ? GenerateShortTitle(base::UTF8ToUTF16(suggestion_pb.title())) - : base::UTF8ToUTF16(suggestion_pb.title()); - tile.url = url; - tile.source = TileSource::SUGGESTIONS_SERVICE; - // The title is an aggregation of multiple history entries of one site. - tile.title_source = TileTitleSource::INFERRED; - tile.allowlist_icon_path = GetAllowlistLargeIconPath(url); - tile.favicon_url = GURL(suggestion_pb.favicon_url()); - tile.data_generation_time = profile_timestamp; - - icon_cacher_->StartFetchMostLikely( - url, base::BindRepeating(&MostVisitedSites::OnIconMadeAvailable, - base::Unretained(this), url)); - - tiles.push_back(std::move(tile)); - } - - mv_source_ = TileSource::SUGGESTIONS_SERVICE; - InitiateNotificationForNewTiles(std::move(tiles)); + mv_source_ = TileSource::TOP_SITES; + InitiateTopSitesQuery(); } NTPTilesVector MostVisitedSites::CreateAllowlistEntryPointTiles(
diff --git a/components/ntp_tiles/most_visited_sites.h b/components/ntp_tiles/most_visited_sites.h index 301dec5..b86c71a30 100644 --- a/components/ntp_tiles/most_visited_sites.h +++ b/components/ntp_tiles/most_visited_sites.h
@@ -31,8 +31,6 @@ #include "components/ntp_tiles/popular_sites.h" #include "components/ntp_tiles/section_type.h" #include "components/ntp_tiles/tile_source.h" -#include "components/suggestions/proto/suggestions.pb.h" -#include "components/suggestions/suggestions_service.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/gurl.h" @@ -122,7 +120,6 @@ // optional and if null, the associated features will be disabled. MostVisitedSites(PrefService* prefs, scoped_refptr<history::TopSites> top_sites, - suggestions::SuggestionsService* suggestions, std::unique_ptr<PopularSites> popular_sites, std::unique_ptr<CustomLinksManager> custom_links, std::unique_ptr<IconCacher> icon_cacher, @@ -137,9 +134,6 @@ // Returns the corresponding object passed at construction. history::TopSites* top_sites() { return top_sites_.get(); } - suggestions::SuggestionsService* suggestions() { - return suggestions_service_; - } PopularSites* popular_sites() { return popular_sites_.get(); } MostVisitedSitesSupervisor* supervisor() { return supervisor_.get(); } @@ -266,8 +260,7 @@ // including the "Add shortcut" button. size_t GetMaxNumSites() const; - // Initialize the query to Top Sites. Called if the SuggestionsService - // returned no data. + // Initialize the query to Top Sites. void InitiateTopSitesQuery(); // If there's a allowlist entry point for the URL, return the large icon path. @@ -277,18 +270,10 @@ void OnMostVisitedURLsAvailable( const history::MostVisitedURLList& visited_list); - // Callback for when an update is reported by the SuggestionsService. - void OnSuggestionsProfileChanged( - const suggestions::SuggestionsProfile& suggestions_profile); - // Builds the current tileset based on available caches and notifies the // observer. void BuildCurrentTiles(); - // Same as above the SuggestionsProfile is provided, no need to read cache. - void BuildCurrentTilesGivenSuggestionsProfile( - const suggestions::SuggestionsProfile& suggestions_profile); - // Creates allowlist entry point suggestions whose hosts weren't used yet. NTPTilesVector CreateAllowlistEntryPointTiles( const std::set<std::string>& used_hosts, @@ -360,7 +345,6 @@ PrefService* prefs_; scoped_refptr<history::TopSites> top_sites_; - suggestions::SuggestionsService* suggestions_service_; std::unique_ptr<PopularSites> const popular_sites_; std::unique_ptr<CustomLinksManager> const custom_links_; std::unique_ptr<IconCacher> const icon_cacher_; @@ -381,14 +365,12 @@ bool is_custom_links_enabled_ = true; bool is_shortcuts_visible_ = true; - base::CallbackListSubscription suggestions_subscription_; - base::ScopedObservation<history::TopSites, history::TopSitesObserver> top_sites_observation_{this}; base::CallbackListSubscription custom_links_subscription_; - // The main source of personal tiles - either TOP_SITES or SUGGESTIONS_SEVICE. + // The main source of personal tiles - either TOP_SITES or CUSTOM_LINKS. TileSource mv_source_; // Current set of tiles. Optional so that the observer can be notified
diff --git a/components/ntp_tiles/most_visited_sites_unittest.cc b/components/ntp_tiles/most_visited_sites_unittest.cc index e7352df..ee23bae 100644 --- a/components/ntp_tiles/most_visited_sites_unittest.cc +++ b/components/ntp_tiles/most_visited_sites_unittest.cc
@@ -56,9 +56,6 @@ using history::MostVisitedURL; using history::MostVisitedURLList; using history::TopSites; -using suggestions::ChromeSuggestion; -using suggestions::SuggestionsProfile; -using suggestions::SuggestionsService; using testing::_; using testing::AllOf; using testing::AnyNumber; @@ -144,23 +141,6 @@ return tile; } -ChromeSuggestion MakeSuggestion(const std::string& title, - const std::string& url) { - ChromeSuggestion suggestion; - suggestion.set_title(title); - suggestion.set_url(url); - return suggestion; -} - -SuggestionsProfile MakeProfile( - const std::vector<ChromeSuggestion>& suggestions) { - SuggestionsProfile profile; - for (const ChromeSuggestion& suggestion : suggestions) { - *profile.add_suggestions() = suggestion; - } - return profile; -} - MostVisitedURL MakeMostVisitedURL(const std::u16string& title, const std::string& url) { MostVisitedURL result; @@ -196,19 +176,6 @@ ~MockTopSites() override = default; }; -class MockSuggestionsService : public SuggestionsService { - public: - MOCK_METHOD0(FetchSuggestionsData, bool()); - MOCK_CONST_METHOD0(GetSuggestionsDataFromCache, - absl::optional<SuggestionsProfile>()); - MOCK_METHOD1( - AddCallback, - base::CallbackListSubscription(const ResponseCallback& callback)); - MOCK_METHOD1(BlocklistURL, bool(const GURL& candidate_url)); - MOCK_METHOD1(UndoBlocklistURL, bool(const GURL& url)); - MOCK_METHOD0(ClearBlocklist, void()); -}; - class MockMostVisitedSitesObserver : public MostVisitedSites::Observer { public: MOCK_METHOD1(OnURLsAvailable, @@ -393,12 +360,8 @@ } // namespace -// Param is a tuple with two components: -// * The first specifies whether Popular Sites is enabled via variations. -// * The second specifies whether Suggestions Service tiles are enabled via -// variations. -class MostVisitedSitesTest - : public ::testing::TestWithParam<std::tuple<bool, bool>> { +// Param specifies whether Popular Sites is enabled via variations. +class MostVisitedSitesTest : public ::testing::TestWithParam<bool> { protected: using TopSitesCallbackList = base::OnceCallbackList<TopSites::GetMostVisitedURLsCallback::RunType>; @@ -415,11 +378,6 @@ } else { disabled_features.push_back(kUsePopularSitesSuggestions); } - if (IsDisplaySuggestionsServiceTilesEnabled()) { - enabled_features.push_back(kDisplaySuggestionsServiceTiles); - } else { - disabled_features.push_back(kDisplaySuggestionsServiceTiles); - } feature_list_.InitWithFeatures(enabled_features, disabled_features); if (IsPopularSitesFeatureEnabled()) @@ -472,22 +430,17 @@ EXPECT_CALL(*icon_cacher, StartFetchMostLikely(_, _)).Times(AtLeast(0)); most_visited_sites_ = std::make_unique<MostVisitedSites>( - &pref_service_, mock_top_sites_, &mock_suggestions_service_, - popular_sites_factory_.New(), std::move(mock_custom_links), - std::move(icon_cacher), + &pref_service_, mock_top_sites_, popular_sites_factory_.New(), + std::move(mock_custom_links), std::move(icon_cacher), /*supervisor=*/nullptr); } - bool IsPopularSitesFeatureEnabled() const { return std::get<0>(GetParam()); } - bool IsDisplaySuggestionsServiceTilesEnabled() const { - return std::get<1>(GetParam()); - } + bool IsPopularSitesFeatureEnabled() const { return GetParam(); } bool VerifyAndClearExpectations() { base::RunLoop().RunUntilIdle(); const bool success = Mock::VerifyAndClearExpectations(mock_top_sites_.get()) && - Mock::VerifyAndClearExpectations(&mock_suggestions_service_) && Mock::VerifyAndClearExpectations(&mock_observer_); // For convenience, restore the expectations for IsBlocked(). if (IsPopularSitesFeatureEnabled()) { @@ -510,24 +463,9 @@ return raw_client_ptr; } - void DisableRemoteSuggestions() { - EXPECT_CALL(mock_suggestions_service_, AddCallback(_)) - .Times(AnyNumber()) - .WillRepeatedly(Invoke(&suggestions_service_callbacks_, - &SuggestionsService::ResponseCallbackList::Add)); - EXPECT_CALL(mock_suggestions_service_, GetSuggestionsDataFromCache()) - .Times(AnyNumber()) - .WillRepeatedly(Return(SuggestionsProfile())); // Empty cache. - EXPECT_CALL(mock_suggestions_service_, FetchSuggestionsData()) - .Times(AnyNumber()) - .WillRepeatedly(Return(true)); - } - void EnableCustomLinks() { is_custom_links_enabled_ = true; } bool is_custom_links_enabled_ = false; - base::RepeatingCallbackList<SuggestionsService::ResponseCallback::RunType> - suggestions_service_callbacks_; TopSitesCallbackList top_sites_callbacks_; base::test::SingleThreadTaskEnvironment task_environment_; @@ -536,7 +474,6 @@ PopularSitesFactoryForTest popular_sites_factory_{&pref_service_}; scoped_refptr<StrictMock<MockTopSites>> mock_top_sites_ = base::MakeRefCounted<StrictMock<MockTopSites>>(); - StrictMock<MockSuggestionsService> mock_suggestions_service_; StrictMock<MockMostVisitedSitesObserver> mock_observer_; StrictMock<MockMostVisitedSitesObserver> mock_other_observer_; std::unique_ptr<MostVisitedSites> most_visited_sites_; @@ -551,16 +488,14 @@ base::RunLoop().RunUntilIdle(); } -TEST_P(MostVisitedSitesTest, ShouldRefreshBothBackends) { +TEST_P(MostVisitedSitesTest, ShouldRefreshBackends) { EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); - EXPECT_CALL(mock_suggestions_service_, FetchSuggestionsData()); most_visited_sites_->Refresh(); } TEST_P(MostVisitedSitesTest, ShouldIncludeTileForHomepage) { FakeHomepageClient* homepage_client = RegisterNewHomepageClient(); homepage_client->SetHomepageTileEnabled(true); - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{})); EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); @@ -575,7 +510,6 @@ } TEST_P(MostVisitedSitesTest, ShouldNotIncludeHomepageWithoutClient) { - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{})); EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); @@ -596,7 +530,6 @@ FakeHomepageClient* homepage_client = RegisterNewHomepageClient(); homepage_client->SetHomepageTileEnabled(true); homepage_client->SetHomepageTitle(kHomepageTitle); - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{})); EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); @@ -624,7 +557,6 @@ TEST_P(MostVisitedSitesTest, ShouldUpdateHomepageTileWhenRefreshHomepageTile) { FakeHomepageClient* homepage_client = RegisterNewHomepageClient(); homepage_client->SetHomepageTileEnabled(true); - DisableRemoteSuggestions(); // Ensure that home tile is available as usual. EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) @@ -642,7 +574,6 @@ // Disable home page and rebuild _without_ Resync. The tile should be gone. homepage_client->SetHomepageTileEnabled(false); - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{})); EXPECT_CALL(*mock_top_sites_, SyncWithHistory()).Times(0); @@ -655,7 +586,6 @@ TEST_P(MostVisitedSitesTest, ShouldNotIncludeHomepageIfNoTileRequested) { FakeHomepageClient* homepage_client = RegisterNewHomepageClient(); homepage_client->SetHomepageTileEnabled(true); - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{})); EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); @@ -673,7 +603,6 @@ TEST_P(MostVisitedSitesTest, ShouldReturnHomepageIfOneTileRequested) { FakeHomepageClient* homepage_client = RegisterNewHomepageClient(); homepage_client->SetHomepageTileEnabled(true); - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>(( MostVisitedURLList{MakeMostVisitedURL(u"Site 1", "http://site1/")}))); @@ -694,7 +623,6 @@ TEST_P(MostVisitedSitesTest, ShouldHaveHomepageFirstInListWhenFull) { FakeHomepageClient* homepage_client = RegisterNewHomepageClient(); homepage_client->SetHomepageTileEnabled(true); - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>((MostVisitedURLList{ MakeMostVisitedURL(u"Site 1", "http://site1/"), @@ -723,7 +651,6 @@ TEST_P(MostVisitedSitesTest, ShouldHaveHomepageFirstInListWhenNotFull) { FakeHomepageClient* homepage_client = RegisterNewHomepageClient(); homepage_client->SetHomepageTileEnabled(true); - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>((MostVisitedURLList{ MakeMostVisitedURL(u"Site 1", "http://site1/"), @@ -752,7 +679,6 @@ TEST_P(MostVisitedSitesTest, ShouldDeduplicateHomepageWithTopSites) { FakeHomepageClient* homepage_client = RegisterNewHomepageClient(); homepage_client->SetHomepageTileEnabled(true); - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>( (MostVisitedURLList{MakeMostVisitedURL(u"Site 1", "http://site1/"), @@ -776,7 +702,6 @@ TEST_P(MostVisitedSitesTest, ShouldNotIncludeHomepageIfThereIsNone) { FakeHomepageClient* homepage_client = RegisterNewHomepageClient(); homepage_client->SetHomepageTileEnabled(false); - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{})); EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); @@ -798,7 +723,6 @@ FakeHomepageClient* homepage_client = RegisterNewHomepageClient(); homepage_client->SetHomepageTileEnabled(true); homepage_client->SetHomepageUrl(GURL(kEmptyHomepageUrl)); - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{})); EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); @@ -816,7 +740,6 @@ TEST_P(MostVisitedSitesTest, ShouldNotIncludeHomepageIfBlocked) { FakeHomepageClient* homepage_client = RegisterNewHomepageClient(); homepage_client->SetHomepageTileEnabled(true); - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>( (MostVisitedURLList{MakeMostVisitedURL(u"", kHomepageUrl)}))); @@ -842,8 +765,6 @@ TEST_P(MostVisitedSitesTest, ShouldPinHomepageAgainIfBlockedUndone) { FakeHomepageClient* homepage_client = RegisterNewHomepageClient(); homepage_client->SetHomepageTileEnabled(true); - - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillOnce(base::test::RunOnceCallback<0>( (MostVisitedURLList{MakeMostVisitedURL(u"", kHomepageUrl)}))); @@ -861,8 +782,6 @@ /*max_num_sites=*/3); base::RunLoop().RunUntilIdle(); VerifyAndClearExpectations(); - - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillOnce(base::test::RunOnceCallback<0>(MostVisitedURLList{})); EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(GURL(kHomepageUrl)))) @@ -880,8 +799,6 @@ TEST_P(MostVisitedSitesTest, ShouldNotIncludeTileForExploreSitesIfNoClient) { // Does not register an explore sites client. - - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{ MakeMostVisitedURL(u"ESPN", "http://espn.com/"), @@ -903,7 +820,6 @@ // and popular sites. TEST_P(MostVisitedSitesTest, ShouldIncludeTileForExploreSites) { RegisterNewExploreSitesClient(); - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{ MakeMostVisitedURL(u"ESPN", "http://espn.com/"), @@ -922,7 +838,6 @@ TEST_P(MostVisitedSitesTest, RemovesPersonalSiteIfExploreSitesTilePresent) { RegisterNewExploreSitesClient(); - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{ MakeMostVisitedURL(u"ESPN", "http://espn.com/"), @@ -945,15 +860,10 @@ TEST_P(MostVisitedSitesTest, ShouldInformSuggestionSourcesWhenBlocked) { EXPECT_CALL(*mock_top_sites_, AddBlockedUrl(Eq(GURL(kHomepageUrl)))).Times(1); - EXPECT_CALL(mock_suggestions_service_, BlocklistURL(Eq(GURL(kHomepageUrl)))) - .Times(AnyNumber()); most_visited_sites_->AddOrRemoveBlockedUrl(GURL(kHomepageUrl), /*add_url=*/true); EXPECT_CALL(*mock_top_sites_, RemoveBlockedUrl(Eq(GURL(kHomepageUrl)))) .Times(1); - EXPECT_CALL(mock_suggestions_service_, - UndoBlocklistURL(Eq(GURL(kHomepageUrl)))) - .Times(AnyNumber()); most_visited_sites_->AddOrRemoveBlockedUrl(GURL(kHomepageUrl), /*add_url=*/false); } @@ -962,7 +872,6 @@ ShouldDeduplicatePopularSitesWithMostVisitedIffHostAndTitleMatches) { pref_service_.SetString(prefs::kPopularSitesOverrideCountry, "US"); RecreateMostVisitedSites(); // Refills cache with ESPN and Google News. - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{ MakeMostVisitedURL(u"ESPN", "http://espn.com/"), @@ -1004,11 +913,6 @@ MostVisitedURLList{MakeMostVisitedURL(u"Site 1", "http://site1/")})); InSequence seq; - EXPECT_CALL(mock_suggestions_service_, AddCallback(_)) - .WillOnce(Invoke(&suggestions_service_callbacks_, - &SuggestionsService::ResponseCallbackList::Add)); - EXPECT_CALL(mock_suggestions_service_, GetSuggestionsDataFromCache()) - .WillOnce(Return(SuggestionsProfile())); // Empty cache. if (IsPopularSitesFeatureEnabled()) { EXPECT_CALL( mock_observer_, @@ -1028,13 +932,10 @@ TileSource::TOP_SITES)))))); } EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); - EXPECT_CALL(mock_suggestions_service_, FetchSuggestionsData()) - .WillOnce(Return(true)); most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_, /*max_num_sites=*/3); VerifyAndClearExpectations(); - EXPECT_FALSE(suggestions_service_callbacks_.empty()); CHECK(top_sites_callbacks_.empty()); // Update by TopSites is propagated. @@ -1052,7 +953,6 @@ // Tests that multiple observers can be added to the MostVisitedSites. TEST_P(MostVisitedSitesTest, MultipleObservers) { - DisableRemoteSuggestions(); EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{ MakeMostVisitedURL(u"ESPN", "http://espn.com/"), @@ -1103,8 +1003,7 @@ INSTANTIATE_TEST_SUITE_P(MostVisitedSitesTest, MostVisitedSitesTest, - ::testing::Combine(::testing::Bool(), - ::testing::Bool())); + ::testing::Bool()); TEST(MostVisitedSitesTest, ShouldDeduplicateDomainWithNoWwwDomain) { EXPECT_TRUE(MostVisitedSites::IsHostOrMobilePageKnown({"www.mobile.de"}, @@ -1161,23 +1060,6 @@ .WillOnce(SaveArg<0>(sections)); } - void ExpectBuildWithSuggestions( - const std::vector<ChromeSuggestion>& suggestions, - std::map<SectionType, NTPTilesVector>* sections) { - EXPECT_CALL(mock_suggestions_service_, AddCallback(_)) - .WillOnce(Invoke(&suggestions_service_callbacks_, - &SuggestionsService::ResponseCallbackList::Add)); - EXPECT_CALL(mock_suggestions_service_, GetSuggestionsDataFromCache()) - .WillOnce(Return(MakeProfile(suggestions))); - EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); - EXPECT_CALL(mock_suggestions_service_, FetchSuggestionsData()) - .WillOnce(Return(true)); - EXPECT_CALL(*mock_custom_links_, IsInitialized()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(mock_observer_, OnURLsAvailable(_)) - .WillOnce(SaveArg<0>(sections)); - } - void ExpectBuildWithCustomLinks( const std::vector<CustomLinksManager::Link>& expected_links, std::map<SectionType, NTPTilesVector>* sections) { @@ -1194,7 +1076,6 @@ const char kTestUrl[] = "http://site1/"; const char16_t kTestTitle[] = u"Site 1"; std::map<SectionType, NTPTilesVector> sections; - DisableRemoteSuggestions(); // Build tiles when custom links is not initialized. Tiles should be Top // Sites. @@ -1241,7 +1122,6 @@ std::vector<CustomLinksManager::Link> expected_links( {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle}}); std::map<SectionType, NTPTilesVector> sections; - DisableRemoteSuggestions(); // Build tiles when custom links is not initialized. Tiles should be Top // Sites. @@ -1290,7 +1170,6 @@ std::vector<CustomLinksManager::Link> expected_links( {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle}}); std::map<SectionType, NTPTilesVector> sections; - DisableRemoteSuggestions(); // Build tiles when custom links is not initialized. Tiles should be Top // Sites. @@ -1316,10 +1195,6 @@ ElementsAre(MatchesTile(kTestTitle, kTestUrl, TileSource::CUSTOM_LINKS))); // Initiate notification for new Top Sites. This should be ignored. - EXPECT_CALL(*mock_custom_links_, IsInitialized()).WillOnce(Return(true)); - // Notify with an empty SuggestionsProfile first to trigger a query for - // TopSites. - suggestions_service_callbacks_.Notify(SuggestionsProfile()); VerifyAndClearExpectations(); EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(0); top_sites_callbacks_.Notify( @@ -1328,76 +1203,37 @@ } TEST_P(MostVisitedSitesWithCustomLinksTest, - ShouldFavorCustomLinksOverSuggestions) { - const char kTestUrl[] = "http://site1/"; - const char kTestTitle[] = "Site 1"; - const char16_t kTestTitle16[] = u"Site 1"; - std::vector<CustomLinksManager::Link> expected_links( - {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle16}}); - std::map<SectionType, NTPTilesVector> sections; - - // Build tiles when custom links is not initialized. Tiles should be from - // suggestions. - EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_)); - ExpectBuildWithSuggestions({MakeSuggestion(kTestTitle, kTestUrl)}, §ions); - most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_, - /*max_num_sites=*/1); - base::RunLoop().RunUntilIdle(); - NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED); - ASSERT_THAT(tiles.size(), Ge(1ul)); - ASSERT_THAT(tiles[0], MatchesTile(kTestTitle16, kTestUrl, - TileSource::SUGGESTIONS_SERVICE)); - - // Initialize custom links and rebuild tiles. Tiles should be custom links. - EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(true)); - ExpectBuildWithCustomLinks(expected_links, §ions); - most_visited_sites_->InitializeCustomLinks(); - most_visited_sites_->RefreshTiles(); - base::RunLoop().RunUntilIdle(); - ASSERT_THAT(sections.at(SectionType::PERSONALIZED), - ElementsAre(MatchesTile(kTestTitle16, kTestUrl, - TileSource::CUSTOM_LINKS))); - - // Initiate notification for new suggestions. This should be ignored. - EXPECT_CALL(*mock_custom_links_, IsInitialized()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(0); - suggestions_service_callbacks_.Notify( - MakeProfile({MakeSuggestion("Site 2", "http://site2/")})); - base::RunLoop().RunUntilIdle(); -} - -TEST_P(MostVisitedSitesWithCustomLinksTest, DisableCustomLinksWhenNotInitialized) { const char kTestUrl[] = "http://site1/"; - const char kTestTitle[] = "Site 1"; const char16_t kTestTitle16[] = u"Site 1"; std::vector<CustomLinksManager::Link> expected_links( {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle16}}); std::map<SectionType, NTPTilesVector> sections; // Build tiles when custom links is not initialized. Tiles should be from - // suggestions. + // Top Sites. EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_)); - ExpectBuildWithSuggestions({MakeSuggestion(kTestTitle, kTestUrl)}, §ions); + ExpectBuildWithTopSites( + MostVisitedURLList{MakeMostVisitedURL(kTestTitle16, kTestUrl)}, + §ions); most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_, /*max_num_sites=*/1); base::RunLoop().RunUntilIdle(); NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED); ASSERT_THAT(tiles.size(), Ge(1ul)); - ASSERT_THAT(tiles[0], MatchesTile(kTestTitle16, kTestUrl, - TileSource::SUGGESTIONS_SERVICE)); + ASSERT_THAT(tiles[0], + MatchesTile(kTestTitle16, kTestUrl, TileSource::TOP_SITES)); // Disable custom links. Tiles should rebuild. - EXPECT_CALL(mock_suggestions_service_, GetSuggestionsDataFromCache()) - .WillOnce(Return(MakeProfile({MakeSuggestion(kTestTitle, kTestUrl)}))); + EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) + .WillRepeatedly(base::test::RunOnceCallback<0>( + MostVisitedURLList{MakeMostVisitedURL(kTestTitle16, kTestUrl)})); EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(1); most_visited_sites_->EnableCustomLinks(false); base::RunLoop().RunUntilIdle(); // Try to disable custom links again. This should not rebuild the tiles. - EXPECT_CALL(mock_suggestions_service_, GetSuggestionsDataFromCache()) - .Times(0); + EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)).Times(0); EXPECT_CALL(*mock_custom_links_, GetLinks()).Times(0); most_visited_sites_->EnableCustomLinks(false); base::RunLoop().RunUntilIdle(); @@ -1405,7 +1241,6 @@ TEST_P(MostVisitedSitesWithCustomLinksTest, DisableCustomLinksWhenInitialized) { const char kTestUrl[] = "http://site1/"; - const char kTestTitle[] = "Site 1"; const char16_t kTestTitle16[] = u"Site 1"; std::vector<CustomLinksManager::Link> expected_links( {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle16}}); @@ -1414,12 +1249,7 @@ // Build tiles when custom links is initialized and not disabled. Tiles should // be custom links. EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_)); - EXPECT_CALL(mock_suggestions_service_, AddCallback(_)) - .WillOnce(Invoke(&suggestions_service_callbacks_, - &SuggestionsService::ResponseCallbackList::Add)); EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); - EXPECT_CALL(mock_suggestions_service_, FetchSuggestionsData()) - .WillOnce(Return(false)); ExpectBuildWithCustomLinks(expected_links, §ions); most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_, /*max_num_sites=*/1); @@ -1428,18 +1258,19 @@ ElementsAre(MatchesTile(kTestTitle16, kTestUrl, TileSource::CUSTOM_LINKS))); - // Disable custom links. Tiles should rebuild and return suggestions. - EXPECT_CALL(mock_suggestions_service_, GetSuggestionsDataFromCache()) - .WillOnce(Return(MakeProfile({MakeSuggestion(kTestTitle, kTestUrl)}))); + // Disable custom links. Tiles should rebuild and return Top Sites. + EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) + .WillRepeatedly(base::test::RunOnceCallback<0>( + MostVisitedURLList{MakeMostVisitedURL(kTestTitle16, kTestUrl)})); EXPECT_CALL(*mock_custom_links_, IsInitialized()) .WillRepeatedly(Return(false)); EXPECT_CALL(mock_observer_, OnURLsAvailable(_)) .WillOnce(SaveArg<0>(§ions)); most_visited_sites_->EnableCustomLinks(false); base::RunLoop().RunUntilIdle(); - EXPECT_THAT(sections.at(SectionType::PERSONALIZED), - ElementsAre(MatchesTile(kTestTitle16, kTestUrl, - TileSource::SUGGESTIONS_SERVICE))); + EXPECT_THAT( + sections.at(SectionType::PERSONALIZED), + ElementsAre(MatchesTile(kTestTitle16, kTestUrl, TileSource::TOP_SITES))); // Re-enable custom links. Tiles should rebuild and return custom links. ExpectBuildWithCustomLinks(expected_links, §ions); @@ -1463,7 +1294,6 @@ u"Books, " u"DVDs & more"; std::map<SectionType, NTPTilesVector> sections; - DisableRemoteSuggestions(); // Build tiles from Top Sites. The tiles should have short titles. EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_)); @@ -1495,54 +1325,12 @@ } TEST_P(MostVisitedSitesWithCustomLinksTest, - ShouldGenerateShortTitleForSuggestions) { - std::string kTestUrl1 = "https://www.imdb.com/"; - std::string kTestTitle1 = "IMDb - Movies, TV and Celebrities - IMDb"; - std::string kTestUrl2 = "https://drive.google.com/"; - std::string kTestTitle2 = - "Google Drive - Cloud Storage & File Backup for Photos, Docs & More"; - std::string kTestUrl3 = "https://amazon.com/"; - std::string kTestTitle3 = - "Amazon.com: Online Shopping for Electronics, Apparel, Computers, Books, " - "DVDs & more"; - std::map<SectionType, NTPTilesVector> sections; - - // Build tiles from Suggestions. The tiles should have short titles. - EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_)); - ExpectBuildWithSuggestions({MakeSuggestion(kTestTitle1, kTestUrl1), - MakeSuggestion(kTestTitle2, kTestUrl2), - MakeSuggestion(kTestTitle3, kTestUrl3)}, - §ions); - most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_, - /*max_num_sites=*/3); - base::RunLoop().RunUntilIdle(); - - NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED); - ASSERT_THAT(tiles.size(), Ge(3ul)); - ASSERT_THAT( - tiles[0], - MatchesTile(/* The short title generated by the heuristic */ u"IMDb", - kTestUrl1, TileSource::SUGGESTIONS_SERVICE)); - ASSERT_THAT( - tiles[1], - MatchesTile( - /* The short title generated by the heuristic */ u"Google Drive", - kTestUrl2, TileSource::SUGGESTIONS_SERVICE)); - ASSERT_THAT( - tiles[2], - MatchesTile( - /* The short title generated by the heuristic */ u"Amazon.com", - kTestUrl3, TileSource::SUGGESTIONS_SERVICE)); -} - -TEST_P(MostVisitedSitesWithCustomLinksTest, ShouldNotCrashIfReceiveAnEmptyTitle) { std::string kTestUrl1 = "https://site1/"; std::u16string kTestTitle1 = u""; // Empty title std::string kTestUrl2 = "https://site2/"; std::u16string kTestTitle2 = u" "; // Title only contains spaces std::map<SectionType, NTPTilesVector> sections; - DisableRemoteSuggestions(); // Build tiles from Top Sites. The tiles should have short titles. EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_)); @@ -1568,7 +1356,6 @@ std::vector<CustomLinksManager::Link> expected_links( {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle}}); std::map<SectionType, NTPTilesVector> sections; - DisableRemoteSuggestions(); // Build initial tiles with Top Sites. EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_)); @@ -1622,7 +1409,6 @@ std::vector<CustomLinksManager::Link> expected_links( {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle}}); std::map<SectionType, NTPTilesVector> sections; - DisableRemoteSuggestions(); // Build initial tiles with Top Sites. EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_)); @@ -1679,7 +1465,6 @@ std::vector<CustomLinksManager::Link> expected_links( {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle}}); std::map<SectionType, NTPTilesVector> sections; - DisableRemoteSuggestions(); // Build initial tiles with Top Sites. EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_)); @@ -1747,7 +1532,6 @@ std::vector<CustomLinksManager::Link> expected_links( {CustomLinksManager::Link{GURL(kTestUrl2), kTestTitle2}}); std::map<SectionType, NTPTilesVector> sections; - DisableRemoteSuggestions(); // Build initial tiles with Top Sites. base::RepeatingClosure custom_links_callback; @@ -1798,473 +1582,12 @@ MatchesTile(kTestTitle1, kTestUrl1, TileSource::TOP_SITES)); } -// These tests expect Most Likely to be enabled, and exclude Android and iOS, -// so this will continue to be the case. +// These exclude Android and iOS. INSTANTIATE_TEST_SUITE_P(MostVisitedSitesWithCustomLinksTest, MostVisitedSitesWithCustomLinksTest, - ::testing::Combine(::testing::Bool(), - ::testing::Values(true))); + ::testing::Bool()); #endif -class MostVisitedSitesWithCacheHitTest : public MostVisitedSitesTest { - public: - // Constructor sets the common expectations for the case where suggestions - // service has cached results when the observer is registered. - MostVisitedSitesWithCacheHitTest() { - InSequence seq; - EXPECT_CALL(mock_suggestions_service_, AddCallback(_)) - .WillOnce(Invoke(&suggestions_service_callbacks_, - &SuggestionsService::ResponseCallbackList::Add)); - EXPECT_CALL(mock_suggestions_service_, GetSuggestionsDataFromCache()) - .WillOnce(Return(MakeProfile({ - MakeSuggestion("Site 1", "http://site1/"), - MakeSuggestion("Site 2", "http://site2/"), - MakeSuggestion("Site 3", "http://site3/"), - }))); - - if (IsPopularSitesFeatureEnabled()) { - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre(MatchesTile(u"Site 1", "http://site1/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"Site 2", "http://site2/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"Site 3", "http://site3/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"PopularSite1", "http://popularsite1/", - TileSource::POPULAR)))))); - } else { - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre(MatchesTile(u"Site 1", "http://site1/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"Site 2", "http://site2/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"Site 3", "http://site3/", - TileSource::SUGGESTIONS_SERVICE)))))); - } - EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); - EXPECT_CALL(mock_suggestions_service_, FetchSuggestionsData()) - .WillOnce(Return(true)); - - most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_, - /*max_num_sites=*/4); - VerifyAndClearExpectations(); - - EXPECT_FALSE(suggestions_service_callbacks_.empty()); - EXPECT_TRUE(top_sites_callbacks_.empty()); - } -}; - -TEST_P(MostVisitedSitesWithCacheHitTest, ShouldFavorSuggestionsServiceCache) { - // Constructor sets basic expectations for a suggestions service cache hit. -} - -TEST_P(MostVisitedSitesWithCacheHitTest, - ShouldPropagateUpdateBySuggestionsService) { - EXPECT_CALL(mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre(MatchesTile(u"Site 4", "http://site4/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"Site 5", "http://site5/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"Site 6", "http://site6/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"Site 7", "http://site7/", - TileSource::SUGGESTIONS_SERVICE)))))); - suggestions_service_callbacks_.Notify( - MakeProfile({MakeSuggestion("Site 4", "http://site4/"), - MakeSuggestion("Site 5", "http://site5/"), - MakeSuggestion("Site 6", "http://site6/"), - MakeSuggestion("Site 7", "http://site7/")})); - base::RunLoop().RunUntilIdle(); -} - -TEST_P(MostVisitedSitesWithCacheHitTest, ShouldTruncateList) { - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains(Pair(SectionType::PERSONALIZED, SizeIs(4))))); - suggestions_service_callbacks_.Notify( - MakeProfile({MakeSuggestion("Site 4", "http://site4/"), - MakeSuggestion("Site 5", "http://site5/"), - MakeSuggestion("Site 6", "http://site6/"), - MakeSuggestion("Site 7", "http://site7/"), - MakeSuggestion("Site 8", "http://site8/")})); - base::RunLoop().RunUntilIdle(); -} - -TEST_P(MostVisitedSitesWithCacheHitTest, - ShouldCompleteWithPopularSitesIffEnabled) { - if (IsPopularSitesFeatureEnabled()) { - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre(MatchesTile(u"Site 4", "http://site4/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"PopularSite1", "http://popularsite1/", - TileSource::POPULAR), - MatchesTile(u"PopularSite2", "http://popularsite2/", - TileSource::POPULAR)))))); - } else { - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains( - Pair(SectionType::PERSONALIZED, - ElementsAre(MatchesTile(u"Site 4", "http://site4/", - TileSource::SUGGESTIONS_SERVICE)))))); - } - suggestions_service_callbacks_.Notify( - MakeProfile({MakeSuggestion("Site 4", "http://site4/")})); - base::RunLoop().RunUntilIdle(); -} - -TEST_P(MostVisitedSitesWithCacheHitTest, - ShouldSwitchToTopSitesIfEmptyUpdateBySuggestionsService) { - EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) - .WillOnce( - Invoke(&top_sites_callbacks_, &TopSitesCallbackList::AddUnsafe)); - suggestions_service_callbacks_.Notify(SuggestionsProfile()); - VerifyAndClearExpectations(); - - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre( - MatchesTile(u"Site 4", "http://site4/", TileSource::TOP_SITES), - MatchesTile(u"Site 5", "http://site5/", TileSource::TOP_SITES), - MatchesTile(u"Site 6", "http://site6/", TileSource::TOP_SITES), - MatchesTile(u"Site 7", "http://site7/", - TileSource::TOP_SITES)))))); - top_sites_callbacks_.Notify( - MostVisitedURLList({MakeMostVisitedURL(u"Site 4", "http://site4/"), - MakeMostVisitedURL(u"Site 5", "http://site5/"), - MakeMostVisitedURL(u"Site 6", "http://site6/"), - MakeMostVisitedURL(u"Site 7", "http://site7/")})); - base::RunLoop().RunUntilIdle(); -} - -TEST_P(MostVisitedSitesWithCacheHitTest, ShouldFetchFaviconsIfEnabled) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kNtpMostLikelyFaviconsFromServerFeature); - - EXPECT_CALL(mock_observer_, OnURLsAvailable(_)); - EXPECT_CALL(*icon_cacher_, StartFetchMostLikely(GURL("http://site4/"), _)); - - suggestions_service_callbacks_.Notify( - MakeProfile({MakeSuggestion("Site 4", "http://site4/")})); - base::RunLoop().RunUntilIdle(); -} - -// Tests only apply when the suggestions service is enabled. -INSTANTIATE_TEST_SUITE_P(MostVisitedSitesWithCacheHitTest, - MostVisitedSitesWithCacheHitTest, - ::testing::Combine(::testing::Bool(), - testing::Values(true))); - -class MostVisitedSitesWithEmptyCacheTest : public MostVisitedSitesTest { - public: - // Constructor sets the common expectations for the case where suggestions - // service doesn't have cached results when the observer is registered. - MostVisitedSitesWithEmptyCacheTest() { - InSequence seq; - EXPECT_CALL(mock_suggestions_service_, AddCallback(_)) - .WillOnce(Invoke(&suggestions_service_callbacks_, - &SuggestionsService::ResponseCallbackList::Add)); - EXPECT_CALL(mock_suggestions_service_, GetSuggestionsDataFromCache()) - .WillOnce(Return(SuggestionsProfile())); // Empty cache. - EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) - .WillOnce( - Invoke(&top_sites_callbacks_, &TopSitesCallbackList::AddUnsafe)); - EXPECT_CALL(*mock_top_sites_, SyncWithHistory()); - EXPECT_CALL(mock_suggestions_service_, FetchSuggestionsData()) - .WillOnce(Return(true)); - - most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_, - /*max_num_sites=*/3); - VerifyAndClearExpectations(); - - EXPECT_FALSE(suggestions_service_callbacks_.empty()); - EXPECT_FALSE(top_sites_callbacks_.empty()); - } -}; - -TEST_P(MostVisitedSitesWithEmptyCacheTest, - ShouldQueryTopSitesAndSuggestionsService) { - // Constructor sets basic expectations for a suggestions service cache miss. -} - -TEST_P(MostVisitedSitesWithEmptyCacheTest, - ShouldCompleteWithPopularSitesIffEnabled) { - if (IsPopularSitesFeatureEnabled()) { - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre(MatchesTile(u"Site 4", "http://site4/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"PopularSite1", "http://popularsite1/", - TileSource::POPULAR), - MatchesTile(u"PopularSite2", "http://popularsite2/", - TileSource::POPULAR)))))); - } else { - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains( - Pair(SectionType::PERSONALIZED, - ElementsAre(MatchesTile(u"Site 4", "http://site4/", - TileSource::SUGGESTIONS_SERVICE)))))); - } - suggestions_service_callbacks_.Notify( - MakeProfile({MakeSuggestion("Site 4", "http://site4/")})); - base::RunLoop().RunUntilIdle(); -} - -TEST_P(MostVisitedSitesWithEmptyCacheTest, - ShouldIgnoreTopSitesIfSuggestionsServiceFaster) { - // Reply from suggestions service triggers and update to our observer. - EXPECT_CALL(mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre(MatchesTile(u"Site 1", "http://site1/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"Site 2", "http://site2/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"Site 3", "http://site3/", - TileSource::SUGGESTIONS_SERVICE)))))); - suggestions_service_callbacks_.Notify( - MakeProfile({MakeSuggestion("Site 1", "http://site1/"), - MakeSuggestion("Site 2", "http://site2/"), - MakeSuggestion("Site 3", "http://site3/")})); - VerifyAndClearExpectations(); - - // Reply from top sites is ignored (i.e. not reported to observer). - top_sites_callbacks_.Notify( - MostVisitedURLList({MakeMostVisitedURL(u"Site 4", "http://site4/")})); - VerifyAndClearExpectations(); - - // Update by TopSites is also ignored. - mock_top_sites_->NotifyTopSitesChanged( - history::TopSitesObserver::ChangeReason::MOST_VISITED); - base::RunLoop().RunUntilIdle(); -} - -TEST_P(MostVisitedSitesWithEmptyCacheTest, - ShouldExposeTopSitesIfSuggestionsServiceFasterButEmpty) { - // Empty reply from suggestions service causes no update to our observer. - suggestions_service_callbacks_.Notify(SuggestionsProfile()); - VerifyAndClearExpectations(); - - // Reply from top sites is propagated to observer. - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre( - MatchesTile(u"Site 1", "http://site1/", TileSource::TOP_SITES), - MatchesTile(u"Site 2", "http://site2/", TileSource::TOP_SITES), - MatchesTile(u"Site 3", "http://site3/", - TileSource::TOP_SITES)))))); - top_sites_callbacks_.Notify( - MostVisitedURLList({MakeMostVisitedURL(u"Site 1", "http://site1/"), - MakeMostVisitedURL(u"Site 2", "http://site2/"), - MakeMostVisitedURL(u"Site 3", "http://site3/")})); - base::RunLoop().RunUntilIdle(); -} - -TEST_P(MostVisitedSitesWithEmptyCacheTest, - ShouldFavorSuggestionsServiceAlthoughSlower) { - // Reply from top sites is propagated to observer. - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre( - MatchesTile(u"Site 1", "http://site1/", TileSource::TOP_SITES), - MatchesTile(u"Site 2", "http://site2/", TileSource::TOP_SITES), - MatchesTile(u"Site 3", "http://site3/", - TileSource::TOP_SITES)))))); - top_sites_callbacks_.Notify( - MostVisitedURLList({MakeMostVisitedURL(u"Site 1", "http://site1/"), - MakeMostVisitedURL(u"Site 2", "http://site2/"), - MakeMostVisitedURL(u"Site 3", "http://site3/")})); - VerifyAndClearExpectations(); - - // Reply from suggestions service overrides top sites. - InSequence seq; - EXPECT_CALL(mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre(MatchesTile(u"Site 4", "http://site4/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"Site 5", "http://site5/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"Site 6", "http://site6/", - TileSource::SUGGESTIONS_SERVICE)))))); - suggestions_service_callbacks_.Notify( - MakeProfile({MakeSuggestion("Site 4", "http://site4/"), - MakeSuggestion("Site 5", "http://site5/"), - MakeSuggestion("Site 6", "http://site6/")})); - base::RunLoop().RunUntilIdle(); -} - -TEST_P(MostVisitedSitesWithEmptyCacheTest, - ShouldIgnoreSuggestionsServiceIfSlowerAndEmpty) { - // Reply from top sites is propagated to observer. - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre( - MatchesTile(u"Site 1", "http://site1/", TileSource::TOP_SITES), - MatchesTile(u"Site 2", "http://site2/", TileSource::TOP_SITES), - MatchesTile(u"Site 3", "http://site3/", - TileSource::TOP_SITES)))))); - top_sites_callbacks_.Notify( - MostVisitedURLList({MakeMostVisitedURL(u"Site 1", "http://site1/"), - MakeMostVisitedURL(u"Site 2", "http://site2/"), - MakeMostVisitedURL(u"Site 3", "http://site3/")})); - VerifyAndClearExpectations(); - - // Reply from suggestions service is empty and thus ignored. - suggestions_service_callbacks_.Notify(SuggestionsProfile()); - base::RunLoop().RunUntilIdle(); -} - -TEST_P(MostVisitedSitesWithEmptyCacheTest, ShouldPropagateUpdateByTopSites) { - // Reply from top sites is propagated to observer. - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre( - MatchesTile(u"Site 1", "http://site1/", TileSource::TOP_SITES), - MatchesTile(u"Site 2", "http://site2/", TileSource::TOP_SITES), - MatchesTile(u"Site 3", "http://site3/", - TileSource::TOP_SITES)))))); - top_sites_callbacks_.Notify( - MostVisitedURLList({MakeMostVisitedURL(u"Site 1", "http://site1/"), - MakeMostVisitedURL(u"Site 2", "http://site2/"), - MakeMostVisitedURL(u"Site 3", "http://site3/")})); - VerifyAndClearExpectations(); - - // Reply from suggestions service is empty and thus ignored. - suggestions_service_callbacks_.Notify(SuggestionsProfile()); - VerifyAndClearExpectations(); - EXPECT_TRUE(top_sites_callbacks_.empty()); - - // Update from top sites is propagated to observer. - EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) - .WillOnce(base::test::RunOnceCallback<0>( - MostVisitedURLList{MakeMostVisitedURL(u"Site 4", "http://site4/"), - MakeMostVisitedURL(u"Site 5", "http://site5/"), - MakeMostVisitedURL(u"Site 6", "http://site6/")})); - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre( - MatchesTile(u"Site 4", "http://site4/", TileSource::TOP_SITES), - MatchesTile(u"Site 5", "http://site5/", TileSource::TOP_SITES), - MatchesTile(u"Site 6", "http://site6/", - TileSource::TOP_SITES)))))); - mock_top_sites_->NotifyTopSitesChanged( - history::TopSitesObserver::ChangeReason::MOST_VISITED); - base::RunLoop().RunUntilIdle(); -} - -TEST_P(MostVisitedSitesWithEmptyCacheTest, - ShouldSendEmptyListIfBothTopSitesAndSuggestionsServiceEmpty) { - if (IsPopularSitesFeatureEnabled()) { - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre(MatchesTile(u"PopularSite1", "http://popularsite1/", - TileSource::POPULAR), - MatchesTile(u"PopularSite2", "http://popularsite2/", - TileSource::POPULAR)))))); - } else { - // The Android NTP doesn't finish initialization until it gets tiles, so a - // 0-tile notification is always needed. - EXPECT_CALL(mock_observer_, OnURLsAvailable(ElementsAre(Pair( - SectionType::PERSONALIZED, IsEmpty())))); - } - suggestions_service_callbacks_.Notify(SuggestionsProfile()); - top_sites_callbacks_.Notify(MostVisitedURLList()); - - base::RunLoop().RunUntilIdle(); -} - -TEST_P(MostVisitedSitesWithEmptyCacheTest, - ShouldStillNotifyIfTopSitesUnchanged) { - EXPECT_CALL( - mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre( - MatchesTile(u"Site 1", "http://site1/", TileSource::TOP_SITES), - MatchesTile(u"Site 2", "http://site2/", TileSource::TOP_SITES), - MatchesTile(u"Site 3", "http://site3/", - TileSource::TOP_SITES)))))) - .Times(5); - - suggestions_service_callbacks_.Notify(SuggestionsProfile()); - - top_sites_callbacks_.Notify( - MostVisitedURLList({MakeMostVisitedURL(u"Site 1", "http://site1/"), - MakeMostVisitedURL(u"Site 2", "http://site2/"), - MakeMostVisitedURL(u"Site 3", "http://site3/")})); - base::RunLoop().RunUntilIdle(); - - for (int i = 0; i < 4; ++i) { - EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)) - .WillOnce( - Invoke(&top_sites_callbacks_, &TopSitesCallbackList::AddUnsafe)); - mock_top_sites_->NotifyTopSitesChanged( - history::TopSitesObserver::ChangeReason::MOST_VISITED); - EXPECT_FALSE(top_sites_callbacks_.empty()); - top_sites_callbacks_.Notify( - MostVisitedURLList({MakeMostVisitedURL(u"Site 1", "http://site1/"), - MakeMostVisitedURL(u"Site 2", "http://site2/"), - MakeMostVisitedURL(u"Site 3", "http://site3/")})); - base::RunLoop().RunUntilIdle(); - } -} - -TEST_P(MostVisitedSitesWithEmptyCacheTest, - ShouldStillNotifyIfSuggestionsUnchanged) { - EXPECT_CALL(mock_observer_, - OnURLsAvailable(Contains(Pair( - SectionType::PERSONALIZED, - ElementsAre(MatchesTile(u"Site 1", "http://site1/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"Site 2", "http://site2/", - TileSource::SUGGESTIONS_SERVICE), - MatchesTile(u"Site 3", "http://site3/", - TileSource::SUGGESTIONS_SERVICE)))))) - .Times(5); - - for (int i = 0; i < 5; ++i) { - suggestions_service_callbacks_.Notify( - MakeProfile({MakeSuggestion("Site 1", "http://site1/"), - MakeSuggestion("Site 2", "http://site2/"), - MakeSuggestion("Site 3", "http://site3/")})); - } -} - -// Tests only apply when the suggestions service is enabled. -INSTANTIATE_TEST_SUITE_P(MostVisitedSitesWithEmptyCacheTest, - MostVisitedSitesWithEmptyCacheTest, - ::testing::Combine(::testing::Bool(), - testing::Values(true))); - // This a test for MostVisitedSites::MergeTiles(...) method, and thus has the // same scope as the method itself. This tests merging popular sites with // personal tiles.
diff --git a/components/ntp_tiles/tile_source.h b/components/ntp_tiles/tile_source.h index ea067c1d..b758725 100644 --- a/components/ntp_tiles/tile_source.h +++ b/components/ntp_tiles/tile_source.h
@@ -14,8 +14,6 @@ enum class TileSource { // Tile comes from the personal top sites list, based on local history. TOP_SITES, - // Tile comes from the suggestions service, based on synced history. - SUGGESTIONS_SERVICE, // Tile is regionally popular. POPULAR, // Tile is a popular site baked into the binary.
diff --git a/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc b/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc index f879bad5..07fdfea 100644 --- a/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc +++ b/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc
@@ -79,12 +79,6 @@ base::Unretained(this))); client_->RegisterMessageCallback( - "fetchSuggestions", - base::BindRepeating( - &NTPTilesInternalsMessageHandler::HandleFetchSuggestions, - base::Unretained(this))); - - client_->RegisterMessageCallback( "viewPopularSitesJson", base::BindRepeating( &NTPTilesInternalsMessageHandler::HandleViewPopularSitesJson, @@ -96,7 +90,6 @@ if (!client_->SupportsNTPTiles()) { base::Value disabled(base::Value::Type::DICTIONARY); disabled.SetBoolKey("topSites", false); - disabled.SetBoolKey("suggestionsService", false); disabled.SetBoolKey("popular", false); disabled.SetBoolKey("customLinks", false); disabled.SetBoolKey("allowlist", false); @@ -108,7 +101,6 @@ } DCHECK_EQ(0u, args->GetSize()); - suggestions_status_.clear(); popular_sites_json_.clear(); most_visited_sites_ = client_->MakeMostVisitedSites(); most_visited_sites_->AddMostVisitedURLsObserver(this, site_count_); @@ -175,22 +167,6 @@ SendSourceInfo(); } -void NTPTilesInternalsMessageHandler::HandleFetchSuggestions( - const base::ListValue* args) { - DCHECK_EQ(0u, args->GetSize()); - if (!most_visited_sites_->DoesSourceExist( - ntp_tiles::TileSource::SUGGESTIONS_SERVICE)) { - return; - } - - if (most_visited_sites_->suggestions()->FetchSuggestionsData()) { - suggestions_status_ = "fetching..."; - } else { - suggestions_status_ = "history sync is disabled, or not yet initialized"; - } - SendSourceInfo(); -} - void NTPTilesInternalsMessageHandler::HandleViewPopularSitesJson( const base::ListValue* args) { DCHECK_EQ(0u, args->GetSize()); @@ -214,12 +190,6 @@ value.SetBoolKey("allowlist", most_visited_sites_->DoesSourceExist(TileSource::ALLOWLIST)); - if (most_visited_sites_->DoesSourceExist(TileSource::SUGGESTIONS_SERVICE)) { - value.SetStringKey("suggestionsService.status", suggestions_status_); - } else { - value.SetBoolKey("suggestionsService", false); - } - if (most_visited_sites_->DoesSourceExist(TileSource::POPULAR)) { auto* popular_sites = most_visited_sites_->popular_sites(); value.SetStringKey("popular.url", popular_sites->GetURLToFetch().spec());
diff --git a/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.h b/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.h index 63ee466..b50d2ada 100644 --- a/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.h +++ b/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.h
@@ -78,7 +78,6 @@ int site_count_; std::unique_ptr<MostVisitedSites> most_visited_sites_; - std::string suggestions_status_; std::string popular_sites_json_; base::CancelableTaskTracker cancelable_task_tracker_;
diff --git a/components/ntp_tiles/webui/resources/ntp_tiles_internals.html b/components/ntp_tiles/webui/resources/ntp_tiles_internals.html index 3a97d0e..3165479f 100644 --- a/components/ntp_tiles/webui/resources/ntp_tiles_internals.html +++ b/components/ntp_tiles/webui/resources/ntp_tiles_internals.html
@@ -31,21 +31,6 @@ <td class="value" jsdisplay="$this">yes</td> <td class="value" jsdisplay="!$this">no</td> </tr> - <tr> - <th colspan="2">SUGGESTIONS_SERVICE</th> - </tr> - </tbody> - <tbody jsselect="suggestionsService"> - <tr jsdisplay="$this"> - <td class="detail"> - <input id="suggestions-fetch" type="submit" value="Fetch"> - </td> - <td class="value" jscontent="status"></td> - </tr> - <tr jsdisplay="!$this"> - <td class="detail">enabled</td> - <td class="value">no</td> - </tr> </tbody> <tbody jsselect="popular"> <tr> @@ -115,12 +100,11 @@ <td class="detail">Source</td> <td class="value" jsdisplay="source < 0">???</td> <td class="value" jsdisplay="source == 0">TOP_SITES</td> - <td class="value" jsdisplay="source == 1">SUGGESTIONS_SERVICE</td> - <td class="value" jsdisplay="source == 2">POPULAR</td> - <td class="value" jsdisplay="source == 3">POPULAR_BAKED_IN</td> - <td class="value" jsdisplay="source == 4">CUSTOM_LINKS</td> - <td class="value" jsdisplay="source == 5">ALLOWLIST</td> - <td class="value" jsdisplay="source == 6">HOMEPAGE</td> + <td class="value" jsdisplay="source == 1">POPULAR</td> + <td class="value" jsdisplay="source == 2">POPULAR_BAKED_IN</td> + <td class="value" jsdisplay="source == 3">CUSTOM_LINKS</td> + <td class="value" jsdisplay="source == 4">ALLOWLIST</td> + <td class="value" jsdisplay="source == 5">HOMEPAGE</td> <td class="value" jsdisplay="source > 6">???</td> </tr> <tr>
diff --git a/components/ntp_tiles/webui/resources/ntp_tiles_internals.js b/components/ntp_tiles/webui/resources/ntp_tiles_internals.js index ff27a08..d56537a 100644 --- a/components/ntp_tiles/webui/resources/ntp_tiles_internals.js +++ b/components/ntp_tiles/webui/resources/ntp_tiles_internals.js
@@ -23,11 +23,6 @@ }]); }); - $('suggestions-fetch').addEventListener('click', function(event) { - event.preventDefault(); - chrome.send('fetchSuggestions'); - }); - $('popular-view-json').addEventListener('click', function(event) { event.preventDefault(); if ($('popular-json-value').textContent === '') {
diff --git a/components/omnibox/browser/history_quick_provider_performance_unittest.cc b/components/omnibox/browser/history_quick_provider_performance_unittest.cc index e71114a1..7efeb9b 100644 --- a/components/omnibox/browser/history_quick_provider_performance_unittest.cc +++ b/components/omnibox/browser/history_quick_provider_performance_unittest.cc
@@ -32,7 +32,7 @@ std::string GenerateFakeHashedString(size_t sym_count) { static constexpr char kSyms[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,/=+?#"; - static base::NoDestructor<std::mt19937> engine; + static std::mt19937 engine; std::uniform_int_distribution<size_t> index_distribution( 0, base::size(kSyms) - 2 /* trailing \0 */); @@ -40,7 +40,7 @@ res.reserve(sym_count); std::generate_n(std::back_inserter(res), sym_count, [&index_distribution] { - return kSyms[index_distribution(*engine)]; + return kSyms[index_distribution(engine)]; }); return res;
diff --git a/components/password_manager/core/browser/password_scripts_fetcher_impl.cc b/components/password_manager/core/browser/password_scripts_fetcher_impl.cc index bd8acc8..703316a 100644 --- a/components/password_manager/core/browser/password_scripts_fetcher_impl.cc +++ b/components/password_manager/core/browser/password_scripts_fetcher_impl.cc
@@ -9,7 +9,6 @@ #include "base/json/json_reader.h" #include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_functions.h" -#include "base/no_destructor.h" #include "base/version.h" #include "components/password_manager/core/common/password_manager_features.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -165,7 +164,7 @@ } void PasswordScriptsFetcherImpl::StartFetch() { - static const base::NoDestructor<base::TimeDelta> kFetchTimeout( + static const base::TimeDelta kFetchTimeout( base::TimeDelta::FromSeconds(kFetchTimeoutInSeconds)); if (url_loader_) return; @@ -195,7 +194,7 @@ })"); url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request), traffic_annotation); - url_loader_->SetTimeoutDuration(*kFetchTimeout); + url_loader_->SetTimeoutDuration(kFetchTimeout); url_loader_->DownloadToString( url_loader_factory_.get(), base::BindOnce(&PasswordScriptsFetcherImpl::OnFetchComplete, @@ -268,10 +267,10 @@ } bool PasswordScriptsFetcherImpl::IsCacheStale() const { - static const base::NoDestructor<base::TimeDelta> kCacheTimeout( + static const base::TimeDelta kCacheTimeout( base::TimeDelta::FromMinutes(kCacheTimeoutInMinutes)); return last_fetch_timestamp_.is_null() || - base::TimeTicks::Now() - last_fetch_timestamp_ >= *kCacheTimeout; + base::TimeTicks::Now() - last_fetch_timestamp_ >= kCacheTimeout; } void PasswordScriptsFetcherImpl::RunResponseCallback(
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc index cd9e734..2cf67a7f 100644 --- a/components/password_manager/core/common/password_manager_features.cc +++ b/components/password_manager/core/common/password_manager_features.cc
@@ -139,6 +139,11 @@ const base::Feature kSecondaryServerFieldPredictions = { "SecondaryServerFieldPredictions", base::FEATURE_ENABLED_BY_DEFAULT}; +// Enables the addition of passwords in Chrome Settings. +// TODO(crbug/1226008): Remove once it's launched. +const base::Feature kSupportForAddPasswordsInSettings = { + "SupportForAddPasswordsInSettings", base::FEATURE_DISABLED_BY_DEFAULT}; + // Treat heuritistics to find new password fields as reliable. This enables // password generation on more forms, but could lead to false positives. const base::Feature kTreatNewPasswordHeuristicsAsReliable = {
diff --git a/components/password_manager/core/common/password_manager_features.h b/components/password_manager/core/common/password_manager_features.h index dfccebb2..0774350c 100644 --- a/components/password_manager/core/common/password_manager_features.h +++ b/components/password_manager/core/common/password_manager_features.h
@@ -39,6 +39,7 @@ extern const base::Feature kRecoverFromNeverSaveAndroid; extern const base::Feature kReparseServerPredictionsFollowingFormChange; extern const base::Feature kSecondaryServerFieldPredictions; +extern const base::Feature kSupportForAddPasswordsInSettings; extern const base::Feature kTreatNewPasswordHeuristicsAsReliable; extern const base::Feature kUnifiedPasswordManagerAndroid; extern const base::Feature kUseNewHeaderForLegacySavePasswordBubble;
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentFeatureList.java b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentFeatureList.java index 632697b..86fc117 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentFeatureList.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentFeatureList.java
@@ -22,6 +22,7 @@ public static final String PAYMENT_REQUEST_SKIP_TO_GPAY = "PaymentRequestSkipToGPay"; public static final String PAYMENT_REQUEST_SKIP_TO_GPAY_IF_NO_CARD = "PaymentRequestSkipToGPayIfNoCard"; + public static final String SECURE_PAYMENT_CONFIRMATION = "SecurePaymentConfirmationBrowser"; public static final String SERVICE_WORKER_PAYMENT_APPS = "ServiceWorkerPaymentApps"; public static final String STRICT_HAS_ENROLLED_AUTOFILL_INSTRUMENT = "StrictHasEnrolledAutofillInstrument";
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java index 04da245..1d077c217 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java
@@ -531,6 +531,16 @@ PaymentErrorReason.INVALID_DATA_FROM_RENDERER); return false; } + if (PaymentFeatureList.isEnabledOrExperimentalFeaturesEnabled( + PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION) + && methodData.containsKey(MethodStrings.SECURE_PAYMENT_CONFIRMATION) + && (methodData.size() > 1 || options.requestPayerEmail || options.requestPayerPhone + || options.requestShipping || options.requestPayerName)) { + mJourneyLogger.setAborted(AbortReason.INVALID_DATA_FROM_RENDERER); + disconnectFromClientWithDebugMessage(ErrorStrings.INVALID_PAYMENT_METHODS_OR_DATA, + PaymentErrorReason.INVALID_DATA_FROM_RENDERER); + return false; + } mBrowserPaymentRequest.modifyMethodDataIfNeeded(methodData); methodData = Collections.unmodifiableMap(methodData); @@ -888,7 +898,9 @@ PaymentApp selectedApp = mBrowserPaymentRequest.getSelectedPaymentApp(); // TODO(crbug.com/1211947): Deduplicate this part with // SecurePaymentConfirmationController::SetupModelAndShowDialogIfApplicable(). - return selectedApp != null && selectedApp.getPaymentAppType() == PaymentAppType.INTERNAL + return PaymentFeatureList.isEnabledOrExperimentalFeaturesEnabled( + PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION) + && selectedApp != null && selectedApp.getPaymentAppType() == PaymentAppType.INTERNAL && selectedApp.getInstrumentMethodNames().size() == 1 && selectedApp.getInstrumentMethodNames().contains( MethodStrings.SECURE_PAYMENT_CONFIRMATION)
diff --git a/components/payments/content/android/junit/src/org/chromium/components/payments/PaymentRequestServiceTest.java b/components/payments/content/android/junit/src/org/chromium/components/payments/PaymentRequestServiceTest.java index 0efea44..5a7d2f91 100644 --- a/components/payments/content/android/junit/src/org/chromium/components/payments/PaymentRequestServiceTest.java +++ b/components/payments/content/android/junit/src/org/chromium/components/payments/PaymentRequestServiceTest.java
@@ -162,6 +162,7 @@ @After public void tearDown() { PaymentRequestService.resetShowingPaymentRequestForTest(); + ShadowPaymentFeatureList.reset(); } @Override @@ -709,4 +710,37 @@ show(service2); assertErrorAndReason(ErrorStrings.ANOTHER_UI_SHOWING, PaymentErrorReason.ALREADY_SHOWING); } + + @Test + @Feature({"Payments"}) + public void testSpcCanOnlyBeRequestedAlone_success() { + ShadowPaymentFeatureList.setEnabledFeature(PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION); + Assert.assertNotNull(defaultBuilder().setOnlySpcMethodWithoutPaymentOptions().build()); + } + + @Test + @Feature({"Payments"}) + public void testSpcCanOnlyBeRequestedAlone_failedForHavingOptions() { + ShadowPaymentFeatureList.setEnabledFeature(PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION); + PaymentOptions options = new PaymentOptions(); + options.requestShipping = true; + Assert.assertNull(defaultBuilder() + .setOnlySpcMethodWithoutPaymentOptions() + .setOptions(options) + .build()); + assertErrorAndReason(ErrorStrings.INVALID_PAYMENT_METHODS_OR_DATA, + PaymentErrorReason.INVALID_DATA_FROM_RENDERER); + } + + // The restriction is imposed only when the SPC flag is enabled. + @Test + @Feature({"Payments"}) + public void testSpcCanOnlyBeRequestedAlone_notApplicableWhenSpcDisabled() { + PaymentOptions options = new PaymentOptions(); + options.requestShipping = true; + Assert.assertNotNull(defaultBuilder() + .setOnlySpcMethodWithoutPaymentOptions() + .setOptions(options) + .build()); + } }
diff --git a/components/payments/content/android/junit/src/org/chromium/components/payments/test_support/PaymentRequestServiceBuilder.java b/components/payments/content/android/junit/src/org/chromium/components/payments/test_support/PaymentRequestServiceBuilder.java index 2154116..08ae6e3 100644 --- a/components/payments/content/android/junit/src/org/chromium/components/payments/test_support/PaymentRequestServiceBuilder.java +++ b/components/payments/content/android/junit/src/org/chromium/components/payments/test_support/PaymentRequestServiceBuilder.java
@@ -10,6 +10,7 @@ import org.chromium.components.payments.BrowserPaymentRequest; import org.chromium.components.payments.JourneyLogger; +import org.chromium.components.payments.MethodStrings; import org.chromium.components.payments.PaymentAppService; import org.chromium.components.payments.PaymentRequestService; import org.chromium.components.payments.PaymentRequestService.Delegate; @@ -223,6 +224,14 @@ return this; } + public PaymentRequestServiceBuilder setOnlySpcMethodWithoutPaymentOptions() { + mMethodData = new PaymentMethodData[1]; + mMethodData[0] = new PaymentMethodData(); + mMethodData[0].supportedMethod = MethodStrings.SECURE_PAYMENT_CONFIRMATION; + mOptions = new PaymentOptions(); + return this; + } + public PaymentRequestServiceBuilder setGooglePayBridgeEligible(boolean eligible) { mGooglePayBridgeEligible = eligible; return this;
diff --git a/components/payments/content/android/payment_feature_list.cc b/components/payments/content/android/payment_feature_list.cc index a1fc98f..64653e5 100644 --- a/components/payments/content/android/payment_feature_list.cc +++ b/components/payments/content/android/payment_feature_list.cc
@@ -20,6 +20,7 @@ // components/payments/core/features.h, content/public/common/content_features.h // or the .h file (for Android only features). const base::Feature* const kFeaturesExposedToJava[] = { + &::features::kSecurePaymentConfirmation, &::features::kServiceWorkerPaymentApps, &::features::kWebPayments, &::features::kWebPaymentsMinimalUI,
diff --git a/components/performance_manager/performance_manager_lifetime.cc b/components/performance_manager/performance_manager_lifetime.cc index f0517f5..156f988 100644 --- a/components/performance_manager/performance_manager_lifetime.cc +++ b/components/performance_manager/performance_manager_lifetime.cc
@@ -32,8 +32,8 @@ } absl::optional<Decorators>* GetDecoratorsOverride() { - static base::NoDestructor<absl::optional<Decorators>> decorators_override; - return decorators_override.get(); + static absl::optional<Decorators> decorators_override; + return &decorators_override; } void OnGraphCreated(Decorators decorators,
diff --git a/components/policy/core/browser/BUILD.gn b/components/policy/core/browser/BUILD.gn index 75d6559..b3eb3275 100644 --- a/components/policy/core/browser/BUILD.gn +++ b/components/policy/core/browser/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//build/config/features.gni") +import("//testing/libfuzzer/fuzzer_test.gni") group("browser") { if (is_component_build) { @@ -87,6 +88,10 @@ "//net", "//third_party/icu", ] + + if (use_libfuzzer) { + visibility += [ "//chrome/browser/chromeos:policy_fuzzer" ] + } } static_library("test_support") {
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index 53fed4b0..12025c3 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto
@@ -1304,7 +1304,7 @@ // Available memory, in KiB. optional uint32 available_memory_kib = 3; // Number of page faults since the last boot. - optional uint32 page_faults_since_last_boot = 4; + optional uint64 page_faults_since_last_boot = 4; } // Information about the device's backlights.
diff --git a/components/search/ntp_features.cc b/components/search/ntp_features.cc index 32ee416..ebe5364b 100644 --- a/components/search/ntp_features.cc +++ b/components/search/ntp_features.cc
@@ -122,6 +122,8 @@ "NtpDriveModuleManagedUsersOnlyParam"; const char kNtpDriveModuleCacheMaxAgeSParam[] = "NtpDriveModuleCacheMaxAgeSParam"; +const char kNtpDriveModuleExperimentGroupParam[] = + "NtpDriveModuleExperimentGroupParam"; base::TimeDelta GetModulesLoadTimeout() { std::string param_value = base::GetFieldTrialParamValueByFeature(
diff --git a/components/search/ntp_features.h b/components/search/ntp_features.h index 147056cd..5e2a7c4 100644 --- a/components/search/ntp_features.h +++ b/components/search/ntp_features.h
@@ -64,6 +64,9 @@ extern const char kNtpDriveModuleManagedUsersOnlyParam[]; // Parameter determining the max age in seconds of the cache for drive data. extern const char kNtpDriveModuleCacheMaxAgeSParam[]; +// Parameter for communicating the experiment group of the Drive module +// experiment. +extern const char kNtpDriveModuleExperimentGroupParam[]; // Returns the timeout after which the load of a module should be aborted. base::TimeDelta GetModulesLoadTimeout();
diff --git a/components/site_isolation/site_isolation_policy_unittest.cc b/components/site_isolation/site_isolation_policy_unittest.cc index a9f9bf6..0f0df68 100644 --- a/components/site_isolation/site_isolation_policy_unittest.cc +++ b/components/site_isolation/site_isolation_policy_unittest.cc
@@ -5,6 +5,7 @@ #include "components/site_isolation/site_isolation_policy.h" #include "base/base_switches.h" +#include "base/no_destructor.h" #include "base/system/sys_info.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/mock_entropy_provider.h"
diff --git a/components/translate/content/renderer/translate_agent.cc b/components/translate/content/renderer/translate_agent.cc index b18415c..e94c3dae 100644 --- a/components/translate/content/renderer/translate_agent.cc +++ b/components/translate/content/renderer/translate_agent.cc
@@ -15,6 +15,7 @@ #include "base/location.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros_local.h" +#include "base/no_destructor.h" #include "base/notreached.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_util.h"
diff --git a/components/viz/common/viz_utils.cc b/components/viz/common/viz_utils.cc index c7a8265..d50d6a0 100644 --- a/components/viz/common/viz_utils.cc +++ b/components/viz/common/viz_utils.cc
@@ -14,7 +14,6 @@ #include <string> #include "base/android/build_info.h" -#include "base/no_destructor.h" #endif namespace viz { @@ -37,7 +36,8 @@ if (command_line.HasSwitch(kDisableWCGForTest)) return false; - auto compute_always_use_wide_color_gamut = []() { + // As it takes some work to compute this, cache the result. + static bool is_always_use_wide_color_gamut_enabled = [] { const char* current_model = base::android::BuildInfo::GetInstance()->model(); const std::array<std::string, 2> enabled_models = { @@ -48,12 +48,9 @@ } return false; - }; + }(); - // As it takes some work to compute this, cache the result. - static base::NoDestructor<bool> is_always_use_wide_color_gamut_enabled( - compute_always_use_wide_color_gamut()); - return *is_always_use_wide_color_gamut_enabled; + return is_always_use_wide_color_gamut_enabled; } #endif
diff --git a/components/viz/service/display_embedder/skia_output_device.cc b/components/viz/service/display_embedder/skia_output_device.cc index 3a123f8..e1521f3 100644 --- a/components/viz/service/display_embedder/skia_output_device.cc +++ b/components/viz/service/display_embedder/skia_output_device.cc
@@ -233,6 +233,38 @@ } pending_swaps_.pop(); + + // If there are skipped swaps at the front of the queue, they are now ready + // to be acknowledged without breaking ordering. + if (!pending_swaps_.empty()) { + auto iter = skipped_swap_info_.find(pending_swaps_.front().SwapId()); + if (iter != skipped_swap_info_.end()) { + OutputSurfaceFrame frame = std::move(iter->second); + gfx::Size frame_size = frame.size; + skipped_swap_info_.erase(iter); + // Recursively call into FinishSwapBuffers until the head of the queue is + // no longer a skipped swap. + FinishSwapBuffers( + gfx::SwapCompletionResult(gfx::SwapResult::SWAP_SKIPPED), frame_size, + std::move(frame)); + } + } +} + +void SkiaOutputDevice::SwapBuffersSkipped(BufferPresentedCallback feedback, + OutputSurfaceFrame frame) { + StartSwapBuffers(std::move(feedback)); + // If there are no other pending swaps, we can immediately close out the + // "skipped" swap that was just enqueued. If there are outstanding pending + // swaps, however, we need to wait for them to complete to avoid reordering + // complete/presentation callbacks. + if (pending_swaps_.size() == 1) { + gfx::Size frame_size = frame.size; + FinishSwapBuffers(gfx::SwapCompletionResult(gfx::SwapResult::SWAP_SKIPPED), + frame_size, std::move(frame)); + } else { + skipped_swap_info_[swap_id_] = std::move(frame); + } } SkiaOutputDevice::SwapInfo::SwapInfo( @@ -253,6 +285,10 @@ SkiaOutputDevice::SwapInfo::~SwapInfo() = default; +uint64_t SkiaOutputDevice::SwapInfo::SwapId() { + return params_.swap_response.swap_id; +} + const gpu::SwapBuffersCompleteParams& SkiaOutputDevice::SwapInfo::Complete( gfx::SwapCompletionResult result, const absl::optional<gfx::Rect>& damage_rect,
diff --git a/components/viz/service/display_embedder/skia_output_device.h b/components/viz/service/display_embedder/skia_output_device.h index b0185225..0a19355 100644 --- a/components/viz/service/display_embedder/skia_output_device.h +++ b/components/viz/service/display_embedder/skia_output_device.h
@@ -166,6 +166,13 @@ virtual void EnsureBackbuffer(); virtual void DiscardBackbuffer(); + // Acknowledges a SwapBuffers request without actually attempting to swap. + // This should be called when the GPU thread decides to skip a swap that was + // invoked by the viz thread to ensure that we still run the relevant metrics + // bookkeeping. + virtual void SwapBuffersSkipped(BufferPresentedCallback feedback, + OutputSurfaceFrame frame); + bool is_emulated_rgbx() const { return is_emulated_rgbx_; } void SetDrawTimings(base::TimeTicks submitted, base::TimeTicks started); @@ -183,6 +190,7 @@ base::TimeTicks task_ready); SwapInfo(SwapInfo&& other); ~SwapInfo(); + uint64_t SwapId(); const gpu::SwapBuffersCompleteParams& Complete( gfx::SwapCompletionResult result, const absl::optional<gfx::Rect>& damage_area, @@ -252,6 +260,8 @@ std::unique_ptr<ui::LatencyTracker> latency_tracker_; // task runner for latency tracker. scoped_refptr<base::SequencedTaskRunner> latency_tracker_runner_; + // A mapping from skipped swap ID to its corresponding OutputSurfaceFrame. + base::flat_map<uint64_t, OutputSurfaceFrame> skipped_swap_info_; DISALLOW_COPY_AND_ASSIGN(SkiaOutputDevice); };
diff --git a/components/viz/service/display_embedder/skia_output_device_buffer_queue_unittest.cc b/components/viz/service/display_embedder/skia_output_device_buffer_queue_unittest.cc index 8cb6fd8..3ee73ec 100644 --- a/components/viz/service/display_embedder/skia_output_device_buffer_queue_unittest.cc +++ b/components/viz/service/display_embedder/skia_output_device_buffer_queue_unittest.cc
@@ -13,9 +13,11 @@ #include "base/callback_helpers.h" #include "base/memory/ptr_util.h" #include "base/test/bind.h" +#include "base/test/mock_callback.h" #include "build/build_config.h" #include "components/viz/common/resources/resource_sizes.h" #include "components/viz/service/display_embedder/output_presenter_gl.h" +#include "components/viz/service/display_embedder/skia_output_device.h" #include "components/viz/service/display_embedder/skia_output_surface_dependency_impl.h" #include "components/viz/service/gl/gpu_service_impl.h" #include "components/viz/test/test_gpu_service_holder.h" @@ -195,13 +197,15 @@ void SwapBuffersAsync(SwapCompletionCallback completion_callback, PresentationCallback presentation_callback) override { - callbacks_.push_back(std::move(completion_callback)); + swap_completion_callbacks_.push_back(std::move(completion_callback)); + presentation_callbacks_.push_back(std::move(presentation_callback)); } void CommitOverlayPlanesAsync( SwapCompletionCallback completion_callback, PresentationCallback presentation_callback) override { - callbacks_.push_back(std::move(completion_callback)); + swap_completion_callbacks_.push_back(std::move(completion_callback)); + presentation_callbacks_.push_back(std::move(presentation_callback)); } bool ScheduleOverlayPlane(int z_order, @@ -219,15 +223,20 @@ } void SwapComplete() { - DCHECK(!callbacks_.empty()); - std::move(callbacks_.front()) + DCHECK(!swap_completion_callbacks_.empty()); + std::move(swap_completion_callbacks_.front()) .Run(gfx::SwapCompletionResult(gfx::SwapResult::SWAP_ACK)); - callbacks_.pop_front(); + swap_completion_callbacks_.pop_front(); + + DCHECK(!presentation_callbacks_.empty()); + std::move(presentation_callbacks_.front()).Run({}); + presentation_callbacks_.pop_front(); } protected: ~MockGLSurfaceAsync() override = default; - base::circular_deque<SwapCompletionCallback> callbacks_; + base::circular_deque<SwapCompletionCallback> swap_completion_callbacks_; + base::circular_deque<PresentationCallback> presentation_callbacks_; }; class MemoryTrackerStub : public gpu::MemoryTracker { @@ -260,6 +269,13 @@ } // namespace +using DidSwapBufferCompleteCallback = + base::RepeatingCallback<void(gpu::SwapBuffersCompleteParams, + const gfx::Size& pixel_size, + gfx::GpuFenceHandle release_fence)>; +using BufferPresentedCallback = + base::OnceCallback<void(const gfx::PresentationFeedback& feedback)>; + class SkiaOutputDeviceBufferQueueTest : public TestOnGpu { public: SkiaOutputDeviceBufferQueueTest() = default; @@ -270,6 +286,11 @@ gpu_service_holder_->gpu_service(), surface_handle_); } + virtual DidSwapBufferCompleteCallback GetDidSwapBuffersCompleteCallback() { + return base::DoNothing::Repeatedly<gpu::SwapBuffersCompleteParams, + const gfx::Size&, gfx::GpuFenceHandle>(); + } + void SetUpOnGpu() override { gl_surface_ = base::MakeRefCounted<MockGLSurfaceAsync>(); memory_tracker_ = std::make_unique<MemoryTrackerStub>(); @@ -286,9 +307,7 @@ std::make_unique<gpu::SharedImageRepresentationFactory>( dependency_->GetSharedImageManager(), memory_tracker_.get()); - auto present_callback = - base::DoNothing::Repeatedly<gpu::SwapBuffersCompleteParams, - const gfx::Size&, gfx::GpuFenceHandle>(); + auto present_callback = GetDidSwapBuffersCompleteCallback(); output_device_ = std::make_unique<SkiaOutputDeviceBufferQueue>( std::make_unique<OutputPresenterGL>( @@ -380,7 +399,7 @@ output_device_->SchedulePrimaryPlane(no_plane); } - void SwapBuffers() { + virtual void SwapBuffers() { auto present_callback = base::DoNothing::Once<const gfx::PresentationFeedback&>(); @@ -733,4 +752,76 @@ } } // namespace + +class SkiaOutputDeviceSwapSkippedTest : public SkiaOutputDeviceBufferQueueTest { + public: + SkiaOutputDeviceSwapSkippedTest() = default; + + DidSwapBufferCompleteCallback GetDidSwapBuffersCompleteCallback() override { + return swap_buffers_complete_cb.Get(); + } + + void SwapBuffers() override { + output_device_->SwapBuffers(buffer_presented_cb.Get(), + OutputSurfaceFrame()); + } + + void SwapBuffersSkipped() { + output_device_->SwapBuffersSkipped(buffer_presented_cb.Get(), + OutputSurfaceFrame()); + } + + base::MockCallback<DidSwapBufferCompleteCallback> swap_buffers_complete_cb; + base::MockCallback<BufferPresentedCallback> buffer_presented_cb; +}; + +namespace { + +MATCHER_P2(CheckSwapResponse, expected_swap_id, expected_result, "") { + return arg.swap_response.swap_id == expected_swap_id && + arg.swap_response.result == expected_result; +} + +MATCHER_P(CheckPresentationFeedback, expected_fail, "") { + return expected_fail == arg.failed(); +} + +TEST_F_GPU(SkiaOutputDeviceSwapSkippedTest, SkipWithoutPending) { + // Check that skipping a SwapBuffers without any pending swaps immediately + // invokes the complete/presented callbacks. + output_device_->Reshape(screen_size, 1.0f, gfx::ColorSpace(), kDefaultFormat, + gfx::OVERLAY_TRANSFORM_NONE); + EXPECT_CALL(swap_buffers_complete_cb, + Run(CheckSwapResponse(1U, gfx::SwapResult::SWAP_SKIPPED), _, _)); + EXPECT_CALL(buffer_presented_cb, + Run(CheckPresentationFeedback(true /* failed */))); + + SwapBuffersSkipped(); +} + +TEST_F_GPU(SkiaOutputDeviceSwapSkippedTest, SkipWithPending) { + // Check that skipping a SwapBuffers with existing pending swaps waits for + // the pending swaps to complete before invoking the complete/presented + // callbacks. + output_device_->Reshape(screen_size, 1.0f, gfx::ColorSpace(), kDefaultFormat, + gfx::OVERLAY_TRANSFORM_NONE); + EXPECT_NE(PaintAndSchedulePrimaryPlane(), nullptr); + EXPECT_NE(current_image(), nullptr); + + SwapBuffers(); + SwapBuffersSkipped(); + + EXPECT_CALL(swap_buffers_complete_cb, + Run(CheckSwapResponse(1U, gfx::SwapResult::SWAP_ACK), _, _)); + EXPECT_CALL(buffer_presented_cb, + Run(CheckPresentationFeedback(false /* failed */))); + EXPECT_CALL(swap_buffers_complete_cb, + Run(CheckSwapResponse(2U, gfx::SwapResult::SWAP_SKIPPED), _, _)); + EXPECT_CALL(buffer_presented_cb, + Run(CheckPresentationFeedback(true /* failed */))); + + PageFlipComplete(); +} + +} // namespace } // namespace viz
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index 8207496..86df379 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -1600,6 +1600,8 @@ if (frame->sub_buffer_rect && capabilities().supports_post_sub_buffer && frame->sub_buffer_rect->size() != size_) { + output_device_->SwapBuffersSkipped(buffer_presented_callback_, + std::move(*frame)); output_surface_plane_.reset(); destroy_after_swap_.clear(); return;
diff --git a/content/browser/audio/audio_service.cc b/content/browser/audio/audio_service.cc index 659d904a..450272a8 100644 --- a/content/browser/audio/audio_service.cc +++ b/content/browser/audio/audio_service.cc
@@ -7,7 +7,6 @@ #include "base/command_line.h" #include "base/deferred_sequenced_task_runner.h" #include "base/metrics/field_trial_params.h" -#include "base/no_destructor.h" #include "base/strings/string_number_conversions.h" #include "base/threading/sequence_local_storage_slot.h" #include "base/time/time.h" @@ -109,10 +108,10 @@ base::BindOnce( [](media::AudioManager* audio_manager, mojo::PendingReceiver<audio::mojom::AudioService> receiver) { - static base::NoDestructor< - base::SequenceLocalStorageSlot<std::unique_ptr<audio::Service>>> + static base::SequenceLocalStorageSlot< + std::unique_ptr<audio::Service>> service; - service->GetOrCreateValue() = audio::CreateEmbeddedService( + service.GetOrCreateValue() = audio::CreateEmbeddedService( audio_manager, std::move(receiver)); }, BrowserMainLoop::GetAudioManager(), std::move(receiver))); @@ -162,10 +161,10 @@ // any sequence, but to limit the lifetime of this Remote to the lifetime of // UI-thread sequence. This is to support re-creation after task environment // shutdown and reinitialization e.g. between unit tests. - static base::NoDestructor< - base::SequenceLocalStorageSlot<mojo::Remote<audio::mojom::AudioService>>> + static base::SequenceLocalStorageSlot< + mojo::Remote<audio::mojom::AudioService>> remote_slot; - auto& remote = remote_slot->GetOrCreateValue(); + auto& remote = remote_slot.GetOrCreateValue(); if (!remote) LaunchAudioService(&remote); return *remote.get();
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index 4e7094c9..5d09ecf7 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc
@@ -274,12 +274,7 @@ void BindConversionInternalsHandler( content::RenderFrameHost* host, mojo::PendingReceiver<::mojom::ConversionInternalsHandler> receiver) { - auto* contents = WebContents::FromRenderFrameHost(host); - DCHECK_EQ(contents->GetLastCommittedURL().host_piece(), - kChromeUIConversionInternalsHost); - DCHECK(contents->GetLastCommittedURL().SchemeIs(kChromeUIScheme)); - - content::WebUI* web_ui = contents->GetWebUI(); + content::WebUI* web_ui = host->GetWebUI(); // Performs a safe downcast to the concrete ConversionInternalsUI subclass. ConversionInternalsUI* conversion_internals_ui = @@ -295,17 +290,17 @@ return; } + DCHECK_EQ(host->GetLastCommittedURL().host_piece(), + kChromeUIConversionInternalsHost); + DCHECK(host->GetLastCommittedURL().SchemeIs(kChromeUIScheme)); + conversion_internals_ui->BindInterface(std::move(receiver)); } void BindProcessInternalsHandler( content::RenderFrameHost* host, mojo::PendingReceiver<::mojom::ProcessInternalsHandler> receiver) { - auto* contents = WebContents::FromRenderFrameHost(host); - DCHECK_EQ(contents->GetLastCommittedURL().host_piece(), - kChromeUIProcessInternalsHost); - - content::WebUI* web_ui = contents->GetWebUI(); + content::WebUI* web_ui = host->GetWebUI(); // Performs a safe downcast to the concrete ProcessInternalsUI subclass. ProcessInternalsUI* process_internals_ui = @@ -320,6 +315,10 @@ return; } + DCHECK_EQ(host->GetLastCommittedURL().host_piece(), + kChromeUIProcessInternalsHost); + DCHECK(host->GetLastCommittedURL().SchemeIs(kChromeUIScheme)); + process_internals_ui->BindProcessInternalsHandler(std::move(receiver), host); }
diff --git a/content/browser/browser_thread_unittest.cc b/content/browser/browser_thread_unittest.cc index 413de99..70fdae16 100644 --- a/content/browser/browser_thread_unittest.cc +++ b/content/browser/browser_thread_unittest.cc
@@ -98,8 +98,8 @@ ui_thread_ = std::make_unique<base::Thread>( BrowserThreadImpl::GetThreadName(BrowserThread::UI)); base::Thread::Options ui_options; - ui_options.delegate = new SequenceManagerThreadDelegate(); - ui_thread_->StartWithOptions(ui_options); + ui_options.delegate = std::make_unique<SequenceManagerThreadDelegate>(); + ui_thread_->StartWithOptions(std::move(ui_options)); io_thread_ = BrowserTaskExecutor::CreateIOThread(); io_thread_->RegisterAsBrowserThread();
diff --git a/content/browser/device/device_service.cc b/content/browser/device/device_service.cc index b0875ed9..d7a7866 100644 --- a/content/browser/device/device_service.cc +++ b/content/browser/device/device_service.cc
@@ -5,7 +5,6 @@ #include "content/public/browser/device_service.h" #include "base/memory/scoped_refptr.h" -#include "base/no_destructor.h" #include "base/single_thread_task_runner.h" #include "base/task/thread_pool.h" #include "base/threading/sequence_local_storage_slot.h" @@ -80,10 +79,9 @@ mojo::PendingReceiver<device::mojom::DeviceService> receiver) { // Bind the lifetime of the service instance to that of the sequence it's // running on. - static base::NoDestructor< - base::SequenceLocalStorageSlot<std::unique_ptr<device::DeviceService>>> + static base::SequenceLocalStorageSlot<std::unique_ptr<device::DeviceService>> service_slot; - auto& service = service_slot->GetOrCreateValue(); + auto& service = service_slot.GetOrCreateValue(); if (service) { service->AddReceiver(std::move(receiver)); @@ -128,11 +126,11 @@ } // namespace device::mojom::DeviceService& GetDeviceService() { - static base::NoDestructor<base::SequenceLocalStorageSlot< - mojo::Remote<device::mojom::DeviceService>>> + static base::SequenceLocalStorageSlot< + mojo::Remote<device::mojom::DeviceService>> remote_slot; mojo::Remote<device::mojom::DeviceService>& remote = - remote_slot->GetOrCreateValue(); + remote_slot.GetOrCreateValue(); if (!remote) { // This may be called very early in startup, too early for some Device // Service initialization steps (for example, in browser test environments,
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc index ade819f..c9e673b3 100644 --- a/content/browser/download/download_browsertest.cc +++ b/content/browser/download/download_browsertest.cc
@@ -4148,6 +4148,26 @@ EXPECT_TRUE(item->GetOriginalMimeType().empty()); } +// Verify that for download that is not triggered by navigation, MIME sniffing +// is working. +IN_PROC_BROWSER_TEST_F(DownloadContentTest, SniffedMimeTypeForDownloadURL) { + GURL download_url = + embedded_test_server()->GetURL("/download/gzip-content.gz"); + std::unique_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1)); + auto download_parameters = std::make_unique<download::DownloadUrlParameters>( + download_url, TRAFFIC_ANNOTATION_FOR_TESTS); + // Download URL without navigation. + DownloadManagerForShell(shell())->DownloadUrl(std::move(download_parameters)); + observer->WaitForFinished(); + + // Verify download failed. + std::vector<download::DownloadItem*> downloads; + DownloadManagerForShell(shell())->GetAllDownloads(&downloads); + EXPECT_EQ(1u, downloads.size()); + EXPECT_EQ(download::DownloadItem::COMPLETE, downloads[0]->GetState()); + EXPECT_STREQ("application/x-gzip", downloads[0]->GetMimeType().c_str()); +} + IN_PROC_BROWSER_TEST_F(DownloadContentTest, DuplicateContentDisposition) { // double-content-disposition.txt is served with two Content-Disposition // headers, both of which are identical.
diff --git a/content/browser/font_access/font_enumeration_cache_fontconfig.h b/content/browser/font_access/font_enumeration_cache_fontconfig.h index 9d254fcb..b296ce9 100644 --- a/content/browser/font_access/font_enumeration_cache_fontconfig.h +++ b/content/browser/font_access/font_enumeration_cache_fontconfig.h
@@ -5,16 +5,12 @@ #ifndef CONTENT_BROWSER_FONT_ACCESS_FONT_ENUMERATION_CACHE_FONTCONFIG_H_ #define CONTENT_BROWSER_FONT_ACCESS_FONT_ENUMERATION_CACHE_FONTCONFIG_H_ +#include "base/no_destructor.h" #include "content/browser/font_access/font_enumeration_cache.h" #include "content/common/content_export.h" using blink::mojom::FontEnumerationStatus; -namespace base { -template <typename T> -class NoDestructor; -} - namespace content { // ChromeOS and Linux implementation of FontEnumerationCache.
diff --git a/content/browser/font_access/font_enumeration_cache_mac.h b/content/browser/font_access/font_enumeration_cache_mac.h index 65ccb13..f3fc03f 100644 --- a/content/browser/font_access/font_enumeration_cache_mac.h +++ b/content/browser/font_access/font_enumeration_cache_mac.h
@@ -6,17 +6,13 @@ #define CONTENT_BROWSER_FONT_ACCESS_FONT_ENUMERATION_CACHE_MAC_H_ #include "base/memory/scoped_refptr.h" +#include "base/no_destructor.h" #include "base/task_runner.h" #include "content/browser/font_access/font_enumeration_cache.h" #include "content/common/content_export.h" using blink::mojom::FontEnumerationStatus; -namespace base { -template <typename T> -class NoDestructor; -} - namespace content { // Mac implementation of FontEnumerationCache.
diff --git a/content/browser/font_access/font_enumeration_cache_win.h b/content/browser/font_access/font_enumeration_cache_win.h index b9bd0d5..dc30234 100644 --- a/content/browser/font_access/font_enumeration_cache_win.h +++ b/content/browser/font_access/font_enumeration_cache_win.h
@@ -10,6 +10,7 @@ #include "base/deferred_sequenced_task_runner.h" #include "base/memory/read_only_shared_memory_region.h" +#include "base/no_destructor.h" #include "base/synchronization/atomic_flag.h" #include "content/browser/font_access/font_enumeration_cache.h" #include "content/common/content_export.h" @@ -18,9 +19,6 @@ using blink::mojom::FontEnumerationStatus; namespace base { -template <typename T> -class NoDestructor; - class ElapsedTimer; }
diff --git a/content/browser/media/media_service.cc b/content/browser/media/media_service.cc index c8d7216..46752c564 100644 --- a/content/browser/media/media_service.cc +++ b/content/browser/media/media_service.cc
@@ -54,10 +54,10 @@ // that of the UI-thread sequence. This ensures that the Remote is destroyed // when the task environment is torn down and reinitialized, e.g. between unit // tests. - static base::NoDestructor< - base::SequenceLocalStorageSlot<mojo::Remote<media::mojom::MediaService>>> + static base::SequenceLocalStorageSlot< + mojo::Remote<media::mojom::MediaService>> remote_slot; - auto& remote = remote_slot->GetOrCreateValue(); + auto& remote = remote_slot.GetOrCreateValue(); if (!remote) { auto receiver = remote.BindNewPipeAndPassReceiver(); remote.reset_on_disconnect();
diff --git a/content/browser/media/service_factory.cc b/content/browser/media/service_factory.cc index b9174bb..6988bf5 100644 --- a/content/browser/media/service_factory.cc +++ b/content/browser/media/service_factory.cc
@@ -11,7 +11,6 @@ #include "base/bind.h" #include "base/feature_list.h" #include "base/logging.h" -#include "base/no_destructor.h" #include "base/threading/sequence_local_storage_slot.h" #include "base/time/time.h" #include "content/browser/service_sandbox_type.h" @@ -154,8 +153,8 @@ // objects to that of the UI-thread sequence. This ensures the Remotes are // destroyed when the task environment is torn down and reinitialized, e.g., // between unit tests. - static base::NoDestructor<base::SequenceLocalStorageSlot<ServiceMap<T>>> slot; - return slot->GetOrCreateValue(); + static base::SequenceLocalStorageSlot<ServiceMap<T>> slot; + return slot.GetOrCreateValue(); } // Erases the service instance identified by `key`.
diff --git a/content/browser/media/session/audio_focus_delegate_default.cc b/content/browser/media/session/audio_focus_delegate_default.cc index 4729b013..13abe82 100644 --- a/content/browser/media/session/audio_focus_delegate_default.cc +++ b/content/browser/media/session/audio_focus_delegate_default.cc
@@ -5,7 +5,6 @@ #include "content/browser/media/session/audio_focus_delegate.h" #include "base/bind.h" -#include "base/no_destructor.h" #include "base/unguessable_token.h" #include "build/build_config.h" #include "content/browser/media/session/media_session_impl.h" @@ -32,9 +31,8 @@ // Use a shared audio focus group id for the whole browser. This will means // that tabs will share audio focus if the enforcement mode is set to // kSingleGroup. - static const base::NoDestructor<base::UnguessableToken> token( - base::UnguessableToken::Create()); - return *token; + static const base::UnguessableToken token(base::UnguessableToken::Create()); + return token; } // AudioFocusDelegateDefault is the default implementation of
diff --git a/content/browser/network_service_instance_impl.cc b/content/browser/network_service_instance_impl.cc index c44b89fd..32ff2690 100644 --- a/content/browser/network_service_instance_impl.cc +++ b/content/browser/network_service_instance_impl.cc
@@ -79,10 +79,10 @@ base::Time g_last_network_service_crash; std::unique_ptr<network::NetworkService>& GetLocalNetworkService() { - static base::NoDestructor< - base::SequenceLocalStorageSlot<std::unique_ptr<network::NetworkService>>> + static base::SequenceLocalStorageSlot< + std::unique_ptr<network::NetworkService>> service; - return service->GetOrCreateValue(); + return service.GetOrCreateValue(); } // If this feature is enabled, the Network Service will run on its own thread @@ -135,7 +135,7 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner; if (base::FeatureList::IsEnabled(kNetworkServiceDedicatedThread)) { base::Thread::Options options(base::MessagePumpType::IO, 0); - GetNetworkServiceDedicatedThread().StartWithOptions(options); + GetNetworkServiceDedicatedThread().StartWithOptions(std::move(options)); task_runner = GetNetworkServiceDedicatedThread().task_runner(); } else { task_runner = GetIOThreadTaskRunner({}); @@ -575,10 +575,10 @@ DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::UI) || BrowserThread::CurrentlyOn(BrowserThread::UI)); #endif - static base::NoDestructor<base::SequenceLocalStorageSlot< - std::unique_ptr<cert_verifier::CertVerifierServiceFactoryImpl>>> + static base::SequenceLocalStorageSlot< + std::unique_ptr<cert_verifier::CertVerifierServiceFactoryImpl>> service_factory_slot; - service_factory_slot->GetOrCreateValue() = + service_factory_slot.GetOrCreateValue() = std::make_unique<cert_verifier::CertVerifierServiceFactoryImpl>( std::move(receiver)); } @@ -587,10 +587,10 @@ // Lives on the UI thread. mojo::Remote<cert_verifier::mojom::CertVerifierServiceFactory>& GetCertVerifierServiceFactoryRemoteStorage() { - static base::NoDestructor<base::SequenceLocalStorageSlot< - mojo::Remote<cert_verifier::mojom::CertVerifierServiceFactory>>> + static base::SequenceLocalStorageSlot< + mojo::Remote<cert_verifier::mojom::CertVerifierServiceFactory>> cert_verifier_service_factory_remote; - return cert_verifier_service_factory_remote->GetOrCreateValue(); + return cert_verifier_service_factory_remote.GetOrCreateValue(); } // Returns a pointer to a CertVerifierServiceFactory usable on the UI thread.
diff --git a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.h b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.h index c827a6f..9db23bb1 100644 --- a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.h +++ b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.h
@@ -19,6 +19,7 @@ #include "base/macros.h" #include "base/memory/read_only_shared_memory_region.h" #include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "base/synchronization/atomic_flag.h" #include "base/time/time.h" #include "content/common/content_export.h" @@ -26,11 +27,6 @@ #include "third_party/blink/public/common/font_unique_name_lookup/font_unique_name_table.pb.h" #include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom.h" -namespace base { -template <typename T> -class NoDestructor; -} - namespace content { // Singleton class which encapsulates building the font unique name table lookup
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc b/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc index 4c6b0c47..cb22853 100644 --- a/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc +++ b/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
@@ -391,8 +391,9 @@ TouchSelectionControllerClientAuraSiteIsolationTest, testing::Bool()); +// TODO(crbug.com/1225345): Re-enable this test. IN_PROC_BROWSER_TEST_P(TouchSelectionControllerClientAuraSiteIsolationTest, - BasicSelectionIsolatedIframe) { + DISABLED_BasicSelectionIsolatedIframe) { GURL test_url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(a)")); EXPECT_TRUE(NavigateToURL(shell(), test_url));
diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc index 8c57809..beed2dd5 100644 --- a/content/browser/renderer_host/media/video_capture_manager.cc +++ b/content/browser/renderer_host/media/video_capture_manager.cc
@@ -17,7 +17,6 @@ #include "base/location.h" #include "base/logging.h" #include "base/metrics/histogram_functions.h" -#include "base/no_destructor.h" #include "base/single_thread_task_runner.h" #include "base/task_runner_util.h" #include "base/threading/thread_task_runner_handle.h" @@ -42,10 +41,10 @@ } const base::UnguessableToken& FakeSessionId() { - static const base::NoDestructor<base::UnguessableToken> fake_session_id( + static const base::UnguessableToken fake_session_id( base::UnguessableToken::Deserialize(0xFFFFFFFFFFFFFFFFU, 0xFFFFFFFFFFFFFFFFU)); - return *fake_session_id; + return fake_session_id; } } // namespace
diff --git a/content/browser/renderer_host/media/video_capture_unittest.cc b/content/browser/renderer_host/media/video_capture_unittest.cc index a2cee0dc..d2dd3fc1 100644 --- a/content/browser/renderer_host/media/video_capture_unittest.cc +++ b/content/browser/renderer_host/media/video_capture_unittest.cc
@@ -13,7 +13,6 @@ #include "base/location.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/no_destructor.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" @@ -70,9 +69,9 @@ // Id used to identify the capture session between renderer and // video_capture_host. This is an arbitrary value. const base::UnguessableToken& DeviceId() { - static const base::NoDestructor<base::UnguessableToken> device_id( + static const base::UnguessableToken device_id( base::UnguessableToken::Deserialize(555, 555)); - return *device_id; + return device_id; } } // namespace
diff --git a/content/browser/renderer_host/render_frame_host_delegate.cc b/content/browser/renderer_host/render_frame_host_delegate.cc index 58c9d3ec..dadd5be 100644 --- a/content/browser/renderer_host/render_frame_host_delegate.cc +++ b/content/browser/renderer_host/render_frame_host_delegate.cc
@@ -89,6 +89,10 @@ return true; } +bool RenderFrameHostDelegate::HasEnteredFullscreenMode() { + return false; +} + void RenderFrameHostDelegate::FullscreenStateChanged( RenderFrameHostImpl* rfh, bool is_fullscreen,
diff --git a/content/browser/renderer_host/render_frame_host_delegate.h b/content/browser/renderer_host/render_frame_host_delegate.h index 369377b..a4111f72 100644 --- a/content/browser/renderer_host/render_frame_host_delegate.h +++ b/content/browser/renderer_host/render_frame_host_delegate.h
@@ -302,6 +302,9 @@ // Returns whether entering fullscreen with EnterFullscreenMode() is allowed. virtual bool CanEnterFullscreenMode(); + // Returns whether this frame is already fullscreen. + virtual bool HasEnteredFullscreenMode(); + // Notification that the frame with the given host wants to enter fullscreen // mode. Must only be called if CanEnterFullscreenMode returns true. virtual void EnterFullscreenMode(
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index a9e3441e..4f9dde2 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -5474,11 +5474,16 @@ // side when the renderer is compromised and the fullscreen request is denied. // Fullscreen can only be triggered by: a user activation, a user-generated // screen orientation change, or another feature-specific transient allowance. + // If the frame is already fullscreen (and this request is a noop or + // this request is changing from one display to another), then no user + // activation is checked or consumed. + // // CanEnterFullscreenWithoutUserActivation is only ever true in tests, to // allow fullscreen when mocking screen orientation changes. // TODO(lanwei): Investigate whether we can terminate the renderer when the // user activation has already been consumed. - if (!delegate_->HasSeenRecentScreenOrientationChange() && + if (!delegate_->HasEnteredFullscreenMode() && + !delegate_->HasSeenRecentScreenOrientationChange() && !WindowPlacementAllowsFullscreen() && !HasSeenRecentXrOverlaySetup() && !GetContentClient() ->browser()
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index b2d855b..6bfb14af 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -2285,6 +2285,12 @@ FRIEND_TEST_ALL_PREFIXES( RenderFrameHostManagerUnloadBrowserTest, PendingDeleteRFHProcessShutdownDoesNotRemoveSubframes); + FRIEND_TEST_ALL_PREFIXES(SecurityExploitBrowserTest, + AttemptDuplicateRenderViewHost); + FRIEND_TEST_ALL_PREFIXES(SecurityExploitBrowserTest, + AttemptDuplicateRenderWidgetHost); + FRIEND_TEST_ALL_PREFIXES(SecurityExploitBrowserTest, + BindToWebUIFromWebViaMojo); FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, RenderViewHostIsNotReusedAfterDelayedUnloadACK); FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, @@ -2301,8 +2307,6 @@ RenderFrameProxyNotRecreatedDuringProcessShutdown); FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, UnloadACKArrivesPriorToProcessShutdownRequest); - FRIEND_TEST_ALL_PREFIXES(SecurityExploitBrowserTest, - AttemptDuplicateRenderViewHost); FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest, FullscreenAfterFrameUnload); FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, UnloadHandlerSubframes); @@ -2329,8 +2333,6 @@ FRIEND_TEST_ALL_PREFIXES(SitePerProcessSSLBrowserTest, UnloadHandlersArePowerfulGrandChild); FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplTest, ExpectedMainWorldOrigin); - FRIEND_TEST_ALL_PREFIXES(SecurityExploitBrowserTest, - AttemptDuplicateRenderWidgetHost); FRIEND_TEST_ALL_PREFIXES(RenderDocumentHostUserDataTest, CheckInPendingDeletionState); FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest, FrozenAndUnfrozenIPC);
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index c12ab7e0..43c270f8 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -5243,8 +5243,11 @@ const SiteInfo& site_info) { if (IsKeepAliveRefCountDisabled()) return; + + // Unset |is_shutdown_delayed| and remove from the delayed-shutdown tracker. + // This may have already been done in CancelAllProcessShutdownDelays() if the + // process was reused before this task executed. if (is_shutdown_delayed_) { - // Remove from the delayed-shutdown tracker. if (base::FeatureList::IsEnabled(features::kSubframeShutdownDelay) && ShouldTrackProcessForSite(GetBrowserContext(), this, site_info)) { SiteProcessCountTracker* tracker = SiteProcessCountTracker::GetInstance(
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 3e2034f0..18f90f71 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -562,6 +562,11 @@ const base::TimeDelta& unload_handler_timeout, const SiteInfo& site_info); bool IsProcessShutdownDelayedForTesting() { return is_shutdown_delayed_; } + // Remove the host from the delayed-shutdown tracker, if present. This does + // not decrement |keep_alive_ref_count_|; if it was incremented by a shutdown + // delay, it will be decremented when the delay expires. This ensures that + // the host is not destroyed between cancelling its shutdown delay and the new + // navigation adding listeners to keep it alive. void CancelAllProcessShutdownDelays() override; // Binds |receiver| to the FileSystemManager instance owned by the render
diff --git a/content/browser/renderer_host/render_widget_host_view_event_handler.cc b/content/browser/renderer_host/render_widget_host_view_event_handler.cc index a598fff..7337fd8 100644 --- a/content/browser/renderer_host/render_widget_host_view_event_handler.cc +++ b/content/browser/renderer_host/render_widget_host_view_event_handler.cc
@@ -38,12 +38,6 @@ #include "ui/gfx/delegated_ink_point.h" #include "ui/touch_selection/touch_selection_controller.h" -#if defined(OS_WIN) -#include "content/browser/renderer_host/render_frame_host_impl.h" -#include "ui/aura/window_tree_host.h" -#include "ui/display/screen.h" -#endif // defined(OS_WIN) - namespace { // In mouse lock mode, we need to prevent the (invisible) cursor from hitting @@ -55,16 +49,6 @@ // of the border area, in percentage of the corresponding dimension. const int kMouseLockBorderPercentage = 15; -// While the mouse is locked we want the invisible mouse to stay within the -// confines of the screen so we keep it in a capture region the size of the -// screen. However, on windows when the mouse hits the edge of the screen some -// events trigger and cause strange issues to occur. To stop those events from -// occuring we add a small border around the edge of the capture region. -// This constant controls how many pixels wide that border is. -#if defined(OS_WIN) -const int KMouseCaptureRegionBorder = 5; -#endif - #if defined(OS_WIN) // A callback function for EnumThreadWindows to enumerate and dismiss // any owned popup windows. @@ -149,20 +133,6 @@ popup_child_event_handler_ = popup_child_event_handler; } -#if defined(OS_WIN) -void RenderWidgetHostViewEventHandler::UpdateMouseLockRegion() { - RECT window_rect = - display::Screen::GetScreen() - ->DIPToScreenRectInWindow(window_, window_->GetBoundsInScreen()) - .ToRECT(); - window_rect.left += KMouseCaptureRegionBorder; - window_rect.right -= KMouseCaptureRegionBorder; - window_rect.top += KMouseCaptureRegionBorder; - window_rect.bottom -= KMouseCaptureRegionBorder; - ::ClipCursor(&window_rect); -} -#endif - blink::mojom::PointerLockResult RenderWidgetHostViewEventHandler::LockMouse( bool request_unadjusted_movement) { aura::Window* root_window = window_->GetRootWindow(); @@ -180,17 +150,7 @@ } mouse_locked_ = true; -#if !defined(OS_WIN) - window_->SetCapture(); -#else - UpdateMouseLockRegion(); -#endif - aura::client::CursorClient* cursor_client = - aura::client::GetCursorClient(root_window); - if (cursor_client) { - cursor_client->HideCursor(); - cursor_client->LockCursor(); - } + window_->GetHost()->LockMouse(window_); if (ShouldMoveToCenter(unlocked_global_mouse_position_)) MoveCursorToCenter(nullptr); @@ -241,12 +201,7 @@ mouse_locked_ = false; mouse_locked_unadjusted_movement_.reset(); - if (window_->HasCapture()) - window_->ReleaseCapture(); - -#if defined(OS_WIN) - ::ClipCursor(NULL); -#endif + window_->GetHost()->UnlockMouse(window_); // Ensure that the global mouse position is updated here to its original // value. If we don't do this then the synthesized mouse move which is posted @@ -258,12 +213,6 @@ synthetic_move_position_ = gfx::ToFlooredPoint(unlocked_global_mouse_position_); - aura::client::CursorClient* cursor_client = - aura::client::GetCursorClient(root_window); - if (cursor_client) { - cursor_client->UnlockCursor(); - cursor_client->ShowCursor(); - } host_->LostMouseLock(); }
diff --git a/content/browser/renderer_host/render_widget_host_view_event_handler.h b/content/browser/renderer_host/render_widget_host_view_event_handler.h index 6d41f4d..6af11db 100644 --- a/content/browser/renderer_host/render_widget_host_view_event_handler.h +++ b/content/browser/renderer_host/render_widget_host_view_event_handler.h
@@ -124,9 +124,6 @@ // Sets the ContextMenuParams when a context menu is triggered. Required for // subsequent event processing. void SetContextMenuParams(const ContextMenuParams& params); - - // Updates the cursor clip region. Used for mouse locking. - void UpdateMouseLockRegion(); #endif // defined(OS_WIN) bool accept_return_character() { return accept_return_character_; }
diff --git a/content/browser/sandbox_host_linux.h b/content/browser/sandbox_host_linux.h index eccad333..7526010 100644 --- a/content/browser/sandbox_host_linux.h +++ b/content/browser/sandbox_host_linux.h
@@ -9,15 +9,11 @@ #include "base/check.h" #include "base/macros.h" +#include "base/no_destructor.h" #include "base/threading/simple_thread.h" #include "content/browser/sandbox_ipc_linux.h" #include "content/common/content_export.h" -namespace base { -template <typename T> -class NoDestructor; -} - namespace content { // This is a singleton object which handles sandbox requests from the
diff --git a/content/browser/scheduler/browser_io_thread_delegate_unittest.cc b/content/browser/scheduler/browser_io_thread_delegate_unittest.cc index ed39160..65b4904 100644 --- a/content/browser/scheduler/browser_io_thread_delegate_unittest.cc +++ b/content/browser/scheduler/browser_io_thread_delegate_unittest.cc
@@ -25,8 +25,8 @@ handle->EnableAllQueues(); base::Thread::Options options; - options.delegate = delegate.release(); - thread.StartWithOptions(options); + options.delegate = std::move(delegate); + thread.StartWithOptions(std::move(options)); auto runner = handle->GetBrowserTaskRunner(BrowserTaskQueues::QueueType::kDefault); @@ -44,8 +44,8 @@ auto task_runner = delegate->GetDefaultTaskRunner(); base::Thread::Options options; - options.delegate = delegate.release(); - thread.StartWithOptions(options); + options.delegate = std::move(delegate); + thread.StartWithOptions(std::move(options)); base::WaitableEvent event; task_runner->PostTask(FROM_HERE, base::BindOnce(&base::WaitableEvent::Signal,
diff --git a/content/browser/scheduler/browser_task_executor.cc b/content/browser/scheduler/browser_task_executor.cc index 28e75e5..c04efa1 100644 --- a/content/browser/scheduler/browser_task_executor.cc +++ b/content/browser/scheduler/browser_task_executor.cc
@@ -349,13 +349,13 @@ base::Thread::Options options; options.message_pump_type = base::MessagePumpType::IO; - options.delegate = browser_io_thread_delegate.release(); + options.delegate = std::move(browser_io_thread_delegate); // Up the priority of the |io_thread_| as some of its IPCs relate to // display tasks. if (base::FeatureList::IsEnabled( ::features::kBrowserUseDisplayThreadPriority)) options.priority = base::ThreadPriority::DISPLAY; - if (!io_thread->StartWithOptions(options)) + if (!io_thread->StartWithOptions(std::move(options))) LOG(FATAL) << "Failed to start BrowserThread:IO"; return io_thread; }
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc index 4edd6f1..cb47453 100644 --- a/content/browser/security_exploit_browsertest.cc +++ b/content/browser/security_exploit_browsertest.cc
@@ -1305,6 +1305,46 @@ EXPECT_EQ(bad_message::RFH_CAN_COMMIT_URL_BLOCKED, kill_waiter.Wait()); } +// Tests that a web page cannot bind to a WebUI interface if a WebUI page is the +// currently committed RenderFrameHost in the tab (https://crbug.com/1225929). +IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, BindToWebUIFromWebViaMojo) { + // Navigate to a non-privileged web page, and simulate a renderer compromise + // by granting MojoJS. + GURL web_url(embedded_test_server()->GetURL("a.com", "/title1.html")); + TestNavigationManager navigation(shell()->web_contents(), web_url); + shell()->LoadURL(web_url); + EXPECT_TRUE(navigation.WaitForResponse()); + RenderFrameHostImpl* main_frame = static_cast<RenderFrameHostImpl*>( + shell()->web_contents()->GetMainFrame()); + main_frame->GetFrameBindingsControl()->EnableMojoJsBindings(); + navigation.ResumeNavigation(); + + // When the page unloads (after the cross-process navigation to an actual + // WebUI page below), try to bind to a WebUI interface from the web + // RenderFrameHost. Ensure the unload timer and bfcache are disabled so that + // the handler has a chance to run. + main_frame->DisableUnloadTimerForTesting(); + DisableBackForwardCacheForTesting(shell()->web_contents(), + BackForwardCache::TEST_USES_UNLOAD_EVENT); + ASSERT_TRUE(ExecJs(main_frame, R"( + onunload = function () { + newMessagePipe = Mojo.createMessagePipe(); + Mojo.bindInterface('mojom.ProcessInternalsHandler', + newMessagePipe.handle0); + }; + )")); + + // Now navigate to a WebUI page and expect the previous renderer process to be + // killed when asking to bind to the WebUI interface. + GURL webui_url( + GetWebUIURL(kChromeUIProcessInternalsHost).Resolve("#general")); + RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame->GetProcess()); + EXPECT_TRUE(NavigateToURL(shell(), webui_url)); + + // Verify that the previous renderer was terminated. + EXPECT_EQ(bad_message::RFH_INVALID_WEB_UI_CONTROLLER, kill_waiter.Wait()); +} + class BeginNavigationTransitionReplacer : public FrameHostInterceptor { public: BeginNavigationTransitionReplacer(WebContents* web_contents,
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index 4b0423d..168918b 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -154,19 +154,19 @@ // NOTE: This use of sequence-local storage is only to ensure that the Remote // only lives as long as the UI-thread sequence, since the UI-thread sequence // may be torn down and reinitialized e.g. between unit tests. - static base::NoDestructor<base::SequenceLocalStorageSlot< - mojo::Remote<storage::mojom::StorageService>>> + static base::SequenceLocalStorageSlot< + mojo::Remote<storage::mojom::StorageService>> remote_slot; - return remote_slot->GetOrCreateValue(); + return remote_slot.GetOrCreateValue(); } void RunInProcessStorageService( mojo::PendingReceiver<storage::mojom::StorageService> receiver) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - static base::NoDestructor<base::SequenceLocalStorageSlot< - std::unique_ptr<storage::StorageServiceImpl>>> + static base::SequenceLocalStorageSlot< + std::unique_ptr<storage::StorageServiceImpl>> service_storage_slot; - service_storage_slot->GetOrCreateValue() = + service_storage_slot.GetOrCreateValue() = std::make_unique<storage::StorageServiceImpl>(std::move(receiver), /*io_task_runner=*/nullptr); }
diff --git a/content/browser/tracing/background_tracing_manager_impl.h b/content/browser/tracing/background_tracing_manager_impl.h index e9d7ba5..708498a 100644 --- a/content/browser/tracing/background_tracing_manager_impl.h +++ b/content/browser/tracing/background_tracing_manager_impl.h
@@ -12,17 +12,13 @@ #include <vector> #include "base/macros.h" +#include "base/no_destructor.h" #include "content/browser/tracing/background_tracing_config_impl.h" #include "content/public/browser/background_tracing_manager.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/tracing/public/cpp/perfetto/trace_event_data_source.h" #include "services/tracing/public/mojom/background_tracing_agent.mojom.h" -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - namespace tracing { namespace mojom { class BackgroundTracingAgent;
diff --git a/content/browser/video_capture_service.cc b/content/browser/video_capture_service.cc index c408d3b..3f9dcbb 100644 --- a/content/browser/video_capture_service.cc +++ b/content/browser/video_capture_service.cc
@@ -45,10 +45,10 @@ // NOTE: This use of sequence-local storage is only to ensure that the Remote // only lives as long as the UI-thread sequence, since the UI-thread sequence // may be torn down and reinitialized e.g. between unit tests. - static base::NoDestructor<base::SequenceLocalStorageSlot< - mojo::Remote<video_capture::mojom::VideoCaptureService>>> + static base::SequenceLocalStorageSlot< + mojo::Remote<video_capture::mojom::VideoCaptureService>> remote_slot; - return remote_slot->GetOrCreateValue(); + return remote_slot.GetOrCreateValue(); } // This is a custom traits type we use in conjunction with mojo::ReceiverSetBase @@ -79,10 +79,10 @@ video_capture::mojom::VideoCaptureService& GetVideoCaptureService() { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - static base::NoDestructor<base::SequenceLocalStorageSlot< - mojo::Remote<video_capture::mojom::VideoCaptureService>>> + static base::SequenceLocalStorageSlot< + mojo::Remote<video_capture::mojom::VideoCaptureService>> storage; - auto& remote = storage->GetOrCreateValue(); + auto& remote = storage.GetOrCreateValue(); if (!remote.is_bound()) { GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(&BindProxyRemoteOnUIThread,
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 4d28d754..8eb069f 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3294,6 +3294,10 @@ }); } +bool WebContentsImpl::HasEnteredFullscreenMode() { + return IsFullscreen(); +} + void WebContentsImpl::EnterFullscreenMode( RenderFrameHostImpl* requesting_frame, const blink::mojom::FullscreenOptions& options) {
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index f594cfd..46f7b55 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -650,6 +650,7 @@ mojo::PendingReceiver<device::mojom::NFC>) override; #endif bool CanEnterFullscreenMode() override; + bool HasEnteredFullscreenMode() override; void EnterFullscreenMode( RenderFrameHostImpl* requesting_frame, const blink::mojom::FullscreenOptions& options) override;
diff --git a/content/browser/web_package/signed_exchange_utils.cc b/content/browser/web_package/signed_exchange_utils.cc index ff01e25..dab316b 100644 --- a/content/browser/web_package/signed_exchange_utils.cc +++ b/content/browser/web_package/signed_exchange_utils.cc
@@ -6,7 +6,6 @@ #include "base/command_line.h" #include "base/feature_list.h" -#include "base/no_destructor.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -254,9 +253,9 @@ // uninitialized variables.) This way, we no longer have the unlikely (but // observed in the real world!) event where we have two requests with the same // request_id_. - static base::NoDestructor<std::atomic_int> request_id(-1); + static std::atomic_int request_id(-1); - return --*request_id; + return --request_id; } base::Time GetVerificationTime() {
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc index 5b90c3d..3deeacb1 100644 --- a/content/child/blink_platform_impl.cc +++ b/content/child/blink_platform_impl.cc
@@ -69,7 +69,7 @@ struct DataResource { const char* name; int id; - ui::ScaleFactor scale_factor; + ui::ResourceScaleFactor scale_factor; }; class NestedMessageLoopRunnerImpl @@ -150,8 +150,9 @@ child_thread->RecordComputedAction(name.Action()); } -WebData BlinkPlatformImpl::GetDataResource(int resource_id, - ui::ScaleFactor scale_factor) { +WebData BlinkPlatformImpl::GetDataResource( + int resource_id, + ui::ResourceScaleFactor scale_factor) { base::StringPiece resource = GetContentClient()->GetDataResource(resource_id, scale_factor); return WebData(resource.data(), resource.size());
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h index 2f5cddc..16932b54 100644 --- a/content/child/blink_platform_impl.h +++ b/content/child/blink_platform_impl.h
@@ -38,7 +38,7 @@ bool IsLowEndDevice() override; void RecordAction(const blink::UserMetricsAction&) override; blink::WebData GetDataResource(int resource_id, - ui::ScaleFactor scale_factor) override; + ui::ResourceScaleFactor scale_factor) override; blink::WebData UncompressDataResource(int resource_id) override; blink::WebString QueryLocalizedString(int resource_id) override; blink::WebString QueryLocalizedString(int resource_id,
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/OWebContentsAccessibility.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/OWebContentsAccessibility.java index a3b125f2..604a6d7 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/OWebContentsAccessibility.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/OWebContentsAccessibility.java
@@ -63,7 +63,7 @@ for (int i = 0; i < positionInfoLength; i++) { Rect rect = new Rect( coords[4 * i + 0], coords[4 * i + 1], coords[4 * i + 2], coords[4 * i + 3]); - convertWebRectToAndroidCoordinates(rect); + convertWebRectToAndroidCoordinates(rect, info.getExtras()); boundingRects[i] = new RectF(rect); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java index 5690199..ef1d7a6c 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
@@ -1770,7 +1770,7 @@ return charSequence; } - protected void convertWebRectToAndroidCoordinates(Rect rect) { + protected void convertWebRectToAndroidCoordinates(Rect rect, Bundle extras) { // Offset by the scroll position. AccessibilityCoordinates ac = mDelegate.getAccessibilityCoordinates(); rect.offset(-(int) ac.getScrollX(), -(int) ac.getScrollY()); @@ -1789,11 +1789,17 @@ mView.getLocationOnScreen(viewLocation); rect.offset(viewLocation[0], viewLocation[1]); - // Clip to the viewport bounds. + // Clip to the viewport bounds, and add unclipped values to the Bundle. int viewportRectTop = viewLocation[1] + (int) ac.getContentOffsetYPix(); int viewportRectBottom = viewportRectTop + ac.getLastFrameViewportHeightPixInt(); - if (rect.top < viewportRectTop) rect.top = viewportRectTop; - if (rect.bottom > viewportRectBottom) rect.bottom = viewportRectBottom; + if (rect.top < viewportRectTop) { + extras.putInt("AccessibilityNodeInfo.unclippedTop", rect.top); + rect.top = viewportRectTop; + } + if (rect.bottom > viewportRectBottom) { + extras.putInt("AccessibilityNodeInfo.unclippedBottom", rect.bottom); + rect.bottom = viewportRectBottom; + } } protected void requestSendAccessibilityEvent(AccessibilityEvent event) { @@ -1835,7 +1841,7 @@ node.setBoundsInParent(boundsInParent); Rect rect = new Rect(absoluteLeft, absoluteTop, absoluteLeft + width, absoluteTop + height); - convertWebRectToAndroidCoordinates(rect); + convertWebRectToAndroidCoordinates(rect, node.getExtras()); node.setBoundsInScreen(rect);
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java index 19e272f..bb8f137 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
@@ -90,6 +90,8 @@ private static final String INPUT_RANGE_EVENT_ERROR = "TYPE_VIEW_SCROLLED event not received before timeout."; private static final String CACHING_ERROR = "AccessibilityNodeInfo cache has stale data"; + private static final String NODE_EXTRAS_UNCLIPPED_ERROR = + "AccessibilityNodeInfo object should have unclipped bounds in extras bundle"; // Constant values for unit tests private static final int UNSUPPRESSED_EXPECTED_COUNT = 25; @@ -1048,6 +1050,35 @@ Assert.assertTrue(result[2].left < result[3].left); } + @Test + @SmallTest + @FlakyTest(message = "https://crbug.com/1225255") + public void testNodeInfo_extras_unclippedBounds() { + // Build a simple web page with a scrollable view. + setupTestFromFile("content/test/data/android/scroll_element_offscreen.html"); + + // Find the <div> that contains example paragraphs that can be scrolled. + int vvIdDiv = waitForNodeMatching(sClassNameMatcher, "android.view.View"); + mNodeInfo = createAccessibilityNodeInfo(vvIdDiv); + Assert.assertNotNull(NODE_TIMEOUT_ERROR, mNodeInfo); + + // Scroll window up so container goes slightly off-screen. + executeJS("scrollUp()"); + + // Signal end of test. + mActivityTestRule.sendEndOfTestSignal(); + + // Refresh the AccessibilityNodeInfo object for the container. + mNodeInfo = createAccessibilityNodeInfo(vvIdDiv); + + // Check that the container has unclipped values set. + Assert.assertNotNull(NODE_EXTRAS_UNCLIPPED_ERROR, mNodeInfo.getExtras()); + Assert.assertTrue(NODE_EXTRAS_UNCLIPPED_ERROR, + mNodeInfo.getExtras().getInt("AccessibilityNodeInfo.unclippedTop") < 0); + Assert.assertTrue(NODE_EXTRAS_UNCLIPPED_ERROR, + mNodeInfo.getExtras().getInt("AccessibilityNodeInfo.unclippedBottom") > 0); + } + /** * Test |AccessibilityNodeInfo| object actions to ensure we are not adding ACTION_LONG_CLICK * to nodes due to verbose utterances issue.
diff --git a/content/public/browser/renderer_preferences_util.cc b/content/public/browser/renderer_preferences_util.cc index e7bd0ec11..050e5114 100644 --- a/content/public/browser/renderer_preferences_util.cc +++ b/content/public/browser/renderer_preferences_util.cc
@@ -5,7 +5,6 @@ #include "content/public/browser/renderer_preferences_util.h" #include "base/command_line.h" -#include "base/no_destructor.h" #include "base/strings/string_number_conversions.h" #include "build/build_config.h" #include "content/public/common/content_switches.h" @@ -16,14 +15,14 @@ void UpdateFontRendererPreferencesFromSystemSettings( blink::RendererPreferences* prefs) { - static const base::NoDestructor<gfx::FontRenderParams> params( + static const gfx::FontRenderParams params( gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr)); - prefs->should_antialias_text = params->antialiasing; - prefs->use_subpixel_positioning = params->subpixel_positioning; - prefs->hinting = params->hinting; - prefs->use_autohinter = params->autohinter; - prefs->use_bitmaps = params->use_bitmaps; - prefs->subpixel_rendering = params->subpixel_rendering; + prefs->should_antialias_text = params.antialiasing; + prefs->use_subpixel_positioning = params.subpixel_positioning; + prefs->hinting = params.hinting; + prefs->use_autohinter = params.autohinter; + prefs->use_bitmaps = params.use_bitmaps; + prefs->subpixel_rendering = params.subpixel_rendering; } } // namespace content
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 1598c5d..b6e892a 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -626,14 +626,8 @@ // actually enable the feature by default. The feature is also controlled by the // Blink runtime feature "SecurePaymentConfirmation". Both have to be enabled // for SecurePaymentConfirmation to be available. -const base::Feature kSecurePaymentConfirmation { - "SecurePaymentConfirmationBrowser", -#if defined(OS_MAC) || defined(OS_WIN) - base::FEATURE_ENABLED_BY_DEFAULT -#else - base::FEATURE_DISABLED_BY_DEFAULT -#endif -}; +const base::Feature kSecurePaymentConfirmation{ + "SecurePaymentConfirmationBrowser", base::FEATURE_ENABLED_BY_DEFAULT}; // Used to enable API changes for Secure Payment Confirmation. // TODO(crbug.com/1216464): Enable by default in M93.
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 6e121e3..4dbdc2d4 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -3590,7 +3590,8 @@ blink::mojom::PortalClientInterfaceBase> client_endpoint, const blink::WebElement& portal_element) { int proxy_routing_id = MSG_ROUTING_NONE; - auto initial_replicated_state = blink::mojom::FrameReplicationState::New(); + blink::mojom::FrameReplicationStatePtr initial_replicated_state = + blink::mojom::FrameReplicationState::New(); blink::PortalToken portal_token; blink::RemoteFrameToken frame_token; base::UnguessableToken devtools_frame_token; @@ -3598,7 +3599,7 @@ std::move(client_endpoint), &proxy_routing_id, &initial_replicated_state, &portal_token, &frame_token, &devtools_frame_token); - RenderFrameProxy* proxy = RenderFrameProxy::CreateProxyForPortal( + RenderFrameProxy* proxy = RenderFrameProxy::CreateProxyForPortalOrFencedFrame( agent_scheduling_group_, this, proxy_routing_id, frame_token, devtools_frame_token, portal_element); proxy->SetReplicatedState(std::move(initial_replicated_state)); @@ -3609,13 +3610,14 @@ const blink::PortalToken& portal_token, const blink::WebElement& portal_element) { int proxy_routing_id = MSG_ROUTING_NONE; + blink::mojom::FrameReplicationStatePtr replicated_state = + blink::mojom::FrameReplicationState::New(); blink::RemoteFrameToken frame_token; base::UnguessableToken devtools_frame_token; - auto replicated_state = blink::mojom::FrameReplicationState::New(); GetFrameHost()->AdoptPortal(portal_token, &proxy_routing_id, &replicated_state, &frame_token, &devtools_frame_token); - RenderFrameProxy* proxy = RenderFrameProxy::CreateProxyForPortal( + RenderFrameProxy* proxy = RenderFrameProxy::CreateProxyForPortalOrFencedFrame( agent_scheduling_group_, this, proxy_routing_id, frame_token, devtools_frame_token, portal_element); proxy->SetReplicatedState(std::move(replicated_state)); @@ -3623,10 +3625,21 @@ } blink::WebRemoteFrame* RenderFrameImpl::CreateFencedFrame( - const blink::WebElement& fenced_frame_element) { - // TODO(crbug.com/1123606): Initialize and register remote frame and return it - // from here. - return nullptr; + const blink::WebElement& fenced_frame) { + int proxy_routing_id = MSG_ROUTING_NONE; + blink::mojom::FrameReplicationStatePtr initial_replicated_state = + blink::mojom::FrameReplicationState::New(); + blink::RemoteFrameToken frame_token; + base::UnguessableToken devtools_frame_token; + + // TODO(crbug.com/1123606): Call mojom::FrameHost::CreateFencedFrame() once we + // introduce it in a subsequent CL. + + RenderFrameProxy* proxy = RenderFrameProxy::CreateProxyForPortalOrFencedFrame( + agent_scheduling_group_, this, proxy_routing_id, frame_token, + devtools_frame_token, fenced_frame); + proxy->SetReplicatedState(std::move(initial_replicated_state)); + return proxy->web_frame(); } blink::WebFrame* RenderFrameImpl::FindFrame(const blink::WebString& name) {
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 355db6f..5c8c75f 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -151,20 +151,21 @@ return proxy.release(); } -RenderFrameProxy* RenderFrameProxy::CreateProxyForPortal( +RenderFrameProxy* RenderFrameProxy::CreateProxyForPortalOrFencedFrame( AgentSchedulingGroup& agent_scheduling_group, RenderFrameImpl* parent, int proxy_routing_id, const blink::RemoteFrameToken& frame_token, const base::UnguessableToken& devtools_frame_token, - const blink::WebElement& portal_element) { + const blink::WebElement& frame_owner) { auto proxy = base::WrapUnique( new RenderFrameProxy(agent_scheduling_group, proxy_routing_id)); - blink::WebRemoteFrame* web_frame = blink::WebRemoteFrame::CreateForPortal( - blink::mojom::TreeScopeType::kDocument, proxy.get(), - proxy->blink_interface_registry_.get(), - proxy->GetRemoteAssociatedInterfaces(), frame_token, devtools_frame_token, - portal_element); + blink::WebRemoteFrame* web_frame = + blink::WebRemoteFrame::CreateForPortalOrFencedFrame( + blink::mojom::TreeScopeType::kDocument, proxy.get(), + proxy->blink_interface_registry_.get(), + proxy->GetRemoteAssociatedInterfaces(), frame_token, + devtools_frame_token, frame_owner); proxy->Init(web_frame, parent->render_view()); return proxy.release(); }
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h index 6f2ca3b5..ff54d72 100644 --- a/content/renderer/render_frame_proxy.h +++ b/content/renderer/render_frame_proxy.h
@@ -97,15 +97,15 @@ const base::UnguessableToken& devtools_frame_token, mojom::RemoteMainFrameInterfacesPtr remote_main_frame_interfaces); - // Creates a RenderFrameProxy to be used with a portal owned by |parent|. - // |routing_id| is the routing id of this new RenderFrameProxy. - static RenderFrameProxy* CreateProxyForPortal( + // Creates a RenderFrameProxy to be used with a portal or fenced frame owned + // by |parent|. |routing_id| is the routing id of this new RenderFrameProxy. + static RenderFrameProxy* CreateProxyForPortalOrFencedFrame( AgentSchedulingGroup& agent_scheduling_group, RenderFrameImpl* parent, int proxy_routing_id, const blink::RemoteFrameToken& frame_token, const base::UnguessableToken& devtools_frame_token, - const blink::WebElement& portal_element); + const blink::WebElement& frame_owner_element); // Returns the RenderFrameProxy for the given routing ID. static RenderFrameProxy* FromRoutingID(int routing_id);
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 3a5834f..0bc7245 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -631,9 +631,14 @@ // but the system default is true. #if defined(OS_MAC) is_elastic_overscroll_enabled_ = true; -#elif defined(OS_WIN) || defined(OS_ANDROID) +#elif defined(OS_WIN) is_elastic_overscroll_enabled_ = base::FeatureList::IsEnabled(features::kElasticOverscroll); +#elif defined(OS_ANDROID) + is_elastic_overscroll_enabled_ = + !base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableOverscrollEdgeEffect) && + base::FeatureList::IsEnabled(features::kElasticOverscroll); #else is_elastic_overscroll_enabled_ = false; #endif
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index 0274833..911a272 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -14,7 +14,6 @@ #include "base/feature_list.h" #include "base/files/file.h" #include "base/files/file_util.h" -#include "base/no_destructor.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -402,10 +401,9 @@ ShellContentBrowserClient::RunSecondaryMediaService() { mojo::Remote<::media::mojom::MediaService> remote; #if BUILDFLAG(ENABLE_CAST_RENDERER) - static base::NoDestructor< - base::SequenceLocalStorageSlot<std::unique_ptr<::media::MediaService>>> + static base::SequenceLocalStorageSlot<std::unique_ptr<::media::MediaService>> service; - service->emplace(::media::CreateMediaServiceForTesting( + service.emplace(::media::CreateMediaServiceForTesting( remote.BindNewPipeAndPassReceiver())); #endif return remote;
diff --git a/content/test/data/accessibility/html/video-text-only-expected-blink.txt b/content/test/data/accessibility/html/video-text-only-expected-blink.txt index c38319c..344d39f 100644 --- a/content/test/data/accessibility/html/video-text-only-expected-blink.txt +++ b/content/test/data/accessibility/html/video-text-only-expected-blink.txt
@@ -3,45 +3,123 @@ ++++genericContainer ++++++video name='Unable to play media.' restriction=disabled ++++++++genericContainer ignored +++++++++++genericContainer ignored invisible ++++++++++genericContainer ignored +++++++++++++button ignored invisible ++++++++++genericContainer ignored +++++++++++++genericContainer ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++button ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored name='0:00' +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored name='/ 0:00' +++++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++genericContainer ignored invisible +++++++++++++++++++slider ignored invisible +++++++++++++++++++button ignored invisible +++++++++++++++++button ignored invisible +++++++++++++++++button ignored invisible +++++++++++++++slider ignored invisible ++++++++++menu ignored invisible ++++++++++menu ignored invisible ++++++++++menu ignored invisible -++++++++++++button ignored invisible -++++++++++++genericContainer ignored invisible -++++++++++++button ignored invisible -++++++++++++genericContainer ignored invisible -++++++++++++button ignored invisible -++++++++++++genericContainer ignored invisible -++++++++++++button ignored invisible -++++++++++++genericContainer ignored invisible -++++++++++++button ignored invisible -++++++++++++genericContainer ignored invisible -++++++++++++button ignored invisible -++++++++++++genericContainer ignored invisible -++++++++++++button ignored invisible -++++++++++++genericContainer ignored invisible +++++++++++++menuItem ignored invisible +++++++++++++++button ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored invisible name='Play' +++++++++++++menuItem ignored invisible +++++++++++++++button ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored invisible name='Fullscreen' +++++++++++++menuItem ignored invisible +++++++++++++++button ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored invisible name='Download' +++++++++++++menuItem ignored invisible +++++++++++++++button ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored invisible name='Mute' +++++++++++++menuItem ignored invisible +++++++++++++++button ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored invisible name='Cast' +++++++++++++menuItem ignored invisible +++++++++++++++button ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored invisible name='Captions' +++++++++++++menuItem ignored invisible +++++++++++++++button ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored invisible name='Picture in picture' ++++++staticText name=' ' ++++++++inlineTextBox name=' ' ++++++video name='Unable to play media.' restriction=disabled ++++++++genericContainer ignored +++++++++++genericContainer ignored invisible ++++++++++genericContainer ignored +++++++++++++button ignored invisible ++++++++++genericContainer ignored +++++++++++++genericContainer ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++button ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored name='0:00' +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored name='/ 0:00' +++++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++genericContainer ignored invisible +++++++++++++++++++slider ignored invisible +++++++++++++++++++button ignored invisible +++++++++++++++++button ignored invisible +++++++++++++++++button ignored invisible +++++++++++++++slider ignored invisible ++++++++++menu ignored invisible ++++++++++menu ignored invisible ++++++++++menu ignored invisible -++++++++++++button ignored invisible -++++++++++++genericContainer ignored invisible -++++++++++++button ignored invisible -++++++++++++genericContainer ignored invisible -++++++++++++button ignored invisible -++++++++++++genericContainer ignored invisible -++++++++++++button ignored invisible -++++++++++++genericContainer ignored invisible -++++++++++++button ignored invisible -++++++++++++genericContainer ignored invisible -++++++++++++button ignored invisible -++++++++++++genericContainer ignored invisible -++++++++++++button ignored invisible -++++++++++++genericContainer ignored invisible +++++++++++++menuItem ignored invisible +++++++++++++++button ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored invisible name='Play' +++++++++++++menuItem ignored invisible +++++++++++++++button ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored invisible name='Fullscreen' +++++++++++++menuItem ignored invisible +++++++++++++++button ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored invisible name='Download' +++++++++++++menuItem ignored invisible +++++++++++++++button ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored invisible name='Mute' +++++++++++++menuItem ignored invisible +++++++++++++++button ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored invisible name='Cast' +++++++++++++menuItem ignored invisible +++++++++++++++button ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored invisible name='Captions' +++++++++++++menuItem ignored invisible +++++++++++++++button ignored invisible +++++++++++++++genericContainer ignored invisible +++++++++++++++++genericContainer ignored invisible +++++++++++++++++++staticText ignored invisible name='Picture in picture'
diff --git a/content/test/data/android/scroll_element_offscreen.html b/content/test/data/android/scroll_element_offscreen.html new file mode 100644 index 0000000..09943d00 --- /dev/null +++ b/content/test/data/android/scroll_element_offscreen.html
@@ -0,0 +1,24 @@ +<!-- Simple test page to scroll an element partially off-screen and check bounding box --> +<html> + <head> + <script> + function scrollUp() { + window.scrollBy(0,200); + } + + function createText() { + var containingDiv = document.getElementById("scroll_view"); + for (i = 0; i < 100; i++) { + var paragraph = document.createElement('p'); + paragraph.innerHTML = "Example Text " + i; + + containingDiv.appendChild(paragraph); + } + } + </script> + </head> + <body onload="createText()"> + <div id="scroll_view"> + </div> + </body> +</html> \ No newline at end of file
diff --git a/device/vr/android/arcore/arcore_anchor_manager.cc b/device/vr/android/arcore/arcore_anchor_manager.cc index 4c4a466d..e82d31b 100644 --- a/device/vr/android/arcore/arcore_anchor_manager.cc +++ b/device/vr/android/arcore/arcore_anchor_manager.cc
@@ -33,6 +33,13 @@ << anchor_id_to_anchor_info_.size() << ", updated_anchor_ids_.size()=" << updated_anchor_ids_.size(); +#if DCHECK_IS_ON() + DCHECK(was_anchor_data_retrieved_in_current_frame_) + << "Update() must not be called twice in a row without a call to " + "GetAnchorsData() in between"; + was_anchor_data_retrieved_in_current_frame_ = false; +#endif + std::vector<uint64_t> all_anchors_ids; all_anchors_ids.reserve(anchor_id_to_anchor_info_.size()); for (const auto& anchor_id_and_object : anchor_id_to_anchor_info_) { @@ -66,6 +73,10 @@ } } +#if DCHECK_IS_ON() + was_anchor_data_retrieved_in_current_frame_ = true; +#endif + return mojom::XRAnchorsData::New(std::move(all_anchors_ids), std::move(updated_anchors)); }
diff --git a/device/vr/android/arcore/arcore_anchor_manager.h b/device/vr/android/arcore/arcore_anchor_manager.h index 8bbcacc..449a20c 100644 --- a/device/vr/android/arcore/arcore_anchor_manager.h +++ b/device/vr/android/arcore/arcore_anchor_manager.h
@@ -29,8 +29,7 @@ ~ArCoreAnchorManager(); // Updates anchor manager state - it should be called in every frame if the - // ARCore session supports anchors. Currently, all ARCore sessions support - // anchors. + // ARCore session has anchors feature enabled. void Update(ArFrame* ar_frame); mojom::XRAnchorsDataPtr GetAnchorsData() const; @@ -87,6 +86,17 @@ // Set containing IDs of anchors updated in the last frame. It should be // modified only during calls to |Update()|. std::set<AnchorId> updated_anchor_ids_; + +#if DCHECK_IS_ON() + // True if |GetAnchorsData()| was called after |Update()|. It is used to track + // if |Update()| was called twice in a row w/o a call to |GetAnchorsData()| in + // between. Initially true since we expect the call to |Update()| to happen + // next. + // TODO(https://crbug.com/1192844): remove the assumption that the calls to + // |Update()| will always be followed by at least one call to + // |GetAnchorsData()| before the next call to |Update()| happens. + mutable bool was_anchor_data_retrieved_in_current_frame_ = true; +#endif }; } // namespace device
diff --git a/device/vr/android/arcore/arcore_impl.cc b/device/vr/android/arcore/arcore_impl.cc index 0c27a88..54a5609 100644 --- a/device/vr/android/arcore/arcore_impl.cc +++ b/device/vr/android/arcore/arcore_impl.cc
@@ -875,6 +875,8 @@ } mojom::VRPosePtr ArCoreImpl::Update(bool* camera_updated) { + DVLOG(3) << __func__; + TRACE_EVENT0("gpu", "ArCoreImpl Update"); DCHECK(IsOnGlThread()); @@ -882,10 +884,9 @@ DCHECK(arcore_frame_.is_valid()); DCHECK(camera_updated); - ArStatus status; - TRACE_EVENT_BEGIN0("gpu", "ArCore Update"); - status = ArSession_update(arcore_session_.get(), arcore_frame_.get()); + ArStatus status = + ArSession_update(arcore_session_.get(), arcore_frame_.get()); TRACE_EVENT_END0("gpu", "ArCore Update"); if (status != AR_SUCCESS) { @@ -894,8 +895,15 @@ return nullptr; } - // TODO(https://crbug.com/1192844): If the call was successful, we should - // Update() the ArCore entity managers. + if (plane_manager_) { + TRACE_EVENT0("gpu", "ArCorePlaneManager Update"); + plane_manager_->Update(arcore_frame_.get()); + } + + if (anchor_manager_) { + TRACE_EVENT0("gpu", "ArCoreAnchorManager Update"); + anchor_manager_->Update(arcore_frame_.get()); + } // If we get here, assume we have a valid camera image, but we don't know yet // if tracking is working. @@ -954,16 +962,6 @@ auto mojo_from_viewer = GetMojomVRPoseFromArPose(arcore_session_.get(), arcore_pose.get()); - if (plane_manager_) { - TRACE_EVENT0("gpu", "ArCorePlaneManager Update"); - plane_manager_->Update(arcore_frame_.get()); - } - - if (anchor_manager_) { - TRACE_EVENT0("gpu", "ArCoreAnchorManager Update"); - anchor_manager_->Update(arcore_frame_.get()); - } - return mojo_from_viewer; } @@ -1188,6 +1186,10 @@ case mojom::XRNativeOriginInformation::Tag::HAND_JOINT_SPACE_INFO: // Unsupported by ARCore: return absl::nullopt; + case mojom::XRNativeOriginInformation::Tag::IMAGE_INDEX: + // TODO(https://crbug.com/1143575): Add hit test support for tracked + // images. + return absl::nullopt; case mojom::XRNativeOriginInformation::Tag::ANCHOR_ID: // Validate that we know which anchor's space the hit test is interested // in tracking. @@ -1427,6 +1429,10 @@ : false; case mojom::XRNativeOriginInformation::Tag::HAND_JOINT_SPACE_INFO: return false; + case mojom::XRNativeOriginInformation::Tag::IMAGE_INDEX: + // TODO(https://crbug.com/1143575): Needed for anchor creation relaitve to + // tracked images. + return false; } } @@ -1472,6 +1478,11 @@ : absl::nullopt; case mojom::XRNativeOriginInformation::Tag::HAND_JOINT_SPACE_INFO: return absl::nullopt; + + case mojom::XRNativeOriginInformation::Tag::IMAGE_INDEX: + // TODO(https://crbug.com/1143575): Needed for hit test and anchors + // support for tracked images. + return absl::nullopt; } }
diff --git a/device/vr/android/arcore/arcore_plane_manager.cc b/device/vr/android/arcore/arcore_plane_manager.cc index d77ba65..23bc273 100644 --- a/device/vr/android/arcore/arcore_plane_manager.cc +++ b/device/vr/android/arcore/arcore_plane_manager.cc
@@ -126,6 +126,13 @@ } void ArCorePlaneManager::Update(ArFrame* ar_frame) { +#if DCHECK_IS_ON() + DCHECK(was_plane_data_retrieved_in_current_frame_) + << "Update() must not be called twice in a row without a call to " + "GetDetectedPlanesData() in between"; + was_plane_data_retrieved_in_current_frame_ = false; +#endif + ArTrackableType plane_tracked_type = AR_TRACKABLE_PLANE; // First, ask ARCore about all Plane trackables updated in the current frame. @@ -196,12 +203,17 @@ return !base::Contains(new_plane_id_to_plane_info, plane_address_and_id.second); }); + plane_id_to_plane_info_.swap(new_plane_id_to_plane_info); updated_plane_ids_.swap(updated_plane_ids); } mojom::XRPlaneDetectionDataPtr ArCorePlaneManager::GetDetectedPlanesData() const { + DVLOG(3) << __func__ << ": plane_id_to_plane_info_.size()=" + << plane_id_to_plane_info_.size() + << ", updated_plane_ids_.size()=" << updated_plane_ids_.size(); + std::vector<uint64_t> all_plane_ids; all_plane_ids.reserve(plane_id_to_plane_info_.size()); for (const auto& plane_id_and_object : plane_id_to_plane_info_) { @@ -261,6 +273,10 @@ } } +#if DCHECK_IS_ON() + was_plane_data_retrieved_in_current_frame_ = true; +#endif + return mojom::XRPlaneDetectionData::New(std::move(all_plane_ids), std::move(updated_planes)); }
diff --git a/device/vr/android/arcore/arcore_plane_manager.h b/device/vr/android/arcore/arcore_plane_manager.h index 771f532..4c0e0ba 100644 --- a/device/vr/android/arcore/arcore_plane_manager.h +++ b/device/vr/android/arcore/arcore_plane_manager.h
@@ -103,6 +103,17 @@ // Set containing IDs of planes updated in the last frame. It should be // modified only during calls to |Update()|. std::set<PlaneId> updated_plane_ids_; + +#if DCHECK_IS_ON() + // True if |GetDetectedPlanesData()| was called after |Update()|. It is used + // to track if |Update()| was called twice in a row w/o a call to + // |GetDetectedPlanesData()| in between. Initially true since we expect the + // call to |Update()| to happen next. + // TODO(https://crbug.com/1192844): remove the assumption that the calls to + // |Update()| will always be followed by at least one call to + // |GetDetectedPlanesData()| before the next call to |Update()| happens. + mutable bool was_plane_data_retrieved_in_current_frame_ = true; +#endif }; } // namespace device
diff --git a/device/vr/openxr/openxr_anchor_manager.cc b/device/vr/openxr/openxr_anchor_manager.cc index 111bf9d2..03cb72c 100644 --- a/device/vr/openxr/openxr_anchor_manager.cc +++ b/device/vr/openxr/openxr_anchor_manager.cc
@@ -199,6 +199,7 @@ native_origin_from_anchor); case mojom::XRNativeOriginInformation::Tag::PLANE_ID: case mojom::XRNativeOriginInformation::Tag::HAND_JOINT_SPACE_INFO: + case mojom::XRNativeOriginInformation::Tag::IMAGE_INDEX: // Unsupported for now return absl::nullopt; case mojom::XRNativeOriginInformation::Tag::ANCHOR_ID:
diff --git a/device/vr/openxr/openxr_scene_understanding_manager.cc b/device/vr/openxr/openxr_scene_understanding_manager.cc index 259556a5..1860309 100644 --- a/device/vr/openxr/openxr_scene_understanding_manager.cc +++ b/device/vr/openxr/openxr_scene_understanding_manager.cc
@@ -378,6 +378,8 @@ return absl::nullopt; case mojom::XRNativeOriginInformation::Tag::HAND_JOINT_SPACE_INFO: return absl::nullopt; + case mojom::XRNativeOriginInformation::Tag::IMAGE_INDEX: + return absl::nullopt; } }
diff --git a/device/vr/public/mojom/vr_service.mojom b/device/vr/public/mojom/vr_service.mojom index 6427f99c..5a72941 100644 --- a/device/vr/public/mojom/vr_service.mojom +++ b/device/vr/public/mojom/vr_service.mojom
@@ -514,14 +514,15 @@ // XRReferenceSpaceType, XRBoundedReferenceSpace) or returns an XRSpace (for // example XRAnchor, XRPlane, XRInputSource). Native origin can be identified, // depending on its type, by the id of the entity (this is the case for planes -// and anchors), by reference space type, handedness & joint, or by input source -// id & input source space type. +// and anchors), index (for tracked images), by reference space type, handedness +// & joint, or by input source id & input source space type. union XRNativeOriginInformation { XRInputSourceSpaceInfo input_source_space_info; uint64 plane_id; uint64 anchor_id; XRReferenceSpaceType reference_space_type; XRHandJointSpaceInfo hand_joint_space_info; + uint32 image_index; }; // Input sources have 2 kinds of native origins, each of them backs a different
diff --git a/extensions/browser/extension_action.cc b/extensions/browser/extension_action.cc index 1e931fba..66d4ecf 100644 --- a/extensions/browser/extension_action.cc +++ b/extensions/browser/extension_action.cc
@@ -61,7 +61,7 @@ // SetIcon function arguments. const char* size_string; // Scale factor for which the represantion should be used. - ui::ScaleFactor scale; + ui::ResourceScaleFactor scale; }; template <class T>
diff --git a/extensions/browser/extension_function.cc b/extensions/browser/extension_function.cc index 69ab9ce..d4793b28 100644 --- a/extensions/browser/extension_function.cc +++ b/extensions/browser/extension_function.cc
@@ -16,6 +16,7 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" +#include "base/no_destructor.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" #include "base/trace_event/memory_allocator_dump.h"
diff --git a/extensions/browser/extension_icon_image_unittest.cc b/extensions/browser/extension_icon_image_unittest.cc index e132e1d..8fc50b0 100644 --- a/extensions/browser/extension_icon_image_unittest.cc +++ b/extensions/browser/extension_icon_image_unittest.cc
@@ -29,9 +29,10 @@ namespace extensions { namespace { -SkBitmap CreateBlankBitmapForScale(int size_dip, ui::ScaleFactor scale_factor) { +SkBitmap CreateBlankBitmapForScale(int size_dip, + ui::ResourceScaleFactor scale_factor) { SkBitmap bitmap; - const float scale = ui::GetScaleForScaleFactor(scale_factor); + const float scale = ui::GetScaleForResourceScaleFactor(scale_factor); bitmap.allocN32Pixels(static_cast<int>(size_dip * scale), static_cast<int>(size_dip * scale)); bitmap.eraseColor(SkColorSetARGB(0, 0, 0, 0)); @@ -134,10 +135,11 @@ } // namespace TEST_F(ExtensionIconImageTest, Basic) { - std::vector<ui::ScaleFactor> supported_factors; + std::vector<ui::ResourceScaleFactor> supported_factors; supported_factors.push_back(ui::SCALE_FACTOR_100P); supported_factors.push_back(ui::SCALE_FACTOR_200P); - ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors); + ui::test::ScopedSetSupportedResourceScaleFactors scoped_supported( + supported_factors); scoped_refptr<Extension> extension(CreateExtension( "extension_icon_image", ManifestLocation::kInvalidLocation)); ASSERT_TRUE(extension.get() != nullptr); @@ -208,10 +210,11 @@ // There is no resource with either exact or bigger size, but there is a smaller // resource. TEST_F(ExtensionIconImageTest, FallbackToSmallerWhenNoBigger) { - std::vector<ui::ScaleFactor> supported_factors; + std::vector<ui::ResourceScaleFactor> supported_factors; supported_factors.push_back(ui::SCALE_FACTOR_100P); supported_factors.push_back(ui::SCALE_FACTOR_200P); - ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors); + ui::test::ScopedSetSupportedResourceScaleFactors scoped_supported( + supported_factors); scoped_refptr<Extension> extension(CreateExtension( "extension_icon_image", ManifestLocation::kInvalidLocation)); ASSERT_TRUE(extension.get() != nullptr);
diff --git a/extensions/browser/image_loader.cc b/extensions/browser/image_loader.cc index ec061ddc..c738684c 100644 --- a/extensions/browser/image_loader.cc +++ b/extensions/browser/image_loader.cc
@@ -239,8 +239,8 @@ std::vector<ImageRepresentation> info_list; std::set<float> scales; - for (auto scale : ui::GetSupportedScaleFactors()) - scales.insert(ui::GetScaleForScaleFactor(scale)); + for (auto scale : ui::GetSupportedResourceScaleFactors()) + scales.insert(ui::GetScaleForResourceScaleFactor(scale)); // There may not be a screen in unit tests. auto* screen = display::Screen::GetScreen();
diff --git a/extensions/renderer/script_context.cc b/extensions/renderer/script_context.cc index d44ac6a..6ffc155 100644 --- a/extensions/renderer/script_context.cc +++ b/extensions/renderer/script_context.cc
@@ -8,6 +8,7 @@ #include "base/containers/contains.h" #include "base/containers/flat_set.h" #include "base/logging.h" +#include "base/no_destructor.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/values.h"
diff --git a/extensions/shell/common/shell_content_client.cc b/extensions/shell/common/shell_content_client.cc index 422734cf..18deacb1 100644 --- a/extensions/shell/common/shell_content_client.cc +++ b/extensions/shell/common/shell_content_client.cc
@@ -88,7 +88,7 @@ base::StringPiece ShellContentClient::GetDataResource( int resource_id, - ui::ScaleFactor scale_factor) { + ui::ResourceScaleFactor scale_factor) { return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale( resource_id, scale_factor); }
diff --git a/extensions/shell/common/shell_content_client.h b/extensions/shell/common/shell_content_client.h index 06db44e..7ea87ce 100644 --- a/extensions/shell/common/shell_content_client.h +++ b/extensions/shell/common/shell_content_client.h
@@ -21,8 +21,9 @@ std::vector<content::PepperPluginInfo>* plugins) override; void AddAdditionalSchemes(Schemes* schemes) override; std::u16string GetLocalizedString(int message_id) override; - base::StringPiece GetDataResource(int resource_id, - ui::ScaleFactor scale_factor) override; + base::StringPiece GetDataResource( + int resource_id, + ui::ResourceScaleFactor scale_factor) override; base::RefCountedMemory* GetDataResourceBytes(int resource_id) override; gfx::Image& GetNativeImageNamed(int resource_id) override;
diff --git a/fuchsia/engine/DEPS b/fuchsia/engine/DEPS index c9c4265..c4accdd 100644 --- a/fuchsia/engine/DEPS +++ b/fuchsia/engine/DEPS
@@ -19,6 +19,7 @@ "+third_party/blink/public/common/switches.h", "+third_party/widevine/cdm/widevine_cdm_common.h", "+ui/base", + "+ui/display/display_switches.h", "+ui/gfx", "+ui/gl/gl_switches.h", "+ui/ozone/public",
diff --git a/fuchsia/engine/browser/accessibility_bridge.cc b/fuchsia/engine/browser/accessibility_bridge.cc index 7bc6fbf..3179b236 100644 --- a/fuchsia/engine/browser/accessibility_bridge.cc +++ b/fuchsia/engine/browser/accessibility_bridge.cc
@@ -26,7 +26,7 @@ constexpr size_t kMaxNodesPerUpdate = 16; constexpr size_t kMaxNodesPerDelete = - fuchsia::accessibility::semantics::MAX_NODES_PER_UPDATE - 1; + fuchsia::accessibility::semantics::MAX_NODES_PER_UPDATE; // Error allowed for each edge when converting from gfx::RectF to gfx::Rect. constexpr float kRectConversionError = 0.5; @@ -47,29 +47,6 @@ return offset_container_id; } -// Applies |op| to elements of |items| in batches. Maximum batch size is set -// by |batch_size|. -template <typename T> -inline void BatchApply(std::vector<T> items, - size_t batch_size, - base::RepeatingCallback<void(std::vector<T>)> op) { - const size_t total_items = items.size(); - if (total_items == 0) { - return; - } - - std::vector<T> batch; - batch.reserve(batch_size); - for (size_t current = 0; current < total_items; current += batch_size) { - const size_t next_batch_size = std::min(total_items - current, batch_size); - std::move(items.begin() + current, - items.begin() + current + next_batch_size, - std::back_inserter(batch)); - op.Run(std::move(batch)); - batch.clear(); - } -} - } // namespace AccessibilityBridge::AccessibilityBridge( @@ -159,28 +136,25 @@ void AccessibilityBridge::TryCommit() { if (commit_inflight_ || (to_delete_.empty() && to_update_.empty()) || - ShouldHoldCommit()) + ShouldHoldCommit()) { return; + } // Deletions come before updates because first the nodes are deleted, and // then we update the parents to no longer point at them. - BatchApply( - std::move(to_delete_), kMaxNodesPerDelete, - base::BindRepeating( - &fuchsia::accessibility::semantics::SemanticTree::DeleteSemanticNodes, - base::Unretained(semantic_tree_.get()))); + for (auto& batch : to_delete_) { + semantic_tree_->DeleteSemanticNodes(std::move(batch)); + } + to_delete_.clear(); - BatchApply( - std::move(to_update_), kMaxNodesPerUpdate, - base::BindRepeating( - &fuchsia::accessibility::semantics::SemanticTree::UpdateSemanticNodes, - base::Unretained(semantic_tree_.get()))); + for (auto& batch : to_update_) { + semantic_tree_->UpdateSemanticNodes(std::move(batch)); + } + to_update_.clear(); semantic_tree_->CommitUpdates( fit::bind_member(this, &AccessibilityBridge::OnCommitComplete)); commit_inflight_ = true; - to_delete_.clear(); - to_update_.clear(); } void AccessibilityBridge::OnCommitComplete() { @@ -380,7 +354,7 @@ void AccessibilityBridge::OnNodeDeleted(ui::AXTree* tree, int32_t node_id) { DCHECK(tree); - to_delete_.push_back( + AppendToDeleteList( id_mapper_->ToFuchsiaNodeID(tree->GetAXTreeID(), node_id, false)); } @@ -429,8 +403,8 @@ // that OnAtomicUpdateFinished() is called, offset_container_children_ will // be correct, so we can simply overwrite the existing update. auto* fuchsia_node = - GetUpdatedNode(tree->GetAXTreeID(), child_node->data().id, - /*replace_existing=*/true); + EnsureAndGetUpdatedNode(tree->GetAXTreeID(), child_node->data().id, + /*replace_existing=*/true); DCHECK(fuchsia_node); } } @@ -461,8 +435,8 @@ // there's an existing update for this node from OnNodeDataChanged(). This // update may not have the correct offset container and/or transform, so we // should replace it. - auto* fuchsia_node = GetUpdatedNode(tree->GetAXTreeID(), node.id, - /*replace_existing=*/true); + auto* fuchsia_node = EnsureAndGetUpdatedNode(tree->GetAXTreeID(), node.id, + /*replace_existing=*/true); DCHECK(fuchsia_node); if (node.HasStringAttribute(ax::mojom::StringAttribute::kChildTreeId)) { @@ -547,8 +521,9 @@ if (kv.second.is_connected) continue; // No work to do, trees connected and present. - auto* fuchsia_node = GetUpdatedNode(parent_ax_tree_id, ax_node->id(), - /*replace_existing=*/false); + auto* fuchsia_node = + EnsureAndGetUpdatedNode(parent_ax_tree_id, ax_node->id(), + /*replace_existing=*/false); DCHECK(fuchsia_node); // Now, the connection really happens: // This node, from the parent tree, will have a child that points to the @@ -577,21 +552,22 @@ // data changed. This makes sure that it contains the focus information. If // it is not part of the current update, no need to send this information, // as it is redundant. - auto* node = - focus_changed - ? GetUpdatedNode(new_focused_node->first, new_focused_node->second, - /*replace_existing=*/false) - : GetNodeIfChangingInUpdate(new_focused_node->first, - new_focused_node->second); + auto* node = focus_changed + ? EnsureAndGetUpdatedNode(new_focused_node->first, + new_focused_node->second, + /*replace_existing=*/false) + : GetNodeIfChangingInUpdate(new_focused_node->first, + new_focused_node->second); if (node) node->mutable_states()->set_has_input_focus(true); } if (last_focused_node_id_) { - auto* node = focus_changed ? GetUpdatedNode(last_focused_node_id_->first, - last_focused_node_id_->second, - /*replace_existing=*/false) - : nullptr /*already updated above*/; + auto* node = focus_changed + ? EnsureAndGetUpdatedNode(last_focused_node_id_->first, + last_focused_node_id_->second, + /*replace_existing=*/false) + : nullptr /*already updated above*/; if (node) node->mutable_states()->set_has_input_focus(false); } @@ -738,25 +714,44 @@ return std::make_pair(tree->GetAXTreeID(), node->id()); } +void AccessibilityBridge::AppendToDeleteList(uint32_t node_id) { + if (to_delete_.empty() || to_delete_.back().size() == kMaxNodesPerDelete) { + to_delete_.emplace_back(); + } + to_delete_.back().push_back(std::move(node_id)); +} + +void AccessibilityBridge::AppendToUpdateList( + fuchsia::accessibility::semantics::Node node) { + if (to_update_.empty() || to_update_.back().size() == kMaxNodesPerUpdate) { + to_update_.emplace_back(); + } + to_update_.back().push_back(std::move(node)); +} + fuchsia::accessibility::semantics::Node* AccessibilityBridge::GetNodeIfChangingInUpdate(const ui::AXTreeID& tree_id, ui::AXNodeID node_id) { auto fuchsia_node_id = id_mapper_->ToFuchsiaNodeID(tree_id, node_id, false); - auto result = std::find_if( - to_update_.rbegin(), to_update_.rend(), - [&fuchsia_node_id](const fuchsia::accessibility::semantics::Node& node) { - return node.node_id() == fuchsia_node_id; - }); - if (result == to_update_.rend()) - return nullptr; - return &(*result); + for (auto& update_batch : to_update_) { + auto result = + std::find_if(update_batch.rbegin(), update_batch.rend(), + [&fuchsia_node_id]( + const fuchsia::accessibility::semantics::Node& node) { + return node.node_id() == fuchsia_node_id; + }); + if (result != update_batch.rend()) + return &(*result); + } + + return nullptr; } -fuchsia::accessibility::semantics::Node* AccessibilityBridge::GetUpdatedNode( - const ui::AXTreeID& tree_id, - ui::AXNodeID node_id, - bool replace_existing) { +fuchsia::accessibility::semantics::Node* +AccessibilityBridge::EnsureAndGetUpdatedNode(const ui::AXTreeID& tree_id, + ui::AXNodeID node_id, + bool replace_existing) { auto* fuchsia_node = GetNodeIfChangingInUpdate(tree_id, node_id); if (fuchsia_node && !replace_existing) return fuchsia_node; @@ -785,6 +780,6 @@ return fuchsia_node; } - to_update_.push_back(std::move(new_fuchsia_node)); - return &to_update_.back(); + AppendToUpdateList(std::move(new_fuchsia_node)); + return &to_update_.back().back(); }
diff --git a/fuchsia/engine/browser/accessibility_bridge.h b/fuchsia/engine/browser/accessibility_bridge.h index 48287f0..2b77843 100644 --- a/fuchsia/engine/browser/accessibility_bridge.h +++ b/fuchsia/engine/browser/accessibility_bridge.h
@@ -161,7 +161,7 @@ // existing update for the node (if one exists). // // Returns nullptr if the node does not exist. - fuchsia::accessibility::semantics::Node* GetUpdatedNode( + fuchsia::accessibility::semantics::Node* EnsureAndGetUpdatedNode( const ui::AXTreeID& tree_id, ui::AXNodeID node_id, bool replace_existing); @@ -171,6 +171,12 @@ absl::optional<AXNodeID> GetFocusFromThisOrDescendantFrame( const ui::AXSerializableTree* tree) const; + // Enqueues |node_id| for deletion in the subsequent tree update. + void AppendToDeleteList(uint32_t node_id); + + // Enqueues changes to |node| in the subsequent tree update. + void AppendToUpdateList(fuchsia::accessibility::semantics::Node node); + // content::WebContentsObserver implementation. void AccessibilityEventReceived( const content::AXEventNotificationDetails& details) override; @@ -225,9 +231,9 @@ // Whether semantic updates are enabled. bool enable_semantic_updates_ = false; - // Cache for pending data to be sent to the Semantic Tree between commits. - std::vector<uint32_t> to_delete_; - std::vector<fuchsia::accessibility::semantics::Node> to_update_; + // Buffer for pending data to be sent to the Semantic Tree between commits. + std::vector<std::vector<uint32_t>> to_delete_; + std::vector<std::vector<fuchsia::accessibility::semantics::Node>> to_update_; bool commit_inflight_ = false; // Maintain a map from AXNode IDs to a list of the AXNode IDs of descendant
diff --git a/fuchsia/engine/browser/frame_impl.cc b/fuchsia/engine/browser/frame_impl.cc index 34a11c7..533c51e 100644 --- a/fuchsia/engine/browser/frame_impl.cc +++ b/fuchsia/engine/browser/frame_impl.cc
@@ -176,8 +176,8 @@ base::small_map<std::map<content::WebContents*, FrameImpl*>>; FrameImplMap& WebContentsToFrameImplMap() { - static base::NoDestructor<FrameImplMap> frame_impl_map; - return *frame_impl_map; + static FrameImplMap frame_impl_map; + return frame_impl_map; } content::PermissionType FidlPermissionTypeToContentPermissionType(
diff --git a/fuchsia/engine/web_instance_host/web_instance_host.cc b/fuchsia/engine/web_instance_host/web_instance_host.cc index 1b2e53d5..adbc3763c 100644 --- a/fuchsia/engine/web_instance_host/web_instance_host.cc +++ b/fuchsia/engine/web_instance_host/web_instance_host.cc
@@ -61,6 +61,7 @@ #include "services/network/public/cpp/network_switches.h" #include "third_party/blink/public/common/switches.h" #include "third_party/widevine/cdm/widevine_cdm_common.h" +#include "ui/display/display_switches.h" #include "ui/gfx/switches.h" #include "ui/gl/gl_switches.h" #include "ui/ozone/public/ozone_switches.h" @@ -331,6 +332,7 @@ switches::kEnableCastStreamingReceiver, switches::kEnableFeatures, switches::kEnableLowEndDeviceMode, + switches::kForceDeviceScaleFactor, switches::kForceGpuMemAvailableMb, switches::kForceGpuMemDiscardableLimitMb, switches::kForceMaxTextureSize,
diff --git a/google_apis/BUILD.gn b/google_apis/BUILD.gn index fddf591..a0ec864 100644 --- a/google_apis/BUILD.gn +++ b/google_apis/BUILD.gn
@@ -243,6 +243,7 @@ "//base/test:test_support", "//build:branding_buildflags", "//build:chromeos_buildflags", + "//google_apis/calendar:calendar_unittests", "//testing/gmock", "//testing/gtest", ] @@ -253,6 +254,11 @@ data = [ "test/" ] } + if (is_fuchsia) { + additional_manifest_fragments = + [ "//build/config/fuchsia/test/network_capabilities.test-cmx" ] + } + if (enable_extensions) { deps += [ "//google_apis/drive:drive_unittests" ] } @@ -267,6 +273,8 @@ bundle_data("google_apis_unittest_bundle_data") { testonly = true sources = [ + "test/data/calendar/events.json", + "test/data/calendar/invalid_events.json", "test/data/gaia/all_base_urls.json", "test/data/gaia/all_urls.json", "test/data/gaia/api_keys.json",
diff --git a/google_apis/calendar/BUILD.gn b/google_apis/calendar/BUILD.gn new file mode 100644 index 0000000..5fb7f58 --- /dev/null +++ b/google_apis/calendar/BUILD.gn
@@ -0,0 +1,64 @@ +# Copyright 2021 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. + +import("//build/config/features.gni") +import("//testing/test.gni") + +static_library("calendar") { + sources = [ + "calendar_api_requests.cc", + "calendar_api_requests.h", + "calendar_api_response_types.cc", + "calendar_api_response_types.h", + "calendar_api_url_generator.cc", + "calendar_api_url_generator.h", + ] + + deps = [ + "//base", + "//base/third_party/dynamic_annotations", + "//components/signin/public/identity_manager", + "//crypto", + "//google_apis:google_apis", + "//google_apis/drive:drive", + "//net", + "//services/network/public/cpp", + ] +} + +source_set("test_support") { + testonly = true + + sources = [] + + public_deps = [ + ":calendar", + "//base", + "//base/test:test_support", + "//google_apis:test_support", + "//google_apis/drive:drive", + "//google_apis/drive:test_support", + "//net:test_support", + ] +} + +source_set("calendar_unittests") { + testonly = true + + sources = [ + "calendar_api_requests_unittest.cc", + "calendar_api_response_types_unittest.cc", + "calendar_api_url_generator_unittest.cc", + ] + + deps = [ + ":calendar", + ":test_support", + "//base", + "//base/test:test_support", + "//services/network:test_support", + "//testing/gmock", + "//testing/gtest", + ] +}
diff --git a/google_apis/calendar/DEPS b/google_apis/calendar/DEPS new file mode 100644 index 0000000..c30fdc3 --- /dev/null +++ b/google_apis/calendar/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+third_party/googletest/src/googletest/include/gtest/gtest.h", +] \ No newline at end of file
diff --git a/google_apis/calendar/calendar_api_requests.cc b/google_apis/calendar/calendar_api_requests.cc new file mode 100644 index 0000000..a85931d --- /dev/null +++ b/google_apis/calendar/calendar_api_requests.cc
@@ -0,0 +1,98 @@ +// Copyright 2021 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. + +#include "google_apis/calendar/calendar_api_requests.h" + +#include <stddef.h> + +#include "base/task_runner_util.h" +#include "net/base/url_util.h" + +namespace google_apis { + +namespace calendar { + +const char kCalendarEventListFields[] = + "timeZone,etag,kind,items(id,summary,colorId, " + "status,start(dateTime),end(dateTime),htmlLink)"; + +CalendarApiGetRequest::CalendarApiGetRequest(RequestSender* sender, + const std::string& fields) + : UrlFetchRequestBase(sender, ProgressCallback(), ProgressCallback()), + fields_(fields) {} + +CalendarApiGetRequest::~CalendarApiGetRequest() = default; + +GURL CalendarApiGetRequest::GetURL() const { + GURL url = GetURLInternal(); + if (!fields_.empty()) + url = net::AppendOrReplaceQueryParameter(url, "fields", fields_); + return url; +} + +CalendarApiEventsRequest::CalendarApiEventsRequest( + RequestSender* sender, + const CalendarApiUrlGenerator& url_generator, + CalendarEventListCallback callback, + const base::Time& start_time, + const base::Time& end_time) + : CalendarApiGetRequest(sender, kCalendarEventListFields), + callback_(std::move(callback)), + url_generator_(url_generator), + start_time_(start_time), + end_time_(end_time) { + DCHECK(!callback_.is_null()); +} + +CalendarApiEventsRequest::~CalendarApiEventsRequest() = default; + +GURL CalendarApiEventsRequest::GetURLInternal() const { + return url_generator_.GetCalendarEventListUrl(start_time_, end_time_); +} + +void CalendarApiEventsRequest::ProcessURLFetchResults( + const network::mojom::URLResponseHead* response_head, + base::FilePath response_file, + std::string response_body) { + // TODO(https://crbug.com/1222483): use common error code. + DriveApiErrorCode error = GetErrorCode(); + switch (error) { + case HTTP_SUCCESS: + base::PostTaskAndReplyWithResult( + blocking_task_runner(), FROM_HERE, + base::BindOnce(&CalendarApiEventsRequest::Parse, + std::move(response_body)), + base::BindOnce(&CalendarApiEventsRequest::OnDataParsed, + weak_ptr_factory_.GetWeakPtr(), error)); + break; + default: + RunCallbackOnPrematureFailure(error); + OnProcessURLFetchResultsComplete(); + break; + } +} + +void CalendarApiEventsRequest::OnDataParsed(DriveApiErrorCode error, + std::unique_ptr<EventList> events) { + // TODO(https://crbug.com/1222483): use common error code. + if (!events) + error = DRIVE_PARSE_ERROR; + std::move(callback_).Run(error, std::move(events)); + OnProcessURLFetchResultsComplete(); +} + +void CalendarApiEventsRequest::RunCallbackOnPrematureFailure( + DriveApiErrorCode error) { + std::move(callback_).Run(error, std::unique_ptr<EventList>()); +} + +// static +std::unique_ptr<EventList> CalendarApiEventsRequest::Parse(std::string json) { + std::unique_ptr<base::Value> value = ParseJson(json); + + return value ? EventList::CreateFrom(*value) : nullptr; +} + +} // namespace calendar +} // namespace google_apis
diff --git a/google_apis/calendar/calendar_api_requests.h b/google_apis/calendar/calendar_api_requests.h new file mode 100644 index 0000000..232bdc5 --- /dev/null +++ b/google_apis/calendar/calendar_api_requests.h
@@ -0,0 +1,96 @@ +// Copyright 2021 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. + +#ifndef GOOGLE_APIS_CALENDAR_CALENDAR_API_REQUESTS_H_ +#define GOOGLE_APIS_CALENDAR_CALENDAR_API_REQUESTS_H_ + +#include "google_apis/calendar/calendar_api_response_types.h" +#include "google_apis/calendar/calendar_api_url_generator.h" +#include "google_apis/drive/base_requests.h" +#include "google_apis/drive/drive_api_error_codes.h" + +namespace google_apis { + +namespace calendar { + +// Callback used for requests that the server returns Events data +// formatted into JSON value. +// TODO(https://crbug.com/1222483): use common error code. +using CalendarEventListCallback = + base::OnceCallback<void(DriveApiErrorCode error, + std::unique_ptr<EventList> events)>; + +// This is base class of the Calendar API related requests. +class CalendarApiGetRequest : public UrlFetchRequestBase { + public: + // `fields` is an optional request parameter that allows you to specify the + // fields you want returned in the response data. Documentation: + // https://developers.google.com/calendar/api/guides/performance?hl=en#partial-response + CalendarApiGetRequest(RequestSender* sender, const std::string& fields); + + CalendarApiGetRequest(const CalendarApiGetRequest&) = delete; + CalendarApiGetRequest& operator=(const CalendarApiGetRequest&) = delete; + ~CalendarApiGetRequest() override; + + protected: + // UrlFetchRequestBase: + GURL GetURL() const override; + + // Derived classes should override GetURLInternal instead of GetURL() + // directly since fields are appended in the GetURL() method. + virtual GURL GetURLInternal() const = 0; + + private: + // Optional parameter in the request. + std::string fields_; +}; + +// Request to fetch calendar events. +class CalendarApiEventsRequest : public CalendarApiGetRequest { + public: + CalendarApiEventsRequest(RequestSender* sender, + const CalendarApiUrlGenerator& url_generator, + CalendarEventListCallback callback, + const base::Time& start_time, + const base::Time& end_time); + CalendarApiEventsRequest(const CalendarApiEventsRequest&) = delete; + CalendarApiEventsRequest& operator=(const CalendarApiEventsRequest&) = delete; + ~CalendarApiEventsRequest() override; + + protected: + // CalendarApiGetRequest: + GURL GetURLInternal() const override; + + // UrlFetchRequestBase: + void ProcessURLFetchResults( + const network::mojom::URLResponseHead* response_head, + const base::FilePath response_file, + std::string response_body) override; + + // TODO(https://crbug.com/1222483): use common error code. + void RunCallbackOnPrematureFailure(DriveApiErrorCode code) override; + + private: + // Parses the |json| string to EventList. + static std::unique_ptr<EventList> Parse(std::string json); + + // Receives the parsed result and invokes the callback. + // TODO(https://crbug.com/1222483): use common error code. + void OnDataParsed(DriveApiErrorCode error, std::unique_ptr<EventList> events); + + CalendarEventListCallback callback_; + const CalendarApiUrlGenerator url_generator_; + + const base::Time start_time_; + const base::Time end_time_; + + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<CalendarApiEventsRequest> weak_ptr_factory_{this}; +}; + +} // namespace calendar +} // namespace google_apis + +#endif // GOOGLE_APIS_CALENDAR_CALENDAR_API_REQUESTS_H_
diff --git a/google_apis/calendar/calendar_api_requests_unittest.cc b/google_apis/calendar/calendar_api_requests_unittest.cc new file mode 100644 index 0000000..36b692c43 --- /dev/null +++ b/google_apis/calendar/calendar_api_requests_unittest.cc
@@ -0,0 +1,121 @@ +// Copyright 2021 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. + +#include "google_apis/calendar/calendar_api_requests.h" + +#include "base/run_loop.h" +#include "base/strings/stringprintf.h" +#include "base/test/task_environment.h" +#include "google_apis/calendar/calendar_api_response_types.h" +#include "google_apis/drive/dummy_auth_service.h" +#include "google_apis/drive/request_sender.h" +#include "google_apis/drive/test_util.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "services/network/test/test_shared_url_loader_factory.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace google_apis { + +namespace calendar { + +namespace { +const char kTestUserAgent[] = "test-user-agent"; +} + +class CalendarApiRequestsTest : public testing::Test { + public: + CalendarApiRequestsTest() + : test_shared_loader_factory_( + base::MakeRefCounted<network::TestSharedURLLoaderFactory>( + nullptr /* network_service */, + true /* is_trusted */)) {} + + void SetUp() override { + request_sender_ = std::make_unique<RequestSender>( + std::make_unique<DummyAuthService>(), test_shared_loader_factory_, + task_environment_.GetMainThreadTaskRunner(), kTestUserAgent, + TRAFFIC_ANNOTATION_FOR_TESTS); + + test_server_.RegisterRequestHandler( + base::BindRepeating(&CalendarApiRequestsTest::HandleDataFileRequest, + base::Unretained(this))); + ASSERT_TRUE(test_server_.Start()); + url_generator_ = std::make_unique<CalendarApiUrlGenerator>(); + url_generator_->SetBaseUrlForTesting(test_server_.base_url().spec()); + } + + void TearDown() override { + // Deleting the sender here will delete all request objects. + request_sender_.reset(); + // Wait for any DeleteSoon tasks to run. + task_environment_.RunUntilIdle(); + } + + base::test::TaskEnvironment task_environment_{ + base::test::TaskEnvironment::MainThreadType::IO}; + net::EmbeddedTestServer test_server_; + std::unique_ptr<RequestSender> request_sender_; + std::unique_ptr<CalendarApiUrlGenerator> url_generator_; + scoped_refptr<network::TestSharedURLLoaderFactory> + test_shared_loader_factory_; + net::test_server::HttpRequest http_request_; + + // Returns the mock calendar event list. + std::unique_ptr<net::test_server::HttpResponse> HandleDataFileRequest( + const net::test_server::HttpRequest& request) { + http_request_ = request; + + // Return the response from the event json file. + return test_util::CreateHttpResponseFromFile( + test_util::GetTestFilePath("calendar/events.json")); + } +}; + +// Tests the CalendarApiRequestsTest can generate the correct url and get the +// correct response. +TEST_F(CalendarApiRequestsTest, GetEventListRequest) { + DriveApiErrorCode error = DRIVE_OTHER_ERROR; + std::unique_ptr<EventList> events; + base::Time start; + base::Time end; + + EXPECT_TRUE(base::Time::FromString("13 Jun 2021 10:00 GMT", &start)); + EXPECT_TRUE(base::Time::FromString("16 Jun 2021 10:00 GMT", &end)); + + { + base::RunLoop run_loop; + auto request = std::make_unique<CalendarApiEventsRequest>( + request_sender_.get(), *url_generator_, + test_util::CreateQuitCallback( + &run_loop, test_util::CreateCopyResultCallback(&error, &events)), + start, end); + + request_sender_->StartRequestWithAuthRetry(std::move(request)); + run_loop.Run(); + } + + EXPECT_EQ(HTTP_SUCCESS, error); + EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method); + EXPECT_EQ( + "/calendar/v3/calendars/primary/" + "events?timeMin=2021-06-13T10%3A00%3A00.000Z" + "&timeMax=2021-06-16T10%3A00%3A00.000Z" + "&fields=timeZone%2Cetag%2Ckind%2C" + "items(id%2Csummary%2CcolorId%2C+status%2C" + "start(dateTime)%2Cend(dateTime)%2ChtmlLink)", + http_request_.relative_url); + + ASSERT_TRUE(events.get()); + + EXPECT_EQ(events->time_zone(), "America/Los_Angeles"); + base::Time::Exploded exploded; + events->items()[0]->start_time().date_time().LocalExplode(&exploded); + EXPECT_EQ(exploded.month, 11); +} + +} // namespace calendar +} // namespace google_apis
diff --git a/google_apis/calendar/calendar_api_response_types.cc b/google_apis/calendar/calendar_api_response_types.cc new file mode 100644 index 0000000..3e57cac --- /dev/null +++ b/google_apis/calendar/calendar_api_response_types.cc
@@ -0,0 +1,139 @@ +// Copyright 2021 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. + +#include "google_apis/calendar/calendar_api_response_types.h" + +#include <stddef.h> + +#include <memory> + +#include "base/json/json_value_converter.h" +#include "base/stl_util.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_piece.h" +#include "base/strings/string_util.h" +#include "base/values.h" +#include "google_apis/drive/time_util.h" + +namespace google_apis { + +namespace calendar { + +namespace { + +// EventList +const char kKind[] = "kind"; +const char kTimeZone[] = "timeZone"; +const char kETag[] = "etag"; +const char kItems[] = "items"; +const char kCalendarEventListKind[] = "calendar#events"; + +// DateTime +const char kDateTime[] = "dateTime"; + +// CalendarEvent +const char kId[] = "id"; +const char kSummary[] = "summary"; +const char kStart[] = "start"; +const char kEnd[] = "end"; +const char kColorId[] = "colorId"; +const char kStatus[] = "status"; +const char kHtmlLink[] = "htmlLink"; +const char kCalendarEventKind[] = "calendar#event"; + +// Checks if the JSON is expected kind. +// TODO(https://crbug.com/1222483): move this to common and share with drive api +// parsers. +bool IsResourceKindExpected(const base::Value& value, + const std::string& expected_kind) { + const std::string* kind = value.FindStringKey(kKind); + return kind && *kind == expected_kind; +} +} // namespace + +DateTime::DateTime() = default; + +DateTime::DateTime(const DateTime& src) = default; + +DateTime& DateTime::operator=(const DateTime& src) = default; + +DateTime::~DateTime() = default; + +// static +void DateTime::RegisterJSONConverter( + base::JSONValueConverter<DateTime>* converter) { + converter->RegisterCustomField<base::Time>(kDateTime, &DateTime::date_time_, + &util::GetTimeFromString); +} + +// static +bool DateTime::CreateDateTimeFromValue(const base::Value* value, + DateTime* time) { + base::JSONValueConverter<DateTime> converter; + if (!converter.Convert(*value, time)) { + DVLOG(1) << "Unable to create: Invalid DateTime JSON!"; + return false; + } + return true; +} + +CalendarEvent::CalendarEvent() = default; + +CalendarEvent::~CalendarEvent() = default; + +// static +void CalendarEvent::RegisterJSONConverter( + base::JSONValueConverter<CalendarEvent>* converter) { + converter->RegisterStringField(kId, &CalendarEvent::id_); + converter->RegisterStringField(kSummary, &CalendarEvent::summary_); + converter->RegisterStringField(kHtmlLink, &CalendarEvent::html_link_); + converter->RegisterStringField(kColorId, &CalendarEvent::color_id_); + converter->RegisterStringField(kStatus, &CalendarEvent::status_); + converter->RegisterCustomValueField(kStart, &CalendarEvent::start_time_, + &DateTime::CreateDateTimeFromValue); + converter->RegisterCustomValueField(kEnd, &CalendarEvent::end_time_, + &DateTime::CreateDateTimeFromValue); +} + +// static +std::unique_ptr<CalendarEvent> CalendarEvent::CreateFrom( + const base::Value& value) { + auto event = std::make_unique<CalendarEvent>(); + base::JSONValueConverter<CalendarEvent> converter; + if (!IsResourceKindExpected(value, kCalendarEventKind) || + !converter.Convert(value, event.get())) { + DVLOG(1) << "Unable to create: Invalid CalendarEvent JSON!"; + return nullptr; + } + + return event; +} + +EventList::EventList() = default; + +EventList::~EventList() = default; + +// static +void EventList::RegisterJSONConverter( + base::JSONValueConverter<EventList>* converter) { + converter->RegisterStringField(kTimeZone, &EventList::time_zone_); + converter->RegisterStringField(kETag, &EventList::etag_); + converter->RegisterStringField(kKind, &EventList::kind_); + converter->RegisterRepeatedMessage<CalendarEvent>(kItems, &EventList::items_); +} + +// static +std::unique_ptr<EventList> EventList::CreateFrom(const base::Value& value) { + auto events = std::make_unique<EventList>(); + base::JSONValueConverter<EventList> converter; + if (!IsResourceKindExpected(value, kCalendarEventListKind) || + !converter.Convert(value, events.get())) { + DVLOG(1) << "Unable to create: Invalid EventList JSON!"; + return nullptr; + } + return events; +} + +} // namespace calendar +} // namespace google_apis
diff --git a/google_apis/calendar/calendar_api_response_types.h b/google_apis/calendar/calendar_api_response_types.h new file mode 100644 index 0000000..603eaa9 --- /dev/null +++ b/google_apis/calendar/calendar_api_response_types.h
@@ -0,0 +1,156 @@ +// Copyright 2021 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. + +#ifndef GOOGLE_APIS_CALENDAR_CALENDAR_API_RESPONSE_TYPES_H_ +#define GOOGLE_APIS_CALENDAR_CALENDAR_API_RESPONSE_TYPES_H_ + +#include <stdint.h> + +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "base/compiler_specific.h" +#include "base/gtest_prod_util.h" +#include "base/macros.h" +#include "base/strings/string_piece.h" +#include "base/time/time.h" +#include "url/gurl.h" + +namespace base { +class Value; +template <class StructType> +class JSONValueConverter; +} // namespace base + +namespace google_apis { + +namespace calendar { + +// Parses the time filed in the calendar Events.list response. +class DateTime { + public: + DateTime(); + DateTime(const DateTime&); + DateTime& operator=(const DateTime& src); + ~DateTime(); + + // Registers the mapping between JSON field names and the members in this + // class. + static void RegisterJSONConverter( + base::JSONValueConverter<DateTime>* converter); + + // Creates DateTime from parsed JSON. + static bool CreateDateTimeFromValue(const base::Value* value, DateTime* time); + + const base::Time& date_time() const { return date_time_; } + void set_date_time(const base::Time& date_time) { date_time_ = date_time; } + + private: + base::Time date_time_; +}; + +// Parses the event item from the response. Not every field is parsed. If you +// find the field you want to use is not parsed here, you will need to add it. +class CalendarEvent { + public: + CalendarEvent(); + CalendarEvent(const CalendarEvent&) = delete; + CalendarEvent& operator=(const CalendarEvent&) = delete; + ~CalendarEvent(); + + // Registers the mapping between JSON field names and the members in this + // class. + static void RegisterJSONConverter( + base::JSONValueConverter<CalendarEvent>* converter); + + // Creates CalendarEvent from parsed JSON. + static std::unique_ptr<CalendarEvent> CreateFrom(const base::Value& value); + + // The ID of this Calendar Event. + const std::string& id() const { return id_; } + void set_id(const std::string& id) { id_ = id; } + + // The title of the event (meeting's name). + const std::string& summary() const { return summary_; } + void set_summary(const std::string& summary) { summary_ = summary; } + + // An absolute link to this event in the Google Calendar Web UI. + const std::string& html_link() const { return html_link_; } + void set_html_link(const std::string& link) { html_link_ = link; } + + // The color id of the event. + const std::string& color_id() const { return color_id_; } + void set_color_id(const std::string& color_id) { color_id_ = color_id; } + + // The status of the event. + const std::string& status() const { return status_; } + void set_status(const std::string& status) { status_ = status; } + + const DateTime& start_time() const { return start_time_; } + void set_start_time(const DateTime& start_time) { start_time_ = start_time; } + + const DateTime& end_time() const { return end_time_; } + void set_end_time(const DateTime& end_time) { end_time_ = end_time; } + + private: + std::string id_; + std::string summary_; + std::string html_link_; + std::string color_id_; + std::string status_; + DateTime start_time_; + DateTime end_time_; +}; + +// Parses a list of calendar events. +class EventList { + public: + EventList(); + EventList(const EventList&) = delete; + EventList& operator=(const EventList&) = delete; + ~EventList(); + + // Registers the mapping between JSON field names and the members in this + // class. + static void RegisterJSONConverter( + base::JSONValueConverter<EventList>* converter); + + // Creates EventList from parsed JSON. + static std::unique_ptr<EventList> CreateFrom(const base::Value& value); + + // Returns time zone. + const std::string& time_zone() const { return time_zone_; } + + // Returns ETag for this calendar. + const std::string& etag() const { return etag_; } + + // Returns the kind. + const std::string& kind() const { return kind_; } + + void set_time_zone(const std::string& time_zone) { time_zone_ = time_zone; } + void set_etag(const std::string& etag) { etag_ = etag; } + void set_kind(const std::string& kind) { kind_ = kind; } + + // Returns a set of events in this calendar. + const std::vector<std::unique_ptr<CalendarEvent>>& items() const { + return items_; + } + std::vector<std::unique_ptr<CalendarEvent>>* mutable_items() { + return &items_; + } + + private: + std::string time_zone_; + std::string etag_; + std::string kind_; + + std::vector<std::unique_ptr<CalendarEvent>> items_; +}; + +} // namespace calendar +} // namespace google_apis + +#endif // GOOGLE_APIS_CALENDAR_CALENDAR_API_RESPONSE_TYPES_H_
diff --git a/google_apis/calendar/calendar_api_response_types_unittest.cc b/google_apis/calendar/calendar_api_response_types_unittest.cc new file mode 100644 index 0000000..92dddb7 --- /dev/null +++ b/google_apis/calendar/calendar_api_response_types_unittest.cc
@@ -0,0 +1,58 @@ +// Copyright 2021 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. + +#include "google_apis/calendar/calendar_api_response_types.h" + +#include "base/time/time.h" +#include "base/values.h" +#include "google_apis/drive/test_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace google_apis { + +namespace calendar { + +TEST(CalendarAPIResponseTypesTest, ParseEventList) { + std::unique_ptr<base::Value> events = + test_util::LoadJSONFile("calendar/events.json"); + ASSERT_TRUE(events.get()); + + ASSERT_EQ(base::Value::Type::DICTIONARY, events->type()); + auto event_list = EventList::CreateFrom(*events); + + EXPECT_EQ("America/Los_Angeles", event_list->time_zone()); + EXPECT_EQ("calendar#events", event_list->kind()); + EXPECT_EQ("\"p32ofplf5q6gf20g\"", event_list->etag()); + EXPECT_EQ(3U, event_list->items().size()); + + const CalendarEvent& event = *event_list->items()[0]; + base::Time start_time; + ASSERT_TRUE(base::Time::FromUTCExploded( + {2020, 11 /* November */, 1 /* Monday */, 2, 18, 0, 0, 0}, &start_time)); + EXPECT_EQ(start_time, event.start_time().date_time()); + + base::Time end_time; + ASSERT_TRUE(base::Time::FromUTCExploded( + {2020, 11 /* November */, 1 /* Monday */, 2, 18, 30, 0, 0}, &end_time)); + EXPECT_EQ(end_time, event.end_time().date_time()); + EXPECT_EQ(event.summary(), "Mobile weekly team meeting "); + EXPECT_EQ(event.id(), "or8221sirt4ogftest"); + EXPECT_EQ( + event.html_link(), + "https://www.google.com/calendar/event?eid=b3I4MjIxc2lydDRvZ2Ztest"); + EXPECT_EQ(event.color_id(), "3"); + EXPECT_EQ(event.status(), "confirmed"); +} + +TEST(CalendarAPIResponseTypesTest, ParseFailed) { + std::unique_ptr<base::Value> events = + test_util::LoadJSONFile("calendar/invalid_events.json"); + ASSERT_TRUE(events.get()); + + ASSERT_EQ(base::Value::Type::DICTIONARY, events->type()); + auto event_list = EventList::CreateFrom(*events); + ASSERT_EQ(event_list, nullptr); +} +} // namespace calendar +} // namespace google_apis
diff --git a/google_apis/calendar/calendar_api_url_generator.cc b/google_apis/calendar/calendar_api_url_generator.cc new file mode 100644 index 0000000..f6e1b2a6 --- /dev/null +++ b/google_apis/calendar/calendar_api_url_generator.cc
@@ -0,0 +1,58 @@ +// Copyright 2021 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. + +#include "google_apis/calendar/calendar_api_url_generator.h" + +#include "google_apis/drive/time_util.h" +#include "net/base/url_util.h" + +namespace google_apis { + +namespace calendar { + +namespace { + +// Hard coded URLs for communication with a google calendar server. +const char kCalendarV3EventsUrl[] = "calendar/v3/calendars/primary/events"; +const char kCalendarV3ColorUrl[] = "calendar/v3/colors"; +const char kTimeMaxParameterName[] = "timeMax"; +const char kTimeMinParameterName[] = "timeMin"; + +} // namespace + +CalendarApiUrlGenerator::CalendarApiUrlGenerator() = default; + +CalendarApiUrlGenerator::CalendarApiUrlGenerator( + const CalendarApiUrlGenerator& src) = default; + +CalendarApiUrlGenerator& CalendarApiUrlGenerator::operator=( + const CalendarApiUrlGenerator& src) = default; + +CalendarApiUrlGenerator::~CalendarApiUrlGenerator() = default; + +// TODO(https://crbug.com/1222483): get this from GaiaUrls class instead. +// The same for the DriveApiUrlGenerator. +const char CalendarApiUrlGenerator::kBaseUrlForProduction[] = + "https://www.googleapis.com"; + +GURL CalendarApiUrlGenerator::GetCalendarEventListUrl( + const base::Time& start_time, + const base::Time& end_time) const { + GURL url = base_url_.Resolve(kCalendarV3EventsUrl); + std::string start_time_string = util::FormatTimeAsString(start_time); + std::string end_time_string = util::FormatTimeAsString(end_time); + url = net::AppendOrReplaceQueryParameter(url, kTimeMinParameterName, + start_time_string); + url = net::AppendOrReplaceQueryParameter(url, kTimeMaxParameterName, + end_time_string); + return url; +} + +GURL CalendarApiUrlGenerator::GetCalendarColorListUrl() const { + GURL url = base_url_.Resolve(kCalendarV3ColorUrl); + return url; +} + +} // namespace calendar +} // namespace google_apis
diff --git a/google_apis/calendar/calendar_api_url_generator.h b/google_apis/calendar/calendar_api_url_generator.h new file mode 100644 index 0000000..3ac0c1c --- /dev/null +++ b/google_apis/calendar/calendar_api_url_generator.h
@@ -0,0 +1,46 @@ +// Copyright 2021 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. + +#ifndef GOOGLE_APIS_CALENDAR_CALENDAR_API_URL_GENERATOR_H_ +#define GOOGLE_APIS_CALENDAR_CALENDAR_API_URL_GENERATOR_H_ + +#include <string> + +#include "base/time/time.h" +#include "url/gurl.h" + +namespace google_apis { + +namespace calendar { + +// This class is used to generate URLs for communicating with calendar api +// servers for production, and a local server for testing. +class CalendarApiUrlGenerator { + public: + CalendarApiUrlGenerator(); + CalendarApiUrlGenerator(const CalendarApiUrlGenerator& src); + CalendarApiUrlGenerator& operator=(const CalendarApiUrlGenerator& src); + ~CalendarApiUrlGenerator(); + + // The base URL for communicating with the production calendar api server. + static const char kBaseUrlForProduction[]; + + // Returns a URL to fetch a list of calendar events. + GURL GetCalendarEventListUrl(const base::Time& start_time, + const base::Time& end_time) const; + + // Returns a URL to fetch a map of calendar color id to color code. + GURL GetCalendarColorListUrl() const; + + // The base url can be set here. It defaults to the production base url. + void SetBaseUrlForTesting(const std::string& url) { base_url_ = GURL(url); } + + private: + GURL base_url_{CalendarApiUrlGenerator::kBaseUrlForProduction}; +}; + +} // namespace calendar +} // namespace google_apis + +#endif // GOOGLE_APIS_CALENDAR_CALENDAR_API_URL_GENERATOR_H_
diff --git a/google_apis/calendar/calendar_api_url_generator_unittest.cc b/google_apis/calendar/calendar_api_url_generator_unittest.cc new file mode 100644 index 0000000..3176571f2 --- /dev/null +++ b/google_apis/calendar/calendar_api_url_generator_unittest.cc
@@ -0,0 +1,34 @@ +// Copyright 2021 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. + +#include "google_apis/calendar/calendar_api_url_generator.h" + +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" + +namespace google_apis { + +namespace calendar { + +// Make sure the hard-coded urls are returned. +TEST(CalendarApiUrlGeneratorTest, GetColorListUrl) { + CalendarApiUrlGenerator url_generator_; + EXPECT_EQ("https://www.googleapis.com/calendar/v3/colors", + url_generator_.GetCalendarColorListUrl().spec()); +} + +TEST(CalendarApiUrlGeneratorTest, GetEventListUrl) { + CalendarApiUrlGenerator url_generator_; + base::Time start; + EXPECT_TRUE(base::Time::FromString("13 Jun 2021 10:00 PST", &start)); + base::Time end; + EXPECT_TRUE(base::Time::FromString("16 Jun 2021 10:00 PST", &end)); + EXPECT_EQ( + "https://www.googleapis.com/calendar/v3/calendars/primary/" + "events?timeMin=2021-06-13T18%3A00%3A00.000Z" + "&timeMax=2021-06-16T18%3A00%3A00.000Z", + url_generator_.GetCalendarEventListUrl(start, end).spec()); +} + +} // namespace calendar +} // namespace google_apis
diff --git a/google_apis/test/data/calendar/events.json b/google_apis/test/data/calendar/events.json new file mode 100644 index 0000000..f54619b --- /dev/null +++ b/google_apis/test/data/calendar/events.json
@@ -0,0 +1,270 @@ +{ + "kind": "calendar#events", + "etag": "\"p32ofplf5q6gf20g\"", + "summary": "test1@google.com", + "updated": "2021-06-18T07:17:10.718Z", + "timeZone": "America/Los_Angeles", + "accessRole": "owner", + "defaultReminders": [ + { + "method": "popup", + "minutes": 10 + } + ], + "nextSyncToken": "CLD81eXRoPECtest", + "items": [ + { + "kind": "calendar#event", + "etag": "\"3231955547274000\"", + "id": "or8221sirt4ogftest", + "status": "confirmed", + "htmlLink": "https://www.google.com/calendar/event?eid=b3I4MjIxc2lydDRvZ2Ztest", + "created": "2018-05-14T18:55:59.000Z", + "updated": "2021-03-17T10:42:53.637Z", + "summary": "Mobile weekly team meeting ", + "description": "\u003ca href=\"https://docs.google.com/document/d/1BSA5pn6dpPQOIBuvtest/edit\"\u003eMeeting agenda and notes\u003c/a\u003e", + "colorId": "3", + "creator": { + "email": "test2@google.com", + "displayName": "test2 testlatname2" + }, + "organizer": { + "email": "test3@google.com" + }, + "start": { + "dateTime": "2020-11-02T10:00:00-08:00", + "timeZone": "America/Los_Angeles" + }, + "end": { + "dateTime": "2020-11-02T10:30:00-08:00", + "timeZone": "America/Los_Angeles" + }, + "recurrence": [ + "RRULE:FREQ=WEEKLY;UNTIL=20201109T075959Z;BYDAY=MO" + ], + "iCalUID": "or8221test@google.com", + "sequence": 6, + "attendees": [ + { + "email": "test4@google.com", + "responseStatus": "needsAction" + }, + { + "email": "google.com_726f6f6d5f75735f6d7test@resource.calendar.google.com", + "displayName": "MTV-1055-2-Pellucid (3) [GVC, Jamboard, Phone]", + "resource": true, + "responseStatus": "declined" + }, + { + "email": "test1@google.com", + "displayName": "test1 testlatname1", + "self": true, + "responseStatus": "needsAction" + }, + { + "email": "test2@google.com", + "displayName": "test2 testlatname2", + "responseStatus": "accepted" + } + ], + "hangoutLink": "https://meet.google.com/jbe-test", + "conferenceData": { + "entryPoints": [ + { + "entryPointType": "video", + "uri": "https://meet.google.com/jbe-test", + "label": "meet.google.com/jbe-test" + }, + { + "entryPointType": "more", + "uri": "https://tel.meet/jbe-test?pin=6390031303227", + "pin": "6390031303227" + }, + { + "regionCode": "US", + "entryPointType": "phone", + "uri": "tel:+1-469-305-0860", + "label": "+1 469-305-0860", + "pin": "383483" + } + ], + "conferenceSolution": { + "key": { + "type": "hangoutsMeet" + }, + "name": "Google Meet", + "iconUri": "https://fonts.gstatic.com/s/i/productlogos/meet_2020q4/v6/web-512dp/logo_meet_2020q4_color_2x_web_512dp.png" + }, + "conferenceId": "jbe-test", + "signature": "ACn9hYFMw8sU85VncET68xXqnRrE" + }, + "guestsCanModify": true, + "reminders": { + "useDefault": true + }, + "eventType": "default" + }, + { + "kind": "calendar#event", + "etag": "\"3246207098130000\"", + "id": "7749obefodf44k4kt7r8lr0l8b", + "status": "confirmed", + "htmlLink": "https://www.google.com/calendar/event?eid=Nzc0OW9iZWZvZGY0NGs0a3Q3cjtest", + "created": "2021-05-24T18:52:31.000Z", + "updated": "2021-06-07T22:05:49.065Z", + "summary": "Calendar view weekly meeting", + "description": "meeting notes: \u003ca href=\"https://docs.google.com/document/d/1UikvkL__BYOtest/edit?resourcekey=0-e1MW5R3-74eHVaj4Fad_vw#\"\u003ehttps://docs.google.com/document/d/1UikvkL__BYOtest/edit?resourcekey=0-e1MW5R3-74eHVaj4Fad_vw#\u003c/a\u003e", + "colorId": "3", + "creator": { + "email": "test1@google.com", + "displayName": "test1 testlatname1", + "self": true + }, + "organizer": { + "email": "test1@google.com", + "displayName": "test1 testlatname1", + "self": true + }, + "start": { + "dateTime": "2021-06-07T15:00:00-07:00" + }, + "end": { + "dateTime": "2021-06-07T15:30:00-07:00" + }, + "iCalUID": "7749obefodf44k4kt7r8lr0l8b@google.com", + "sequence": 1, + "attendees": [ + { + "email": "test4@google.com", + "displayName": "test test4", + "responseStatus": "accepted" + }, + { + "email": "test6@google.com", + "displayName": "test test6", + "responseStatus": "accepted" + }, + { + "email": "test1@google.com", + "displayName": "test1 testlatname1", + "organizer": true, + "self": true, + "responseStatus": "accepted" + } + ], + "hangoutLink": "https://meet.google.com/dbp-qnpu-dtr", + "conferenceData": { + "entryPoints": [ + { + "entryPointType": "video", + "uri": "https://meet.google.com/dbp-qnpu-dtr", + "label": "meet.google.com/dbp-qnpu-dtr" + }, + { + "entryPointType": "more", + "uri": "https://tel.meet/dbp-qnpu-dtr?pin=9643865380295", + "pin": "9643865380295" + }, + { + "regionCode": "US", + "entryPointType": "phone", + "uri": "tel:+1-505-445-7759", + "label": "+1 505-445-7759", + "pin": "537999715" + } + ], + "conferenceSolution": { + "key": { + "type": "hangoutsMeet" + }, + "name": "Google Meet", + "iconUri": "https://fonts.gstatic.com/s/i/productlogos/meet_2020q4/v6/web-512dp/logo_meet_2020q4_color_2x_web_512dp.png" + }, + "conferenceId": "dbp-qnpu-dtr", + "signature": "ACn9hYEoGEiIFbVraLJKk6nZMT8W" + }, + "reminders": { + "useDefault": true + }, + "eventType": "default" + }, + { + "kind": "calendar#event", + "etag": "\"3246695702310000\"", + "id": "1a5n209tijjtrd1mhn2lkgdaq9", + "status": "confirmed", + "htmlLink": "https://www.google.com/calendar/event?eid=MWE1bjIwOXRpamp0cmQxbWhuMmxrZ2RhcTlfMjAyMTA1MTBUMTgzMDAwWiBqaWFtaW5nY0Bnb29nbGUuY29t", + "created": "2021-05-07T18:17:01.000Z", + "updated": "2021-06-10T17:57:31.155Z", + "summary": "System UI sync", + "creator": { + "email": "test5@google.com", + "displayName": "test test5" + }, + "organizer": { + "email": "test5@google.com", + "displayName": "test test5" + }, + "start": { + "dateTime": "2021-05-10T11:30:00-07:00", + "timeZone": "America/Los_Angeles" + }, + "end": { + "dateTime": "2021-05-10T12:00:00-07:00", + "timeZone": "America/Los_Angeles" + }, + "recurrence": [ + "RRULE:FREQ=WEEKLY;UNTIL=20210614T065959Z;BYDAY=MO" + ], + "iCalUID": "1a5n209tijjtrd1mhn2lkgdaq9@google.com", + "sequence": 0, + "attendees": [ + { + "email": "test4@google.com", + "responseStatus": "needsAction" + }, + { + "email": "test1@google.com", + "displayName": "test1 testlatname1", + "self": true, + "responseStatus": "accepted" + } + ], + "hangoutLink": "https://meet.google.com/kid-test", + "conferenceData": { + "entryPoints": [ + { + "entryPointType": "video", + "uri": "https://meet.google.com/kid-test", + "label": "meet.google.com/kid-test" + }, + { + "entryPointType": "more", + "uri": "https://tel.meet/kid-test?pin=2281762872233", + "pin": "2281762872233" + }, + { + "regionCode": "US", + "entryPointType": "phone", + "uri": "tel:+1-631-621-7845", + "label": "+1 631-621-7845", + "pin": "757210" + } + ], + "conferenceSolution": { + "key": { + "type": "hangoutsMeet" + }, + "name": "Google Meet", + "iconUri": "https://fonts.gstatic.com/s/i/productlogos/meet_2020q4/v6/web-512dp/logo_meet_2020q4_color_2x_web_512dp.png" + }, + "conferenceId": "kid-test", + "signature": "ACn9hYECv1wqAa2nRcODwiTjDSb9" + }, + "reminders": { + "useDefault": true + }, + "eventType": "default" + } + ] + } \ No newline at end of file
diff --git a/google_apis/test/data/calendar/invalid_events.json b/google_apis/test/data/calendar/invalid_events.json new file mode 100644 index 0000000..229968d --- /dev/null +++ b/google_apis/test/data/calendar/invalid_events.json
@@ -0,0 +1,8 @@ +{ + "kind": [], + "etag": "\"p32ofplf5q6gf20g\"", + "summary": "test1@google.com", + "updated": "2021-06-18T07:17:10.718Z", + "timeZone": [], + "accessRole": "owner" +} \ No newline at end of file
diff --git a/gpu/command_buffer/service/external_vk_image_factory_unittest.cc b/gpu/command_buffer/service/external_vk_image_factory_unittest.cc index e759d18a..422eee8 100644 --- a/gpu/command_buffer/service/external_vk_image_factory_unittest.cc +++ b/gpu/command_buffer/service/external_vk_image_factory_unittest.cc
@@ -355,7 +355,6 @@ dst_copy_view.buffer = dst_buffer; dst_copy_view.layout.bytesPerRow = 256; dst_copy_view.layout.offset = 0; - dst_copy_view.layout.rowsPerImage = 0; wgpu::Extent3D copy_extent = {static_cast<uint32_t>(size.width()), static_cast<uint32_t>(size.height()), 1};
diff --git a/gpu/command_buffer/tests/webgpu_mailbox_unittest.cc b/gpu/command_buffer/tests/webgpu_mailbox_unittest.cc index a442e19..63a1033 100644 --- a/gpu/command_buffer/tests/webgpu_mailbox_unittest.cc +++ b/gpu/command_buffer/tests/webgpu_mailbox_unittest.cc
@@ -308,7 +308,7 @@ // Clear the texture using a render pass. wgpu::RenderPassColorAttachmentDescriptor color_desc = {}; - color_desc.attachment = texture.CreateView(); + color_desc.view = texture.CreateView(); color_desc.loadOp = wgpu::LoadOp::Clear; color_desc.storeOp = wgpu::StoreOp::Store; color_desc.clearColor = {0, 255, 0, 255}; @@ -355,7 +355,6 @@ copy_dst.buffer = readback_buffer; copy_dst.layout.offset = 0; copy_dst.layout.bytesPerRow = 256; - copy_dst.layout.rowsPerImage = 0; wgpu::Extent3D copy_size = {1, 1, 1};
diff --git a/infra/config/generated/commit-queue.cfg b/infra/config/generated/commit-queue.cfg index c8f3648..af982016 100644 --- a/infra/config/generated/commit-queue.cfg +++ b/infra/config/generated/commit-queue.cfg
@@ -1689,6 +1689,14 @@ includable_only: true } builders { + name: "chromium/try/win10-rel-compilator" + includable_only: true + } + builders { + name: "chromium/try/win10-rel-orchestrator" + includable_only: true + } + builders { name: "chromium/try/win10.20h2-blink-rel" includable_only: true }
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index ea0f04a..4e9fd617 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -61912,6 +61912,163 @@ } } builders { + name: "win10-rel-compilator" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builder:win10-rel-compilator" + dimensions: "cores:16" + dimensions: "cpu:x86-64" + dimensions: "os:Windows-10" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:1" + exe { + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + cmd: "luciexe" + } + properties: "{\"$build/goma\":{\"enable_ats\":false,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"tryserver.chromium.win\",\"orchestrator\":{\"builder_group\":\"tryserver.chromium.win\",\"builder_name\":\"win10-orchestrator\"},\"recipe\":\"chromium/compilator\"}" + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + caches { + name: "win_toolchain" + path: "win_toolchain" + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "chromium.resultdb.result_sink" + value: 100 + } + experiments { + key: "chromium.resultdb.result_sink.junit_tests" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + experiments { + key: "use_rbe_cas" + value: 5 + } + resultdb { + enable: true + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { + name: "win10-rel-orchestrator" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builder:win10-rel-orchestrator" + dimensions: "cores:2" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.try" + exe { + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + cmd: "luciexe" + } + properties: "{\"$build/code_coverage\":{\"coverage_test_types\":[\"unit\",\"overall\"],\"use_clang_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"tryserver.chromium.linux\",\"compilator\":\"win10-compilator\",\"recipe\":\"chromium/orchestrator\"}" + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + caches { + name: "win_toolchain" + path: "win_toolchain" + } + build_numbers: YES + service_account: "chromium-orchestrator@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "chromium.resultdb.result_sink" + value: 100 + } + experiments { + key: "chromium.resultdb.result_sink.junit_tests" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + experiments { + key: "use_rbe_cas" + value: 5 + } + resultdb { + enable: true + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "win10.20h2-blink-rel" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper"
diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg index e5fa87f..db4d53eb 100644 --- a/infra/config/generated/luci-milo.cfg +++ b/infra/config/generated/luci-milo.cfg
@@ -14341,6 +14341,12 @@ name: "buildbucket/luci.chromium.try/win10-blink-rel" } builders { + name: "buildbucket/luci.chromium.try/win10-rel-compilator" + } + builders { + name: "buildbucket/luci.chromium.try/win10-rel-orchestrator" + } + builders { name: "buildbucket/luci.chromium.try/win10.20h2-blink-rel" } builders { @@ -15134,6 +15140,9 @@ builders { name: "buildbucket/luci.chromium.try/tricium-simple" } + builders { + name: "buildbucket/luci.chromium.try/win10-rel-orchestrator" + } builder_view_only: true } consoles { @@ -15403,6 +15412,9 @@ name: "buildbucket/luci.chromium.try/win-libfuzzer-asan-rel" } builders { + name: "buildbucket/luci.chromium.try/win10-rel-compilator" + } + builders { name: "buildbucket/luci.chromium.try/win10_chromium_inverse_fieldtrials_x64_fyi_rel_ng" } builders {
diff --git a/infra/config/generated/realms.cfg b/infra/config/generated/realms.cfg index 25f4c5b..91c8ffe 100644 --- a/infra/config/generated/realms.cfg +++ b/infra/config/generated/realms.cfg
@@ -252,6 +252,7 @@ role: "role/buildbucket.builderServiceAccount" principals: "user:chromium-cipd-try-builder@chops-service-accounts.iam.gserviceaccount.com" principals: "user:chromium-mini-orchestrator@chops-service-accounts.iam.gserviceaccount.com" + principals: "user:chromium-orchestrator@chops-service-accounts.iam.gserviceaccount.com" principals: "user:chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" principals: "user:chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" }
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star index 50cff18..ce06af13 100644 --- a/infra/config/subprojects/chromium/try.star +++ b/infra/config/subprojects/chromium/try.star
@@ -1853,6 +1853,37 @@ tryjob = try_.job(), ) +try_.chromium_linux_builder( + name = "win10-rel-orchestrator", + branch_selector = branches.STANDARD_MILESTONE, + builderless = False, + cores = 2, + executable = "recipe:chromium/orchestrator", + use_clang_coverage = True, + coverage_test_types = ["unit", "overall"], + properties = { + "compilator": "win10-compilator", + }, + service_account = "chromium-orchestrator@chops-service-accounts.iam.gserviceaccount.com", +) + +try_.chromium_win_builder( + name = "win10-rel-compilator", + branch_selector = branches.STANDARD_MILESTONE, + builderless = False, + cores = 16, + os = os.WINDOWS_10, + ssd = True, + goma_jobs = goma.jobs.J300, + executable = "recipe:chromium/compilator", + properties = { + "orchestrator": { + "builder_name": "win10-orchestrator", + "builder_group": "tryserver.chromium.win", + }, + }, +) + try_.chromium_win_builder( name = "win10_chromium_x64_rel_ng_exp", builderless = False,
diff --git a/ios/chrome/browser/favicon/favicon_client_impl.mm b/ios/chrome/browser/favicon/favicon_client_impl.mm index 83031f7..7dc60c9 100644 --- a/ios/chrome/browser/favicon/favicon_client_impl.mm +++ b/ios/chrome/browser/favicon/favicon_client_impl.mm
@@ -43,13 +43,14 @@ if (resource_id == -1) return; - // Use ui::GetSupportedScaleFactors() because native URL favicon comes from - // resources. - std::vector<ui::ScaleFactor> scale_factors = ui::GetSupportedScaleFactors(); + // Use ui::GetSupportedResourceScaleFactors() because native URL favicon comes + // from resources. + std::vector<ui::ResourceScaleFactor> scale_factors = + ui::GetSupportedResourceScaleFactors(); std::vector<gfx::Size> candidate_sizes; - for (ui::ScaleFactor scale_factor : scale_factors) { - float scale = ui::GetScaleForScaleFactor(scale_factor); + for (ui::ResourceScaleFactor scale_factor : scale_factors) { + float scale = ui::GetScaleForResourceScaleFactor(scale_factor); int candidate_size = static_cast<int>(gfx::kFaviconSize * scale + 0.5f); candidate_sizes.push_back(gfx::Size(candidate_size, candidate_size)); } @@ -59,7 +60,7 @@ &selected_indices, nullptr); for (size_t selected_index : selected_indices) { - ui::ScaleFactor scale_factor = scale_factors[selected_index]; + ui::ResourceScaleFactor scale_factor = scale_factors[selected_index]; favicon_base::FaviconRawBitmapResult favicon_bitmap; favicon_bitmap.icon_type = favicon_base::IconType::kFavicon; favicon_bitmap.pixel_size = candidate_sizes[selected_index];
diff --git a/ios/chrome/browser/ntp_tiles/ios_most_visited_sites_factory.cc b/ios/chrome/browser/ntp_tiles/ios_most_visited_sites_factory.cc index 46f89893..92443d1e 100644 --- a/ios/chrome/browser/ntp_tiles/ios_most_visited_sites_factory.cc +++ b/ios/chrome/browser/ntp_tiles/ios_most_visited_sites_factory.cc
@@ -16,7 +16,6 @@ #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h" #include "ios/chrome/browser/history/top_sites_factory.h" #include "ios/chrome/browser/ntp_tiles/ios_popular_sites_factory.h" -#include "ios/chrome/browser/suggestions/suggestions_service_factory.h" #include "services/network/public/cpp/shared_url_loader_factory.h" std::unique_ptr<ntp_tiles::MostVisitedSites> @@ -25,7 +24,6 @@ return std::make_unique<ntp_tiles::MostVisitedSites>( browser_state->GetPrefs(), ios::TopSitesFactory::GetForBrowserState(browser_state), - suggestions::SuggestionsServiceFactory::GetForBrowserState(browser_state), IOSPopularSitesFactory::NewForBrowserState(browser_state), /*custom_links=*/nullptr, std::make_unique<ntp_tiles::IconCacherImpl>(
diff --git a/ios/chrome/browser/policy/BUILD.gn b/ios/chrome/browser/policy/BUILD.gn index 0e5d29d..6f4f0adc 100644 --- a/ios/chrome/browser/policy/BUILD.gn +++ b/ios/chrome/browser/policy/BUILD.gn
@@ -279,6 +279,9 @@ "//components/policy/core/browser", "//components/policy/core/common", "//ios/chrome/browser", + "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/policy_url_blocking", + "//ios/chrome/test/app:test_support", ] frameworks = [ "Foundation.framework" ] }
diff --git a/ios/chrome/browser/policy/policy_app_interface.h b/ios/chrome/browser/policy/policy_app_interface.h index 400d6b9..28a3d46a 100644 --- a/ios/chrome/browser/policy/policy_app_interface.h +++ b/ios/chrome/browser/policy/policy_app_interface.h
@@ -21,6 +21,10 @@ // Clear all policy values. + (void)clearPolicies; +// Returns YES if the given |URL| is blocked by the URLBlocklist and +// URLAllowlist policies. ++ (BOOL)isURLBlocked:(NSString*)URL; + @end #endif // IOS_CHROME_BROWSER_POLICY_POLICY_APP_INTERFACE_H_
diff --git a/ios/chrome/browser/policy/policy_app_interface.mm b/ios/chrome/browser/policy/policy_app_interface.mm index 352af2c..6a78104 100644 --- a/ios/chrome/browser/policy/policy_app_interface.mm +++ b/ios/chrome/browser/policy/policy_app_interface.mm
@@ -10,6 +10,7 @@ #include "base/strings/sys_string_conversions.h" #include "base/values.h" #include "components/policy/core/browser/browser_policy_connector.h" +#include "components/policy/core/browser/url_blocklist_manager.h" #include "components/policy/core/common/configuration_policy_provider.h" #include "components/policy/core/common/policy_bundle.h" #include "components/policy/core/common/policy_map.h" @@ -17,8 +18,11 @@ #include "components/policy/core/common/policy_types.h" #include "components/policy/policy_constants.h" #include "ios/chrome/browser/application_context.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/policy/browser_policy_connector_ios.h" #include "ios/chrome/browser/policy/test_platform_policy_provider.h" +#import "ios/chrome/browser/policy_url_blocking/policy_url_blocking_service.h" +#import "ios/chrome/test/app/chrome_test_util.h" #include "third_party/abseil-cpp/absl/types/optional.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -99,4 +103,13 @@ GetTestPlatformPolicyProvider()->UpdateChromePolicy(values); } ++ (BOOL)isURLBlocked:(NSString*)URL { + GURL gurl = GURL(base::SysNSStringToUTF8(URL)); + PolicyBlocklistService* service = + PolicyBlocklistServiceFactory::GetForBrowserState( + chrome_test_util::GetOriginalBrowserState()); + return service->GetURLBlocklistState(gurl) == + policy::URLBlocklist::URLBlocklistState::URL_IN_BLOCKLIST; +} + @end
diff --git a/ios/chrome/browser/policy_url_blocking/policy_url_blocking_egtest.mm b/ios/chrome/browser/policy_url_blocking/policy_url_blocking_egtest.mm index 0de4a84..6f5594b 100644 --- a/ios/chrome/browser/policy_url_blocking/policy_url_blocking_egtest.mm +++ b/ios/chrome/browser/policy_url_blocking/policy_url_blocking_egtest.mm
@@ -5,6 +5,7 @@ #include <string> #include "base/strings/sys_string_conversions.h" +#import "base/test/ios/wait_util.h" #include "components/policy/policy_constants.h" #import "ios/chrome/browser/chrome_switches.h" #import "ios/chrome/browser/policy/policy_app_interface.h" @@ -21,6 +22,22 @@ #error "This file requires ARC support." #endif +namespace { + +// Waits until |url| has the expected blocked state. +void WaitForURLBlockedStatus(const GURL& url, bool blocked) { + NSString* nsurl = base::SysUTF8ToNSString(url.spec()); + GREYAssertTrue(base::test::ios::WaitUntilConditionOrTimeout( + base::test::ios::kWaitForActionTimeout, + ^{ + return + [PolicyAppInterface isURLBlocked:nsurl] == blocked; + }), + @"Waiting for policy url blocklist to update."); +} + +} + // Tests the URLBlocklist and URLWhitelist enterprise policies. @interface PolicyURLBlockingTestCase : ChromeTestCase @end @@ -45,6 +62,15 @@ - (void)setUp { [super setUp]; GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); + + // Check that the policy blocklist is reset. + WaitForURLBlockedStatus(self.testServer->GetURL("/echo"), false); + WaitForURLBlockedStatus(self.testServer->GetURL("/testpage"), false); +} + +- (void)tearDown { + [PolicyAppInterface clearPolicies]; + [super tearDown]; } // Tests that pages are not blocked when the blocklist exists, but is empty. @@ -64,6 +90,7 @@ [PolicyAppInterface setPolicyValue:@"[\"*\"]" forKey:base::SysUTF8ToNSString(policy::key::kURLBlocklist)]; + WaitForURLBlockedStatus(self.testServer->GetURL("/echo"), true); [ChromeEarlGrey loadURL:self.testServer->GetURL("/echo")]; @@ -77,6 +104,7 @@ [PolicyAppInterface setPolicyValue:@"[\"*\"]" forKey:base::SysUTF8ToNSString(policy::key::kURLBlocklist)]; + WaitForURLBlockedStatus(self.testServer->GetURL("/echo"), true); [[EarlGrey selectElementWithMatcher:chrome_test_util::FakeOmnibox()] assertWithMatcher:grey_sufficientlyVisible()]; @@ -88,6 +116,7 @@ [PolicyAppInterface setPolicyValue:@"[\"*/echo\"]" forKey:base::SysUTF8ToNSString(policy::key::kURLBlocklist)]; + WaitForURLBlockedStatus(self.testServer->GetURL("/echo"), true); [ChromeEarlGrey loadURL:self.testServer->GetURL("/echo")]; @@ -98,12 +127,18 @@ // Tests that pages are loaded when explicitly listed in the URLAllowlist. - (void)testAllowlist { + // The URLBlocklistPolicyHandler will discard policy updates that occur while + // it is already computing a new blocklist, so wait between calls to set new + // policy values. [PolicyAppInterface setPolicyValue:@"[\"*\"]" forKey:base::SysUTF8ToNSString(policy::key::kURLBlocklist)]; + WaitForURLBlockedStatus(self.testServer->GetURL("/testpage"), true); + [PolicyAppInterface setPolicyValue:@"[\"*/echo\"]" forKey:base::SysUTF8ToNSString(policy::key::kURLAllowlist)]; + WaitForURLBlockedStatus(self.testServer->GetURL("/echo"), false); [ChromeEarlGrey loadURL:self.testServer->GetURL("/echo")];
diff --git a/ios/chrome/browser/sync/ios_trusted_vault_client.mm b/ios/chrome/browser/sync/ios_trusted_vault_client.mm index e055719..ac97a02b 100644 --- a/ios/chrome/browser/sync/ios_trusted_vault_client.mm +++ b/ios/chrome/browser/sync/ios_trusted_vault_client.mm
@@ -50,10 +50,8 @@ ios::ChromeBrowserProvider* browser_provider = ios::GetChromeBrowserProvider(); - ios::ChromeTrustedVaultService* trusted_vault_service = - browser_provider->GetChromeTrustedVaultService(); - DCHECK(trusted_vault_service); - trusted_vault_service->FetchKeys(identity, std::move(callback)); + browser_provider->GetChromeTrustedVaultService()->FetchKeys( + identity, std::move(callback)); } void IOSTrustedVaultClient::StoreKeys( @@ -67,8 +65,13 @@ void IOSTrustedVaultClient::MarkKeysAsStale( const CoreAccountInfo& account_info, base::OnceCallback<void(bool)> callback) { - // TODO(crbug.com/1100278): Needs implementation. - std::move(callback).Run(false); + ChromeIdentity* identity = + account_manager_service_->GetIdentityWithGaiaID(account_info.gaia); + + ios::ChromeBrowserProvider* browser_provider = + ios::GetChromeBrowserProvider(); + browser_provider->GetChromeTrustedVaultService()->MarkLocalKeysAsStale( + identity, std::move(callback)); } void IOSTrustedVaultClient::GetIsRecoverabilityDegraded( @@ -87,6 +90,6 @@ const std::vector<uint8_t>& public_key, int method_type_hint, base::OnceClosure callback) { - // TODO(crbug.com/1100278): Needs implementation. - std::move(callback).Run(); + // Not used on iOS. + NOTREACHED(); }
diff --git a/ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc b/ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc index 5207b8a4..c8d22f9 100644 --- a/ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc +++ b/ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
@@ -68,7 +68,6 @@ ntp_tiles::TileSource source) { switch (source) { case ntp_tiles::TileSource::TOP_SITES: - case ntp_tiles::TileSource::SUGGESTIONS_SERVICE: case ntp_tiles::TileSource::POPULAR: case ntp_tiles::TileSource::POPULAR_BAKED_IN: case ntp_tiles::TileSource::HOMEPAGE:
diff --git a/ios/chrome/browser/web/chrome_web_client.h b/ios/chrome/browser/web/chrome_web_client.h index 57816f7..0ea7cc19 100644 --- a/ios/chrome/browser/web/chrome_web_client.h +++ b/ios/chrome/browser/web/chrome_web_client.h
@@ -29,7 +29,7 @@ std::u16string GetLocalizedString(int message_id) const override; base::StringPiece GetDataResource( int resource_id, - ui::ScaleFactor scale_factor) const override; + ui::ResourceScaleFactor scale_factor) const override; base::RefCountedMemory* GetDataResourceBytes(int resource_id) const override; void GetAdditionalWebUISchemes( std::vector<std::string>* additional_schemes) override;
diff --git a/ios/chrome/browser/web/chrome_web_client.mm b/ios/chrome/browser/web/chrome_web_client.mm index 379705c5..70b8ce0962 100644 --- a/ios/chrome/browser/web/chrome_web_client.mm +++ b/ios/chrome/browser/web/chrome_web_client.mm
@@ -267,7 +267,7 @@ base::StringPiece ChromeWebClient::GetDataResource( int resource_id, - ui::ScaleFactor scale_factor) const { + ui::ResourceScaleFactor scale_factor) const { return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale( resource_id, scale_factor); }
diff --git a/ios/chrome/browser/web/error_page_util.mm b/ios/chrome/browser/web/error_page_util.mm index b4015e9..9ea56c5c 100644 --- a/ios/chrome/browser/web/error_page_util.mm +++ b/ios/chrome/browser/web/error_page_util.mm
@@ -59,7 +59,7 @@ GetApplicationContext()->GetApplicationLocale(), /*is_blocked_by_extension=*/false); - ui::ScaleFactor scale_factor = + ui::ResourceScaleFactor scale_factor = ui::ResourceBundle::GetSharedInstance().GetMaxScaleFactor(); std::string extracted_string =
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 index 17e663c..35ecfcf9 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -7ed61a58f40f945dbb74c00a79bf03faaf7af52b \ No newline at end of file +1ca9c38a2c875423f580a9682e305b4109fa392d \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 index 5e2563c..3d643642 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -5823d62ba8ba4ef6a4060bbea629e5ab61720547 \ No newline at end of file +68b5257e494bd125f3150e9a572ff98f53f77b54 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 index 921cff6..462de5b 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -a5b6c422bb7aed25f522081fd7d9bd07698b4f59 \ No newline at end of file +0699d15b2a47348f55728db8cac322749fb64511 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 index 0991f09..994f711 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -8f38d3b36675af5ef20a5007abbf31218808d0d9 \ No newline at end of file +25059d05998ec8fc50c67c0062419ecd9dfb6ca6 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 index 42e8b37..d4f15f9 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -3679a77fb019998b103932756f12af49ed0f3554 \ No newline at end of file +7b98f81cda420d754cee55bbec6695610d1693b4 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 index 57b54a16..581b62b 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -a31816740e900542b0d038e0dae2e3e83293d935 \ No newline at end of file +bc5b701a9bd198c0ea9ae73589e9d38c0293bc51 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 index 9399f65b..1b52fd95 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -62c91bb98f7a96a08ed6d07de64a8d520e67431c \ No newline at end of file +0108cad53273467da40ac6a64c03b8386cd9889a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 index 5efda37..32987f0 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -1c57f20e633c98d14efa6bbb773c1e753d192d87 \ No newline at end of file +6ce178db7d7ed99625da2fcfc1957d719f556f86 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 index ae2edf6..df6fdbf 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -d922439466cccfa2be595a8f17c6cf27770c3374 \ No newline at end of file +8a6cc02d8cb925a2492749e9aa7e79dd237389ff \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 index 126e59e9..b4f51085 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -78751e21d0d5586c383e75a4f6fa6b755a4b9200 \ No newline at end of file +866ae9097d2c05236a24272b4d4450c8d4c7e493 \ No newline at end of file
diff --git a/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.h b/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.h index 85a9611..ef806f1 100644 --- a/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.h +++ b/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.h
@@ -41,6 +41,18 @@ ChromeIdentity* chrome_identity, base::OnceCallback<void(const TrustedVaultSharedKeyList&)> callback) = 0; + // Invoked when the result of FetchKeys() contains keys that are not + // up-to-date. |cb| is run upon completion and returns false if the call did + // not make any difference (e.g. the operation is unsupported) or true if + // some change may have occurred (which indicates a second FetchKeys() attempt + // is worth). During the execution, before |cb| is invoked, the behavior is + // unspecified if FetchKeys() is invoked, that is, FetchKeys() may or may not + // treat existing keys as stale (only guaranteed upon completion of + // MarkLocalKeysAsStale()). + // TODO(crbug.com/1100278): Make pure virtual. + virtual void MarkLocalKeysAsStale(ChromeIdentity* chrome_identity, + base::OnceCallback<void(bool)> callback); + // Returns whether recoverability of the keys is degraded and user action is // required to add a new method. virtual void GetDegradedRecoverabilityStatus(
diff --git a/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.mm b/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.mm index 38a7004..d60436e 100644 --- a/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.mm +++ b/ios/public/provider/chrome/browser/signin/chrome_trusted_vault_service.mm
@@ -22,6 +22,12 @@ observer_list_.RemoveObserver(observer); } +void ChromeTrustedVaultService::MarkLocalKeysAsStale( + ChromeIdentity* chrome_identity, + base::OnceCallback<void(bool)> callback) { + std::move(callback).Run(false); +} + void ChromeTrustedVaultService::Reauthentication( ChromeIdentity* chrome_identity, UIViewController* presentingViewController,
diff --git a/ios/third_party/fishhook/fishhook.c b/ios/third_party/fishhook/fishhook.c index 22cd1e3..3ae6355 100644 --- a/ios/third_party/fishhook/fishhook.c +++ b/ios/third_party/fishhook/fishhook.c
@@ -26,6 +26,7 @@ #include <dlfcn.h> #include <stdbool.h> #include <stdlib.h> +#include <stdio.h> #include <string.h> #include <sys/mman.h> #include <sys/types.h> @@ -126,7 +127,17 @@ trunc_size =(vm_size_t)indirect_symbol_bindings -trunc_address; pthread_mutex_lock(&mutex); oldProtection = get_protection((void *)trunc_address); - mprotect((void *)trunc_address, section->size+trunc_size, PROT_READ | PROT_WRITE); + + // Use vm_protect to also set VM_PROT_COPY. + kern_return_t err = vm_protect(mach_task_self(), + (uintptr_t)trunc_address, + section->size+trunc_size, + 0, + VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY); + if (err != KERN_SUCCESS) { + fprintf(stderr, "perform_rebinding_with_section vm_protect failed.\n"); + return; + } } for (uint i = 0; i < section->size / sizeof(void *); i++) { uint32_t symtab_index = indirect_symbol_indices[i];
diff --git a/ios/web/public/web_client.h b/ios/web/public/web_client.h index f8148ee7f..b6545328 100644 --- a/ios/web/public/web_client.h +++ b/ios/web/public/web_client.h
@@ -94,8 +94,9 @@ virtual std::u16string GetLocalizedString(int message_id) const; // Returns the contents of a resource in a StringPiece given the resource id. - virtual base::StringPiece GetDataResource(int resource_id, - ui::ScaleFactor scale_factor) const; + virtual base::StringPiece GetDataResource( + int resource_id, + ui::ResourceScaleFactor scale_factor) const; // Returns the raw bytes of a scale independent data resource. virtual base::RefCountedMemory* GetDataResourceBytes(int resource_id) const;
diff --git a/ios/web/shell/shell_web_client.h b/ios/web/shell/shell_web_client.h index 21d60f2..994f7c06 100644 --- a/ios/web/shell/shell_web_client.h +++ b/ios/web/shell/shell_web_client.h
@@ -25,7 +25,7 @@ std::string GetUserAgent(UserAgentType type) const override; base::StringPiece GetDataResource( int resource_id, - ui::ScaleFactor scale_factor) const override; + ui::ResourceScaleFactor scale_factor) const override; base::RefCountedMemory* GetDataResourceBytes(int resource_id) const override; void BindInterfaceReceiverFromMainFrame( WebState* web_state,
diff --git a/ios/web/shell/shell_web_client.mm b/ios/web/shell/shell_web_client.mm index bdd4ce13..f4a0271e 100644 --- a/ios/web/shell/shell_web_client.mm +++ b/ios/web/shell/shell_web_client.mm
@@ -63,7 +63,7 @@ base::StringPiece ShellWebClient::GetDataResource( int resource_id, - ui::ScaleFactor scale_factor) const { + ui::ResourceScaleFactor scale_factor) const { return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale( resource_id, scale_factor); }
diff --git a/ios/web/web_client.mm b/ios/web/web_client.mm index 1d3d655..ad9e40b 100644 --- a/ios/web/web_client.mm +++ b/ios/web/web_client.mm
@@ -58,7 +58,7 @@ base::StringPiece WebClient::GetDataResource( int resource_id, - ui::ScaleFactor scale_factor) const { + ui::ResourceScaleFactor scale_factor) const { return base::StringPiece(); }
diff --git a/ios/web_view/internal/web_view_web_client.h b/ios/web_view/internal/web_view_web_client.h index 8ed0669..652530a0 100644 --- a/ios/web_view/internal/web_view_web_client.h +++ b/ios/web_view/internal/web_view_web_client.h
@@ -25,7 +25,7 @@ std::string GetUserAgent(web::UserAgentType type) const override; base::StringPiece GetDataResource( int resource_id, - ui::ScaleFactor scale_factor) const override; + ui::ResourceScaleFactor scale_factor) const override; base::RefCountedMemory* GetDataResourceBytes(int resource_id) const override; std::vector<web::JavaScriptFeature*> GetJavaScriptFeatures( web::BrowserState* browser_state) const override;
diff --git a/ios/web_view/internal/web_view_web_client.mm b/ios/web_view/internal/web_view_web_client.mm index d33754e..1f12a8e6 100644 --- a/ios/web_view/internal/web_view_web_client.mm +++ b/ios/web_view/internal/web_view_web_client.mm
@@ -90,7 +90,7 @@ base::StringPiece WebViewWebClient::GetDataResource( int resource_id, - ui::ScaleFactor scale_factor) const { + ui::ResourceScaleFactor scale_factor) const { return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale( resource_id, scale_factor); }
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc index e5012b7..b72315cb 100644 --- a/media/gpu/vaapi/vaapi_wrapper.cc +++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -1479,18 +1479,17 @@ bool VaapiWrapper::IsDecodingSupportedForInternalFormat( VAProfile va_profile, unsigned int rt_format) { - static const base::NoDestructor<VaapiWrapper::InternalFormats> - supported_internal_formats( - VaapiWrapper::GetDecodeSupportedInternalFormats(va_profile)); + static const VaapiWrapper::InternalFormats supported_internal_formats( + VaapiWrapper::GetDecodeSupportedInternalFormats(va_profile)); switch (rt_format) { case VA_RT_FORMAT_YUV420: - return supported_internal_formats->yuv420; + return supported_internal_formats.yuv420; case VA_RT_FORMAT_YUV420_10: - return supported_internal_formats->yuv420_10; + return supported_internal_formats.yuv420_10; case VA_RT_FORMAT_YUV422: - return supported_internal_formats->yuv422; + return supported_internal_formats.yuv422; case VA_RT_FORMAT_YUV444: - return supported_internal_formats->yuv444; + return supported_internal_formats.yuv444; } return false; }
diff --git a/media/mojo/clients/mojo_video_decoder.cc b/media/mojo/clients/mojo_video_decoder.cc index 0112cb3..2b79916 100644 --- a/media/mojo/clients/mojo_video_decoder.cc +++ b/media/mojo/clients/mojo_video_decoder.cc
@@ -14,7 +14,6 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/metrics/histogram_macros.h" -#include "base/no_destructor.h" #include "base/sequenced_task_runner.h" #include "base/unguessable_token.h" #include "build/build_config.h" @@ -39,8 +38,8 @@ namespace { // Number of functional instances of MojoVideoDecoder in the current process. std::atomic<int>& get_mojo_instance_counter() { - static base::NoDestructor<std::atomic<int>> gInstanceCounter(0); - return *gInstanceCounter; + static std::atomic<int> instance_counter(0); + return instance_counter; } } // namespace
diff --git a/media/video/fake_gpu_memory_buffer.cc b/media/video/fake_gpu_memory_buffer.cc index 8722397..fbaae57 100644 --- a/media/video/fake_gpu_memory_buffer.cc +++ b/media/video/fake_gpu_memory_buffer.cc
@@ -75,8 +75,8 @@ handle_.type = gfx::NATIVE_PIXMAP; - static base::NoDestructor<base::AtomicSequenceNumber> buffer_id_generator; - handle_.id = gfx::GpuMemoryBufferId(buffer_id_generator->GetNext()); + static base::AtomicSequenceNumber buffer_id_generator; + handle_.id = gfx::GpuMemoryBufferId(buffer_id_generator.GetNext()); #if defined(OS_LINUX) || defined(OS_CHROMEOS) for (size_t i = 0; i < VideoFrame::NumPlanes(video_pixel_format_); i++) {
diff --git a/mojo/core/mojo_core.cc b/mojo/core/mojo_core.cc index 5f22533..bcbe1210 100644 --- a/mojo/core/mojo_core.cc +++ b/mojo/core/mojo_core.cc
@@ -13,7 +13,6 @@ #include "base/logging.h" #include "base/macros.h" #include "base/message_loop/message_pump_type.h" -#include "base/no_destructor.h" #include "base/rand_util.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" @@ -146,9 +145,9 @@ argv = options->argv; } - static base::NoDestructor<GlobalStateInitializer> global_state_initializer; + static GlobalStateInitializer global_state_initializer; const bool was_global_state_already_initialized = - !global_state_initializer->Initialize(argc, argv); + !global_state_initializer.Initialize(argc, argv); if (!should_initialize_ipc_support) { if (was_global_state_already_initialized)
diff --git a/mojo/core/port_event_fuzzer.cc b/mojo/core/port_event_fuzzer.cc index 8c03adaf..6d91eea 100644 --- a/mojo/core/port_event_fuzzer.cc +++ b/mojo/core/port_event_fuzzer.cc
@@ -5,7 +5,6 @@ #include <stdint.h> #include "base/containers/span.h" -#include "base/no_destructor.h" #include "mojo/core/entrypoints.h" #include "mojo/core/node_controller.h" @@ -16,7 +15,7 @@ }; extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) { - static base::NoDestructor<Environment> environment; + static Environment environment; // Try using the fuzz as the full contents of a port event. mojo::core::NodeController::DeserializeRawBytesAsEventForFuzzer(
diff --git a/mojo/core/user_message_fuzzer.cc b/mojo/core/user_message_fuzzer.cc index 6b6091d..7365d2d 100644 --- a/mojo/core/user_message_fuzzer.cc +++ b/mojo/core/user_message_fuzzer.cc
@@ -5,7 +5,6 @@ #include <stdint.h> #include "base/containers/span.h" -#include "base/no_destructor.h" #include "mojo/core/entrypoints.h" #include "mojo/core/node_controller.h" #include "mojo/core/user_message_impl.h" @@ -17,7 +16,7 @@ }; extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) { - static base::NoDestructor<Environment> environment; + static Environment environment; // Try using our fuzz input as the payload of an otherwise well-formed user // message event.
diff --git a/mojo/public/c/system/thunks.cc b/mojo/public/c/system/thunks.cc index eb2cd668..d7dc6e3 100644 --- a/mojo/public/c/system/thunks.cc +++ b/mojo/public/c/system/thunks.cc
@@ -142,7 +142,9 @@ extern "C" { MojoResult MojoInitialize(const struct MojoInitializeOptions* options) { - static base::NoDestructor<mojo::CoreLibraryInitializer> initializer; + static base::NoDestructor<mojo::CoreLibraryInitializer, + base::AllowForTriviallyDestructibleType> + initializer; base::StringPiece library_path_utf8; if (options) {
diff --git a/mojo/public/cpp/bindings/lib/connector.cc b/mojo/public/cpp/bindings/lib/connector.cc index e2eafb9..92a9756 100644 --- a/mojo/public/cpp/bindings/lib/connector.cc +++ b/mojo/public/cpp/bindings/lib/connector.cc
@@ -16,7 +16,6 @@ #include "base/memory/ptr_util.h" #include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_macros.h" -#include "base/no_destructor.h" #include "base/rand_util.h" #include "base/run_loop.h" #include "base/strings/strcat.h" @@ -105,10 +104,9 @@ // The NestingObserver for each thread. Note that this is always a // Connector::RunLoopNestingObserver; we use the base type here because that // subclass is private to Connector. - static base::NoDestructor< - base::SequenceLocalStorageSlot<RunLoopNestingObserver>> + static base::SequenceLocalStorageSlot<RunLoopNestingObserver> sls_nesting_observer; - return &sls_nesting_observer->GetOrCreateValue(); + return &sls_nesting_observer.GetOrCreateValue(); } private:
diff --git a/mojo/public/cpp/bindings/lib/sequence_local_sync_event_watcher.cc b/mojo/public/cpp/bindings/lib/sequence_local_sync_event_watcher.cc index 1d91787..03ff19e3 100644 --- a/mojo/public/cpp/bindings/lib/sequence_local_sync_event_watcher.cc +++ b/mojo/public/cpp/bindings/lib/sequence_local_sync_event_watcher.cc
@@ -14,7 +14,6 @@ #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" -#include "base/no_destructor.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" #include "base/threading/sequence_local_storage_slot.h" @@ -173,8 +172,8 @@ private: using StorageSlotType = base::SequenceLocalStorageSlot<SequenceLocalState>; static StorageSlotType& GetStorageSlot() { - static base::NoDestructor<StorageSlotType> storage; - return *storage; + static StorageSlotType storage; + return storage; } void OnEventSignaled();
diff --git a/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc b/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc index b6cb0a7..45103af 100644 --- a/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc +++ b/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc
@@ -47,8 +47,8 @@ } size_t& GetSequenceLocalScopedAllowCount() { - static base::NoDestructor<base::SequenceLocalStorageSlot<size_t>> count; - return count->GetOrCreateValue(); + static base::SequenceLocalStorageSlot<size_t> count; + return count.GetOrCreateValue(); } // Sometimes sync calls need to be made while sequence-local storage is not
diff --git a/mojo/public/cpp/bindings/lib/sync_handle_registry.cc b/mojo/public/cpp/bindings/lib/sync_handle_registry.cc index 512bece..ffb49ca7 100644 --- a/mojo/public/cpp/bindings/lib/sync_handle_registry.cc +++ b/mojo/public/cpp/bindings/lib/sync_handle_registry.cc
@@ -35,8 +35,7 @@ // static scoped_refptr<SyncHandleRegistry> SyncHandleRegistry::current() { - static base::NoDestructor< - base::SequenceLocalStorageSlot<scoped_refptr<SyncHandleRegistry>>> + static base::SequenceLocalStorageSlot<scoped_refptr<SyncHandleRegistry>> g_current_sync_handle_watcher; // SyncMessageFilter can be used on threads without sequence-local storage @@ -46,12 +45,12 @@ base::PassKey<SyncHandleRegistry>()); } - if (!*g_current_sync_handle_watcher) { - g_current_sync_handle_watcher->emplace( + if (!g_current_sync_handle_watcher) { + g_current_sync_handle_watcher.emplace( base::MakeRefCounted<SyncHandleRegistry>( base::PassKey<SyncHandleRegistry>())); } - return *g_current_sync_handle_watcher->GetValuePointer(); + return *g_current_sync_handle_watcher.GetValuePointer(); } SyncHandleRegistry::SyncHandleRegistry(base::PassKey<SyncHandleRegistry>) {}
diff --git a/net/base/host_mapping_rules.cc b/net/base/host_mapping_rules.cc index a10be8d..4ec3cc09 100644 --- a/net/base/host_mapping_rules.cc +++ b/net/base/host_mapping_rules.cc
@@ -73,7 +73,7 @@ return false; } -bool HostMappingRules::RewriteUrl(GURL& url) const { +HostMappingRules::RewriteResult HostMappingRules::RewriteUrl(GURL& url) const { // Must be a valid and standard URL. Otherwise, Chrome might not know how to // find/replace the contained host or port. DCHECK(url.is_valid()); @@ -82,17 +82,17 @@ HostPortPair host_port_pair = HostPortPair::FromURL(url); if (!RewriteHost(&host_port_pair)) - return false; + return RewriteResult::kNoMatchingRule; url::Replacements<char> replacements; std::string port_str = base::NumberToString(host_port_pair.port()); replacements.SetPort(port_str.c_str(), url::Component(0, port_str.size())); - replacements.SetHost(host_port_pair.host().c_str(), - url::Component(0, host_port_pair.host().size())); + std::string host_str = host_port_pair.HostForURL(); + replacements.SetHost(host_str.c_str(), url::Component(0, host_str.size())); GURL new_url = url.ReplaceComponents(replacements); if (!new_url.is_valid()) - return false; + return RewriteResult::kInvalidRewrite; DCHECK(new_url.IsStandard()); DCHECK(new_url.has_host()); @@ -100,7 +100,7 @@ new_url.EffectiveIntPort() == url::PORT_UNSPECIFIED); url = std::move(new_url); - return true; + return RewriteResult::kRewritten; } bool HostMappingRules::AddRuleFromString(base::StringPiece rule_string) {
diff --git a/net/base/host_mapping_rules.h b/net/base/host_mapping_rules.h index 738219ef..a8d7f95 100644 --- a/net/base/host_mapping_rules.h +++ b/net/base/host_mapping_rules.h
@@ -19,6 +19,12 @@ class NET_EXPORT_PRIVATE HostMappingRules { public: + enum class RewriteResult { + kRewritten, + kNoMatchingRule, + kInvalidRewrite, + }; + HostMappingRules(); HostMappingRules(const HostMappingRules& host_mapping_rules); ~HostMappingRules(); @@ -29,11 +35,15 @@ // `*host_port` was modified, false otherwise. bool RewriteHost(HostPortPair* host_port) const; - // Modifies the host and port of `url` based on current rules. Returns true if - // `url` was modified, false otherwise. May only be called for URLs with a - // host and a scheme that is standard, and if the scheme does not allow ports, - // only the host will be rewritten. - bool RewriteUrl(GURL& url) const; + // Modifies the host and port of `url` based on current rules. May only be + // called for URLs with a host and a scheme that is standard, and if the + // scheme does not allow ports, only the host will be rewritten. + // + // If `url` is rewritten, returns `kRewritten`. If no matching rule is found, + // returns `kNoMatchingRule` and `url` is not modified. If a matching rule is + // found but it results in an invalid URL, e.g. if the rule maps to + // "~NOTFOUND", returns `kInvalidRewrite` and `url` is not modified. + RewriteResult RewriteUrl(GURL& url) const; // Adds a rule to this mapper. The format of the rule can be one of: //
diff --git a/net/base/host_mapping_rules_unittest.cc b/net/base/host_mapping_rules_unittest.cc index 272a42b..8226858 100644 --- a/net/base/host_mapping_rules_unittest.cc +++ b/net/base/host_mapping_rules_unittest.cc
@@ -92,16 +92,25 @@ rules.AddRuleFromString("MAP initial.test replacement.test:1000"); GURL url("http://initial.test:111"); - EXPECT_TRUE(rules.RewriteUrl(url)); + EXPECT_EQ(rules.RewriteUrl(url), HostMappingRules::RewriteResult::kRewritten); EXPECT_EQ(url, GURL("http://replacement.test:1000")); } +TEST(HostMappingRulesTest, RewritesUrlToIpv6Literal) { + HostMappingRules rules; + rules.AddRuleFromString("MAP initial.test [2345:6789::0abc]:1112"); + + GURL url("http://initial.test:111"); + EXPECT_EQ(rules.RewriteUrl(url), HostMappingRules::RewriteResult::kRewritten); + EXPECT_EQ(url, GURL("http://[2345:6789::0abc]:1112")); +} + TEST(HostMappingRulesTest, RewritesUrlPreservingScheme) { HostMappingRules rules; rules.AddRuleFromString("MAP initial.test replacement.test:1000"); GURL url("wss://initial.test:222"); - EXPECT_TRUE(rules.RewriteUrl(url)); + EXPECT_EQ(rules.RewriteUrl(url), HostMappingRules::RewriteResult::kRewritten); EXPECT_EQ(url, GURL("wss://replacement.test:1000")); } @@ -112,7 +121,7 @@ // Expect replacement port to be ignored because file URLs do not use port. GURL url("file://initial.test/file.txt"); ASSERT_EQ(url.EffectiveIntPort(), url::PORT_UNSPECIFIED); - EXPECT_TRUE(rules.RewriteUrl(url)); + EXPECT_EQ(rules.RewriteUrl(url), HostMappingRules::RewriteResult::kRewritten); EXPECT_EQ(url, GURL("file://replacement.test/file.txt")); EXPECT_EQ(url.EffectiveIntPort(), url::PORT_UNSPECIFIED); } @@ -127,7 +136,7 @@ rules.AddRuleFromString("MAP initial.test replacement.test:1000"); GURL url("foo://initial.test:100"); - EXPECT_TRUE(rules.RewriteUrl(url)); + EXPECT_EQ(rules.RewriteUrl(url), HostMappingRules::RewriteResult::kRewritten); EXPECT_EQ(url, GURL("foo://replacement.test:1000")); } @@ -143,7 +152,7 @@ // Expect replacement port to be ignored. GURL url("foo://initial.test"); ASSERT_EQ(url.EffectiveIntPort(), url::PORT_UNSPECIFIED); - EXPECT_TRUE(rules.RewriteUrl(url)); + EXPECT_EQ(rules.RewriteUrl(url), HostMappingRules::RewriteResult::kRewritten); EXPECT_EQ(url, GURL("foo://replacement.test")); EXPECT_EQ(url.EffectiveIntPort(), url::PORT_UNSPECIFIED); } @@ -153,7 +162,8 @@ rules.AddRuleFromString("MAP initial.test replacement.test:1000"); GURL url("http://different.test:111"); - EXPECT_FALSE(rules.RewriteUrl(url)); + EXPECT_EQ(rules.RewriteUrl(url), + HostMappingRules::RewriteResult::kNoMatchingRule); EXPECT_EQ(url, GURL("http://different.test:111")); } @@ -162,7 +172,20 @@ rules.AddRuleFromString("MAP initial.test invalid/url"); GURL url("http://initial.test"); - EXPECT_FALSE(rules.RewriteUrl(url)); + EXPECT_EQ(rules.RewriteUrl(url), + HostMappingRules::RewriteResult::kInvalidRewrite); + EXPECT_EQ(url, GURL("http://initial.test")); +} + +// Remapping to "~NOTFOUND" is documented as a special case for +// MappedHostResolver usage. Ensure that it is handled as invalid as expected. +TEST(HostMappingRulesTest, NotFoundIgnoredAsInvalidUrl) { + HostMappingRules rules; + rules.AddRuleFromString("MAP initial.test ~NOTFOUND"); + + GURL url("http://initial.test"); + EXPECT_EQ(rules.RewriteUrl(url), + HostMappingRules::RewriteResult::kInvalidRewrite); EXPECT_EQ(url, GURL("http://initial.test")); }
diff --git a/net/dns/context_host_resolver.cc b/net/dns/context_host_resolver.cc index 915bc74..9c9c173 100644 --- a/net/dns/context_host_resolver.cc +++ b/net/dns/context_host_resolver.cc
@@ -16,11 +16,15 @@ #include "net/base/network_isolation_key.h" #include "net/dns/dns_config.h" #include "net/dns/host_cache.h" +#include "net/dns/host_resolver.h" #include "net/dns/host_resolver_manager.h" #include "net/dns/host_resolver_proc.h" #include "net/dns/public/resolve_error_info.h" #include "net/dns/resolve_context.h" +#include "net/log/net_log_with_source.h" #include "net/url_request/url_request_context.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/scheme_host_port.h" namespace net { @@ -172,9 +176,8 @@ const absl::optional<HostCache::EntryStaleness>& GetStaleInfo() const override { if (!inner_request_) { - static const base::NoDestructor<absl::optional<HostCache::EntryStaleness>> - nullopt_result; - return *nullopt_result; + static const absl::optional<HostCache::EntryStaleness> nullopt_result; + return nullopt_result; } return inner_request_->GetStaleInfo(); @@ -293,6 +296,29 @@ std::unique_ptr<HostResolver::ResolveHostRequest> ContextHostResolver::CreateRequest( + url::SchemeHostPort host, + NetworkIsolationKey network_isolation_key, + NetLogWithSource source_net_log, + absl::optional<ResolveHostParameters> optional_parameters) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + std::unique_ptr<HostResolverManager::CancellableResolveHostRequest> + inner_request; + if (!shutting_down_) { + inner_request = manager_->CreateRequest( + std::move(host), std::move(network_isolation_key), + std::move(source_net_log), std::move(optional_parameters), + resolve_context_.get(), resolve_context_->host_cache()); + } + + auto request = std::make_unique<WrappedResolveHostRequest>( + std::move(inner_request), this, shutting_down_); + handed_out_requests_.insert(request.get()); + return request; +} + +std::unique_ptr<HostResolver::ResolveHostRequest> +ContextHostResolver::CreateRequest( const HostPortPair& host, const NetworkIsolationKey& network_isolation_key, const NetLogWithSource& source_net_log,
diff --git a/net/dns/context_host_resolver.h b/net/dns/context_host_resolver.h index 5faba8da..eed4048 100644 --- a/net/dns/context_host_resolver.h +++ b/net/dns/context_host_resolver.h
@@ -12,7 +12,11 @@ #include "base/macros.h" #include "base/sequence_checker.h" #include "net/base/net_export.h" +#include "net/base/network_isolation_key.h" #include "net/dns/host_resolver.h" +#include "net/log/net_log_with_source.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/scheme_host_port.h" namespace base { class TickClock; @@ -45,6 +49,11 @@ // HostResolver methods: void OnShutdown() override; std::unique_ptr<ResolveHostRequest> CreateRequest( + url::SchemeHostPort host, + NetworkIsolationKey network_isolation_key, + NetLogWithSource net_log, + absl::optional<ResolveHostParameters> optional_parameters) override; + std::unique_ptr<ResolveHostRequest> CreateRequest( const HostPortPair& host, const NetworkIsolationKey& network_isolation_key, const NetLogWithSource& net_log,
diff --git a/net/dns/context_host_resolver_unittest.cc b/net/dns/context_host_resolver_unittest.cc index c4a51e5..39e71f1a 100644 --- a/net/dns/context_host_resolver_unittest.cc +++ b/net/dns/context_host_resolver_unittest.cc
@@ -4,6 +4,7 @@ #include "net/dns/context_host_resolver.h" +#include <memory> #include <utility> #include "base/bind.h" @@ -17,12 +18,14 @@ #include "net/base/ip_address.h" #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" +#include "net/base/network_isolation_key.h" #include "net/base/schemeful_site.h" #include "net/base/test_completion_callback.h" #include "net/dns/dns_config.h" #include "net/dns/dns_test_util.h" #include "net/dns/dns_util.h" #include "net/dns/host_cache.h" +#include "net/dns/host_resolver.h" #include "net/dns/host_resolver_manager.h" #include "net/dns/host_resolver_source.h" #include "net/dns/mock_host_resolver.h" @@ -37,6 +40,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/gurl.h" +#include "url/scheme_host_port.h" namespace net { @@ -123,6 +127,59 @@ testing::ElementsAre(kEndpoint)); } +TEST_F(ContextHostResolverTest, ResolveWithScheme) { + URLRequestContext context; + + MockDnsClientRuleList rules; + rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */, + MockDnsClientRule::Result(BuildTestDnsAddressResponse( + "example.com", kEndpoint.address())), + false /* delay */, &context); + rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */, + MockDnsClientRule::Result(MockDnsClientRule::EMPTY), + false /* delay */, &context); + SetMockDnsRules(std::move(rules)); + + auto resolve_context = + std::make_unique<ResolveContext>(&context, false /* enable_caching */); + auto resolver = std::make_unique<ContextHostResolver>( + manager_.get(), std::move(resolve_context)); + std::unique_ptr<HostResolver::ResolveHostRequest> request = + resolver->CreateRequest( + url::SchemeHostPort(url::kHttpsScheme, "example.com", 100), + NetworkIsolationKey(), NetLogWithSource(), absl::nullopt); + + TestCompletionCallback callback; + int rv = request->Start(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), test::IsOk()); + EXPECT_THAT(request->GetResolveErrorInfo().error, test::IsError(net::OK)); + EXPECT_THAT(request->GetAddressResults().value().endpoints(), + testing::ElementsAre(kEndpoint)); +} + +TEST_F(ContextHostResolverTest, ResolveWithSchemeAndIpLiteral) { + URLRequestContext context; + + IPAddress expected_address; + ASSERT_TRUE(expected_address.AssignFromIPLiteral("1234::5678")); + + auto resolve_context = + std::make_unique<ResolveContext>(&context, false /* enable_caching */); + auto resolver = std::make_unique<ContextHostResolver>( + manager_.get(), std::move(resolve_context)); + std::unique_ptr<HostResolver::ResolveHostRequest> request = + resolver->CreateRequest( + url::SchemeHostPort(url::kHttpsScheme, "[1234::5678]", 100), + NetworkIsolationKey(), NetLogWithSource(), absl::nullopt); + + TestCompletionCallback callback; + int rv = request->Start(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), test::IsOk()); + EXPECT_THAT(request->GetResolveErrorInfo().error, test::IsError(net::OK)); + EXPECT_THAT(request->GetAddressResults().value().endpoints(), + testing::ElementsAre(IPEndPoint(expected_address, 100))); +} + // Test that destroying a request silently cancels that request. TEST_F(ContextHostResolverTest, DestroyRequest) { // Set up delayed results for "example.com".
diff --git a/net/dns/dns_test_util.cc b/net/dns/dns_test_util.cc index 4c86ee84..1193eff 100644 --- a/net/dns/dns_test_util.cc +++ b/net/dns/dns_test_util.cc
@@ -339,7 +339,7 @@ public base::SupportsWeakPtr<MockTransaction> { public: MockTransaction(const MockDnsClientRuleList& rules, - const std::string& hostname, + std::string hostname, uint16_t qtype, bool secure, bool force_doh_server_available, @@ -348,7 +348,7 @@ bool fast_timeout, DnsTransactionFactory::CallbackType callback) : result_(MockDnsClientRule::FAIL), - hostname_(hostname), + hostname_(std::move(hostname)), qtype_(qtype), callback_(std::move(callback)), started_(false), @@ -359,13 +359,13 @@ resolve_context->NumAvailableDohServers( resolve_context->current_session_for_testing()) > 0) { // Find the relevant rule which matches |qtype|, |secure|, prefix of - // |hostname|, and |url_request_context| (iff the rule context is not + // |hostname_|, and |url_request_context| (iff the rule context is not // null). for (size_t i = 0; i < rules.size(); ++i) { const std::string& prefix = rules[i].prefix; if ((rules[i].qtype == qtype) && (rules[i].secure == secure) && - (hostname.size() >= prefix.size()) && - (hostname.compare(0, prefix.size(), prefix) == 0) && + (hostname_.size() >= prefix.size()) && + (hostname_.compare(0, prefix.size(), prefix) == 0) && (!rules[i].context || rules[i].context == resolve_context->url_request_context())) { const MockDnsClientRule::Result* result = &rules[i].result; @@ -537,7 +537,7 @@ MockDnsTransactionFactory::~MockDnsTransactionFactory() = default; std::unique_ptr<DnsTransaction> MockDnsTransactionFactory::CreateTransaction( - const std::string& hostname, + std::string hostname, uint16_t qtype, DnsTransactionFactory::CallbackType callback, const NetLogWithSource&, @@ -546,9 +546,10 @@ ResolveContext* resolve_context, bool fast_timeout) { std::unique_ptr<MockTransaction> transaction = - std::make_unique<MockTransaction>( - rules_, hostname, qtype, secure, force_doh_server_available_, - secure_dns_mode, resolve_context, fast_timeout, std::move(callback)); + std::make_unique<MockTransaction>(rules_, std::move(hostname), qtype, + secure, force_doh_server_available_, + secure_dns_mode, resolve_context, + fast_timeout, std::move(callback)); if (transaction->delayed()) delayed_transactions_.push_back(transaction->AsWeakPtr()); return transaction;
diff --git a/net/dns/dns_test_util.h b/net/dns/dns_test_util.h index 5e2895b4..8c04281 100644 --- a/net/dns/dns_test_util.h +++ b/net/dns/dns_test_util.h
@@ -330,7 +330,7 @@ ~MockDnsTransactionFactory() override; std::unique_ptr<DnsTransaction> CreateTransaction( - const std::string& hostname, + std::string hostname, uint16_t qtype, DnsTransactionFactory::CallbackType callback, const NetLogWithSource&,
diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc index 57d5663..7be16510 100644 --- a/net/dns/dns_transaction.cc +++ b/net/dns/dns_transaction.cc
@@ -1040,7 +1040,7 @@ public base::SupportsWeakPtr<DnsTransactionImpl> { public: DnsTransactionImpl(DnsSession* session, - const std::string& hostname, + std::string hostname, uint16_t qtype, DnsTransactionFactory::CallbackType callback, const NetLogWithSource& net_log, @@ -1050,7 +1050,7 @@ ResolveContext* resolve_context, bool fast_timeout) : session_(session), - hostname_(hostname), + hostname_(std::move(hostname)), qtype_(qtype), opt_rdata_(opt_rdata), secure_(secure), @@ -1648,7 +1648,7 @@ } std::unique_ptr<DnsTransaction> CreateTransaction( - const std::string& hostname, + std::string hostname, uint16_t qtype, CallbackType callback, const NetLogWithSource& net_log, @@ -1657,8 +1657,8 @@ ResolveContext* resolve_context, bool fast_timeout) override { return std::make_unique<DnsTransactionImpl>( - session_.get(), hostname, qtype, std::move(callback), net_log, - opt_rdata_.get(), secure, secure_dns_mode, resolve_context, + session_.get(), std::move(hostname), qtype, std::move(callback), + net_log, opt_rdata_.get(), secure, secure_dns_mode, resolve_context, fast_timeout); }
diff --git a/net/dns/dns_transaction.h b/net/dns/dns_transaction.h index c6e3471..3b47b8a 100644 --- a/net/dns/dns_transaction.h +++ b/net/dns/dns_transaction.h
@@ -112,7 +112,7 @@ // and it would be beneficial to move on to those options sooner on signals // that the transaction is potentially slow or problematic. virtual std::unique_ptr<DnsTransaction> CreateTransaction( - const std::string& hostname, + std::string hostname, uint16_t qtype, CallbackType callback, const NetLogWithSource& net_log,
diff --git a/net/dns/host_cache.cc b/net/dns/host_cache.cc index 17bd553..9af27e2 100644 --- a/net/dns/host_cache.cc +++ b/net/dns/host_cache.cc
@@ -112,12 +112,12 @@ MAX_ERASE_REASON }; -HostCache::Key::Key(const std::string& hostname, +HostCache::Key::Key(std::string hostname, DnsQueryType dns_query_type, HostResolverFlags host_resolver_flags, HostResolverSource host_resolver_source, const NetworkIsolationKey& network_isolation_key) - : hostname(hostname), + : hostname(std::move(hostname)), dns_query_type(dns_query_type), host_resolver_flags(host_resolver_flags), host_resolver_source(host_resolver_source),
diff --git a/net/dns/host_cache.h b/net/dns/host_cache.h index 0aa5e37..2f83993 100644 --- a/net/dns/host_cache.h +++ b/net/dns/host_cache.h
@@ -46,7 +46,7 @@ class NET_EXPORT HostCache { public: struct NET_EXPORT Key { - Key(const std::string& hostname, + Key(std::string hostname, DnsQueryType dns_query_type, HostResolverFlags host_resolver_flags, HostResolverSource host_resolver_source,
diff --git a/net/dns/host_resolver.cc b/net/dns/host_resolver.cc index 16c6589c..b13c671 100644 --- a/net/dns/host_resolver.cc +++ b/net/dns/host_resolver.cc
@@ -72,9 +72,8 @@ const absl::optional<HostCache::EntryStaleness>& GetStaleInfo() const override { - static const base::NoDestructor<absl::optional<HostCache::EntryStaleness>> - nullopt_result; - return *nullopt_result; + static const absl::optional<HostCache::EntryStaleness> nullopt_result; + return nullopt_result; } private:
diff --git a/net/dns/host_resolver.h b/net/dns/host_resolver.h index 334527d..93676bb 100644 --- a/net/dns/host_resolver.h +++ b/net/dns/host_resolver.h
@@ -17,6 +17,7 @@ #include "net/base/address_family.h" #include "net/base/completion_once_callback.h" #include "net/base/host_port_pair.h" +#include "net/base/network_isolation_key.h" #include "net/base/request_priority.h" #include "net/dns/host_cache.h" #include "net/dns/host_resolver_source.h" @@ -24,7 +25,9 @@ #include "net/dns/public/dns_query_type.h" #include "net/dns/public/resolve_error_info.h" #include "net/dns/public/secure_dns_policy.h" +#include "net/log/net_log_with_source.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/scheme_host_port.h" namespace base { class Value; @@ -38,7 +41,6 @@ struct DnsConfigOverrides; class HostResolverManager; class NetLog; -class NetLogWithSource; class URLRequestContext; // This class represents the task of resolving hostnames (or IP address @@ -324,7 +326,15 @@ // Profiling information for the request is saved to |net_log| if non-NULL. // // Additional parameters may be set using |optional_parameters|. Reasonable - // defaults will be used if passed |absl::nullopt|. + // defaults will be used if passed |nullptr|. + virtual std::unique_ptr<ResolveHostRequest> CreateRequest( + url::SchemeHostPort host, + NetworkIsolationKey network_isolation_key, + NetLogWithSource net_log, + absl::optional<ResolveHostParameters> optional_parameters) = 0; + + // Create requests when scheme is unknown or non-standard. + // TODO(crbug.com/1206799): Rename to discourage use when scheme is known. virtual std::unique_ptr<ResolveHostRequest> CreateRequest( const HostPortPair& host, const NetworkIsolationKey& network_isolation_key,
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc index 5a901ad..3e1e676 100644 --- a/net/dns/host_resolver_manager.cc +++ b/net/dns/host_resolver_manager.cc
@@ -99,6 +99,9 @@ #include "net/log/net_log_with_source.h" #include "net/socket/client_socket_factory.h" #include "net/socket/datagram_client_socket.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/abseil-cpp/absl/types/variant.h" +#include "url/scheme_host_port.h" #include "url/third_party/mozilla/url_parse.h" #include "url/url_canon_ip.h" @@ -171,7 +174,7 @@ } // True if |hostname| ends with either ".local" or ".local.". -bool ResemblesMulticastDNSName(const std::string& hostname) { +bool ResemblesMulticastDNSName(base::StringPiece hostname) { const char kSuffix[] = ".local."; const size_t kSuffixLen = sizeof(kSuffix) - 1; const size_t kSuffixLenTrimmed = kSuffixLen - 1; @@ -324,7 +327,7 @@ // Creates NetLog parameters for the creation of a HostResolverManager::Job. base::Value NetLogJobCreationParams(const NetLogSource& source, - const std::string& host) { + base::StringPiece host) { base::Value dict(base::Value::Type::DICTIONARY); source.AddToEventParameters(&dict); dict.SetStringKey("host", host); @@ -464,6 +467,57 @@ net_log.AddEntry(type, phase, [&] { return results.NetLogParams(); }); } +base::Value ToLogStringValue( + const absl::variant<url::SchemeHostPort, HostPortPair>& host) { + if (absl::holds_alternative<url::SchemeHostPort>(host)) + return base::Value(absl::get<url::SchemeHostPort>(host).Serialize()); + + return base::Value(absl::get<HostPortPair>(host).ToString()); +} + +base::StringPiece GetHostname( + const absl::variant<url::SchemeHostPort, HostPortPair>& host) { + if (absl::holds_alternative<url::SchemeHostPort>(host)) { + base::StringPiece hostname = absl::get<url::SchemeHostPort>(host).host(); + if (hostname.size() >= 2 && hostname.front() == '[' && + hostname.back() == ']') { + hostname = hostname.substr(1, hostname.size() - 2); + } + return hostname; + } + + return absl::get<HostPortPair>(host).host(); +} + +base::StringPiece GetHostname( + const absl::variant<url::SchemeHostPort, std::string>& host) { + if (absl::holds_alternative<url::SchemeHostPort>(host)) { + base::StringPiece hostname = absl::get<url::SchemeHostPort>(host).host(); + if (hostname.size() >= 2 && hostname.front() == '[' && + hostname.back() == ']') { + hostname = hostname.substr(1, hostname.size() - 2); + } + return hostname; + } + + return absl::get<std::string>(host); +} + +uint16_t GetPort(const absl::variant<url::SchemeHostPort, HostPortPair>& host) { + if (absl::holds_alternative<url::SchemeHostPort>(host)) { + return absl::get<url::SchemeHostPort>(host).port(); + } + + return absl::get<HostPortPair>(host).port(); +} + +// TODO(crbug.com/1206799): Make dependent on status of `kUseDnsHttpsSvcb` +// Feature. +absl::variant<url::SchemeHostPort, std::string> CreateHostForJobKey( + const absl::variant<url::SchemeHostPort, HostPortPair>& input) { + return std::string(GetHostname(input)); +} + } // namespace //----------------------------------------------------------------------------- @@ -494,22 +548,22 @@ : public CancellableResolveHostRequest, public base::LinkNode<HostResolverManager::RequestImpl> { public: - RequestImpl(const NetLogWithSource& source_net_log, - const HostPortPair& request_host, - const NetworkIsolationKey& network_isolation_key, - const absl::optional<ResolveHostParameters>& optional_parameters, + RequestImpl(NetLogWithSource source_net_log, + absl::variant<url::SchemeHostPort, HostPortPair> request_host, + NetworkIsolationKey network_isolation_key, + absl::optional<ResolveHostParameters> optional_parameters, ResolveContext* resolve_context, HostCache* host_cache, base::WeakPtr<HostResolverManager> resolver, const base::TickClock* tick_clock) - : source_net_log_(source_net_log), - request_host_(request_host), + : source_net_log_(std::move(source_net_log)), + request_host_(std::move(request_host)), network_isolation_key_( base::FeatureList::IsEnabled( net::features::kSplitHostCacheByNetworkIsolationKey) - ? network_isolation_key + ? std::move(network_isolation_key) : NetworkIsolationKey()), - parameters_(optional_parameters ? optional_parameters.value() + parameters_(optional_parameters ? std::move(optional_parameters).value() : ResolveHostParameters()), resolve_context_(resolve_context), host_cache_(host_cache), @@ -671,7 +725,9 @@ // NetLog for the source, passed in HostResolver::Resolve. const NetLogWithSource& source_net_log() { return source_net_log_; } - const HostPortPair& request_host() const { return request_host_; } + const absl::variant<url::SchemeHostPort, HostPortPair>& request_host() const { + return request_host_; + } const NetworkIsolationKey& network_isolation_key() const { return network_isolation_key_; @@ -712,7 +768,7 @@ source_net_log_.BeginEvent( NetLogEventType::HOST_RESOLVER_IMPL_REQUEST, [this] { base::Value dict(base::Value::Type::DICTIONARY); - dict.SetStringKey("host", request_host_.ToString()); + dict.SetKey("host", ToLogStringValue(request_host_)); dict.SetIntKey("dns_query_type", static_cast<int>(parameters_.dns_query_type)); dict.SetBoolKey("allow_cached_response", @@ -731,9 +787,9 @@ source_net_log_.EndEventWithNetErrorCode( NetLogEventType::HOST_RESOLVER_IMPL_REQUEST, net_error); + base::StringPiece hostname = GetHostname(request_host_); url::HostSafetyStatus host_safety_status = url::CheckHostnameSafety( - request_host_.host().c_str(), - url::Component(0, request_host_.host().size())); + hostname.data(), url::Component(0, hostname.size())); if (net_error == net::OK) { UMA_HISTOGRAM_ENUMERATION("Net.DNS.Request.Success.HostSafetyStatus", host_safety_status); @@ -760,7 +816,7 @@ const NetLogWithSource source_net_log_; - const HostPortPair request_host_; + const absl::variant<url::SchemeHostPort, HostPortPair> request_host_; const NetworkIsolationKey network_isolation_key_; ResolveHostParameters parameters_; // TODO(ericorth@chromium.org): Use base::UnownedPtr once available. @@ -1117,7 +1173,7 @@ }; DnsTask(DnsClient* client, - base::StringPiece hostname, + absl::variant<url::SchemeHostPort, std::string> host, DnsQueryType query_type, ResolveContext* resolve_context, bool secure, @@ -1127,7 +1183,7 @@ const base::TickClock* tick_clock, bool fallback_available) : client_(client), - hostname_(hostname), + host_(std::move(host)), resolve_context_(resolve_context), secure_(secure), secure_dns_mode_(secure_dns_mode), @@ -1151,9 +1207,9 @@ // Queue up an INTEGRITY/HTTPS query if we are allowed to. const bool is_httpssvc_experiment_domain = - httpssvc_domain_cache_.IsExperimental(hostname); + httpssvc_domain_cache_.IsExperimental(GetHostname(host_)); const bool is_httpssvc_control_domain = - httpssvc_domain_cache_.IsControl(hostname); + httpssvc_domain_cache_.IsControl(GetHostname(host_)); const bool can_query_via_insecure = !secure_ && features::kDnsHttpssvcEnableQueryOverInsecure.Get() && client_->CanQueryAdditionalTypesViaInsecureDns(); @@ -1215,7 +1271,8 @@ std::unique_ptr<DnsTransaction> trans = client_->GetTransactionFactory()->CreateTransaction( - hostname_, DnsQueryTypeToQtype(dns_query_type), + std::string(GetHostname(host_)), + DnsQueryTypeToQtype(dns_query_type), base::BindOnce(&DnsTask::OnTransactionComplete, base::Unretained(this), tick_clock_->NowTicks(), dns_query_type), @@ -1529,7 +1586,9 @@ } DnsClient* client_; - std::string hostname_; + + absl::variant<url::SchemeHostPort, std::string> host_; + // TODO(ericorth@chromium.org): Use base::UnownedPtr once available. ResolveContext* const resolve_context_; @@ -1574,14 +1633,13 @@ struct HostResolverManager::JobKey { bool operator<(const JobKey& other) const { return std::forward_as_tuple(query_type, flags, source, secure_dns_mode, - resolve_context, hostname, - network_isolation_key) < + resolve_context, host, network_isolation_key) < std::forward_as_tuple(other.query_type, other.flags, other.source, other.secure_dns_mode, other.resolve_context, - other.hostname, other.network_isolation_key); + other.host, other.network_isolation_key); } - std::string hostname; + absl::variant<url::SchemeHostPort, std::string> host; NetworkIsolationKey network_isolation_key; DnsQueryType query_type; HostResolverFlags flags; @@ -1591,8 +1649,9 @@ ResolveContext* resolve_context; HostCache::Key ToCacheKey(bool secure) const { - HostCache::Key key(hostname, query_type, flags, source, - network_isolation_key); + // TODO(crbug.com/1206799): Propagate scheme and port to cache key. + HostCache::Key key(std::string(GetHostname(host)), query_type, flags, + source, network_isolation_key); key.secure = secure; return key; } @@ -1634,7 +1693,8 @@ source_net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_CREATE_JOB); net_log_.BeginEvent(NetLogEventType::HOST_RESOLVER_IMPL_JOB, [&] { - return NetLogJobCreationParams(source_net_log.source(), key_.hostname); + return NetLogJobCreationParams(source_net_log.source(), + GetHostname(key_.host)); }); } @@ -1688,7 +1748,9 @@ // HostCache. Since the ResolveContext is part of the JobKey, any request // added to any existing Job should share the same HostCache. DCHECK_EQ(host_cache_, request->host_cache()); - DCHECK_EQ(key_.hostname, request->request_host().host()); + // TODO(crbug.com/1206799): Check equality of whole host once Jobs are + // separated by scheme/port. + DCHECK_EQ(GetHostname(key_.host), GetHostname(request->request_host())); request->AssignJob(this); @@ -1712,7 +1774,9 @@ } void ChangeRequestPriority(RequestImpl* req, RequestPriority priority) { - DCHECK_EQ(key_.hostname, req->request_host().host()); + // TODO(crbug.com/1206799): Check equality of whole host once Jobs are + // separated by scheme/port. + DCHECK_EQ(GetHostname(key_.host), GetHostname(req->request_host())); priority_tracker_.Remove(req->priority()); req->set_priority(priority); @@ -1723,7 +1787,9 @@ // Detach cancelled request. If it was the last active Request, also finishes // this Job. void CancelRequest(RequestImpl* request) { - DCHECK_EQ(key_.hostname, request->request_host().host()); + // TODO(crbug.com/1206799): Check equality of whole host once Jobs are + // separated by scheme/port. + DCHECK_EQ(GetHostname(key_.host), GetHostname(request->request_host())); DCHECK(!requests_.empty()); priority_tracker_.Remove(request->priority()); @@ -1814,7 +1880,7 @@ bool ServeFromHosts() { DCHECK_GT(num_active_requests(), 0u); absl::optional<HostCache::Entry> results = resolver_->ServeFromHosts( - key_.hostname, key_.query_type, + GetHostname(key_.host), key_.query_type, key_.flags & HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6, tasks_); if (results) { // This will destroy the Job. @@ -1986,7 +2052,7 @@ DCHECK(IsAddressType(key_.query_type)); proc_task_ = std::make_unique<ProcTask>( - key_.hostname, + std::string(GetHostname(key_.host)), HostResolver::DnsQueryTypeToAddressFamily(key_.query_type), key_.flags, resolver_->proc_params_, base::BindOnce(&Job::OnProcTaskComplete, base::Unretained(this), @@ -2055,7 +2121,7 @@ // Need to create the task even if we're going to post a failure instead of // running it, as a "started" job needs a task to be properly cleaned up. dns_task_ = std::make_unique<DnsTask>( - resolver_->dns_client_.get(), key_.hostname, key_.query_type, + resolver_->dns_client_.get(), key_.host, key_.query_type, key_.resolve_context, secure, key_.secure_dns_mode, this, net_log_, tick_clock_, !tasks_.empty() /* fallback_available */); dns_task_->StartNextTransaction(); @@ -2195,8 +2261,8 @@ MDnsClient* client = nullptr; int rv = resolver_->GetOrCreateMdnsClient(&client); - mdns_task_ = std::make_unique<HostResolverMdnsTask>(client, key_.hostname, - query_types); + mdns_task_ = std::make_unique<HostResolverMdnsTask>( + client, std::string(GetHostname(key_.host)), query_types); if (rv == OK) { mdns_task_->Start( @@ -2360,7 +2426,7 @@ if (results.error() == OK && !req->parameters().is_speculative) { req->set_results( - results.CopyWithDefaultPort(req->request_host().port())); + results.CopyWithDefaultPort(GetPort(req->request_host()))); // TODO(cammie): Move the sanitization deeper, possibly in // HttpCache::Entry::SetResult(AddressList addresses), so that it @@ -2553,10 +2619,10 @@ std::unique_ptr<HostResolverManager::CancellableResolveHostRequest> HostResolverManager::CreateRequest( - const HostPortPair& host, - const NetworkIsolationKey& network_isolation_key, - const NetLogWithSource& net_log, - const absl::optional<ResolveHostParameters>& optional_parameters, + absl::variant<url::SchemeHostPort, HostPortPair> host, + NetworkIsolationKey network_isolation_key, + NetLogWithSource net_log, + absl::optional<ResolveHostParameters> optional_parameters, ResolveContext* resolve_context, HostCache* host_cache) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -2567,8 +2633,9 @@ DCHECK(registered_contexts_.HasObserver(resolve_context)); return std::make_unique<RequestImpl>( - net_log, host, network_isolation_key, optional_parameters, - resolve_context, host_cache, weak_ptr_factory_.GetWeakPtr(), tick_clock_); + std::move(net_log), std::move(host), std::move(network_isolation_key), + std::move(optional_parameters), resolve_context, host_cache, + weak_ptr_factory_.GetWeakPtr(), tick_clock_); } std::unique_ptr<HostResolverManager::CancellableProbeRequest> @@ -2746,16 +2813,16 @@ const auto& parameters = request->parameters(); JobKey job_key; - job_key.hostname = request->request_host().host(); + job_key.host = CreateHostForJobKey(request->request_host()); job_key.network_isolation_key = request->network_isolation_key(); job_key.source = parameters.source; job_key.resolve_context = request->resolve_context(); IPAddress ip_address; - bool is_ip = ip_address.AssignFromIPLiteral(job_key.hostname); + bool is_ip = ip_address.AssignFromIPLiteral(GetHostname(job_key.host)); GetEffectiveParametersForRequest( - job_key.hostname, parameters.dns_query_type, + GetHostname(job_key.host), parameters.dns_query_type, request->host_resolver_flags(), parameters.secure_dns_policy, parameters.cache_usage, is_ip, request->source_net_log(), &job_key.query_type, &job_key.flags, &job_key.secure_dns_mode); @@ -2770,7 +2837,7 @@ tasks.empty()) { if (results.error() == OK && !request->parameters().is_speculative) { request->set_results( - results.CopyWithDefaultPort(request->request_host().port())); + results.CopyWithDefaultPort(GetPort(request->request_host()))); // TODO(cammie): Sanitize before adding to the cache instead. request->SanitizeDnsAliasResults(); @@ -2806,8 +2873,8 @@ // than implicitly based on |source|. const bool is_valid_hostname = job_key.source == HostResolverSource::MULTICAST_DNS - ? IsValidUnrestrictedDNSDomain(job_key.hostname) - : IsValidDNSDomain(job_key.hostname); + ? IsValidUnrestrictedDNSDomain(GetHostname(job_key.host)) + : IsValidDNSDomain(GetHostname(job_key.host)); if (!is_valid_hostname) { return HostCache::Entry(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_UNKNOWN); @@ -2821,7 +2888,8 @@ // The result of |getaddrinfo| for empty hosts is inconsistent across systems. // On Windows it gives the default interface's address, whereas on Linux it // gives an error. We will make it fail on all platforms for consistency. - if (job_key.hostname.empty() || job_key.hostname.size() > kMaxHostLength) { + if (GetHostname(job_key.host).empty() || + GetHostname(job_key.host).size() > kMaxHostLength) { return HostCache::Entry(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_UNKNOWN); } @@ -2833,7 +2901,7 @@ // Special-case localhost names, as per the recommendations in // https://tools.ietf.org/html/draft-west-let-localhost-be-localhost. - resolved = ServeLocalhost(job_key.hostname, job_key.query_type, + resolved = ServeLocalhost(GetHostname(job_key.host), job_key.query_type, default_family_due_to_no_ipv6); if (resolved) return resolved.value(); @@ -2868,7 +2936,7 @@ // TODO(szym): Do not do this if nsswitch.conf instructs not to. // http://crbug.com/117655 - resolved = ServeFromHosts(job_key.hostname, job_key.query_type, + resolved = ServeFromHosts(GetHostname(job_key.host), job_key.query_type, default_family_due_to_no_ipv6, *out_tasks); if (resolved) { NetLogHostCacheEntry(source_net_log, @@ -3209,7 +3277,7 @@ if ((job_key.flags & HOST_RESOLVER_CANONNAME) && IsAddressType(job_key.query_type)) { out_tasks->push_back(TaskType::PROC); - } else if (!ResemblesMulticastDNSName(job_key.hostname)) { + } else if (!ResemblesMulticastDNSName(GetHostname(job_key.host))) { bool proc_task_allowed = IsAddressType(job_key.query_type) && job_key.secure_dns_mode != SecureDnsMode::kSecure; @@ -3258,7 +3326,7 @@ } void HostResolverManager::GetEffectiveParametersForRequest( - const std::string& hostname, + base::StringPiece hostname, DnsQueryType dns_query_type, HostResolverFlags flags, SecureDnsPolicy secure_dns_policy,
diff --git a/net/dns/host_resolver_manager.h b/net/dns/host_resolver_manager.h index ad14780..d44b51b 100644 --- a/net/dns/host_resolver_manager.h +++ b/net/dns/host_resolver_manager.h
@@ -20,10 +20,13 @@ #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "base/strings/string_piece.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "net/base/completion_once_callback.h" +#include "net/base/host_port_pair.h" #include "net/base/network_change_notifier.h" +#include "net/base/network_isolation_key.h" #include "net/base/prioritized_dispatcher.h" #include "net/dns/dns_config.h" #include "net/dns/host_cache.h" @@ -35,7 +38,11 @@ #include "net/dns/public/secure_dns_policy.h" #include "net/dns/resolve_context.h" #include "net/dns/system_dns_config_change_notifier.h" +#include "net/log/net_log_with_source.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/abseil-cpp/absl/types/variant.h" #include "url/gurl.h" +#include "url/scheme_host_port.h" namespace base { class TickClock; @@ -46,13 +53,10 @@ class AddressList; class DnsClient; class DnsProbeRunner; -class HostPortPair; class IPAddress; class MDnsClient; class MDnsSocketFactory; class NetLog; -class NetLogWithSource; -class NetworkIsolationKey; // Scheduler and controller of host resolution requests. Because of the global // nature of host resolutions, this class is generally expected to be singleton @@ -149,10 +153,10 @@ // TODO(crbug.com/1022059): Use the HostCache out of the ResolveContext // instead of passing it separately. std::unique_ptr<CancellableResolveHostRequest> CreateRequest( - const HostPortPair& host, - const NetworkIsolationKey& network_isolation_key, - const NetLogWithSource& net_log, - const absl::optional<ResolveHostParameters>& optional_parameters, + absl::variant<url::SchemeHostPort, HostPortPair> host, + NetworkIsolationKey network_isolation_key, + NetLogWithSource net_log, + absl::optional<ResolveHostParameters> optional_parameters, ResolveContext* resolve_context, HostCache* host_cache); // |resolve_context| is the context to use for the probes, and it is expected @@ -359,7 +363,7 @@ // Determines "effective" request parameters using manager properties and IPv6 // reachability. void GetEffectiveParametersForRequest( - const std::string& hostname, + base::StringPiece hostname, DnsQueryType dns_query_type, HostResolverFlags flags, SecureDnsPolicy secure_dns_policy,
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc index 3c50380..1d5f655 100644 --- a/net/dns/host_resolver_manager_unittest.cc +++ b/net/dns/host_resolver_manager_unittest.cc
@@ -79,6 +79,8 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" +#include "url/scheme_host_port.h" +#include "url/url_constants.h" #if BUILDFLAG(ENABLE_MDNS) #include "net/dns/mdns_client_impl.h" @@ -663,6 +665,31 @@ EXPECT_TRUE(cache_result); } +// TODO(crbug.com/1206799): Confirm scheme behavior once it affects behavior. +TEST_F(HostResolverManagerTest, AsynchronousLookupWithScheme) { + proc_->AddRuleForAllFamilies("host.test", "192.168.1.42"); + proc_->SignalMultiple(1u); + + ResolveHostResponseHelper response(resolver_->CreateRequest( + url::SchemeHostPort(url::kHttpScheme, "host.test", 80), + NetworkIsolationKey(), NetLogWithSource(), absl::nullopt, + resolve_context_.get(), resolve_context_->host_cache())); + + EXPECT_THAT(response.result_error(), IsOk()); + EXPECT_THAT(response.top_level_result_error(), IsOk()); + EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("192.168.1.42", 80))); + EXPECT_FALSE(response.request()->GetStaleInfo()); + + EXPECT_EQ("host.test", proc_->GetCaptureList()[0].hostname); + + const std::pair<const HostCache::Key, HostCache::Entry>* cache_result = + GetCacheHit(HostCache::Key( + "host.test", DnsQueryType::UNSPECIFIED, 0 /* host_resolver_flags */, + HostResolverSource::ANY, NetworkIsolationKey())); + EXPECT_TRUE(cache_result); +} + TEST_F(HostResolverManagerTest, JobsClearedOnCompletion) { proc_->AddRuleForAllFamilies("just.testing", "192.168.1.42"); proc_->SignalMultiple(1u); @@ -686,7 +713,7 @@ NetLogWithSource(), absl::nullopt, resolve_context_.get(), resolve_context_->host_cache())); ResolveHostResponseHelper response2(resolver_->CreateRequest( - HostPortPair("just.testing", 85), NetworkIsolationKey(), + HostPortPair("just.testing", 80), NetworkIsolationKey(), NetLogWithSource(), absl::nullopt, resolve_context_.get(), resolve_context_->host_cache())); EXPECT_EQ(1u, resolver_->num_jobs_for_testing()); @@ -903,6 +930,17 @@ testing::ElementsAre(CreateExpected("127.1.2.3", 5555))); } +TEST_F(HostResolverManagerTest, NumericIPv4AddressWithScheme) { + ResolveHostResponseHelper response(resolver_->CreateRequest( + url::SchemeHostPort(url::kHttpsScheme, "127.1.2.3", 5555), + NetworkIsolationKey(), NetLogWithSource(), absl::nullopt, + resolve_context_.get(), resolve_context_->host_cache())); + + EXPECT_THAT(response.result_error(), IsOk()); + EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("127.1.2.3", 5555))); +} + TEST_F(HostResolverManagerTest, NumericIPv6Address) { // Resolve a plain IPv6 address. Don't worry about [brackets], because // the caller should have removed them. @@ -916,6 +954,17 @@ testing::ElementsAre(CreateExpected("2001:db8::1", 5555))); } +TEST_F(HostResolverManagerTest, NumericIPv6AddressWithScheme) { + ResolveHostResponseHelper response(resolver_->CreateRequest( + url::SchemeHostPort(url::kFtpScheme, "[2001:db8::1]", 5555), + NetworkIsolationKey(), NetLogWithSource(), absl::nullopt, + resolve_context_.get(), resolve_context_->host_cache())); + + EXPECT_THAT(response.result_error(), IsOk()); + EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("2001:db8::1", 5555))); +} + TEST_F(HostResolverManagerTest, EmptyHost) { ResolveHostResponseHelper response(resolver_->CreateRequest( HostPortPair(std::string(), 5555), NetworkIsolationKey(), @@ -964,6 +1013,49 @@ resolve_context_->host_cache()))); responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("b", 80), NetworkIsolationKey(), NetLogWithSource(), + absl::nullopt, resolve_context_.get(), + resolve_context_->host_cache()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("a", 80), NetworkIsolationKey(), NetLogWithSource(), + absl::nullopt, resolve_context_.get(), + resolve_context_->host_cache()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("b", 80), NetworkIsolationKey(), NetLogWithSource(), + absl::nullopt, resolve_context_.get(), + resolve_context_->host_cache()))); + + for (auto& response : responses) { + ASSERT_FALSE(response->complete()); + } + + proc_->SignalMultiple(2u); // One for "a:80", one for "b:80". + + for (auto& response : responses) { + EXPECT_THAT(response->result_error(), IsOk()); + } +} + +// TODO(crbug.com/1206799): Delete/adapt once requests with different ports are +// not deduped. +TEST_F(HostResolverManagerTest, DeDupeRequestsWithDifferentPorts) { + // Start 5 requests, duplicating hosts "a" and "b". Since the resolver_proc is + // blocked, these should all pile up until we signal it. + std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses; + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("a", 80), NetworkIsolationKey(), NetLogWithSource(), + absl::nullopt, resolve_context_.get(), + resolve_context_->host_cache()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("b", 80), NetworkIsolationKey(), NetLogWithSource(), + absl::nullopt, resolve_context_.get(), + resolve_context_->host_cache()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( HostPortPair("b", 81), NetworkIsolationKey(), NetLogWithSource(), absl::nullopt, resolve_context_.get(), resolve_context_->host_cache()))); @@ -1003,17 +1095,17 @@ resolve_context_->host_cache()))); responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("b", 81), NetworkIsolationKey(), NetLogWithSource(), + HostPortPair("b", 80), NetworkIsolationKey(), NetLogWithSource(), absl::nullopt, resolve_context_.get(), resolve_context_->host_cache()))); responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("a", 82), NetworkIsolationKey(), NetLogWithSource(), + HostPortPair("a", 80), NetworkIsolationKey(), NetLogWithSource(), absl::nullopt, resolve_context_.get(), resolve_context_->host_cache()))); responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("b", 83), NetworkIsolationKey(), NetLogWithSource(), + HostPortPair("b", 80), NetworkIsolationKey(), NetLogWithSource(), absl::nullopt, resolve_context_.get(), resolve_context_->host_cache()))); @@ -1021,7 +1113,7 @@ ASSERT_FALSE(response->complete()); } - // Cancel everything except request for requests[3] ("a", 82). + // Cancel everything except request for requests[3] ("a", 80). responses[0]->CancelRequest(); responses[1]->CancelRequest(); responses[2]->CancelRequest(); @@ -1054,7 +1146,7 @@ responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair(hostname, 81), NetworkIsolationKey(), + HostPortPair(hostname, 80), NetworkIsolationKey(), NetLogWithSource(), absl::nullopt, resolve_context_.get(), resolve_context_->host_cache()))); ASSERT_FALSE(responses.back()->complete()); @@ -1103,12 +1195,12 @@ responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("a", 81), NetworkIsolationKey(), NetLogWithSource(), + HostPortPair("a", 80), NetworkIsolationKey(), NetLogWithSource(), absl::nullopt, resolve_context_.get(), resolve_context_->host_cache()))); responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("a", 82), NetworkIsolationKey(), NetLogWithSource(), + HostPortPair("a", 80), NetworkIsolationKey(), NetLogWithSource(), absl::nullopt, resolve_context_.get(), resolve_context_->host_cache()))); @@ -1199,7 +1291,7 @@ responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("a", 81), NetworkIsolationKey(), NetLogWithSource(), + HostPortPair("a", 80), NetworkIsolationKey(), NetLogWithSource(), absl::nullopt, resolve_context_.get(), resolve_context_->host_cache()))); responses.emplace_back( @@ -1209,7 +1301,7 @@ resolve_context_->host_cache()))); responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("b", 83), NetworkIsolationKey(), NetLogWithSource(), + HostPortPair("b", 82), NetworkIsolationKey(), NetLogWithSource(), absl::nullopt, resolve_context_.get(), resolve_context_->host_cache()))); @@ -1351,7 +1443,7 @@ auto custom_callback = base::BindLambdaForTesting( [&](CompletionOnceCallback completion_callback, int error) { new_response = std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("evictor", 70), + resolver_->CreateRequest(HostPortPair("evictor", 80), NetworkIsolationKey(), NetLogWithSource(), absl::nullopt, resolve_context_.get(), resolve_context_->host_cache())); @@ -4302,6 +4394,21 @@ testing::ElementsAre(CreateExpected("192.168.1.102", 80))); } +TEST_F(HostResolverManagerDnsTest, DnsTaskWithScheme) { + ChangeDnsConfig(CreateValidDnsConfig()); + + ResolveHostResponseHelper response(resolver_->CreateRequest( + url::SchemeHostPort(url::kWsScheme, "ok_fail", 80), NetworkIsolationKey(), + NetLogWithSource(), absl::nullopt, resolve_context_.get(), + resolve_context_->host_cache())); + + // Resolved by MockDnsClient. + EXPECT_THAT(response.result_error(), IsOk()); + EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(), + testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 80), + CreateExpected("::1", 80))); +} + // Test successful and failing resolutions in HostResolverManager::DnsTask when // fallback to ProcTask is disabled. TEST_F(HostResolverManagerDnsTest, NoFallbackToProcTask) {
diff --git a/net/dns/host_resolver_mdns_task.cc b/net/dns/host_resolver_mdns_task.cc index 687b957..84cac53a 100644 --- a/net/dns/host_resolver_mdns_task.cc +++ b/net/dns/host_resolver_mdns_task.cc
@@ -127,9 +127,9 @@ HostResolverMdnsTask::HostResolverMdnsTask( MDnsClient* mdns_client, - const std::string& hostname, + std::string hostname, const std::vector<DnsQueryType>& query_types) - : mdns_client_(mdns_client), hostname_(hostname) { + : mdns_client_(mdns_client), hostname_(std::move(hostname)) { DCHECK(!query_types.empty()); for (DnsQueryType query_type : query_types) { transactions_.emplace_back(query_type, this);
diff --git a/net/dns/host_resolver_mdns_task.h b/net/dns/host_resolver_mdns_task.h index e0e408a..b91e77bd 100644 --- a/net/dns/host_resolver_mdns_task.h +++ b/net/dns/host_resolver_mdns_task.h
@@ -30,7 +30,7 @@ public: // |mdns_client| must outlive |this|. HostResolverMdnsTask(MDnsClient* mdns_client, - const std::string& hostname, + std::string hostname, const std::vector<DnsQueryType>& query_types); ~HostResolverMdnsTask();
diff --git a/net/dns/mapped_host_resolver.cc b/net/dns/mapped_host_resolver.cc index be723810..0faf128 100644 --- a/net/dns/mapped_host_resolver.cc +++ b/net/dns/mapped_host_resolver.cc
@@ -11,6 +11,14 @@ #include "base/values.h" #include "net/base/host_port_pair.h" #include "net/base/net_errors.h" +#include "net/base/network_isolation_key.h" +#include "net/base/url_util.h" +#include "net/dns/host_resolver.h" +#include "net/log/net_log_with_source.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/gurl.h" +#include "url/scheme_host_port.h" +#include "url/url_canon.h" namespace net { @@ -25,6 +33,33 @@ std::unique_ptr<HostResolver::ResolveHostRequest> MappedHostResolver::CreateRequest( + url::SchemeHostPort host, + NetworkIsolationKey network_isolation_key, + NetLogWithSource source_net_log, + absl::optional<ResolveHostParameters> optional_parameters) { + GURL rewritten_url = host.GetURL(); + HostMappingRules::RewriteResult result = rules_.RewriteUrl(rewritten_url); + + switch (result) { + case HostMappingRules::RewriteResult::kRewritten: + DCHECK(rewritten_url.is_valid()); + DCHECK_NE(rewritten_url.host_piece(), "~NOTFOUND"); + return impl_->CreateRequest( + url::SchemeHostPort(rewritten_url), std::move(network_isolation_key), + std::move(source_net_log), std::move(optional_parameters)); + case HostMappingRules::RewriteResult::kInvalidRewrite: + // Treat any invalid mapping as if it was "~NOTFOUND" (which should itself + // result in `kInvalidRewrite`). + return CreateFailingRequest(ERR_NAME_NOT_RESOLVED); + case HostMappingRules::RewriteResult::kNoMatchingRule: + return impl_->CreateRequest( + std::move(host), std::move(network_isolation_key), + std::move(source_net_log), std::move(optional_parameters)); + } +} + +std::unique_ptr<HostResolver::ResolveHostRequest> +MappedHostResolver::CreateRequest( const HostPortPair& host, const NetworkIsolationKey& network_isolation_key, const NetLogWithSource& source_net_log,
diff --git a/net/dns/mapped_host_resolver.h b/net/dns/mapped_host_resolver.h index f27bb71..477f5848 100644 --- a/net/dns/mapped_host_resolver.h +++ b/net/dns/mapped_host_resolver.h
@@ -12,8 +12,12 @@ #include "net/base/completion_once_callback.h" #include "net/base/host_mapping_rules.h" #include "net/base/net_export.h" +#include "net/base/network_isolation_key.h" #include "net/dns/dns_config.h" #include "net/dns/host_resolver.h" +#include "net/log/net_log_with_source.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/scheme_host_port.h" namespace net { @@ -51,6 +55,11 @@ // HostResolver methods: std::unique_ptr<ResolveHostRequest> CreateRequest( + url::SchemeHostPort host, + NetworkIsolationKey network_isolation_key, + NetLogWithSource net_log, + absl::optional<ResolveHostParameters> optional_parameters) override; + std::unique_ptr<ResolveHostRequest> CreateRequest( const HostPortPair& host, const NetworkIsolationKey& network_isolation_key, const NetLogWithSource& net_log,
diff --git a/net/dns/mapped_host_resolver_unittest.cc b/net/dns/mapped_host_resolver_unittest.cc index 8fb3c71f..d5ca366f 100644 --- a/net/dns/mapped_host_resolver_unittest.cc +++ b/net/dns/mapped_host_resolver_unittest.cc
@@ -4,17 +4,24 @@ #include "net/dns/mapped_host_resolver.h" +#include <memory> #include <utility> #include "base/test/task_environment.h" #include "net/base/address_list.h" +#include "net/base/ip_address.h" +#include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" +#include "net/base/network_isolation_key.h" #include "net/base/test_completion_callback.h" #include "net/dns/mock_host_resolver.h" #include "net/log/net_log_with_source.h" #include "net/test/gtest_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/scheme_host_port.h" +#include "url/url_constants.h" using net::test::IsError; using net::test::IsOk; @@ -100,6 +107,138 @@ FirstAddress(request->GetAddressResults().value())); } +TEST(MappedHostResolverTest, MapsHostWithScheme) { + base::test::TaskEnvironment task_environment; + + // Create a mock host resolver, with specific hostname to IP mappings. + std::unique_ptr<MockHostResolver> resolver_impl(new MockHostResolver()); + resolver_impl->rules()->AddRule("remapped.test", "192.168.1.22"); + + // Create a remapped resolver that uses `resolver_impl`. + std::unique_ptr<MappedHostResolver> resolver( + new MappedHostResolver(std::move(resolver_impl))); + ASSERT_TRUE(resolver->AddRuleFromString("MAP to.map.test remapped.test")); + + std::unique_ptr<HostResolver::ResolveHostRequest> request = + resolver->CreateRequest( + url::SchemeHostPort(url::kHttpScheme, "to.map.test", 155), + NetworkIsolationKey(), NetLogWithSource(), absl::nullopt); + + TestCompletionCallback callback; + int rv = request->Start(callback.callback()); + + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_THAT( + request->GetAddressResults().value().endpoints(), + testing::ElementsAre(IPEndPoint(IPAddress(192, 168, 1, 22), 155))); +} + +TEST(MappedHostResolverTest, MapsHostWithSchemeToIpLiteral) { + base::test::TaskEnvironment task_environment; + + // Create a mock host resolver, with specific hostname to IP mappings. + std::unique_ptr<MockHostResolver> resolver_impl(new MockHostResolver()); + resolver_impl->rules()->AddRule("host.test", "192.168.1.22"); + + // Create a remapped resolver that uses `resolver_impl`. + std::unique_ptr<MappedHostResolver> resolver( + new MappedHostResolver(std::move(resolver_impl))); + ASSERT_TRUE(resolver->AddRuleFromString("MAP host.test [1234:5678::000A]")); + + IPAddress expected_address; + ASSERT_TRUE(expected_address.AssignFromIPLiteral("1234:5678::000A")); + + std::unique_ptr<HostResolver::ResolveHostRequest> request = + resolver->CreateRequest( + url::SchemeHostPort(url::kHttpScheme, "host.test", 156), + NetworkIsolationKey(), NetLogWithSource(), absl::nullopt); + + TestCompletionCallback callback; + int rv = request->Start(callback.callback()); + + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_THAT(request->GetAddressResults().value().endpoints(), + testing::ElementsAre(IPEndPoint(expected_address, 156))); +} + +// Tests that remapped URL gets canonicalized when passing scheme. +TEST(MappedHostResolverTest, MapsHostWithSchemeToNonCanon) { + base::test::TaskEnvironment task_environment; + + // Create a mock host resolver, with specific hostname to IP mappings. + std::unique_ptr<MockHostResolver> resolver_impl(new MockHostResolver()); + resolver_impl->rules()->AddRule("remapped.test", "192.168.1.23"); + + // Create a remapped resolver that uses `resolver_impl`. + std::unique_ptr<MappedHostResolver> resolver( + new MappedHostResolver(std::move(resolver_impl))); + ASSERT_TRUE(resolver->AddRuleFromString("MAP host.test reMapped.TEST")); + + std::unique_ptr<HostResolver::ResolveHostRequest> request = + resolver->CreateRequest( + url::SchemeHostPort(url::kHttpScheme, "host.test", 157), + NetworkIsolationKey(), NetLogWithSource(), absl::nullopt); + + TestCompletionCallback callback; + int rv = request->Start(callback.callback()); + + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_THAT( + request->GetAddressResults().value().endpoints(), + testing::ElementsAre(IPEndPoint(IPAddress(192, 168, 1, 23), 157))); +} + +TEST(MappedHostResolverTest, MapsHostWithSchemeToNameWithPort) { + base::test::TaskEnvironment task_environment; + + // Create a mock host resolver, with specific hostname to IP mappings. + std::unique_ptr<MockHostResolver> resolver_impl(new MockHostResolver()); + resolver_impl->rules()->AddRule("remapped.test", "192.168.1.24"); + + // Create a remapped resolver that uses `resolver_impl`. + std::unique_ptr<MappedHostResolver> resolver( + new MappedHostResolver(std::move(resolver_impl))); + ASSERT_TRUE(resolver->AddRuleFromString("MAP host.test remapped.test:258")); + + std::unique_ptr<HostResolver::ResolveHostRequest> request = + resolver->CreateRequest( + url::SchemeHostPort(url::kHttpScheme, "host.test", 158), + NetworkIsolationKey(), NetLogWithSource(), absl::nullopt); + + TestCompletionCallback callback; + int rv = request->Start(callback.callback()); + + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_THAT( + request->GetAddressResults().value().endpoints(), + testing::ElementsAre(IPEndPoint(IPAddress(192, 168, 1, 24), 258))); +} + +TEST(MappedHostResolverTest, HandlesUnmappedHostWithScheme) { + base::test::TaskEnvironment task_environment; + + // Create a mock host resolver, with specific hostname to IP mappings. + std::unique_ptr<MockHostResolver> resolver_impl(new MockHostResolver()); + resolver_impl->rules()->AddRule("unmapped.test", "192.168.1.23"); + + // Create a remapped resolver that uses `resolver_impl`. + std::unique_ptr<MappedHostResolver> resolver( + new MappedHostResolver(std::move(resolver_impl))); + + std::unique_ptr<HostResolver::ResolveHostRequest> request = + resolver->CreateRequest( + url::SchemeHostPort(url::kHttpsScheme, "unmapped.test", 155), + NetworkIsolationKey(), NetLogWithSource(), absl::nullopt); + + TestCompletionCallback callback; + int rv = request->Start(callback.callback()); + + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_THAT( + request->GetAddressResults().value().endpoints(), + testing::ElementsAre(IPEndPoint(IPAddress(192, 168, 1, 23), 155))); +} + // Tests that exclusions are respected. TEST(MappedHostResolverTest, Exclusion) { base::test::TaskEnvironment task_environment; @@ -242,6 +381,28 @@ FirstAddress(request->GetAddressResults().value())); } +TEST(MappedHostResolverTest, MapHostWithSchemeToError) { + base::test::TaskEnvironment task_environment; + + // Create a mock host resolver, with specific hostname to IP mappings. + std::unique_ptr<MockHostResolver> resolver_impl(new MockHostResolver()); + resolver_impl->rules()->AddRule("host.test", "192.168.1.25"); + + // Create a remapped resolver that uses `resolver_impl`. + std::unique_ptr<MappedHostResolver> resolver( + new MappedHostResolver(std::move(resolver_impl))); + ASSERT_TRUE(resolver->AddRuleFromString("MAP host.test ~NOTFOUND")); + + std::unique_ptr<HostResolver::ResolveHostRequest> request = + resolver->CreateRequest( + url::SchemeHostPort(url::kWssScheme, "host.test", 155), + NetworkIsolationKey(), NetLogWithSource(), absl::nullopt); + + TestCompletionCallback callback; + int rv = request->Start(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED)); +} + } // namespace } // namespace net
diff --git a/net/dns/mock_host_resolver.cc b/net/dns/mock_host_resolver.cc index 072373a..a6aae7f 100644 --- a/net/dns/mock_host_resolver.cc +++ b/net/dns/mock_host_resolver.cc
@@ -29,12 +29,16 @@ #include "net/base/ip_address.h" #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" +#include "net/base/network_isolation_key.h" #include "net/base/test_completion_callback.h" #include "net/dns/dns_alias_utility.h" #include "net/dns/host_cache.h" #include "net/dns/public/resolve_error_info.h" #include "net/dns/public/secure_dns_policy.h" +#include "net/log/net_log_with_source.h" #include "net/url_request/url_request_context.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/scheme_host_port.h" #if defined(OS_WIN) #include "net/base/winsock_init.h" @@ -372,6 +376,17 @@ std::unique_ptr<HostResolver::ResolveHostRequest> MockHostResolverBase::CreateRequest( + url::SchemeHostPort host, + NetworkIsolationKey network_isolation_key, + NetLogWithSource net_log, + absl::optional<ResolveHostParameters> optional_parameters) { + // TODO(crbug.com/1206799): Propagate scheme and make affect behavior. + return CreateRequest(HostPortPair::FromSchemeHostPort(host), + network_isolation_key, net_log, optional_parameters); +} + +std::unique_ptr<HostResolver::ResolveHostRequest> +MockHostResolverBase::CreateRequest( const HostPortPair& host, const NetworkIsolationKey& network_isolation_key, const NetLogWithSource& source_net_log, @@ -1108,6 +1123,17 @@ std::unique_ptr<HostResolver::ResolveHostRequest> HangingHostResolver::CreateRequest( + url::SchemeHostPort host, + NetworkIsolationKey network_isolation_key, + NetLogWithSource net_log, + absl::optional<ResolveHostParameters> optional_parameters) { + // TODO(crbug.com/1206799): Propagate scheme and make affect behavior. + return CreateRequest(HostPortPair::FromSchemeHostPort(host), + network_isolation_key, net_log, optional_parameters); +} + +std::unique_ptr<HostResolver::ResolveHostRequest> +HangingHostResolver::CreateRequest( const HostPortPair& host, const NetworkIsolationKey& network_isolation_key, const NetLogWithSource& source_net_log,
diff --git a/net/dns/mock_host_resolver.h b/net/dns/mock_host_resolver.h index 1b121465..a258446 100644 --- a/net/dns/mock_host_resolver.h +++ b/net/dns/mock_host_resolver.h
@@ -27,6 +27,9 @@ #include "net/dns/host_resolver_source.h" #include "net/dns/public/dns_query_type.h" #include "net/dns/public/secure_dns_policy.h" +#include "net/log/net_log_with_source.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/scheme_host_port.h" namespace base { class TickClock; @@ -122,6 +125,11 @@ // HostResolver methods: void OnShutdown() override; std::unique_ptr<ResolveHostRequest> CreateRequest( + url::SchemeHostPort host, + NetworkIsolationKey network_isolation_key, + NetLogWithSource net_log, + absl::optional<ResolveHostParameters> optional_parameters) override; + std::unique_ptr<ResolveHostRequest> CreateRequest( const HostPortPair& host, const NetworkIsolationKey& network_isolation_key, const NetLogWithSource& net_log, @@ -507,6 +515,11 @@ ~HangingHostResolver() override; void OnShutdown() override; std::unique_ptr<ResolveHostRequest> CreateRequest( + url::SchemeHostPort host, + NetworkIsolationKey network_isolation_key, + NetLogWithSource net_log, + absl::optional<ResolveHostParameters> optional_parameters) override; + std::unique_ptr<ResolveHostRequest> CreateRequest( const HostPortPair& host, const NetworkIsolationKey& network_isolation_key, const NetLogWithSource& net_log,
diff --git a/net/http/http_proxy_connect_job.cc b/net/http/http_proxy_connect_job.cc index 20017094..2cb7225 100644 --- a/net/http/http_proxy_connect_job.cc +++ b/net/http/http_proxy_connect_job.cc
@@ -12,7 +12,6 @@ #include "base/metrics/field_trial.h" #include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_macros.h" -#include "base/no_destructor.h" #include "base/numerics/ranges.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -125,9 +124,8 @@ }; HttpProxyTimeoutExperiments* GetProxyTimeoutExperiments() { - static base::NoDestructor<HttpProxyTimeoutExperiments> - proxy_timeout_experiments; - return proxy_timeout_experiments.get(); + static HttpProxyTimeoutExperiments proxy_timeout_experiments; + return &proxy_timeout_experiments; } } // namespace
diff --git a/net/quic/platform/impl/DEPS b/net/quic/platform/impl/DEPS index fbe3824..2c12fec5 100644 --- a/net/quic/platform/impl/DEPS +++ b/net/quic/platform/impl/DEPS
@@ -1,8 +1,4 @@ include_rules = [ - # This is a temporary rule to simplify migrating QUICHE to using Abseil - # directly. - # TODO(b/166325009): remove this rule. - "+third_party/abseil-cpp/absl/base", - "+third_party/abseil-cpp/absl/container", + # Allow string_view.h since absl::string_view is widely used in QUICHE API. "+third_party/abseil-cpp/absl/strings", ]
diff --git a/net/quic/platform/impl/quic_flags_impl.h b/net/quic/platform/impl/quic_flags_impl.h index 6c50b2c..5553084 100644 --- a/net/quic/platform/impl/quic_flags_impl.h +++ b/net/quic/platform/impl/quic_flags_impl.h
@@ -11,7 +11,9 @@ #include <string> #include <vector> +#include "base/command_line.h" #include "base/export_template.h" +#include "base/no_destructor.h" #include "net/third_party/quiche/src/common/platform/api/quiche_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -21,12 +23,6 @@ #include "net/third_party/quiche/src/quic/core/quic_protocol_flags_list.h" #undef QUIC_PROTOCOL_FLAG -namespace base { -class CommandLine; -template <typename T> -class NoDestructor; -} // namespace base - // Sets the flag named |flag_name| to the value of |value| after converting // it from a string to the appropriate type. If |value| is invalid or out of // range, the flag will be unchanged.
diff --git a/net/quiche/common/platform/impl/DEPS b/net/quiche/common/platform/impl/DEPS index c65e978..2c12fec5 100644 --- a/net/quiche/common/platform/impl/DEPS +++ b/net/quiche/common/platform/impl/DEPS
@@ -1,9 +1,4 @@ include_rules = [ - # This is a temporary rule to simplify migrating QUICHE to using Abseil - # directly. - # TODO(b/166325009): remove this rule. - "+third_party/abseil-cpp/absl/base/macros.h", - "+third_party/abseil-cpp/absl/container/node_hash_map.h", - "+third_party/abseil-cpp/absl/hash/hash.h", + # Allow string_view.h since absl::string_view is widely used in QUICHE API. "+third_party/abseil-cpp/absl/strings", ]
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc index 8f94e48..9aa5e39 100644 --- a/pdf/out_of_process_instance.cc +++ b/pdf/out_of_process_instance.cc
@@ -464,15 +464,15 @@ PDFiumFormFiller::ScriptOption script_option = PDFiumFormFiller::DefaultScriptOption(); bool has_edits = false; - const char* stream_url = nullptr; + const char* src_url = nullptr; const char* original_url = nullptr; const char* top_level_url = nullptr; const char* headers = nullptr; for (uint32_t i = 0; i < argc; ++i) { - if (strcmp(argn[i], "src") == 0) { + if (strcmp(argn[i], "original-url") == 0) { original_url = argv[i]; - } else if (strcmp(argn[i], "stream-url") == 0) { - stream_url = argv[i]; + } else if (strcmp(argn[i], "src") == 0) { + src_url = argv[i]; } else if (strcmp(argn[i], "top-level-url") == 0) { top_level_url = argv[i]; } else if (strcmp(argn[i], "headers") == 0) { @@ -492,11 +492,11 @@ } } - if (!original_url) + if (!src_url) return false; - if (!stream_url) - stream_url = original_url; + if (!original_url) + original_url = src_url; InitializeEngine(std::make_unique<PDFiumEngine>(this, script_option)); @@ -507,7 +507,7 @@ if (IsPrintPreview()) return true; - LoadUrl(stream_url, /*is_print_preview=*/false); + LoadUrl(src_url, /*is_print_preview=*/false); set_url(original_url); // Not all edits go through the PDF plugin's form filler. The plugin instance
diff --git a/pdf/parsed_params.cc b/pdf/parsed_params.cc index 898777b..46cada1 100644 --- a/pdf/parsed_params.cc +++ b/pdf/parsed_params.cc
@@ -22,10 +22,10 @@ const blink::WebPluginParams& params) { ParsedParams result; for (size_t i = 0; i < params.attribute_names.size(); ++i) { - if (params.attribute_names[i] == "src") { + if (params.attribute_names[i] == "original-url") { result.original_url = params.attribute_values[i].Utf8(); - } else if (params.attribute_names[i] == "stream-url") { - result.stream_url = params.attribute_values[i].Utf8(); + } else if (params.attribute_names[i] == "src") { + result.src_url = params.attribute_values[i].Utf8(); } else if (params.attribute_names[i] == "full-frame") { result.full_frame = true; } else if (params.attribute_names[i] == "background-color") { @@ -38,11 +38,12 @@ } } - if (result.original_url.empty()) + if (result.src_url.empty()) return absl::nullopt; - if (result.stream_url.empty()) - result.stream_url = result.original_url; + if (result.original_url.empty()) { + result.original_url = result.src_url; + } return result; }
diff --git a/pdf/parsed_params.h b/pdf/parsed_params.h index acc03655..cf08d03 100644 --- a/pdf/parsed_params.h +++ b/pdf/parsed_params.h
@@ -21,11 +21,11 @@ ParsedParams(const ParsedParams& other); ~ParsedParams(); - // Document URL. Must not be empty. + // The document original URL. Must not be empty. std::string original_url; - // Document stream URL. Must not be empty. - std::string stream_url; + // The plugin source URL. Must not be empty. + std::string src_url; // The background color for the PDF viewer. absl::optional<SkColor> background_color;
diff --git a/pdf/parsed_params_unittest.cc b/pdf/parsed_params_unittest.cc index e09a917..99f735b 100644 --- a/pdf/parsed_params_unittest.cc +++ b/pdf/parsed_params_unittest.cc
@@ -18,7 +18,7 @@ namespace { constexpr char kDummyOriginalUrl[] = "https://test.com/dummy.pdf"; -constexpr char kDummyStreamUrl[] = "chrome-extension://dummy-stream-url"; +constexpr char kDummySrcUrl[] = "chrome-extension://dummy-source-url"; constexpr SkColor kNewBackgroundColor = SkColorSetARGB(0xFF, 0x52, 0x56, 0x59); @@ -26,8 +26,8 @@ constexpr char kNewBackgroundColorStr[] = "4283586137"; // Creates a `blink::WebPluginParams` without any URL attributes, namely "src" -// and "stream-url". The return value only contains valid "background-color" and -// "full-frame" attributes. +// and "original-url". The return value only contains valid "background-color" +// and "full-frame" attributes. blink::WebPluginParams CreateWebPluginParamsWithoutUrl() { blink::WebPluginParams params; params.attribute_names.push_back(blink::WebString("background-color")); @@ -38,13 +38,13 @@ } // Creates a `blink::WebPluginParams` with only the URL attributes: "src" and -// "stream-url". +// "original-url". blink::WebPluginParams CreateWebPluginParamsWithUrls() { blink::WebPluginParams params; - params.attribute_names.push_back(blink::WebString("src")); + params.attribute_names.push_back(blink::WebString("original-url")); params.attribute_values.push_back(blink::WebString(kDummyOriginalUrl)); - params.attribute_names.push_back(blink::WebString("stream-url")); - params.attribute_values.push_back(blink::WebString(kDummyStreamUrl)); + params.attribute_names.push_back(blink::WebString("src")); + params.attribute_values.push_back(blink::WebString(kDummySrcUrl)); return params; } @@ -52,41 +52,41 @@ TEST(ParsedParamsTest, ParseValidWebPluginParams) { blink::WebPluginParams params = CreateWebPluginParamsWithoutUrl(); - params.attribute_names.push_back(blink::WebString("src")); + params.attribute_names.push_back(blink::WebString("original-url")); params.attribute_values.push_back(blink::WebString(kDummyOriginalUrl)); - params.attribute_names.push_back(blink::WebString("stream-url")); - params.attribute_values.push_back(blink::WebString(kDummyStreamUrl)); + params.attribute_names.push_back(blink::WebString("src")); + params.attribute_values.push_back(blink::WebString(kDummySrcUrl)); absl::optional<ParsedParams> result = ParseWebPluginParams(params); ASSERT_TRUE(result.has_value()); EXPECT_EQ(kDummyOriginalUrl, result->original_url); - EXPECT_EQ(kDummyStreamUrl, result->stream_url); + EXPECT_EQ(kDummySrcUrl, result->src_url); ASSERT_TRUE(result->background_color.has_value()); EXPECT_EQ(kNewBackgroundColor, result->background_color.value()); EXPECT_TRUE(result->full_frame); } -TEST(ParsedParamsTest, ParseWebPluginParamsWithoutOriginalUrl) { +TEST(ParsedParamsTest, ParseWebPluginParamsWithoutSourceUrl) { blink::WebPluginParams params = CreateWebPluginParamsWithoutUrl(); - params.attribute_names.push_back(blink::WebString("stream-url")); - params.attribute_values.push_back(blink::WebString(kDummyStreamUrl)); + params.attribute_names.push_back(blink::WebString("original-url")); + params.attribute_values.push_back(blink::WebString(kDummyOriginalUrl)); - // Expect the `ParsedParams` to be invalid due to missing the original URL. + // Expect the `ParsedParams` to be invalid due to missing the source URL. absl::optional<ParsedParams> result = ParseWebPluginParams(params); EXPECT_FALSE(result.has_value()); } -TEST(ParseParsedParamsTest, ParseWebPluginParamsWithoutStreamUrl) { +TEST(ParseParsedParamsTest, ParseWebPluginParamsWithoutOriginalUrl) { blink::WebPluginParams params = CreateWebPluginParamsWithoutUrl(); params.attribute_names.push_back(blink::WebString("src")); - params.attribute_values.push_back(blink::WebString(kDummyOriginalUrl)); + params.attribute_values.push_back(blink::WebString(kDummySrcUrl)); - // Expect the `ParsedParams` to be valid and `stream_url` to be the same as - // `original_url`. + // Expect the `ParsedParams` to be valid and `original_url` to be the same as + // `src_url`. absl::optional<ParsedParams> result = ParseWebPluginParams(params); ASSERT_TRUE(result.has_value()); - EXPECT_EQ(kDummyOriginalUrl, result->original_url); - EXPECT_EQ(kDummyOriginalUrl, result->stream_url); + EXPECT_EQ(kDummySrcUrl, result->original_url); + EXPECT_EQ(kDummySrcUrl, result->src_url); ASSERT_TRUE(result->background_color.has_value()); EXPECT_EQ(kNewBackgroundColor, result->background_color.value()); EXPECT_TRUE(result->full_frame); @@ -100,7 +100,7 @@ absl::optional<ParsedParams> result = ParseWebPluginParams(params); ASSERT_TRUE(result.has_value()); EXPECT_EQ(kDummyOriginalUrl, result->original_url); - EXPECT_EQ(kDummyStreamUrl, result->stream_url); + EXPECT_EQ(kDummySrcUrl, result->src_url); EXPECT_FALSE(result->background_color.has_value()); EXPECT_FALSE(result->full_frame); }
diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc index 2e54aae..60e43deb 100644 --- a/pdf/pdf_view_web_plugin.cc +++ b/pdf/pdf_view_web_plugin.cc
@@ -87,7 +87,9 @@ class PerProcessInitializer final { public: static PerProcessInitializer& GetInstance() { - static base::NoDestructor<PerProcessInitializer> instance; + static base::NoDestructor<PerProcessInitializer, + base::AllowForTriviallyDestructibleType> + instance; return *instance; } @@ -262,7 +264,7 @@ PerProcessInitializer::GetInstance().Acquire(); InitializeEngine(std::make_unique<PDFiumEngine>( this, PDFiumFormFiller::ScriptOption::kNoJavaScript)); - LoadUrl(params->stream_url, /*is_print_preview=*/false); + LoadUrl(params->src_url, /*is_print_preview=*/false); set_url(params->original_url); post_message_sender_.set_container(Container()); return true;
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/BUILD.gn b/ppapi/native_client/src/untrusted/pnacl_irt_shim/BUILD.gn index 756d075..2526718 100644 --- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/BUILD.gn +++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/BUILD.gn
@@ -14,10 +14,6 @@ "shim_entry.c", "shim_ppapi.c", ] - deps = [ - "//ppapi/c", - "//ppapi/proxy:proxy", - ] # Indicate that this variant of the shim library should not depend on # the unstable/private IRT hook interface. @@ -45,8 +41,4 @@ "irt_shim_ppapi.c", "pnacl_shim.c", ] - deps = [ - "//ppapi/c", - "//ppapi/proxy:proxy", - ] }
diff --git a/printing/mojom/print.mojom b/printing/mojom/print.mojom index 69130608..0e0b8ae 100644 --- a/printing/mojom/print.mojom +++ b/printing/mojom/print.mojom
@@ -146,3 +146,12 @@ kLocal, kCloud }; + +[EnableIf=is_win] +enum PrinterLanguageType { + kNone = 0, + kTextOnly, + kXps, + kPostscriptLevel2, + kPostscriptLevel3, +};
diff --git a/printing/print_settings.cc b/printing/print_settings.cc index bd3b3d9..b12f1f5 100644 --- a/printing/print_settings.cc +++ b/printing/print_settings.cc
@@ -14,6 +14,10 @@ #include <cups/cups.h> #endif +#if defined(OS_WIN) +#include "printing/mojom/print.mojom.h" +#endif + namespace printing { namespace { @@ -274,7 +278,7 @@ supports_alpha_blend_ = true; #if defined(OS_WIN) print_text_with_gdi_ = false; - printer_type_ = PrintSettings::PrinterType::TYPE_NONE; + printer_language_type_ = mojom::PrinterLanguageType::kNone; #endif is_modifiable_ = true; pages_per_sheet_ = 1;
diff --git a/printing/print_settings.h b/printing/print_settings.h index 451632c..9592024 100644 --- a/printing/print_settings.h +++ b/printing/print_settings.h
@@ -59,16 +59,6 @@ class COMPONENT_EXPORT(PRINTING) PrintSettings { public: -#if defined(OS_WIN) - enum PrinterType { - TYPE_NONE = 0, - TYPE_TEXTONLY, - TYPE_XPS, - TYPE_POSTSCRIPT_LEVEL2, - TYPE_POSTSCRIPT_LEVEL3 - }; -#endif - // Media properties requested by the user. Default instance represents // default media selection. struct RequestedMedia { @@ -202,16 +192,22 @@ void set_print_text_with_gdi(bool use_gdi) { print_text_with_gdi_ = use_gdi; } bool print_text_with_gdi() const { return print_text_with_gdi_; } - void set_printer_type(PrinterType type) { printer_type_ = type; } - bool printer_is_textonly() const { - return printer_type_ == PrinterType::TYPE_TEXTONLY; + void set_printer_language_type(mojom::PrinterLanguageType type) { + printer_language_type_ = type; } - bool printer_is_xps() const { return printer_type_ == PrinterType::TYPE_XPS; } - bool printer_is_ps2() const { - return printer_type_ == PrinterType::TYPE_POSTSCRIPT_LEVEL2; + bool printer_language_is_textonly() const { + return printer_language_type_ == mojom::PrinterLanguageType::kTextOnly; } - bool printer_is_ps3() const { - return printer_type_ == PrinterType::TYPE_POSTSCRIPT_LEVEL3; + bool printer_language_is_xps() const { + return printer_language_type_ == mojom::PrinterLanguageType::kXps; + } + bool printer_language_is_ps2() const { + return printer_language_type_ == + mojom::PrinterLanguageType::kPostscriptLevel2; + } + bool printer_language_is_ps3() const { + return printer_language_type_ == + mojom::PrinterLanguageType::kPostscriptLevel3; } #endif @@ -243,13 +239,13 @@ const std::string& pin_value() const { return pin_value_; } #endif // BUILDFLAG(IS_CHROMEOS_ASH) - // Cookie generator. It is used to initialize PrintedDocument with its - // associated PrintSettings, to be sure that each generated PrintedPage is - // correctly associated with its corresponding PrintedDocument. + // Cookie generator. It is used to initialize `PrintedDocument` with its + // associated `PrintSettings`, to be sure that each generated `PrintedPage` + // is correctly associated with its corresponding `PrintedDocument`. static int NewCookie(); private: - // Multi-page printing. Each PageRange describes a from-to page combination. + // Multi-page printing. Each `PageRange` describes a from-to page combination. // This permits printing selected pages only. PageRanges ranges_; @@ -311,7 +307,7 @@ // True to print text with GDI. bool print_text_with_gdi_; - PrinterType printer_type_; + mojom::PrinterLanguageType printer_language_type_; #endif bool is_modifiable_;
diff --git a/printing/print_settings_initializer_win.cc b/printing/print_settings_initializer_win.cc index 9c1dc4fc9..84a4a4f1 100644 --- a/printing/print_settings_initializer_win.cc +++ b/printing/print_settings_initializer_win.cc
@@ -7,6 +7,7 @@ #include <windows.h> #include "printing/backend/win_helper.h" +#include "printing/mojom/print.mojom.h" #include "printing/print_settings.h" namespace printing { @@ -151,25 +152,26 @@ int level; if (IsPrinterPostScript(hdc, &level)) { if (level == 2) { - print_settings->set_printer_type( - PrintSettings::PrinterType::TYPE_POSTSCRIPT_LEVEL2); + print_settings->set_printer_language_type( + mojom::PrinterLanguageType::kPostscriptLevel2); return; } DCHECK_EQ(3, level); - print_settings->set_printer_type( - PrintSettings::PrinterType::TYPE_POSTSCRIPT_LEVEL3); + print_settings->set_printer_language_type( + mojom::PrinterLanguageType::kPostscriptLevel3); return; } // Detects the generic / text only driver. if (IsPrinterTextOnly(hdc)) { - print_settings->set_printer_type(PrintSettings::PrinterType::TYPE_TEXTONLY); + print_settings->set_printer_language_type( + mojom::PrinterLanguageType::kTextOnly); return; } if (IsPrinterXPS(hdc)) { - print_settings->set_printer_type(PrintSettings::PrinterType::TYPE_XPS); + print_settings->set_printer_language_type(mojom::PrinterLanguageType::kXps); return; } - print_settings->set_printer_type(PrintSettings::PrinterType::TYPE_NONE); + print_settings->set_printer_language_type(mojom::PrinterLanguageType::kNone); } } // namespace printing
diff --git a/remoting/client/input/keycode_map.cc b/remoting/client/input/keycode_map.cc index 4302a46..9dc665a 100644 --- a/remoting/client/input/keycode_map.cc +++ b/remoting/client/input/keycode_map.cc
@@ -109,9 +109,9 @@ } const KeycodeMap& GetKeycodeMapQwerty() { - static const base::NoDestructor<KeycodeMap> map( + static const KeycodeMap map( CreateKeycodeMapFromMapEntries(kKeycodeMapEntriesQwerty)); - return *map; + return map; } } // namespace
diff --git a/remoting/host/desktop_session_win.cc b/remoting/host/desktop_session_win.cc index e1180f3..bedb335 100644 --- a/remoting/host/desktop_session_win.cc +++ b/remoting/host/desktop_session_win.cc
@@ -72,14 +72,34 @@ const int kDefaultRdpScreenWidth = 1280; const int kDefaultRdpScreenHeight = 768; -// RDC 6.1 (W2K8) supports dimensions of up to 4096x2048. -const int kMaxRdpScreenWidth = 4096; -const int kMaxRdpScreenHeight = 2048; - // The minimum effective screen dimensions supported by Windows are 800x600. const int kMinRdpScreenWidth = 800; const int kMinRdpScreenHeight = 600; +// Win7 SP1 (and Vista) supports dimensions up to 4096x2048. +const int kMaxRdpScreenWidthForWin7 = 4096; +const int kMaxRdpScreenHeightForWin7 = 2048; + +// Win8+ supports dimensions up to 8192x8192. +const int kMaxRdpScreenWidthForWin8AndLater = 8192; +const int kMaxRdpScreenHeightForWin8AndLater = 8192; + +int GetMaxRdpScreenWidth() { + static int max_rdp_screen_width = + base::win::GetVersion() >= base::win::Version::WIN8 + ? kMaxRdpScreenWidthForWin8AndLater + : kMaxRdpScreenWidthForWin7; + return max_rdp_screen_width; +} + +int GetMaxRdpScreenHeight() { + static int max_rdp_screen_height = + base::win::GetVersion() >= base::win::Version::WIN8 + ? kMaxRdpScreenHeightForWin8AndLater + : kMaxRdpScreenHeightForWin7; + return max_rdp_screen_height; +} + // Default dots per inch used by RDP is 96 DPI. const int kDefaultRdpDpi = 96; @@ -106,8 +126,8 @@ webrtc::DesktopSize GetBoundedRdpDesktopSize(int width, int height) { return webrtc::DesktopSize( - base::ClampToRange(width, kMinRdpScreenWidth, kMaxRdpScreenWidth), - base::ClampToRange(height, kMinRdpScreenHeight, kMaxRdpScreenHeight)); + base::ClampToRange(width, kMinRdpScreenWidth, GetMaxRdpScreenWidth()), + base::ClampToRange(height, kMinRdpScreenHeight, GetMaxRdpScreenHeight())); } // DesktopSession implementation which attaches to the host's physical console.
diff --git a/remoting/host/security_key/BUILD.gn b/remoting/host/security_key/BUILD.gn index 49bb2b3e..b9c55c5 100644 --- a/remoting/host/security_key/BUILD.gn +++ b/remoting/host/security_key/BUILD.gn
@@ -37,7 +37,10 @@ "//ipc", "//mojo/public/cpp/platform", "//mojo/public/cpp/system", + "//net:net", + "//net/traffic_annotation:traffic_annotation", "//remoting/proto", + "//remoting/protocol:protocol", "//third_party/webrtc_overrides:webrtc_component", ] @@ -62,8 +65,11 @@ "remote_security_key_main.h", ] deps = [ + ":security_key", "//base:debugging_buildflags", "//mojo/core/embedder", + "//remoting/host:base", + "//remoting/host:common", ] } @@ -101,8 +107,16 @@ public_deps = [ ":test_support" ] deps = [ + ":security_key", "//mojo/core/test:test_support", + "//net:net", + "//net:test_support", + "//net/traffic_annotation:test_support", "//remoting:test_support", + "//remoting/host:common", + "//remoting/host:test_support", + "//remoting/host/setup:common", + "//remoting/protocol:protocol", ] if (is_posix) { @@ -129,6 +143,7 @@ ] deps = [ + ":security_key", "//ipc", "//remoting/proto", "//testing/gtest",
diff --git a/sandbox/policy/linux/bpf_libassistant_policy_linux.cc b/sandbox/policy/linux/bpf_libassistant_policy_linux.cc index a00dd4fd..f235efa 100644 --- a/sandbox/policy/linux/bpf_libassistant_policy_linux.cc +++ b/sandbox/policy/linux/bpf_libassistant_policy_linux.cc
@@ -24,16 +24,23 @@ LibassistantProcessPolicy::~LibassistantProcessPolicy() = default; ResultExpr LibassistantProcessPolicy::EvaluateSyscall(int sysno) const { -#if defined(__NR_sched_setscheduler) - if (sysno == __NR_sched_setscheduler) - return Allow(); + switch (sysno) { +#if defined(__NR_getcpu) + // Needed by arm devices. + case __NR_getcpu: + return Allow(); #endif +#if defined(__NR_sched_setscheduler) + case __NR_sched_setscheduler: + return Allow(); +#endif + default: + auto* sandbox_linux = SandboxLinux::GetInstance(); + if (sandbox_linux->ShouldBrokerHandleSyscall(sysno)) + return sandbox_linux->HandleViaBroker(); - auto* sandbox_linux = SandboxLinux::GetInstance(); - if (sandbox_linux->ShouldBrokerHandleSyscall(sysno)) - return sandbox_linux->HandleViaBroker(); - - return BPFBasePolicy::EvaluateSyscall(sysno); + return BPFBasePolicy::EvaluateSyscall(sysno); + } } } // namespace policy
diff --git a/services/device/public/cpp/hid/hid_blocklist.h b/services/device/public/cpp/hid/hid_blocklist.h index e0d145f..40af590 100644 --- a/services/device/public/cpp/hid/hid_blocklist.h +++ b/services/device/public/cpp/hid/hid_blocklist.h
@@ -5,13 +5,9 @@ #ifndef SERVICES_DEVICE_PUBLIC_CPP_HID_HID_BLOCKLIST_H_ #define SERVICES_DEVICE_PUBLIC_CPP_HID_HID_BLOCKLIST_H_ +#include "base/no_destructor.h" #include "services/device/public/mojom/hid.mojom.h" -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - namespace device { class HidBlocklist final {
diff --git a/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc b/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc index ed1a9c72..576df0c 100644 --- a/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc +++ b/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc
@@ -220,10 +220,8 @@ base::SequenceLocalStorageSlot<TracingSamplerProfiler>& GetSequenceLocalStorageProfilerSlot() { - static base::NoDestructor< - base::SequenceLocalStorageSlot<TracingSamplerProfiler>> - storage; - return *storage; + static base::SequenceLocalStorageSlot<TracingSamplerProfiler> storage; + return storage; } // Stores information about the StackFrame, to emit to the trace.
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index fd28d962..1ab125d 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -6824,7 +6824,7 @@ } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 15 }, "test": "content_browsertests", "test_id_prefix": "ninja://content/test:content_browsertests/" @@ -14028,7 +14028,7 @@ } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 15 }, "test": "content_browsertests", "test_id_prefix": "ninja://content/test:content_browsertests/"
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index eb3f0bc2..aadf44e 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1216,11 +1216,17 @@ 'args': [ '--test-launcher-filter-file=../../testing/buildbot/filters/android.lollipop_tablet_tester.content_browsertests.filter', ], + 'swarming': { + 'shards': 15, + }, }, 'Marshmallow Tablet Tester': { 'args': [ '--test-launcher-filter-file=../../testing/buildbot/filters/android.marshmallow_tablet_tester.content_browsertests.filter', ], + 'swarming': { + 'shards': 15, + }, }, 'WebRTC Chromium FYI Android Tests (dbg) (L Nexus5)': { 'args': [
diff --git a/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json b/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json index e958805..3b964e7d 100644 --- a/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json +++ b/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json
@@ -144,8 +144,9 @@ }, "new_tilings": { "ci_095": 0.334, - "avg": 16.692, - "cpu_wall_time_ratio": 0.372 + "avg": 19.224, + "cpu_wall_time_ratio": 0.372, + "_comment": "Return to 16.692 after crbug.com/1225374" }, "chip_tune": { "ci_095": 0.355,
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index d243ff8..4a775e98 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2109,6 +2109,28 @@ ] } ], + "CompositeAfterPaint": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CompositeAfterPaint" + ] + } + ] + } + ], "ContentCapture": [ { "platforms": [
diff --git a/third_party/blink/common/browser_interface_broker_proxy.cc b/third_party/blink/common/browser_interface_broker_proxy.cc index 65826e83..7d30a1d 100644 --- a/third_party/blink/common/browser_interface_broker_proxy.cc +++ b/third_party/blink/common/browser_interface_broker_proxy.cc
@@ -5,7 +5,6 @@ #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "base/macros.h" -#include "base/no_destructor.h" #include "base/threading/sequence_local_storage_slot.h" namespace blink { @@ -62,17 +61,15 @@ } BrowserInterfaceBrokerProxy& GetEmptyBrowserInterfaceBroker() { - static base::NoDestructor< - base::SequenceLocalStorageSlot<BrowserInterfaceBrokerProxy>> - proxy_slot; - if (!proxy_slot->GetValuePointer()) { - auto& proxy = proxy_slot->GetOrCreateValue(); + static base::SequenceLocalStorageSlot<BrowserInterfaceBrokerProxy> proxy_slot; + if (!proxy_slot.GetValuePointer()) { + auto& proxy = proxy_slot.GetOrCreateValue(); mojo::PendingRemote<blink::mojom::BrowserInterfaceBroker> remote; ignore_result(remote.InitWithNewPipeAndPassReceiver()); proxy.Bind(std::move(remote), base::ThreadTaskRunnerHandle::Get()); } - return proxy_slot->GetOrCreateValue(); + return proxy_slot.GetOrCreateValue(); } } // namespace blink
diff --git a/third_party/blink/common/privacy_budget/identifiability_study_settings.cc b/third_party/blink/common/privacy_budget/identifiability_study_settings.cc index bf93086c..b3da1c9 100644 --- a/third_party/blink/common/privacy_budget/identifiability_study_settings.cc +++ b/third_party/blink/common/privacy_budget/identifiability_study_settings.cc
@@ -105,8 +105,7 @@ } bool DecideSample(int sample_rate) { - static base::NoDestructor<base::SequenceLocalStorageSlot<std::mt19937_64>> - prng; + static base::SequenceLocalStorageSlot<std::mt19937_64> prng; if (sample_rate == 0) return false; @@ -114,10 +113,10 @@ if (sample_rate == 1) return true; - if (!prng->GetValuePointer()) - prng->emplace(base::RandUint64()); + if (!prng.GetValuePointer()) + prng.emplace(base::RandUint64()); - return RandGenerator(sample_rate, **prng) == 0; + return RandGenerator(sample_rate, *prng) == 0; } } // namespace
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h index 7691e1e..cd2ebc9 100644 --- a/third_party/blink/public/platform/platform.h +++ b/third_party/blink/public/platform/platform.h
@@ -441,7 +441,7 @@ // used for resources which have compress="gzip" in *.grd. virtual WebData GetDataResource( int resource_id, - ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_NONE) { + ui::ResourceScaleFactor scale_factor = ui::SCALE_FACTOR_NONE) { return WebData(); }
diff --git a/third_party/blink/public/web/web_remote_frame.h b/third_party/blink/public/web/web_remote_frame.h index 2b7f665..c075dc1 100644 --- a/third_party/blink/public/web/web_remote_frame.h +++ b/third_party/blink/public/web/web_remote_frame.h
@@ -53,15 +53,15 @@ WebFrame* opener); // Also performs core initialization to associate the created remote frame - // with the provided <portal> element. - BLINK_EXPORT static WebRemoteFrame* CreateForPortal( + // with the provided <portal> or <fencedframe> element. + BLINK_EXPORT static WebRemoteFrame* CreateForPortalOrFencedFrame( mojom::TreeScopeType, WebRemoteFrameClient*, InterfaceRegistry*, AssociatedInterfaceProvider*, const RemoteFrameToken& frame_token, const base::UnguessableToken& devtools_frame_token, - const WebElement& portal_element); + const WebElement& frame_owner); // Specialized factory methods to allow the embedder to replicate the frame // tree between processes.
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index fd9c44f..3c99fb9 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -289,9 +289,9 @@ }; BackForwardCacheBufferLimitTracker& GetBackForwardCacheBufferLimitTracker() { - static base::NoDestructor<BackForwardCacheBufferLimitTracker> + static BackForwardCacheBufferLimitTracker back_forward_cache_buffer_limit_tracker; - return *back_forward_cache_buffer_limit_tracker; + return back_forward_cache_buffer_limit_tracker; } inline float ParentPageZoomFactor(LocalFrame* frame) {
diff --git a/third_party/blink/renderer/core/frame/remote_frame_view.cc b/third_party/blink/renderer/core/frame/remote_frame_view.cc index ab1faaea..c8f071d 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_view.cc +++ b/third_party/blink/renderer/core/frame/remote_frame_view.cc
@@ -47,8 +47,11 @@ HTMLFrameOwnerElement* owner = remote_frame_->DeprecatedLocalOwner(); if (owner && - owner->OwnerType() == mojom::blink::FrameOwnerElementType::kPortal) + (owner->OwnerType() == mojom::blink::FrameOwnerElementType::kPortal || + owner->OwnerType() == + mojom::blink::FrameOwnerElementType::kFencedframe)) { return owner->GetDocument().GetFrame()->View(); + } // |is_attached_| is only set from AttachToLayout(), which ensures that the // parent is a local frame.
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.cc b/third_party/blink/renderer/core/frame/visual_viewport.cc index 05dc2e87..3338bdf 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport.cc
@@ -37,6 +37,7 @@ #include "cc/input/main_thread_scrolling_reason.h" #include "cc/layers/solid_color_scrollbar_layer.h" #include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h" +#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" @@ -297,7 +298,7 @@ } #if defined(OS_ANDROID) - if (base::FeatureList::IsEnabled(::features::kElasticOverscroll) && + if (Platform::Current()->IsElasticOverscrollEnabled() && base::GetFieldTrialParamValueByFeature( ::features::kElasticOverscroll, ::features::kElasticOverscrollType) != ::features::kElasticOverscrollTypeTransform) {
diff --git a/third_party/blink/renderer/core/frame/web_remote_frame_impl.cc b/third_party/blink/renderer/core/frame/web_remote_frame_impl.cc index bd4421c..86ae1f30 100644 --- a/third_party/blink/renderer/core/frame/web_remote_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_remote_frame_impl.cc
@@ -26,6 +26,7 @@ #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/frame/web_frame_widget_impl.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" +#include "third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.h" #include "third_party/blink/renderer/core/html/html_frame_owner_element.h" #include "third_party/blink/renderer/core/html/portal/html_portal_element.h" #include "third_party/blink/renderer/core/html_names.h" @@ -54,6 +55,7 @@ frame_token); } +// static WebRemoteFrame* WebRemoteFrame::CreateMainFrame( WebView* web_view, WebRemoteFrameClient* client, @@ -67,17 +69,18 @@ frame_token, devtools_frame_token, opener); } -WebRemoteFrame* WebRemoteFrame::CreateForPortal( +// static +WebRemoteFrame* WebRemoteFrame::CreateForPortalOrFencedFrame( mojom::blink::TreeScopeType scope, WebRemoteFrameClient* client, InterfaceRegistry* interface_registry, AssociatedInterfaceProvider* associated_interface_provider, const RemoteFrameToken& frame_token, const base::UnguessableToken& devtools_frame_token, - const WebElement& portal_element) { - return WebRemoteFrameImpl::CreateForPortal( + const WebElement& frame_owner) { + return WebRemoteFrameImpl::CreateForPortalOrFencedFrame( scope, client, interface_registry, associated_interface_provider, - frame_token, devtools_frame_token, portal_element); + frame_token, devtools_frame_token, frame_owner); } // static @@ -111,28 +114,34 @@ return frame; } -WebRemoteFrameImpl* WebRemoteFrameImpl::CreateForPortal( +WebRemoteFrameImpl* WebRemoteFrameImpl::CreateForPortalOrFencedFrame( mojom::blink::TreeScopeType scope, WebRemoteFrameClient* client, InterfaceRegistry* interface_registry, AssociatedInterfaceProvider* associated_interface_provider, const RemoteFrameToken& frame_token, const base::UnguessableToken& devtools_frame_token, - const WebElement& portal_element) { + const WebElement& frame_owner) { auto* frame = MakeGarbageCollected<WebRemoteFrameImpl>( scope, client, interface_registry, associated_interface_provider, frame_token); - Element* element = portal_element; - DCHECK(element->HasTagName(html_names::kPortalTag)); - DCHECK( - RuntimeEnabledFeatures::PortalsEnabled(element->GetExecutionContext())); - HTMLPortalElement* portal = static_cast<HTMLPortalElement*>(element); - LocalFrame* host_frame = portal->GetDocument().GetFrame(); - frame->InitializeCoreFrame(*host_frame->GetPage(), portal, nullptr, nullptr, - FrameInsertType::kInsertInConstructor, g_null_atom, - &host_frame->window_agent_factory(), - devtools_frame_token); + // We first convert this to a raw blink::Element*, and manually convert this + // to an HTMLElement*. That is the only way the IsA<> and To<> casts below + // will work. + Element* element = frame_owner; + DCHECK(IsA<HTMLPortalElement>(element) || + IsA<HTMLFencedFrameElement>(element)); + ExecutionContext* execution_context = element->GetExecutionContext(); + DCHECK(RuntimeEnabledFeatures::PortalsEnabled(execution_context) || + RuntimeEnabledFeatures::FencedFramesEnabled(execution_context)); + HTMLFrameOwnerElement* frame_owner_element = + To<HTMLFrameOwnerElement>(element); + LocalFrame* host_frame = frame_owner_element->GetDocument().GetFrame(); + frame->InitializeCoreFrame( + *host_frame->GetPage(), frame_owner_element, nullptr, nullptr, + FrameInsertType::kInsertInConstructor, g_null_atom, + &host_frame->window_agent_factory(), devtools_frame_token); return frame; } @@ -241,9 +250,11 @@ To<WebLocalFrameImpl>(parent)->LocalRoot()->FrameWidget(); } } else if (owner && owner->IsLocal()) { - // Never gets to this point without |owner| being a portal element. - auto* owner_element = To<HTMLFrameOwnerElement>(owner); - DCHECK(owner_element->IsHTMLPortalElement()); + // Never gets to this point unless |owner| is a <portal> or <fencedframe> + // element. + HTMLFrameOwnerElement* owner_element = To<HTMLFrameOwnerElement>(owner); + DCHECK(owner_element->IsHTMLPortalElement() || + owner_element->IsHTMLFencedFrameElement()); LocalFrame& local_frame = owner_element->GetDocument().GetFrame()->LocalFrameRoot(); ancestor_widget = WebLocalFrameImpl::FromFrame(local_frame)->FrameWidget();
diff --git a/third_party/blink/renderer/core/frame/web_remote_frame_impl.h b/third_party/blink/renderer/core/frame/web_remote_frame_impl.h index b224a36..e995c43 100644 --- a/third_party/blink/renderer/core/frame/web_remote_frame_impl.h +++ b/third_party/blink/renderer/core/frame/web_remote_frame_impl.h
@@ -39,14 +39,14 @@ const RemoteFrameToken& frame_token, const base::UnguessableToken& devtools_frame_token, WebFrame* opener); - static WebRemoteFrameImpl* CreateForPortal( + static WebRemoteFrameImpl* CreateForPortalOrFencedFrame( mojom::blink::TreeScopeType, WebRemoteFrameClient*, InterfaceRegistry*, AssociatedInterfaceProvider*, const RemoteFrameToken& frame_token, const base::UnguessableToken& devtools_frame_token, - const WebElement& portal_element); + const WebElement& frame_owner); WebRemoteFrameImpl(mojom::blink::TreeScopeType, WebRemoteFrameClient*,
diff --git a/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.h b/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.h index c37acd34..d4c8aeab 100644 --- a/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.h +++ b/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.h
@@ -108,6 +108,11 @@ return html_element->IsHTMLFencedFrameElement(); return false; } + static bool AllowFrom(const Element& element) { + if (const HTMLElement* html_element = DynamicTo<HTMLElement>(element)) + return html_element->IsHTMLFencedFrameElement(); + return false; + } }; } // namespace blink
diff --git a/third_party/blink/renderer/core/html/portal/html_portal_element.h b/third_party/blink/renderer/core/html/portal/html_portal_element.h index f9262fd..d6ccd40c 100644 --- a/third_party/blink/renderer/core/html/portal/html_portal_element.h +++ b/third_party/blink/renderer/core/html/portal/html_portal_element.h
@@ -172,6 +172,11 @@ return html_element->IsHTMLPortalElement(); return false; } + static bool AllowFrom(const Element& element) { + if (const HTMLElement* html_element = DynamicTo<HTMLElement>(element)) + return html_element->IsHTMLPortalElement(); + return false; + } }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/accessibility/ax_media_element.cc b/third_party/blink/renderer/modules/accessibility/ax_media_element.cc index 482f14b3..4715a48 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_media_element.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_media_element.cc
@@ -61,24 +61,6 @@ return AXNodeObject::Restriction(); } -bool AccessibilityMediaElement::HasControls() const { - if (IsDetached()) - return false; - if (!IsA<HTMLMediaElement>(GetNode()) || !GetNode()->isConnected()) { - NOTREACHED() << "Accessible media element not ready: " << GetNode() - << " isConnected? " << GetNode()->isConnected(); - return false; - } - return To<HTMLMediaElement>(GetNode())->ShouldShowControls(); -} - -bool AccessibilityMediaElement::HasEmptySource() const { - if (IsDetached()) - return false; - return To<HTMLMediaElement>(GetNode())->getNetworkState() == - HTMLMediaElement::kNetworkEmpty; -} - bool AccessibilityMediaElement::IsUnplayable() const { if (IsDetached()) return true;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_media_element.h b/third_party/blink/renderer/modules/accessibility/ax_media_element.h index afa2cea7..e58ceb9 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_media_element.h +++ b/third_party/blink/renderer/modules/accessibility/ax_media_element.h
@@ -34,8 +34,6 @@ AXRestriction Restriction() const override; protected: - bool HasControls() const; - bool HasEmptySource() const; bool IsUnplayable() const; DISALLOW_COPY_AND_ASSIGN(AccessibilityMediaElement);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index 9424437..0d164be0 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -67,6 +67,7 @@ #include "third_party/blink/renderer/core/html/html_table_row_element.h" #include "third_party/blink/renderer/core/html/html_table_section_element.h" #include "third_party/blink/renderer/core/html/html_title_element.h" +#include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h" #include "third_party/blink/renderer/core/input/context_menu_allowed_scope.h" #include "third_party/blink/renderer/core/input/event_handler.h" @@ -2478,6 +2479,14 @@ return true; } + // The ignored state of media controls can change without a layout update. + // Keep them in the tree at all times so that the serializer isn't + // accidentally working with unincluded nodes, which is not allowed. + if (node->IsInUserAgentShadowRoot() && + IsA<HTMLMediaElement>(node->OwnerShadowHost())) { + return true; + } + Element* element = GetElement(); if (!element) return false;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index f3f23ef..82d3c9f 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -2882,6 +2882,8 @@ HandleUseMapAttributeChangedWithCleanLayout(element); } else if (attr_name == html_names::kNameAttr) { HandleNameAttributeChangedWithCleanLayout(element); + } else if (attr_name == html_names::kControlsAttr) { + ChildrenChangedWithCleanLayout(element); } if (!attr_name.LocalName().StartsWith("aria-"))
diff --git a/third_party/blink/renderer/modules/scheduler/scheduler.idl b/third_party/blink/renderer/modules/scheduler/scheduler.idl index 71f20574..755ec139 100644 --- a/third_party/blink/renderer/modules/scheduler/scheduler.idl +++ b/third_party/blink/renderer/modules/scheduler/scheduler.idl
@@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Experimental Scheduling API Proposal: -// https://docs.google.com/document/d/1Apz-SD-pOagGeyWxIpgOi0ARNkrCrELhPdm18eeu9tw +// https://wicg.github.io/scheduling-apis/#sec-scheduler +// +// currentTaskSignal: +// https://github.com/WICG/scheduling-apis/blob/main/explainers/post-task-propagation.md [ Exposed=(Window,Worker), ImplementedAs=DOMScheduler,
diff --git a/third_party/blink/renderer/modules/scheduler/scheduler_post_task_callback.idl b/third_party/blink/renderer/modules/scheduler/scheduler_post_task_callback.idl index 7dc1b251..97c205c 100644 --- a/third_party/blink/renderer/modules/scheduler/scheduler_post_task_callback.idl +++ b/third_party/blink/renderer/modules/scheduler/scheduler_post_task_callback.idl
@@ -2,6 +2,5 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Experimental Scheduling API Proposal: -// https://docs.google.com/document/d/1Apz-SD-pOagGeyWxIpgOi0ARNkrCrELhPdm18eeu9tw +// https://wicg.github.io/scheduling-apis/#sec-scheduler callback SchedulerPostTaskCallback = any ();
diff --git a/third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl b/third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl index 147b49e..e8459a0 100644 --- a/third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl +++ b/third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Experimental Scheduling API Proposal: -// https://docs.google.com/document/d/1xU7HyNsEsbXhTgt0ZnXDbeSXm5-m5FzkLJAT6LTizEI/edit# +// https://wicg.github.io/scheduling-apis/#sec-task-priorities enum TaskPriority { "user-blocking", "user-visible", "background" }; +// https://wicg.github.io/scheduling-apis/#sec-scheduler dictionary SchedulerPostTaskOptions { AbortSignal signal; TaskPriority priority;
diff --git a/third_party/blink/renderer/modules/scheduler/task_controller.idl b/third_party/blink/renderer/modules/scheduler/task_controller.idl index 15efbca..280744f 100644 --- a/third_party/blink/renderer/modules/scheduler/task_controller.idl +++ b/third_party/blink/renderer/modules/scheduler/task_controller.idl
@@ -2,9 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Experimental Scheduling API Proposal: -// https://docs.google.com/document/d/1xU7HyNsEsbXhTgt0ZnXDbeSXm5-m5FzkLJAT6LTizEI/edit# - +// https://wicg.github.io/scheduling-apis/#sec-task-controller [ Exposed=(Window,Worker), ImplementedAs=DOMTaskController,
diff --git a/third_party/blink/renderer/modules/scheduler/task_signal.idl b/third_party/blink/renderer/modules/scheduler/task_signal.idl index 731e725..1b29200 100644 --- a/third_party/blink/renderer/modules/scheduler/task_signal.idl +++ b/third_party/blink/renderer/modules/scheduler/task_signal.idl
@@ -2,9 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Experimental Scheduling API Proposal: -// https://docs.google.com/document/d/1xU7HyNsEsbXhTgt0ZnXDbeSXm5-m5FzkLJAT6LTizEI/edit# - +// https://wicg.github.io/scheduling-apis/#sec-task-signal [ Exposed=(Window,Worker), ImplementedAs=DOMTaskSignal,
diff --git a/third_party/blink/renderer/modules/scheduler/window_or_worker_scheduler.idl b/third_party/blink/renderer/modules/scheduler/window_or_worker_scheduler.idl index bd65043..5c72942 100644 --- a/third_party/blink/renderer/modules/scheduler/window_or_worker_scheduler.idl +++ b/third_party/blink/renderer/modules/scheduler/window_or_worker_scheduler.idl
@@ -2,8 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Experimental Scheduling API Proposal: -// https://docs.google.com/document/d/1xU7HyNsEsbXhTgt0ZnXDbeSXm5-m5FzkLJAT6LTizEI/edit# +// https://wicg.github.io/scheduling-apis/#sec-patches-html-windoworworkerglobalscope [ ImplementedAs=DOMScheduler, Exposed=(Window,Worker)
diff --git a/third_party/blink/renderer/modules/xr/xr_image_tracking_result.cc b/third_party/blink/renderer/modules/xr/xr_image_tracking_result.cc index 7e3355f..069d9a1 100644 --- a/third_party/blink/renderer/modules/xr/xr_image_tracking_result.cc +++ b/third_party/blink/renderer/modules/xr/xr_image_tracking_result.cc
@@ -48,12 +48,7 @@ device::mojom::blink::XRNativeOriginInformationPtr XRImageTrackingResult::NativeOrigin() const { - // TODO(https://crbug.com/1143575): We'll want these to correspond to an - // actual, independent space eventually, but at the moment it's sufficient for - // the ARCore implementation to have it be equivalent to the local reference - // space. - return device::mojom::blink::XRNativeOriginInformation::NewReferenceSpaceType( - device::mojom::XRReferenceSpaceType::kLocal); + return device::mojom::blink::XRNativeOriginInformation::NewImageIndex(index_); } void XRImageTrackingResult::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/platform/graphics/image.cc b/third_party/blink/renderer/platform/graphics/image.cc index 4665d9d..16ee18e 100644 --- a/third_party/blink/renderer/platform/graphics/image.cc +++ b/third_party/blink/renderer/platform/graphics/image.cc
@@ -95,8 +95,9 @@ return image_decode_cache; } -scoped_refptr<Image> Image::LoadPlatformResource(int resource_id, - ui::ScaleFactor scale_factor) { +scoped_refptr<Image> Image::LoadPlatformResource( + int resource_id, + ui::ResourceScaleFactor scale_factor) { const WebData& resource = Platform::Current()->GetDataResource(resource_id, scale_factor); if (resource.IsEmpty())
diff --git a/third_party/blink/renderer/platform/graphics/image.h b/third_party/blink/renderer/platform/graphics/image.h index 0f3c56aa..4ef1b1a 100644 --- a/third_party/blink/renderer/platform/graphics/image.h +++ b/third_party/blink/renderer/platform/graphics/image.h
@@ -79,7 +79,7 @@ static scoped_refptr<Image> LoadPlatformResource( int resource_id, - ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_100P); + ui::ResourceScaleFactor scale_factor = ui::SCALE_FACTOR_100P); static PaintImage ResizeAndOrientImage( const PaintImage&,
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc index d232a430..c3c7e72 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc
@@ -93,10 +93,10 @@ }; DecoderCounter* GetDecoderCounter() { - static base::NoDestructor<DecoderCounter> s_counter; + static DecoderCounter s_counter; // Note that this will init only in the first call in the ctor, so it's still // single threaded. - return s_counter.get(); + return &s_counter; } void FinishWait(base::WaitableEvent* waiter, bool* result_out, bool result) {
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.cc index a4e347c..3a19c2c 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.cc
@@ -80,10 +80,10 @@ // Number of RTCVideoDecoder instances right now that have started decoding. std::atomic_int* GetDecoderCounter() { - static base::NoDestructor<std::atomic_int> s_counter(0); + static std::atomic_int s_counter(0); // Note that this will init only in the first call in the ctor, so it's still // single threaded. - return s_counter.get(); + return &s_counter; } void RecordInitializationLatency(base::TimeDelta latency) {
diff --git a/third_party/blink/renderer/platform/scheduler/common/features.cc b/third_party/blink/renderer/platform/scheduler/common/features.cc index 525643e..9ef5952 100644 --- a/third_party/blink/renderer/platform/scheduler/common/features.cc +++ b/third_party/blink/renderer/platform/scheduler/common/features.cc
@@ -64,8 +64,6 @@ // use the base::FeatureParams. base::TimeDelta GetIntensiveWakeUpThrottlingGracePeriod() { - DCHECK(IsIntensiveWakeUpThrottlingEnabled()); - // Controls the time that elapses after a page is backgrounded before the // throttling policy takes effect. static const base::FeatureParam<int>
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc index 2cf8fb8..bbe6cf81 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -1370,13 +1370,17 @@ std::unique_ptr<WebSchedulingTaskQueue> FrameSchedulerImpl::CreateWebSchedulingTaskQueue( WebSchedulingPriority priority) { - // Use QueueTraits here that are the same as postMessage, which is one current - // method for scheduling script. - scoped_refptr<MainThreadTaskQueue> task_queue = + scoped_refptr<MainThreadTaskQueue> immediate_task_queue = frame_task_queue_controller_->NewWebSchedulingTaskQueue( - PausableTaskQueueTraits(), priority); + DeferrableTaskQueueTraits(), priority); + scoped_refptr<MainThreadTaskQueue> delayed_task_queue = + frame_task_queue_controller_->NewWebSchedulingTaskQueue( + DeferrableTaskQueueTraits() + .SetCanBeThrottled(true) + .SetCanBeIntensivelyThrottled(true), + priority); return std::make_unique<MainThreadWebSchedulingTaskQueueImpl>( - task_queue->AsWeakPtr()); + immediate_task_queue->AsWeakPtr(), delayed_task_queue->AsWeakPtr()); } void FrameSchedulerImpl::OnWebSchedulingTaskQueuePriorityChanged(
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc index 9b3e078..1f97f072 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -16,6 +16,7 @@ #include "base/metrics/field_trial_param_associator.h" #include "base/metrics/field_trial_params.h" #include "base/run_loop.h" +#include "base/single_thread_task_runner.h" #include "base/task/sequence_manager/test/sequence_manager_for_test.h" #include "base/task/thread_pool.h" #include "base/test/bind.h" @@ -23,6 +24,7 @@ #include "base/test/scoped_command_line.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" +#include "base/time/time.h" #include "base/unguessable_token.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -646,6 +648,26 @@ return GetParam().is_intensive_throttling_expected; } + // Get the TaskRunner from |frame_scheduler_| using the test's task type + // parameter. + scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const { + return GetTaskRunner(frame_scheduler_.get()); + } + + // Get the TaskRunner from the provided |frame_scheduler| using the test's + // task type parameter. + scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner( + FrameSchedulerImpl* frame_scheduler) const { + const TaskType task_type = GetTaskType(); + if (task_type == TaskType::kExperimentalWebScheduling) { + return frame_scheduler + ->CreateWebSchedulingTaskQueue( + WebSchedulingPriority::kUserVisiblePriority) + ->GetTaskRunner(); + } + return frame_scheduler->GetTaskRunner(task_type); + } + base::TimeDelta GetExpectedWakeUpInterval() const { if (IsIntensiveThrottlingExpected()) return kIntensiveThrottledWakeUpInterval; @@ -2761,7 +2783,8 @@ // - 'V': UserVisible // - 'B': Background void PostWebSchedulingTestTasks(Vector<String>* run_order, - const String& task_descriptor) { + const String& task_descriptor, + base::TimeDelta delay = base::TimeDelta()) { std::istringstream stream(task_descriptor.Utf8()); while (!stream.eof()) { std::string task; @@ -2781,9 +2804,11 @@ EXPECT_FALSE(true); return; } - web_scheduling_task_runners_[static_cast<int>(priority)]->PostTask( - FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order, - String::FromUTF8(task))); + web_scheduling_task_runners_[static_cast<int>(priority)]->PostDelayedTask( + FROM_HERE, + base::BindOnce(&AppendToVectorTestTask, run_order, + String::FromUTF8(task)), + delay); } } @@ -2815,12 +2840,29 @@ testing::ElementsAre("V1", "V2", "B1", "B2", "U1", "U2")); } -// Verify that tasks posted with TaskType::kJavascriptTimerDelayed* run at the -// expected time when throttled. +TEST_F(WebSchedulingTaskQueueTest, DynamicTaskPriorityOrderDelayedTasks) { + Vector<String> run_order; + + // We're relying on all of the delays to expire at the same time, in which + // case the tasks will run in the updated priority order. + PostWebSchedulingTestTasks(&run_order, "B1 B2 V1 V2 U1 U2", + base::TimeDelta::FromMilliseconds(5)); + task_queues_[static_cast<int>(WebSchedulingPriority::kUserBlockingPriority)] + ->SetPriority(WebSchedulingPriority::kBackgroundPriority); + + task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(5)); + + EXPECT_THAT(run_order, + testing::ElementsAre("V1", "V2", "B1", "B2", "U1", "U2")); +} + +// Verify that tasks posted with TaskType::kJavascriptTimerDelayed* and +// delayed web scheduling tasks run at the expected time when throttled. TEST_F(FrameSchedulerImplTest, ThrottledJSTimerTasksRunTime) { constexpr TaskType kJavaScriptTimerTaskTypes[] = { TaskType::kJavascriptTimerDelayedLowNesting, - TaskType::kJavascriptTimerDelayedHighNesting}; + TaskType::kJavascriptTimerDelayedHighNesting, + TaskType::kExperimentalWebScheduling}; // Snap the time to a multiple of 1 second. Otherwise, the exact run time // of throttled tasks after hiding the page will vary. @@ -2832,10 +2874,16 @@ std::map<TaskType, std::vector<base::TimeTicks>> run_times; - // Post tasks with each Javascript Timer Task Type. + // Post tasks with each Javascript Timer Task Type and with a + // WebSchedulingTaskQueue. for (TaskType task_type : kJavaScriptTimerTaskTypes) { const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(task_type); + task_type == TaskType::kExperimentalWebScheduling + ? frame_scheduler_ + ->CreateWebSchedulingTaskQueue( + WebSchedulingPriority::kUserVisiblePriority) + ->GetTaskRunner() + : frame_scheduler_->GetTaskRunner(task_type); // Note: Taking the address of an element in |run_times| is safe because // inserting elements in a map does not invalidate references. @@ -2944,7 +2992,7 @@ // Throttled TaskRunner to which tasks are posted in this test. const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(GetTaskType()); + GetTaskRunner(); // Snap the time to a multiple of // |kIntensiveThrottledWakeUpInterval|. Otherwise, the time at which @@ -3122,7 +3170,7 @@ // Throttled TaskRunner to which tasks are posted in this test. const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(GetTaskType()); + GetTaskRunner(); // Snap the time to a multiple of // |kIntensiveThrottledWakeUpInterval|. Otherwise, the time at which @@ -3296,7 +3344,7 @@ ManySameOriginFrames) { ASSERT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame()); const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(GetTaskType()); + GetTaskRunner(); // Create a FrameScheduler that is same-origin with the main frame, and an // associated throttled TaskRunner. @@ -3306,7 +3354,7 @@ FrameScheduler::FrameType::kSubframe); ASSERT_FALSE(other_frame_scheduler->IsCrossOriginToMainFrame()); const scoped_refptr<base::SingleThreadTaskRunner> other_task_runner = - other_frame_scheduler->GetTaskRunner(GetTaskType()); + GetTaskRunner(other_frame_scheduler.get()); // Snap the time to a multiple of // |kIntensiveThrottledWakeUpInterval|. Otherwise, the time at which @@ -3352,14 +3400,14 @@ constexpr int kNumTasks = 3; // |task_runner| is throttled. const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(GetTaskType()); + GetTaskRunner(); // |other_task_runner| is throttled. It belongs to a different frame on the // same page. const auto other_frame_scheduler = CreateFrameScheduler( page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr, FrameScheduler::FrameType::kSubframe); const scoped_refptr<base::SingleThreadTaskRunner> other_task_runner = - other_frame_scheduler->GetTaskRunner(GetTaskType()); + GetTaskRunner(other_frame_scheduler.get()); // Fast-forward the time to a multiple of // |kIntensiveThrottledWakeUpInterval|. Otherwise, @@ -3477,7 +3525,7 @@ FrameChangesOriginType) { EXPECT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame()); const scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame_scheduler_->GetTaskRunner(GetTaskType()); + GetTaskRunner(); // Create a new FrameScheduler that remains cross-origin with the main frame // throughout the test. @@ -3487,7 +3535,7 @@ FrameScheduler::FrameType::kSubframe); cross_origin_frame_scheduler->SetCrossOriginToMainFrame(true); const scoped_refptr<base::SingleThreadTaskRunner> cross_origin_task_runner = - cross_origin_frame_scheduler->GetTaskRunner(GetTaskType()); + GetTaskRunner(cross_origin_frame_scheduler.get()); // Snap the time to a multiple of // |kIntensiveThrottledWakeUpInterval|. Otherwise, the time at which @@ -3579,6 +3627,9 @@ /* is_intensive_throttling_expected=*/false}, IntensiveWakeUpThrottlingTestParam{ /* task_type=*/TaskType::kJavascriptTimerDelayedHighNesting, + /* is_intensive_throttling_expected=*/true}, + IntensiveWakeUpThrottlingTestParam{ + /* task_type=*/TaskType::kExperimentalWebScheduling, /* is_intensive_throttling_expected=*/true}), [](const testing::TestParamInfo<IntensiveWakeUpThrottlingTestParam>& info) { return TaskTypeNames::TaskTypeToString(info.param.task_type); @@ -3841,6 +3892,36 @@ } } +// Verify that non-delayed kExperimentalWebScheduling tasks are not throttled. +TEST_F(FrameSchedulerImplTest, ImmediateWebSchedulingTasksAreNotThrottled) { + std::vector<base::TimeTicks> run_times; + + // Make sure we are *not* aligned to a 1 second boundary by aligning to a 1 + // second boundary and moving past it a bit. If we were throttled, even + // non-delayed tasks will need to wait until the next aligned interval to run. + FastForwardToAlignedTime(base::TimeDelta::FromSeconds(1)); + task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1)); + + const base::TimeTicks start = base::TimeTicks::Now(); + + // Hide the page to start throttling timers. + page_scheduler_->SetPageVisible(false); + + // Post a non-delayed task to a web scheduling task queue. + const scoped_refptr<base::SingleThreadTaskRunner> task_runner = + frame_scheduler_ + ->CreateWebSchedulingTaskQueue( + WebSchedulingPriority::kUserVisiblePriority) + ->GetTaskRunner(); + task_runner->PostTask(FROM_HERE, base::BindOnce(&RecordRunTime, &run_times)); + + // Run any ready tasks, which includes our non-delayed non-throttled web + // scheduling task. If we are throttled, our task will not run. + base::RunLoop().RunUntilIdle(); + + EXPECT_THAT(run_times, testing::ElementsAre(start)); +} + } // namespace frame_scheduler_impl_unittest } // namespace scheduler } // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_web_scheduling_task_queue_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_web_scheduling_task_queue_impl.cc index 0474a99..e93f85f 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_web_scheduling_task_queue_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_web_scheduling_task_queue_impl.cc
@@ -10,16 +10,59 @@ namespace blink { namespace scheduler { +MainThreadWebSchedulingTaskQueueImpl::WebSchedulingTaskRunner:: + WebSchedulingTaskRunner( + scoped_refptr<base::SingleThreadTaskRunner> immediate_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> delayed_task_runner) + : immediate_task_runner_(std::move(immediate_task_runner)), + delayed_task_runner_(std::move(delayed_task_runner)) {} + +bool MainThreadWebSchedulingTaskQueueImpl::WebSchedulingTaskRunner:: + PostDelayedTask(const base::Location& location, + base::OnceClosure task, + base::TimeDelta delay) { + return GetTaskRunnerForDelay(delay)->PostDelayedTask(location, + std::move(task), delay); +} + +bool MainThreadWebSchedulingTaskQueueImpl::WebSchedulingTaskRunner:: + PostNonNestableDelayedTask(const base::Location& location, + base::OnceClosure task, + base::TimeDelta delay) { + return GetTaskRunnerForDelay(delay)->PostNonNestableDelayedTask( + location, std::move(task), delay); +} + +bool MainThreadWebSchedulingTaskQueueImpl::WebSchedulingTaskRunner:: + RunsTasksInCurrentSequence() const { + DCHECK_EQ(immediate_task_runner_->RunsTasksInCurrentSequence(), + delayed_task_runner_->RunsTasksInCurrentSequence()); + return immediate_task_runner_->RunsTasksInCurrentSequence(); +} + +base::SingleThreadTaskRunner* MainThreadWebSchedulingTaskQueueImpl:: + WebSchedulingTaskRunner::GetTaskRunnerForDelay(base::TimeDelta delay) { + return delay > base::TimeDelta() ? delayed_task_runner_.get() + : immediate_task_runner_.get(); +} + MainThreadWebSchedulingTaskQueueImpl::MainThreadWebSchedulingTaskQueueImpl( - base::WeakPtr<MainThreadTaskQueue> task_queue) - : task_runner_( - task_queue->CreateTaskRunner(TaskType::kExperimentalWebScheduling)), - task_queue_(std::move(task_queue)) {} + base::WeakPtr<MainThreadTaskQueue> immediate_task_queue, + base::WeakPtr<MainThreadTaskQueue> delayed_task_queue) + : task_runner_(base::MakeRefCounted<WebSchedulingTaskRunner>( + immediate_task_queue->CreateTaskRunner( + TaskType::kExperimentalWebScheduling), + delayed_task_queue->CreateTaskRunner( + TaskType::kExperimentalWebScheduling))), + immediate_task_queue_(std::move(immediate_task_queue)), + delayed_task_queue_(std::move(delayed_task_queue)) {} void MainThreadWebSchedulingTaskQueueImpl::SetPriority( WebSchedulingPriority priority) { - if (task_queue_) - task_queue_->SetWebSchedulingPriority(priority); + if (immediate_task_queue_) + immediate_task_queue_->SetWebSchedulingPriority(priority); + if (delayed_task_queue_) + delayed_task_queue_->SetWebSchedulingPriority(priority); } scoped_refptr<base::SingleThreadTaskRunner>
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_web_scheduling_task_queue_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_web_scheduling_task_queue_impl.h index 6b572faa..3f70d61 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_web_scheduling_task_queue_impl.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_web_scheduling_task_queue_impl.h
@@ -21,7 +21,9 @@ class PLATFORM_EXPORT MainThreadWebSchedulingTaskQueueImpl : public WebSchedulingTaskQueue { public: - MainThreadWebSchedulingTaskQueueImpl(base::WeakPtr<MainThreadTaskQueue>); + MainThreadWebSchedulingTaskQueueImpl( + base::WeakPtr<MainThreadTaskQueue> immediate_task_queue, + base::WeakPtr<MainThreadTaskQueue> delayed_task_queue); ~MainThreadWebSchedulingTaskQueueImpl() override = default; void SetPriority(WebSchedulingPriority) override; @@ -29,8 +31,36 @@ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() override; private: - const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - base::WeakPtr<MainThreadTaskQueue> task_queue_; + // In order to throttle delayed tasks in the background, we manage two + // MainThreadTaskQueues and their associated TaskRunners---one for delayed + // tasks and one for non-delayed tasks (immediate). Rather than exposing this + // to the web scheduling layer, we implement a simple custom TaskRunner that + // handles picking the appropriate underlying TaskRunner based on the delay + // value and return that in GetTaskRunner(). + class WebSchedulingTaskRunner : public base::SingleThreadTaskRunner { + public: + WebSchedulingTaskRunner( + scoped_refptr<base::SingleThreadTaskRunner> immediate_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> delayed_task_runner); + + bool PostDelayedTask(const base::Location& location, + base::OnceClosure task, + base::TimeDelta delay) override; + bool PostNonNestableDelayedTask(const base::Location& from_here, + base::OnceClosure task, + base::TimeDelta delay) override; + bool RunsTasksInCurrentSequence() const override; + + private: + base::SingleThreadTaskRunner* GetTaskRunnerForDelay(base::TimeDelta delay); + + const scoped_refptr<base::SingleThreadTaskRunner> immediate_task_runner_; + const scoped_refptr<base::SingleThreadTaskRunner> delayed_task_runner_; + }; + + scoped_refptr<WebSchedulingTaskRunner> task_runner_; + base::WeakPtr<MainThreadTaskQueue> immediate_task_queue_; + base::WeakPtr<MainThreadTaskQueue> delayed_task_queue_; }; } // namespace scheduler
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc index fd20e904..c4417cd6 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -725,10 +725,8 @@ for (WakeUpBudgetPool* pool : AllWakeUpBudgetPools()) pool->SetWakeUpDuration(kThrottledWakeUpDuration); - if (IsIntensiveWakeUpThrottlingEnabled()) { - same_origin_intensive_wake_up_budget_pool_ - ->AllowLowerAlignmentIfNoRecentWakeUp(kDefaultThrottledWakeUpInterval); - } + same_origin_intensive_wake_up_budget_pool_ + ->AllowLowerAlignmentIfNoRecentWakeUp(kDefaultThrottledWakeUpInterval); UpdateWakeUpBudgetPools(lazy_now); } @@ -772,11 +770,9 @@ FROM_HERE, do_throttle_cpu_time_callback_.GetCallback(), kThrottlingDelayAfterBackgrounding); } - if (IsIntensiveWakeUpThrottlingEnabled()) { - main_thread_scheduler_->ControlTaskRunner()->PostDelayedTask( - FROM_HERE, do_intensively_throttle_wake_ups_callback_.GetCallback(), - GetIntensiveWakeUpThrottlingGracePeriod()); - } + main_thread_scheduler_->ControlTaskRunner()->PostDelayedTask( + FROM_HERE, do_intensively_throttle_wake_ups_callback_.GetCallback(), + GetIntensiveWakeUpThrottlingGracePeriod()); } if (notification_policy == NotificationPolicy::kNotifyFrames) NotifyFrames(); @@ -793,8 +789,6 @@ } void PageSchedulerImpl::DoIntensivelyThrottleWakeUps() { - DCHECK(IsIntensiveWakeUpThrottlingEnabled()); - do_intensively_throttle_wake_ups_callback_.Cancel(); are_wake_ups_intensively_throttled_ = true;
diff --git a/third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h b/third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h index 049ecb25..04e618d 100644 --- a/third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h +++ b/third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h
@@ -10,8 +10,7 @@ namespace blink { -// Priorities for the experimental scheduling API (see -// https://github.com/WICG/main-thread-scheduling). +// https://wicg.github.io/scheduling-apis/#sec-task-priorities enum class WebSchedulingPriority { kUserBlockingPriority = 0, kUserVisiblePriority = 1,
diff --git a/third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h b/third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h index 0f580027..50d783a 100644 --- a/third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h +++ b/third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h
@@ -12,9 +12,9 @@ namespace blink { -// This class is used by the experimental Scheduling API to submit tasks to the -// platform's scheduler through prioritized task queues (see -// https://github.com/WICG/main-thread-scheduling). +// This class is used by the Prioritized Task Scheduling API to submit tasks to +// the platform's scheduler through prioritized task queues (see +// https://wicg.github.io/scheduling-apis/). class PLATFORM_EXPORT WebSchedulingTaskQueue { public: virtual ~WebSchedulingTaskQueue() = default;
diff --git a/third_party/blink/renderer/platform/testing/testing_platform_support.cc b/third_party/blink/renderer/platform/testing/testing_platform_support.cc index 12ed1318..0b6ebef 100644 --- a/third_party/blink/renderer/platform/testing/testing_platform_support.cc +++ b/third_party/blink/renderer/platform/testing/testing_platform_support.cc
@@ -109,8 +109,9 @@ return WebString::FromUTF8("en-US"); } -WebData TestingPlatformSupport::GetDataResource(int resource_id, - ui::ScaleFactor scale_factor) { +WebData TestingPlatformSupport::GetDataResource( + int resource_id, + ui::ResourceScaleFactor scale_factor) { return old_platform_ ? old_platform_->GetDataResource(resource_id, scale_factor) : WebData();
diff --git a/third_party/blink/renderer/platform/testing/testing_platform_support.h b/third_party/blink/renderer/platform/testing/testing_platform_support.h index c60029c..cf6ed4f 100644 --- a/third_party/blink/renderer/platform/testing/testing_platform_support.h +++ b/third_party/blink/renderer/platform/testing/testing_platform_support.h
@@ -63,7 +63,7 @@ // Platform: WebString DefaultLocale() override; WebData GetDataResource(int resource_id, - ui::ScaleFactor scale_factor) override; + ui::ResourceScaleFactor scale_factor) override; WebData UncompressDataResource(int resource_id) override; ThreadSafeBrowserInterfaceBrokerProxy* GetBrowserInterfaceBroker() override; bool IsThreadedAnimationEnabled() override;
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/driver.py b/third_party/blink/tools/blinkpy/web_tests/port/driver.py index 233462d..eeb5171a 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/driver.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/driver.py
@@ -530,8 +530,18 @@ cmd.extend(self._port.additional_driver_flags()) if self._port.get_option('enable_leak_detection'): cmd.append('--enable-leak-detection') - cmd.extend(per_test_args) + + # The following code temporarily disables CompositeAfterPaint in web + # tests unless it is explicitly enabled. CompositeAfterPaint is enabled + # via fieldtrial_testing_config.json which would make web tests run + # with CompositeAfterPaint. This is disabled in order to stage the + # enabling of the feature because of the number of rebaselines needed. + # TODO(pdr): Remove this code and run web tests with + # CompositeAfterPaint. + if '--enable-blink-features=CompositeAfterPaint' not in cmd: + cmd.append('--disable-blink-features=CompositeAfterPaint') + cmd = coalesce_repeated_switches(cmd) cmd.append('-') return cmd
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng index 470143e..2b2b59c7 100644 --- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng +++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -121,6 +121,10 @@ crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-alignment-implies-size-change-035.html [ Failure ] crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-alignment-implies-size-change-036.html [ Failure ] crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-baseline-004.html [ Failure ] +crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-1.html [ Failure ] +crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-2.html [ Failure ] +crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-3.html [ Failure ] +crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-4.html [ Failure ] crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-001.html [ Failure ] crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-002.html [ Failure ] crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-003.html [ Failure ]
diff --git a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility index 56948e9..23ecbe2c 100644 --- a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility +++ b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
@@ -6,7 +6,6 @@ # crbug.com/1138028 tracks the removal of these failure expectations # Crashes -crbug.com/1012242 external/wpt/webvtt/rendering/cues-with-video/processing-model/disable_controls_reposition.html [ CRASH ] virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-display-none-editable.html [ CRASH ] crbug.com/926685 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-010.html [ CRASH ] virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-017.html [ CRASH ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 637e1a22..9179a5f3 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3926,9 +3926,6 @@ # [css-grid] crbug.com/1045599 external/wpt/css/css-grid/abspos/grid-abspos-staticpos-align-self-safe-001.html [ Failure ] -crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-4.html [ Failure ] -crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-6.html [ Failure ] -crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7.html [ Failure ] crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-004.html [ Failure ] crbug.com/1045599 external/wpt/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-003.html [ Failure ] crbug.com/759665 external/wpt/css/css-grid/animation/grid-template-columns-001.html [ Failure ] @@ -3959,6 +3956,10 @@ virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-alignment-implies-size-change-035.html [ Failure ] virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-alignment-implies-size-change-036.html [ Failure ] virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-baseline-004.html [ Failure ] +virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-1.html [ Failure ] +virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-2.html [ Failure ] +virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-3.html [ Failure ] +virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-4.html [ Failure ] virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-001.html [ Failure ] virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-002.html [ Failure ] virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-003.html [ Failure ] @@ -4008,18 +4009,6 @@ virtual/layout-ng-grid/fast/css-grid-layout/grid-track-sizing-with-orthogonal-flows.html [ Failure ] virtual/layout-ng-grid/fast/css-grid-layout/maximize-tracks-definite-indefinite-height.html [ Failure ] -# Bad stretching of svgs without aspect-ratio. -crbug.com/1114013 external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-5.html [ Failure ] -crbug.com/1114013 external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-8.html [ Failure ] -crbug.com/1114013 external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-9.html [ Failure ] -crbug.com/1114013 external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-10.html [ Failure ] - -# Open discussion of SVG aspect ratios at https://github.com/w3c/csswg-drafts/issues/6286 -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-4.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-5.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-6.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7.html [ Failure ] - # The 'last baseline' keyword is not implemented yet crbug.com/885175 external/wpt/css/css-grid/alignment/grid-item-self-baseline-001.html [ Skip ] crbug.com/885175 external/wpt/css/css-grid/alignment/grid-self-alignment-baseline-with-grid-001.html [ Skip ] @@ -7080,3 +7069,6 @@ # Now also flakily timing-out. crbug.com/1223773 external/wpt/webrtc/simulcast/getStats.https.html [ Failure Pass Timeout ] crbug.com/1193920 virtual/threaded-prefer-compositing/fast/scrolling/events/overscroll-event-fired-to-scrolled-element.html [ Failure Pass Timeout ] + +# Sheriff 2021-07-02 +crbug.com/1226112 http/tests/text-autosizing/narrow-iframe.html [ Failure Pass ] \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-1-ref.html similarity index 73% copy from third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7-ref.html copy to third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-1-ref.html index 0d60375..1120e45f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-1-ref.html
@@ -1,6 +1,6 @@ <!doctype html> <meta charset="utf-8"> -<title>Reference: stretching works for replaced items with no aspect ratio</title> +<title>Reference: stretching works for replaced items with a fallback aspect ratio</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="author" title="Mozilla" href="https://mozilla.org"> <style> @@ -19,9 +19,6 @@ img { display: block; - width: 300px; - height: 150px; - background: blue; } .justify { @@ -35,17 +32,17 @@ <img class="align justify"> </div> <div> - <img class="align" style="width:20px"> + <img class="align"> </div> <div> - <img class="justify" style="height:0px"> + <img class="justify"> </div> <div> - <img style="width:20px; height:0px"> + <img style="width:10px; height:20px"> </div> <script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"></svg>' +var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 100"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' var imgs = document.querySelectorAll('img'); for (var i = 0; i < imgs.length; ++i) { var img = imgs[i];
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-10.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-1.html similarity index 71% rename from third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-10.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-1.html index 6d8d7e8..909406f5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-10.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-1.html
@@ -1,11 +1,12 @@ <!doctype html> <meta charset="utf-8"> -<title>stretching works for replaced items with no aspect ratio</title> +<title>stretching works for replaced items with a fallback aspect ratio</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="author" title="Mozilla" href="https://mozilla.org"> <link rel="help" href="https://drafts.csswg.org/css-grid"> <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1656281"> -<link rel="match" href="grid-item-no-aspect-ratio-stretch-8-ref.html"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/6286#issuecomment-866986544"> +<link rel="match" href="grid-item-aspect-ratio-stretch-1-ref.html"> <style> body { line-height: 0; @@ -13,6 +14,7 @@ div { display: inline-grid; + grid-template: 100% / 100%; height: 250px; width: 350px; background: grey; @@ -41,7 +43,7 @@ </div> <script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="0px" height="0px"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' +var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 50 100"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' var imgs = document.querySelectorAll('img'); for (var i = 0; i < imgs.length; ++i) { var img = imgs[i];
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-2-ref.html similarity index 73% copy from third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7-ref.html copy to third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-2-ref.html index 0d60375..84d7950 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-2-ref.html
@@ -1,6 +1,6 @@ <!doctype html> <meta charset="utf-8"> -<title>Reference: stretching works for replaced items with no aspect ratio</title> +<title>Reference: stretching works for replaced items with a fallback aspect ratio</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="author" title="Mozilla" href="https://mozilla.org"> <style> @@ -19,9 +19,6 @@ img { display: block; - width: 300px; - height: 150px; - background: blue; } .justify { @@ -35,17 +32,17 @@ <img class="align justify"> </div> <div> - <img class="align" style="width:20px"> + <img class="align"> </div> <div> - <img class="justify" style="height:0px"> + <img class="justify"> </div> <div> - <img style="width:20px; height:0px"> + <img style="width:20px; height:40px"> </div> <script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"></svg>' +var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 100"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' var imgs = document.querySelectorAll('img'); for (var i = 0; i < imgs.length; ++i) { var img = imgs[i];
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-10.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-2.html similarity index 71% copy from third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-10.html copy to third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-2.html index 6d8d7e8..f5b7330 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-10.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-2.html
@@ -1,11 +1,12 @@ <!doctype html> <meta charset="utf-8"> -<title>stretching works for replaced items with no aspect ratio</title> +<title>stretching works for replaced items with a fallback aspect ratio</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="author" title="Mozilla" href="https://mozilla.org"> <link rel="help" href="https://drafts.csswg.org/css-grid"> <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1656281"> -<link rel="match" href="grid-item-no-aspect-ratio-stretch-8-ref.html"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/6286#issuecomment-866986544"> +<link rel="match" href="grid-item-aspect-ratio-stretch-2-ref.html"> <style> body { line-height: 0; @@ -13,6 +14,7 @@ div { display: inline-grid; + grid-template: 100% / 100%; height: 250px; width: 350px; background: grey; @@ -41,7 +43,7 @@ </div> <script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="0px" height="0px"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' +var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="20px" viewBox="0 0 50 100"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' var imgs = document.querySelectorAll('img'); for (var i = 0; i < imgs.length; ++i) { var img = imgs[i];
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-3-ref.html similarity index 75% copy from third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7-ref.html copy to third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-3-ref.html index 0d60375..b85803e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-3-ref.html
@@ -1,6 +1,6 @@ <!doctype html> <meta charset="utf-8"> -<title>Reference: stretching works for replaced items with no aspect ratio</title> +<title>Reference: stretching works for replaced items with a fallback aspect ratio</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="author" title="Mozilla" href="https://mozilla.org"> <style> @@ -19,8 +19,6 @@ img { display: block; - width: 300px; - height: 150px; background: blue; } @@ -35,17 +33,17 @@ <img class="align justify"> </div> <div> - <img class="align" style="width:20px"> + <img class="align"> </div> <div> - <img class="justify" style="height:0px"> + <img class="justify"> </div> <div> - <img style="width:20px; height:0px"> + <img style="width:0px; height:20px"> </div> <script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"></svg>' +var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 100"></svg>' var imgs = document.querySelectorAll('img'); for (var i = 0; i < imgs.length; ++i) { var img = imgs[i];
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-3.html similarity index 73% copy from third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7.html copy to third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-3.html index 29dec490..4320254 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-3.html
@@ -1,11 +1,12 @@ <!doctype html> <meta charset="utf-8"> -<title>stretching works for replaced items with no aspect ratio</title> +<title>stretching works for replaced items with a fallback aspect ratio</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="author" title="Mozilla" href="https://mozilla.org"> <link rel="help" href="https://drafts.csswg.org/css-grid"> <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1656281"> -<link rel="match" href="grid-item-no-aspect-ratio-stretch-7-ref.html"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/6286#issuecomment-866986544"> +<link rel="match" href="grid-item-aspect-ratio-stretch-3-ref.html"> <style> body { line-height: 0; @@ -13,6 +14,7 @@ div { display: inline-grid; + grid-template: 100% / 100%; height: 250px; width: 350px; background: grey; @@ -42,7 +44,7 @@ </div> <script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="20px" height="0px" viewBox="0 0 50 100"></svg>' +var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="0px" height="20px" viewBox="0 0 50 100"></svg>' var imgs = document.querySelectorAll('img'); for (var i = 0; i < imgs.length; ++i) { var img = imgs[i];
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-4-ref.html similarity index 78% rename from third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7-ref.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-4-ref.html index 0d60375..8d7fc87 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-4-ref.html
@@ -1,6 +1,6 @@ <!doctype html> <meta charset="utf-8"> -<title>Reference: stretching works for replaced items with no aspect ratio</title> +<title>Reference: stretching works for replaced items with a fallback aspect ratio</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="author" title="Mozilla" href="https://mozilla.org"> <style> @@ -19,8 +19,6 @@ img { display: block; - width: 300px; - height: 150px; background: blue; } @@ -35,17 +33,17 @@ <img class="align justify"> </div> <div> - <img class="align" style="width:20px"> + <img class="align"> </div> <div> - <img class="justify" style="height:0px"> + <img class="justify"> </div> <div> <img style="width:20px; height:0px"> </div> <script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"></svg>' +var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 100"></svg>' var imgs = document.querySelectorAll('img'); for (var i = 0; i < imgs.length; ++i) { var img = imgs[i];
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-4.html similarity index 78% rename from third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-4.html index 29dec490..f689cce 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-4.html
@@ -1,11 +1,12 @@ <!doctype html> <meta charset="utf-8"> -<title>stretching works for replaced items with no aspect ratio</title> +<title>stretching works for replaced items with a fallback aspect ratio</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="author" title="Mozilla" href="https://mozilla.org"> <link rel="help" href="https://drafts.csswg.org/css-grid"> <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1656281"> -<link rel="match" href="grid-item-no-aspect-ratio-stretch-7-ref.html"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/6286#issuecomment-866986544"> +<link rel="match" href="grid-item-aspect-ratio-stretch-4-ref.html"> <style> body { line-height: 0; @@ -13,6 +14,7 @@ div { display: inline-grid; + grid-template: 100% / 100%; height: 250px; width: 350px; background: grey;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-4-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-4-ref.html index 9edb8aa..4a543b4a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-4-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-4-ref.html
@@ -19,8 +19,8 @@ img { display: block; - width: 300px; - height: 150px; + width: 0px; + height: 20px; } .justify { @@ -34,17 +34,17 @@ <img class="align justify"> </div> <div> - <img class="align" style="width:10px"> + <img class="align"> </div> <div> - <img class="justify" style="height:20px"> + <img class="justify"> </div> <div> - <img style="width:10px; height:20px"> + <img> </div> <script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 100"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' +var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' var imgs = document.querySelectorAll('img'); for (var i = 0; i < imgs.length; ++i) { var img = imgs[i];
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-4.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-4.html index 1cf2849..a53c0fd 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-4.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-4.html
@@ -13,6 +13,7 @@ div { display: inline-grid; + grid-template: 100% / 100%; height: 250px; width: 350px; background: grey; @@ -41,7 +42,7 @@ </div> <script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 50 100"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' +var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="0px" height="20px"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' var imgs = document.querySelectorAll('img'); for (var i = 0; i < imgs.length; ++i) { var img = imgs[i];
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-5-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-5-ref.html index 6a34465..98f88fe 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-5-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-5-ref.html
@@ -19,8 +19,8 @@ img { display: block; - width: 300px; - height: 150px; + width: 20px; + height: 0px; } .justify { @@ -34,17 +34,17 @@ <img class="align justify"> </div> <div> - <img class="align" style="width:20px"> + <img class="align"> </div> <div> - <img class="justify" style="width:350px; height:40px"> + <img class="justify"> </div> <div> - <img style="width:20px; height:40px"> + <img> </div> <script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 100"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' +var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' var imgs = document.querySelectorAll('img'); for (var i = 0; i < imgs.length; ++i) { var img = imgs[i];
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-5.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-5.html index 3000e9d..c28022c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-5.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-5.html
@@ -13,6 +13,7 @@ div { display: inline-grid; + grid-template: 100% / 100%; height: 250px; width: 350px; background: grey; @@ -41,7 +42,7 @@ </div> <script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="20px" viewBox="0 0 50 100"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' +var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="20px" height="0px"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' var imgs = document.querySelectorAll('img'); for (var i = 0; i < imgs.length; ++i) { var img = imgs[i];
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-6-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-6-ref.html index 33f472e..8e989d1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-6-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-6-ref.html
@@ -19,9 +19,8 @@ img { display: block; - width: 300px; - height: 150px; - background: blue; + width: 0px; + height: 0px; } .justify { @@ -35,17 +34,17 @@ <img class="align justify"> </div> <div> - <img class="align" style="width:0px"> + <img class="align"> </div> <div> - <img class="justify" style="height:20px"> + <img class="justify"> </div> <div> - <img style="width:0px; height:20px"> + <img> </div> <script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"></svg>' +var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' var imgs = document.querySelectorAll('img'); for (var i = 0; i < imgs.length; ++i) { var img = imgs[i];
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-6.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-6.html index 655040eb..b4f172c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-6.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-6.html
@@ -19,7 +19,6 @@ margin: 10px; vertical-align: top; } - img { background: blue; } .justify { justify-self: stretch; @@ -42,7 +41,7 @@ </div> <script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="0px" height="20px" viewBox="0 0 50 100"></svg>' +var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="0px" height="0px"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' var imgs = document.querySelectorAll('img'); for (var i = 0; i < imgs.length; ++i) { var img = imgs[i];
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-8-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-8-ref.html deleted file mode 100644 index 09dd273..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-8-ref.html +++ /dev/null
@@ -1,27 +0,0 @@ -<!doctype html> -<meta charset="utf-8"> -<title>Reference: stretching works for replaced items with no aspect ratio</title> -<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> -<link rel="author" title="Mozilla" href="https://mozilla.org"> -<style> - body { - line-height: 0; - } - - div { - display: inline-block; - height: 250px; - width: 350px; - background: grey; - margin: 10px; - vertical-align: top; - } -</style> -<div> -</div> -<div> -</div> -<div> -</div> -<div> -</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-8.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-8.html deleted file mode 100644 index 933ddd05..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-8.html +++ /dev/null
@@ -1,50 +0,0 @@ -<!doctype html> -<meta charset="utf-8"> -<title>stretching works for replaced items with no aspect ratio</title> -<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> -<link rel="author" title="Mozilla" href="https://mozilla.org"> -<link rel="help" href="https://drafts.csswg.org/css-grid"> -<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1656281"> -<link rel="match" href="grid-item-no-aspect-ratio-stretch-8-ref.html"> -<style> - body { - line-height: 0; - } - - div { - display: inline-grid; - height: 250px; - width: 350px; - background: grey; - margin: 10px; - vertical-align: top; - } - - .justify { - justify-self: stretch; - } - .align { - align-self: stretch; - } -</style> -<div> - <img class="align justify"> -</div> -<div> - <img class="align"> -</div> -<div> - <img class="justify"> -</div> -<div> - <img> -</div> - -<script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="0px" height="20px"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' -var imgs = document.querySelectorAll('img'); -for (var i = 0; i < imgs.length; ++i) { - var img = imgs[i]; - img.src = url; -} -</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-9.html b/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-9.html deleted file mode 100644 index 367adae..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-9.html +++ /dev/null
@@ -1,50 +0,0 @@ -<!doctype html> -<meta charset="utf-8"> -<title>stretching works for replaced items with no aspect ratio</title> -<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> -<link rel="author" title="Mozilla" href="https://mozilla.org"> -<link rel="help" href="https://drafts.csswg.org/css-grid"> -<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1656281"> -<link rel="match" href="grid-item-no-aspect-ratio-stretch-8-ref.html"> -<style> - body { - line-height: 0; - } - - div { - display: inline-grid; - height: 250px; - width: 350px; - background: grey; - margin: 10px; - vertical-align: top; - } - - .justify { - justify-self: stretch; - } - .align { - align-self: stretch; - } -</style> -<div> - <img class="align justify"> -</div> -<div> - <img class="align"> -</div> -<div> - <img class="justify"> -</div> -<div> - <img> -</div> - -<script> -var url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="20px" height="0px"><circle cx="50%" cy="50%" r="50%" fill="blue"/></svg>' -var imgs = document.querySelectorAll('img'); -for (var i = 0; i < imgs.length; ++i) { - var img = imgs[i]; - img.src = url; -} -</script>
diff --git a/third_party/blink/web_tests/wpt_internal/js-self-profiling/time-domain.window.js b/third_party/blink/web_tests/wpt_internal/js-self-profiling/time-domain.window.js new file mode 100644 index 0000000..4967684 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/js-self-profiling/time-domain.window.js
@@ -0,0 +1,16 @@ +// META: script=resources/profile-utils.js + +promise_test(async () => { + const start = performance.now(); + + const profiler = new Profiler({ sampleInterval: 10 }); + ProfileUtils.forceSample(); + const trace = await profiler.stop(); + + const end = performance.now(); + + assert_greater_than(trace.samples.length, 0); + for (const sample of trace.samples) { + assert_between_inclusive(sample.timestamp, start, end); + } +}, 'sample timestamps use the current high-resolution time');
diff --git a/tools/clang/blink_gc_plugin/RecordInfo.cpp b/tools/clang/blink_gc_plugin/RecordInfo.cpp index d16a828..23c70665 100644 --- a/tools/clang/blink_gc_plugin/RecordInfo.cpp +++ b/tools/clang/blink_gc_plugin/RecordInfo.cpp
@@ -2,8 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "Config.h" #include "RecordInfo.h" + +#include <string> + +#include "Config.h" #include "clang/Sema/Sema.h" using namespace clang; @@ -241,9 +244,24 @@ .first->second; } +bool RecordInfo::HasTypeAlias(std::string marker_name) const { + for (Decl* decl : record_->decls()) { + TypeAliasDecl* alias = dyn_cast<TypeAliasDecl>(decl); + if (!alias) + continue; + if (alias->getName() == marker_name) + return true; + } + return false; +} + bool RecordInfo::IsStackAllocated() { if (is_stack_allocated_ == kNotComputed) { is_stack_allocated_ = kFalse; + if (HasTypeAlias("IsStackAllocatedTypeMarker")) { + is_stack_allocated_ = kTrue; + return is_stack_allocated_; + } for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) {
diff --git a/tools/clang/blink_gc_plugin/RecordInfo.h b/tools/clang/blink_gc_plugin/RecordInfo.h index 20ef058..d6ef638 100644 --- a/tools/clang/blink_gc_plugin/RecordInfo.h +++ b/tools/clang/blink_gc_plugin/RecordInfo.h
@@ -134,6 +134,8 @@ bool HasOptionalFinalizer(); + bool HasTypeAlias(std::string marker_name) const; + RecordCache* cache_; clang::CXXRecordDecl* record_; const std::string name_;
diff --git a/tools/clang/blink_gc_plugin/tests/heap/stubs.h b/tools/clang/blink_gc_plugin/tests/heap/stubs.h index 2e7dfc6..7c7c88d 100644 --- a/tools/clang/blink_gc_plugin/tests/heap/stubs.h +++ b/tools/clang/blink_gc_plugin/tests/heap/stubs.h
@@ -366,10 +366,13 @@ void* operator new(size_t) = delete; \ void* operator new(size_t, void*) = delete; -#define STACK_ALLOCATED() \ - private: \ - __attribute__((annotate("blink_stack_allocated"))) \ - void* operator new(size_t) = delete; \ +#define STACK_ALLOCATED() \ + public: \ + using IsStackAllocatedTypeMarker [[maybe_unused]] = int; \ + \ + private: \ + __attribute__((annotate("blink_stack_allocated"))) void* operator new( \ + size_t) = delete; \ void* operator new(size_t, void*) = delete; #define DISALLOW_NEW_EXCEPT_PLACEMENT_NEW() \
diff --git a/tools/clang/blink_gc_plugin/tests/stack_allocated.txt b/tools/clang/blink_gc_plugin/tests/stack_allocated.txt index 8c678aca..f6742df0 100644 --- a/tools/clang/blink_gc_plugin/tests/stack_allocated.txt +++ b/tools/clang/blink_gc_plugin/tests/stack_allocated.txt
@@ -23,8 +23,8 @@ ./stack_allocated.h:44:3: warning: [blink-gc] Garbage collected class 'DerivedHeapObject2' is not permitted to override its new operator. STACK_ALLOCATED(); ^ -./heap/stubs.h:371:3: note: expanded from macro 'STACK_ALLOCATED' - __attribute__((annotate("blink_stack_allocated"))) \ +./heap/stubs.h:374:3: note: expanded from macro 'STACK_ALLOCATED' + __attribute__((annotate("blink_stack_allocated"))) void* operator new( \ ^ In file included from stack_allocated.cpp:5: ./stack_allocated.h:24:5: warning: [blink-gc] Class 'StackObject' has untraced or not traceable fields.
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 29f4ff0..a56fe29 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -34,18 +34,11 @@ 'win64-chrome': 'official_goma_x64', }, 'chrome.pgo': { + 'android-arm32-pgo': 'official_goma_android_arm32_pgo', 'linux-pgo': 'official_goma_linux_pgo', - 'linux-pgo-beta': 'official_goma_linux_pgo', - 'linux-pgo-stable': 'official_goma_linux_pgo', 'mac-pgo': 'official_goma_mac_pgo', - 'mac-pgo-beta': 'official_goma_mac_pgo', - 'mac-pgo-stable': 'official_goma_mac_pgo', 'win32-pgo': 'official_goma_x86_pgo', - 'win32-pgo-beta': 'official_goma_x86_pgo', - 'win32-pgo-stable': 'official_goma_x86_pgo', 'win64-pgo': 'official_goma_x64_pgo', - 'win64-pgo-beta': 'official_goma_x64_pgo', - 'win64-pgo-stable': 'official_goma_x64_pgo', }, # Take care when changing any of these builders to ensure that you do not # include a configuration with 'chrome_with_codecs' since these builders @@ -909,6 +902,7 @@ }, 'tryserver.chrome.pgo': { + 'android-arm32-pgo': 'official_goma_android_arm32_pgo', 'linux-pgo': 'official_goma_linux_pgo', 'mac-pgo': 'official_goma_mac_pgo', 'win32-pgo': 'official_goma_x86_pgo', @@ -1171,6 +1165,7 @@ 'win10_chromium_x64_rel_ng_exp': 'release_trybot', 'win10_chromium_x64_rel_ng_rts': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage', 'win10_chromium_x64_20h2_fyi_rel_ng': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage', + 'win10-rel-orchestrator': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage', 'win-annotator-rel': 'release_trybot', 'win-asan': 'asan_clang_fuzzer_static_v8_heap_minimal_symbols_release', 'win-celab-try-rel': 'release_bot_minimal_symbols', @@ -2445,6 +2440,10 @@ 'official', 'goma', ], + 'official_goma_android_arm32_pgo': [ + 'official', 'goma', 'android_official', 'arm', 'pgo_phase_1', + ], + 'official_goma_mac': [ 'official', 'goma', 'no_widevine_cdm_host_verification', ], @@ -2853,6 +2852,15 @@ 'gn_args': 'is_java_debug=true', }, + 'android_official': { + 'mixins': ['android', 'android_official_webview_target', 'android_without_codecs', 'clank_custom_args', 'enable_remoting', 'enable_webview_bundles', 'ffmpeg_branding_chrome', 'official'], + 'gn_args': 'use_signing_keys=true' + }, + + 'android_official_webview_target': { + 'gn_args': 'system_webview_apk_target="//clank/android_webview:system_webview_google_apk"', + }, + 'android_without_codecs': { 'gn_args': 'target_os="android"', }, @@ -3003,6 +3011,10 @@ 'gn_args': 'is_clang=true', }, + 'clank_custom_args': { + 'args_file': '//clank/build/custom_args.gn', + }, + # Settings used by the codesearch builders to generate cross-references. 'codesearch': { 'gn_args': 'clang_use_chrome_plugins=false enable_kythe_annotations=true', @@ -3123,6 +3135,10 @@ 'gn_args': 'skip_archive_compression=false', }, + 'enable_remoting': { + 'gn_args': 'enable_remoting=true', + }, + 'enable_v8_oilpan': { 'gn_args': 'enable_blink_heap_use_v8_oilpan=true', }, @@ -3139,6 +3155,10 @@ 'gn_args': 'enable_vulkan=true', }, + 'enable_webview_bundles': { + 'gn_args': 'enable_webview_bundles = true' + }, + 'eve': { 'args_file': '//build/args/chromeos/eve.gni', },
diff --git a/tools/mb/mb_config_expectations/chrome.pgo.json b/tools/mb/mb_config_expectations/chrome.pgo.json index eba01ee..6cb7c02 100644 --- a/tools/mb/mb_config_expectations/chrome.pgo.json +++ b/tools/mb/mb_config_expectations/chrome.pgo.json
@@ -1,4 +1,22 @@ { + "android-arm32-pgo": { + "args_file": "//clank/build/custom_args.gn", + "gn_args": { + "chrome_pgo_phase": 1, + "enable_remoting": true, + "enable_webview_bundles": true, + "ffmpeg_branding": "Chrome", + "is_chrome_branded": true, + "is_official_build": true, + "proprietary_codecs": true, + "strip_absolute_paths_from_debug_symbols": true, + "system_webview_apk_target": "//clank/android_webview:system_webview_google_apk", + "target_cpu": "arm", + "target_os": "android", + "use_goma": true, + "use_signing_keys": true + } + }, "linux-pgo": { "gn_args": { "chrome_pgo_phase": 1, @@ -10,28 +28,6 @@ "use_goma": true } }, - "linux-pgo-beta": { - "gn_args": { - "chrome_pgo_phase": 1, - "is_chrome_branded": true, - "is_component_build": false, - "is_official_build": true, - "strip_absolute_paths_from_debug_symbols": true, - "symbol_level": 0, - "use_goma": true - } - }, - "linux-pgo-stable": { - "gn_args": { - "chrome_pgo_phase": 1, - "is_chrome_branded": true, - "is_component_build": false, - "is_official_build": true, - "strip_absolute_paths_from_debug_symbols": true, - "symbol_level": 0, - "use_goma": true - } - }, "mac-pgo": { "gn_args": { "chrome_pgo_phase": 1, @@ -46,34 +42,6 @@ "use_goma": true } }, - "mac-pgo-beta": { - "gn_args": { - "chrome_pgo_phase": 1, - "enable_keystone_registration_framework": false, - "enable_widevine_cdm_host_verification": false, - "ignore_missing_widevine_signing_cert": true, - "is_chrome_branded": true, - "is_component_build": false, - "is_official_build": true, - "strip_absolute_paths_from_debug_symbols": true, - "symbol_level": 0, - "use_goma": true - } - }, - "mac-pgo-stable": { - "gn_args": { - "chrome_pgo_phase": 1, - "enable_keystone_registration_framework": false, - "enable_widevine_cdm_host_verification": false, - "ignore_missing_widevine_signing_cert": true, - "is_chrome_branded": true, - "is_component_build": false, - "is_official_build": true, - "strip_absolute_paths_from_debug_symbols": true, - "symbol_level": 0, - "use_goma": true - } - }, "win32-pgo": { "gn_args": { "chrome_pgo_phase": 1, @@ -87,32 +55,6 @@ "use_goma": true } }, - "win32-pgo-beta": { - "gn_args": { - "chrome_pgo_phase": 1, - "enable_resource_allowlist_generation": false, - "is_chrome_branded": true, - "is_component_build": false, - "is_official_build": true, - "strip_absolute_paths_from_debug_symbols": true, - "symbol_level": 0, - "target_cpu": "x86", - "use_goma": true - } - }, - "win32-pgo-stable": { - "gn_args": { - "chrome_pgo_phase": 1, - "enable_resource_allowlist_generation": false, - "is_chrome_branded": true, - "is_component_build": false, - "is_official_build": true, - "strip_absolute_paths_from_debug_symbols": true, - "symbol_level": 0, - "target_cpu": "x86", - "use_goma": true - } - }, "win64-pgo": { "gn_args": { "chrome_pgo_phase": 1, @@ -125,31 +67,5 @@ "target_cpu": "x64", "use_goma": true } - }, - "win64-pgo-beta": { - "gn_args": { - "chrome_pgo_phase": 1, - "enable_resource_allowlist_generation": false, - "is_chrome_branded": true, - "is_component_build": false, - "is_official_build": true, - "strip_absolute_paths_from_debug_symbols": true, - "symbol_level": 0, - "target_cpu": "x64", - "use_goma": true - } - }, - "win64-pgo-stable": { - "gn_args": { - "chrome_pgo_phase": 1, - "enable_resource_allowlist_generation": false, - "is_chrome_branded": true, - "is_component_build": false, - "is_official_build": true, - "strip_absolute_paths_from_debug_symbols": true, - "symbol_level": 0, - "target_cpu": "x64", - "use_goma": true - } } } \ No newline at end of file
diff --git a/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json b/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json index 1d89704..6cb7c02 100644 --- a/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json +++ b/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json
@@ -1,4 +1,22 @@ { + "android-arm32-pgo": { + "args_file": "//clank/build/custom_args.gn", + "gn_args": { + "chrome_pgo_phase": 1, + "enable_remoting": true, + "enable_webview_bundles": true, + "ffmpeg_branding": "Chrome", + "is_chrome_branded": true, + "is_official_build": true, + "proprietary_codecs": true, + "strip_absolute_paths_from_debug_symbols": true, + "system_webview_apk_target": "//clank/android_webview:system_webview_google_apk", + "target_cpu": "arm", + "target_os": "android", + "use_goma": true, + "use_signing_keys": true + } + }, "linux-pgo": { "gn_args": { "chrome_pgo_phase": 1,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.win.json b/tools/mb/mb_config_expectations/tryserver.chromium.win.json index 38a6577..2a11a8a 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.win.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.win.json
@@ -253,6 +253,21 @@ "use_libfuzzer": true } }, + "win10-rel-orchestrator": { + "gn_args": { + "blink_enable_generated_code_formatting": false, + "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt", + "dcheck_always_on": true, + "enable_resource_allowlist_generation": false, + "ffmpeg_branding": "Chrome", + "is_component_build": false, + "is_debug": false, + "proprietary_codecs": true, + "symbol_level": 0, + "use_clang_coverage": true, + "use_goma": true + } + }, "win10_chromium_inverse_fieldtrials_x64_fyi_rel_ng": { "gn_args": { "blink_enable_generated_code_formatting": false,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 958b39b1..44d2ffa 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -46350,6 +46350,7 @@ <int value="-1826649921" label="ContextualSuggestionsButton:disabled"/> <int value="-1826309726" label="ArcCustomTabsExperiment:disabled"/> <int value="-1823193038" label="QuietNotificationPrompts:disabled"/> + <int value="-1823073826" label="TabGroupsSave:disabled"/> <int value="-1822825246" label="DragFromShelfToHomeOrOverview:enabled"/> <int value="-1821058653" label="enable-delay-agnostic-aec"/> <int value="-1818947212" label="OutOfBlinkCors:disabled"/> @@ -46394,6 +46395,7 @@ <int value="-1778993296" label="ContextualSearchMlTapSuppression:disabled"/> <int value="-1778202807" label="DelayAsyncScriptExecution:enabled"/> <int value="-1776351704" label="DesktopPWAsOmniboxInstall:disabled"/> + <int value="-1775842908" label="EnableOAuthIpp:disabled"/> <int value="-1774818943" label="VrWebInputEditing:enabled"/> <int value="-1772942854" label="LongPressBackForHistory:enabled"/> <int value="-1772905637" @@ -46972,6 +46974,7 @@ <int value="-1319688939" label="ignore-gpu-blacklist"/> <int value="-1318914924" label="OverflowIconsForMediaControls:enabled"/> <int value="-1316769004" label="CrossOriginOpenerPolicyReporting:disabled"/> + <int value="-1314757884" label="TabGroupsSave:enabled"/> <int value="-1314603238" label="ChromeHomePullToRefreshIphAtTop:enabled"/> <int value="-1313810940" label="StrictOriginIsolation:disabled"/> <int value="-1311575452" @@ -47219,6 +47222,7 @@ <int value="-1134412904" label="PrivacySandboxSettings:disabled"/> <int value="-1134307340" label="stop-loading-in-background:enabled"/> <int value="-1132704128" label="AndroidPaymentAppsFilter:disabled"/> + <int value="-1128981647" label="EnableOAuthIpp:enabled"/> <int value="-1128912963" label="MediaControlsExpandGesture:disabled"/> <int value="-1128221789" label="AutofillEnableSurfacingServerCardNickname:enabled"/> @@ -48938,6 +48942,8 @@ <int value="359896413" label="SplitPartiallyOccludedQuads:disabled"/> <int value="360391863" label="NTPOfflineBadge:enabled"/> <int value="360599302" label="enable-gpu-rasterization"/> + <int value="362623880" + label="HoldingSpaceInProgressDownloadsIntegration:disabled"/> <int value="362644448" label="memlog-in-process"/> <int value="362853088" label="AmbientColor:disabled"/> <int value="363997248" label="UseXpsForPrinting:enabled"/> @@ -49150,6 +49156,8 @@ <int value="529235584" label="PhoneHub:enabled"/> <int value="530828403" label="AllowStartingServiceManagerOnly:disabled"/> <int value="533064367" label="WebRtcHideLocalIpsWithMdns:disabled"/> + <int value="533115840" + label="HoldingSpaceInProgressDownloadsIntegration:enabled"/> <int value="535131384" label="OmniboxTailSuggestions:enabled"/> <int value="535194142" label="TemporaryHoldingSpacePreviews:enabled"/> <int value="535976218" label="enable-plugin-power-saver"/> @@ -61350,6 +61358,44 @@ <int value="17" label="FlingToCloseTabletTouch"/> </enum> +<enum name="OverviewEndAction"> + <int value="0" + label="SplitView related, e.g, both snapped, window activation"/> + <int value="1" label="Dragging window from shelf in tablet mode"/> + <int value="2" label="Exiting overview to home launcher"/> + <int value="3" label="Click or tap outside of the windows in overview"/> + <int value="4" label="Window activated in overview"/> + <int value="5" label="Last window in overview being removed"/> + <int value="6" label="Display added while in overivew"/> + <int value="7" label="Pressing shortcut F5"/> + <int value="8" label="Pressing key Escape or Back"/> + <int value="9" label="Desk activation"/> + <int value="10" label="Pressing overview button"/> + <int value="11" label="Long pressing overview button in split view mode"/> + <int value="12" label="Three fingers swiping down on the trackpad"/> + <int value="13" label="Enabled Docked Magnifier"/> + <int value="14" label="Switching user happens with multi users login"/> + <int value="15" label="Started window cycle"/> + <int value="16" label="Opened app list while in clamshell mode"/> + <int value="17" label="Shelf alignment changed"/> + <int value="18" label="Shutting down"/> + <int value="19" label="Exiting overview through dev tools"/> + <int value="20" label="Exiting overview in tests"/> +</enum> + +<enum name="OverviewStartAction"> + <int value="0" label="SplitView related, e.g, one window snapped"/> + <int value="1" label="Pressing shortcut F5"/> + <int value="2" label="Dragging window from shelf in tablet mode"/> + <int value="3" label="Going from home launcher to overview"/> + <int value="4" label="Pressing overview button"/> + <int value="5" label="Long pressing overview button in split view mode"/> + <int value="6" label="Going from Bento bar to overview"/> + <int value="7" label="Three fingers swiping up on the trackpad"/> + <int value="8" label="Entering overview through dev tools"/> + <int value="9" label="Entering overview in tests"/> +</enum> + <enum name="P2PLookupResult"> <int value="0" label="Found"/> <int value="1" label="Not Found"/> @@ -86438,6 +86484,7 @@ <int value="2" label="Failed (no versions)"/> <int value="3" label="Failed (no file descriptors)"/> <int value="4" label="Failed (error opening file descriptors)"/> + <int value="5" label="Failed (Component Updater SafeMode enabled)"/> </enum> <enum name="WebViewDrawAndSubmissionType">
diff --git a/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml b/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml index 52bdeac..711f931 100644 --- a/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml
@@ -291,6 +291,30 @@ </summary> </histogram> +<histogram + name="Accessibility.CrosDictation.ListeningDuration.NetworkRecognition" + units="ms" expires_after="2021-12-06"> + <owner>katie@chromium.org</owner> + <owner>chrome-a11y-core@google.com</owner> + <summary> + Duration that the network speech recognition service was listening for + dictation. Recorded each time a user toggles dictation on until dictation is + stopped, either by the user action, error, or timeout. + </summary> +</histogram> + +<histogram + name="Accessibility.CrosDictation.ListeningDuration.OnDeviceRecognition" + units="ms" expires_after="2021-12-06"> + <owner>katie@chromium.org</owner> + <owner>chrome-a11y-core@google.com</owner> + <summary> + Duration that the on-device speech recognition service was listening for + dictation. Recorded each time a user toggles dictation on until dictation is + stopped, either by the user action, error, or timeout. + </summary> +</histogram> + <histogram name="Accessibility.CrosDictation.ToggleDictationMethod" enum="CrosDictationToggleDictationMethod" expires_after="2021-11-21"> <owner>anastasi@google.com</owner> @@ -518,7 +542,7 @@ </histogram> <histogram name="Accessibility.CrosStickyKeys" enum="BooleanEnabled" - expires_after="M93"> + expires_after="M96"> <owner>dmazzoni@chromium.org</owner> <owner>kenjibaheux@google.com</owner> <owner>tengs@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/android/histograms.xml b/tools/metrics/histograms/histograms_xml/android/histograms.xml index b66e4cec..47306c8 100644 --- a/tools/metrics/histograms/histograms_xml/android/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/android/histograms.xml
@@ -2892,6 +2892,17 @@ </summary> </histogram> +<histogram name="Android.WebView.ComponentUpdater.SafeModeActionExecuted" + enum="Boolean" expires_after="2022-06-30"> + <owner>nator@chromium.org</owner> + <owner>src/android_webview/OWNERS</owner> + <summary> + Whether a SafeMode action was executed by Component Updater services. This + is logged whenever a nonembedded Component Updater service checks whether + SafeMode is enabled. + </summary> +</histogram> + <histogram name="Android.WebView.ComponentUpdater.UnexpectedExit" enum="Boolean" expires_after="2021-10-08"> <owner>nator@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/ash/histograms.xml b/tools/metrics/histograms/histograms_xml/ash/histograms.xml index 5ce777d..3b0943b 100644 --- a/tools/metrics/histograms/histograms_xml/ash/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/ash/histograms.xml
@@ -734,6 +734,17 @@ </summary> </histogram> +<histogram name="Ash.Desks.BentoBarEnabled" enum="Boolean" + expires_after="2022-05-19"> + <owner>minch@chromium.org</owner> + <owner>janetmac@chromium.org</owner> + <summary> + Emits true if a user clicked `Show deskbar` inside the context menu of bento + bar or desks bar in overview mode, false if `Hide deskbar` inside the same + context menu being clicked. + </summary> +</histogram> + <histogram name="Ash.Desks.ConsecutiveDailyVisits" units="days" expires_after="2022-02-19"> <owner>chinsenj@chromium.org</owner> @@ -1631,6 +1642,16 @@ </summary> </histogram> +<histogram name="Ash.Overview.EndAction" enum="OverviewEndAction" + expires_after="2022-05-19"> + <owner>minch@chromium.org</owner> + <owner>janetmac@chromium.org</owner> + <summary> + Emitted when exiting overview mode. Recording the reasons for ending + overview mode. E.g, pressing the overview button at status area. + </summary> +</histogram> + <histogram name="Ash.Overview.Items" units="units" expires_after="2022-04-08"> <owner>chinsenj@chromium.org</owner> <owner>nupurjain@chromium.org</owner> @@ -1698,6 +1719,16 @@ </summary> </histogram> +<histogram name="Ash.Overview.StartAction" enum="OverviewStartAction" + expires_after="2022-05-19"> + <owner>minch@chromium.org</owner> + <owner>janetmac@chromium.org</owner> + <summary> + Emitted when entering overview mode. Recording the reasons for starting + overview mode. E.g, pressing the overview button at status area. + </summary> +</histogram> + <histogram name="Ash.Overview.TimeBetweenActiveWindowChanges" units="seconds" expires_after="2022-04-08"> <owner>chinsenj@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml index e491294..56d7c5e 100644 --- a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
@@ -11660,6 +11660,9 @@ </histogram_suffixes> <histogram_suffixes name="NewTabPageProviders" separator="."> + <obsolete> + Removed in 06 2021. + </obsolete> <suffix name="allowlist" label="Installed allowlist entry point suggestions."/> <suffix name="client" label="Suggestions coming from the client."/> @@ -11735,7 +11738,11 @@ Deprecated NTP replaced by WebUI NTP M91. </obsolete> </suffix> - <suffix name="MostLikely" label="Loaded server-side suggestions."/> + <suffix name="MostLikely" label="Loaded server-side suggestions."> + <obsolete> + Removed in 06 2021. + </obsolete> + </suffix> <suffix name="MostVisited" label="Loaded client-side suggestions."/> <suffix name="NewTab" label="NTP loaded on a new tab."/> <suffix name="Startup" label="NTP loaded during browser startup."/>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 5bae464..90485154 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,12 +5,12 @@ "remote_path": "perfetto_binaries/trace_processor_shell/win/1de765c9f44ba03cf19433a4e4773c70dff7fdc2/trace_processor_shell.exe" }, "mac": { - "hash": "483154c0035fe858cc81c6bbdee5952f926f6129", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/d27cd04c1f2558bc29856c1357d79f56f92e759b/trace_processor_shell" + "hash": "35f8312274ca0f4e183d62a2553c1fce1126ad84", + "remote_path": "perfetto_binaries/trace_processor_shell/mac/b0345c864e4a2ddeeb3b5084fb6fc7b856957ac8/trace_processor_shell" }, "linux": { - "hash": "74346658e719c8b2669a1a35bb89b4e2ac7cc794", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/1de765c9f44ba03cf19433a4e4773c70dff7fdc2/trace_processor_shell" + "hash": "08053337518f6063718f9ef61292a17475ec550d", + "remote_path": "perfetto_binaries/trace_processor_shell/linux/b0345c864e4a2ddeeb3b5084fb6fc7b856957ac8/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/accelerated_widget_mac/ca_transaction_observer.h b/ui/accelerated_widget_mac/ca_transaction_observer.h index 3155897c..44de148 100644 --- a/ui/accelerated_widget_mac/ca_transaction_observer.h +++ b/ui/accelerated_widget_mac/ca_transaction_observer.h
@@ -9,16 +9,12 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/no_destructor.h" #include "base/observer_list.h" #include "base/time/time.h" #include "ui/accelerated_widget_mac/accelerated_widget_mac_export.h" -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - namespace ui { // CATransactionCoordinator is an interface to undocumented macOS APIs which
diff --git a/ui/accessibility/ax_active_popup.cc b/ui/accessibility/ax_active_popup.cc index 40ef023..366baf1 100644 --- a/ui/accessibility/ax_active_popup.cc +++ b/ui/accessibility/ax_active_popup.cc
@@ -5,7 +5,6 @@ #include "ui/accessibility/ax_active_popup.h" #include "base/macros.h" -#include "base/no_destructor.h" namespace ui { @@ -17,8 +16,8 @@ // currently active autofill popup. This singleton is used for communicating // the live status of the autofill popup between web contents and Views. The // assumption here is that only one autofill popup can exist at a time. - static base::NoDestructor<absl::optional<AXNodeID>> active_popup_ax_unique_id; - return *active_popup_ax_unique_id; + static absl::optional<AXNodeID> active_popup_ax_unique_id; + return active_popup_ax_unique_id; } } // namespace
diff --git a/ui/accessibility/ax_tree_id.cc b/ui/accessibility/ax_tree_id.cc index 15c4f3e..c1050f4 100644 --- a/ui/accessibility/ax_tree_id.cc +++ b/ui/accessibility/ax_tree_id.cc
@@ -8,7 +8,6 @@ #include <iostream> #include "base/check.h" -#include "base/no_destructor.h" #include "base/notreached.h" #include "base/util/values/values_util.h" #include "base/values.h" @@ -108,9 +107,8 @@ } const AXTreeID& AXTreeIDUnknown() { - static const base::NoDestructor<AXTreeID> ax_tree_id_unknown( - ax::mojom::AXTreeIDType::kUnknown); - return *ax_tree_id_unknown; + static const AXTreeID ax_tree_id_unknown(ax::mojom::AXTreeIDType::kUnknown); + return ax_tree_id_unknown; } } // namespace ui
diff --git a/ui/accessibility/ax_tree_id.h b/ui/accessibility/ax_tree_id.h index 9bd07f9..a1da6d9 100644 --- a/ui/accessibility/ax_tree_id.h +++ b/ui/accessibility/ax_tree_id.h
@@ -7,7 +7,6 @@ #include <string> -#include "base/no_destructor.h" #include "base/unguessable_token.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/accessibility/ax_base_export.h" @@ -66,7 +65,7 @@ explicit AXTreeID(const std::string& string); friend struct mojo::UnionTraits<ax::mojom::AXTreeIDDataView, ui::AXTreeID>; - friend class base::NoDestructor<AXTreeID>; + friend AX_BASE_EXPORT const AXTreeID& AXTreeIDUnknown(); friend void swap(AXTreeID& first, AXTreeID& second); ax::mojom::AXTreeIDType type_; @@ -82,7 +81,7 @@ const AXTreeID& value); // The value to use when an AXTreeID is unknown. -AX_BASE_EXPORT extern const AXTreeID& AXTreeIDUnknown(); +AX_BASE_EXPORT const AXTreeID& AXTreeIDUnknown(); } // namespace ui
diff --git a/ui/android/java/res/values/color_palette.xml b/ui/android/java/res/values/color_palette.xml index 94cdbb9..8ef7222 100644 --- a/ui/android/java/res/values/color_palette.xml +++ b/ui/android/java/res/values/color_palette.xml
@@ -7,7 +7,8 @@ <resources xmlns:tools="http://schemas.android.com/tools"> <!-- 2021 color palette --> <color name="modern_blue_100">#D3E3FD</color> - <color name="modern_blue_200">#A8C7FA</color> + <!--TODO: Replace with baseline_primary_200 --> + <color name="modern_blue_200">@color/baseline_primary_200</color> <color name="modern_blue_600">#0B57D0</color> <color name="modern_grey_100_alpha_12">#1EE3E3E3</color> <color name="modern_grey_900_alpha_12">#1E1F1F1F</color> @@ -15,6 +16,13 @@ <color name="neutral_variant_100">#E1E3E1</color> <color name="neutral_variant_400">#8E918F</color> + <color name="baseline_neutral_100">#E3E3E3</color> + <color name="baseline_neutral_variant_200">#C4C7C5</color> + <color name="baseline_primary_200">#A8C7FA</color> + <color name="baseline_primary_800">#062E6F</color> + + <color name="baseline_neutral_900_with_neutral_200_alpha_12_with_primary_200_alpha_2">#353637</color> + <!-- Modern color palette --> <color name="modern_white">@android:color/white</color> <color name="modern_blue_300">#8AB4F8</color>
diff --git a/ui/aura/window_tree_host.cc b/ui/aura/window_tree_host.cc index 28bf20d5..3ccf7461 100644 --- a/ui/aura/window_tree_host.cc +++ b/ui/aura/window_tree_host.cc
@@ -344,6 +344,31 @@ return nullptr; } +void WindowTreeHost::LockMouse(Window* window) { + Window* root_window = window->GetRootWindow(); + DCHECK(root_window); + + auto* cursor_client = client::GetCursorClient(root_window); + if (cursor_client) { + cursor_client->HideCursor(); + cursor_client->LockCursor(); + } +} + +void WindowTreeHost::UnlockMouse(Window* window) { + Window* root_window = window->GetRootWindow(); + DCHECK(root_window); + + if (window->HasCapture()) + window->ReleaseCapture(); + + auto* cursor_client = client::GetCursorClient(root_window); + if (cursor_client) { + cursor_client->UnlockCursor(); + cursor_client->ShowCursor(); + } +} + //////////////////////////////////////////////////////////////////////////////// // WindowTreeHost, protected:
diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h index 6d78efa..dbfdcb0 100644 --- a/ui/aura/window_tree_host.h +++ b/ui/aura/window_tree_host.h
@@ -253,6 +253,9 @@ virtual std::unique_ptr<ScopedEnableUnadjustedMouseEvents> RequestUnadjustedMovement(); + virtual void LockMouse(Window* window); + virtual void UnlockMouse(Window* window); + bool holding_pointer_moves() const { return holding_pointer_moves_; } protected:
diff --git a/ui/aura/window_tree_host_platform.cc b/ui/aura/window_tree_host_platform.cc index 74b8040..95ffa4fe 100644 --- a/ui/aura/window_tree_host_platform.cc +++ b/ui/aura/window_tree_host_platform.cc
@@ -203,6 +203,11 @@ NOTIMPLEMENTED(); } +void WindowTreeHostPlatform::LockMouse(Window* window) { + window->SetCapture(); + WindowTreeHost::LockMouse(window); +} + void WindowTreeHostPlatform::OnBoundsChanged(const BoundsChange& change) { // It's possible this function may be called recursively. Only notify // observers on initial entry. This way observers can safely assume that
diff --git a/ui/aura/window_tree_host_platform.h b/ui/aura/window_tree_host_platform.h index 7e436c9..2969ac7 100644 --- a/ui/aura/window_tree_host_platform.h +++ b/ui/aura/window_tree_host_platform.h
@@ -48,6 +48,7 @@ void MoveCursorToScreenLocationInPixels( const gfx::Point& location_in_pixels) override; void OnCursorVisibilityChangedNative(bool show) override; + void LockMouse(Window* window) override; ui::PlatformWindow* platform_window() { return platform_window_.get(); } const ui::PlatformWindow* platform_window() const {
diff --git a/ui/base/idle/idle_internal.cc b/ui/base/idle/idle_internal.cc index 968d800..5a730a49 100644 --- a/ui/base/idle/idle_internal.cc +++ b/ui/base/idle/idle_internal.cc
@@ -4,13 +4,11 @@ #include "ui/base/idle/idle_internal.h" -#include "base/no_destructor.h" - namespace ui { absl::optional<IdleState>& IdleStateForTesting() { - static base::NoDestructor<absl::optional<IdleState>> idle_state; - return *idle_state; + static absl::optional<IdleState> idle_state; + return idle_state; } } // namespace ui
diff --git a/ui/base/ime/chromeos/component_extension_ime_manager.cc b/ui/base/ime/chromeos/component_extension_ime_manager.cc index b2abfe2..78950bd 100644 --- a/ui/base/ime/chromeos/component_extension_ime_manager.cc +++ b/ui/base/ime/chromeos/component_extension_ime_manager.cc
@@ -9,7 +9,6 @@ #include "base/command_line.h" #include "base/strings/string_util.h" -#include "base/trace_event/trace_event.h" #include "ui/base/ime/chromeos/extension_ime_util.h" namespace chromeos { @@ -76,21 +75,11 @@ bool ComponentExtensionIMEManager::LoadComponentExtensionIME( Profile* profile, - const std::string& input_method_id, - std::set<std::string>* extension_loaded) { - TRACE_EVENT0("ime", - "ComponentExtensionIMEManager::LoadComponentExtensionIME"); + const std::string& input_method_id) { ComponentExtensionIME ime; if (FindEngineEntry(input_method_id, &ime)) { - bool will_load = extension_loaded == nullptr; - if (!will_load && - extension_loaded->find(ime.id) == extension_loaded->end()) { - extension_loaded->insert(ime.id); - will_load = true; - } - if (will_load) - delegate_->Load(profile, ime.id, ime.manifest, ime.path); - return will_load; + delegate_->Load(profile, ime.id, ime.manifest, ime.path); + return true; } return false; }
diff --git a/ui/base/ime/chromeos/component_extension_ime_manager.h b/ui/base/ime/chromeos/component_extension_ime_manager.h index 65d4164..77d646a9 100644 --- a/ui/base/ime/chromeos/component_extension_ime_manager.h +++ b/ui/base/ime/chromeos/component_extension_ime_manager.h
@@ -53,16 +53,11 @@ std::unique_ptr<ComponentExtensionIMEManagerDelegate> delegate); virtual ~ComponentExtensionIMEManager(); - // Loads the IME component extension for |input_method_id| if the extension Id - // is not in the |extension_loaded|. This function returns true once an - // corresponding IME extension will be loaded. This function is safe to call - // multiple times. Returns false if the corresponding component extension is - // already loaded or there is not any IME extension found for the - // |input_method_id|. - bool LoadComponentExtensionIME( - Profile* profile, - const std::string& input_method_id, - std::set<std::string>* extension_loaded = nullptr); + // Loads |input_method_id| component extension IME. This function returns true + // on success. This function is safe to call multiple times. Returns false if + // already corresponding component extension is loaded. + bool LoadComponentExtensionIME(Profile* profile, + const std::string& input_method_id); // Returns true if |input_method_id| is allowlisted component extension input // method.
diff --git a/ui/gfx/android/android_surface_control_compat.cc b/ui/gfx/android/android_surface_control_compat.cc index d840a04..95ec1237 100644 --- a/ui/gfx/android/android_surface_control_compat.cc +++ b/ui/gfx/android/android_surface_control_compat.cc
@@ -15,7 +15,6 @@ #include "base/hash/md5_constexpr.h" #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "base/no_destructor.h" #include "base/strings/string_number_conversions.h" #include "base/system/sys_info.h" #include "base/trace_event/trace_event.h" @@ -133,8 +132,8 @@ struct SurfaceControlMethods { public: static const SurfaceControlMethods& Get() { - static const base::NoDestructor<SurfaceControlMethods> instance; - return *instance; + static const SurfaceControlMethods instance; + return instance; } SurfaceControlMethods() {
diff --git a/ui/gfx/font_render_params_mac.cc b/ui/gfx/font_render_params_mac.cc index 071e786..03bf988c 100644 --- a/ui/gfx/font_render_params_mac.cc +++ b/ui/gfx/font_render_params_mac.cc
@@ -5,7 +5,6 @@ #include "ui/gfx/font_render_params.h" #include "base/macros.h" -#include "base/no_destructor.h" #include "base/notreached.h" namespace gfx { @@ -32,8 +31,8 @@ if (family_out) NOTIMPLEMENTED(); // TODO: Query the OS for font render settings instead of returning defaults. - static const base::NoDestructor<gfx::FontRenderParams> params(LoadDefaults()); - return *params; + static const gfx::FontRenderParams params(LoadDefaults()); + return params; } float GetFontRenderParamsDeviceScaleFactor() {
diff --git a/ui/gfx/font_render_params_skia.cc b/ui/gfx/font_render_params_skia.cc index 01c9024..7e8edf7 100644 --- a/ui/gfx/font_render_params_skia.cc +++ b/ui/gfx/font_render_params_skia.cc
@@ -5,7 +5,6 @@ #include "ui/gfx/font_render_params.h" #include "base/macros.h" -#include "base/no_destructor.h" #include "base/notreached.h" namespace gfx { @@ -40,8 +39,8 @@ if (family_out) NOTIMPLEMENTED(); // Customized font rendering settings are not supported, only defaults. - static const base::NoDestructor<gfx::FontRenderParams> params(LoadDefaults()); - return *params; + static const gfx::FontRenderParams params(LoadDefaults()); + return params; } float GetFontRenderParamsDeviceScaleFactor() {
diff --git a/ui/gfx/mojom/swap_result.mojom b/ui/gfx/mojom/swap_result.mojom index b73d4e43..f206fee 100644 --- a/ui/gfx/mojom/swap_result.mojom +++ b/ui/gfx/mojom/swap_result.mojom
@@ -12,5 +12,6 @@ enum SwapResult { ACK, FAILED, + SKIPPED, NAK_RECREATE_BUFFERS, };
diff --git a/ui/gfx/mojom/swap_result_mojom_traits.h b/ui/gfx/mojom/swap_result_mojom_traits.h index ec531dc..245a5a3 100644 --- a/ui/gfx/mojom/swap_result_mojom_traits.h +++ b/ui/gfx/mojom/swap_result_mojom_traits.h
@@ -19,6 +19,8 @@ return gfx::mojom::SwapResult::ACK; case gfx::SwapResult::SWAP_FAILED: return gfx::mojom::SwapResult::FAILED; + case gfx::SwapResult::SWAP_SKIPPED: + return gfx::mojom::SwapResult::SKIPPED; case gfx::SwapResult::SWAP_NAK_RECREATE_BUFFERS: return gfx::mojom::SwapResult::NAK_RECREATE_BUFFERS; } @@ -34,6 +36,9 @@ case gfx::mojom::SwapResult::FAILED: *out = gfx::SwapResult::SWAP_FAILED; return true; + case gfx::mojom::SwapResult::SKIPPED: + *out = gfx::SwapResult::SWAP_SKIPPED; + return true; case gfx::mojom::SwapResult::NAK_RECREATE_BUFFERS: *out = gfx::SwapResult::SWAP_NAK_RECREATE_BUFFERS; return true;
diff --git a/ui/gfx/swap_result.h b/ui/gfx/swap_result.h index 8d6bbc0a..39a62d5 100644 --- a/ui/gfx/swap_result.h +++ b/ui/gfx/swap_result.h
@@ -18,6 +18,15 @@ enum class SwapResult { SWAP_ACK, SWAP_FAILED, + // Typically, the Viz thread should decide whether to skip a swap based off + // the damage. In rare cases, however, the GPU main thread might skip the + // swap after the Viz thread requests it (e.g. the Viz thread might not know + // that the buffers are not fully initialized yet). For the purposes of + // metrics bookkeeping, we label this scenario as SWAP_SKIPPED and treat it + // much like we do a SWAP_FAILED (e.g. failed PresentationFeedback). + // TODO(https://crbug.com/1226090): Consider more explicit handling of + // SWAP_SKIPPED. + SWAP_SKIPPED, SWAP_NAK_RECREATE_BUFFERS, SWAP_RESULT_LAST = SWAP_NAK_RECREATE_BUFFERS, };
diff --git a/ui/gfx/win/rendering_window_manager.h b/ui/gfx/win/rendering_window_manager.h index 0357d9d..53b2c93 100644 --- a/ui/gfx/win/rendering_window_manager.h +++ b/ui/gfx/win/rendering_window_manager.h
@@ -9,11 +9,10 @@ #include "base/containers/flat_map.h" #include "base/memory/scoped_refptr.h" +#include "base/no_destructor.h" #include "ui/gfx/gfx_export.h" namespace base { -template <typename T> -class NoDestructor; class SingleThreadTaskRunner; }
diff --git a/ui/gl/dcomp_surface_registry.cc b/ui/gl/dcomp_surface_registry.cc index 2446013..899e47d 100644 --- a/ui/gl/dcomp_surface_registry.cc +++ b/ui/gl/dcomp_surface_registry.cc
@@ -4,8 +4,6 @@ #include "ui/gl/dcomp_surface_registry.h" -#include "base/no_destructor.h" - namespace gl { DCOMPSurfaceRegistry* DCOMPSurfaceRegistry::GetInstance() {
diff --git a/ui/gl/dcomp_surface_registry.h b/ui/gl/dcomp_surface_registry.h index 308ba05..cf77519 100644 --- a/ui/gl/dcomp_surface_registry.h +++ b/ui/gl/dcomp_surface_registry.h
@@ -6,15 +6,11 @@ #define UI_GL_DCOMP_SURFACE_REGISTRY_H_ #include "base/containers/flat_map.h" +#include "base/no_destructor.h" #include "base/unguessable_token.h" #include "base/win/scoped_handle.h" #include "ui/gl/gl_export.h" -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - namespace gl { // A registry in the GPU process for mapping an `UnguessableToken` to a
diff --git a/ui/ozone/demo/skia/skia_surfaceless_gl_renderer.cc b/ui/ozone/demo/skia/skia_surfaceless_gl_renderer.cc index 49d848c..cf684a6 100644 --- a/ui/ozone/demo/skia/skia_surfaceless_gl_renderer.cc +++ b/ui/ozone/demo/skia/skia_surfaceless_gl_renderer.cc
@@ -282,6 +282,7 @@ case gfx::SwapResult::SWAP_ACK: SkiaGlRenderer::PostRenderFrameTask(std::move(result)); break; + case gfx::SwapResult::SWAP_SKIPPED: case gfx::SwapResult::SWAP_FAILED: LOG(FATAL) << "Failed to swap buffers"; break;
diff --git a/ui/ozone/demo/surfaceless_gl_renderer.cc b/ui/ozone/demo/surfaceless_gl_renderer.cc index 94b7623..35150df8 100644 --- a/ui/ozone/demo/surfaceless_gl_renderer.cc +++ b/ui/ozone/demo/surfaceless_gl_renderer.cc
@@ -304,6 +304,7 @@ FROM_HERE, base::BindOnce(&SurfacelessGlRenderer::RenderFrame, weak_ptr_factory_.GetWeakPtr())); break; + case gfx::SwapResult::SWAP_SKIPPED: case gfx::SwapResult::SWAP_FAILED: LOG(FATAL) << "Failed to swap buffers"; break;
diff --git a/ui/ozone/platform/wayland/ozone_platform_wayland.cc b/ui/ozone/platform/wayland/ozone_platform_wayland.cc index 19c06510..7439ee7 100644 --- a/ui/ozone/platform/wayland/ozone_platform_wayland.cc +++ b/ui/ozone/platform/wayland/ozone_platform_wayland.cc
@@ -282,25 +282,23 @@ } const PlatformRuntimeProperties& GetPlatformRuntimeProperties() override { - static base::NoDestructor<OzonePlatform::PlatformRuntimeProperties> - properties; + static OzonePlatform::PlatformRuntimeProperties properties; if (connection_) { - properties->supports_server_side_window_decorations = + properties.supports_server_side_window_decorations = (connection_->xdg_decoration_manager_v1() != nullptr); } - return *properties; + return properties; } const InitializedHostProperties& GetInitializedHostProperties() override { - static base::NoDestructor<OzonePlatform::InitializedHostProperties> - properties; + static OzonePlatform::InitializedHostProperties properties; static bool initialized = false; if (!initialized) { - properties->supports_overlays = + properties.supports_overlays = ui::IsWaylandOverlayDelegationEnabled() && connection_->viewporter(); initialized = true; } - return *properties; + return properties; } void AddInterfaces(mojo::BinderMap* binders) override {
diff --git a/ui/ozone/public/ozone_platform.cc b/ui/ozone/public/ozone_platform.cc index bc110794..6a968f0 100644 --- a/ui/ozone/public/ozone_platform.cc +++ b/ui/ozone/public/ozone_platform.cc
@@ -149,9 +149,8 @@ const OzonePlatform::PlatformRuntimeProperties& OzonePlatform::GetPlatformRuntimeProperties() { - static const base::NoDestructor<OzonePlatform::PlatformRuntimeProperties> - properties; - return *properties; + static const OzonePlatform::PlatformRuntimeProperties properties; + return properties; } const OzonePlatform::InitializedHostProperties&
diff --git a/ui/views/accessibility/ax_aura_obj_cache.h b/ui/views/accessibility/ax_aura_obj_cache.h index 646c739..bff702d 100644 --- a/ui/views/accessibility/ax_aura_obj_cache.h +++ b/ui/views/accessibility/ax_aura_obj_cache.h
@@ -12,6 +12,7 @@ #include <set> #include <vector> +#include "base/no_destructor.h" #include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/accessibility/ax_node_data.h" #include "ui/aura/client/focus_change_observer.h" @@ -21,11 +22,6 @@ class Window; } // namespace aura -namespace base { -template <typename T> -class NoDestructor; -} // namespace base - namespace views { class AXAuraObjWrapper; class AXVirtualView;
diff --git a/ui/views/metadata/view_factory.h b/ui/views/metadata/view_factory.h index 16de551..9dbf329 100644 --- a/ui/views/metadata/view_factory.h +++ b/ui/views/metadata/view_factory.h
@@ -27,7 +27,8 @@ BaseViewBuilderT& operator=(BaseViewBuilderT&&) = default; ~BaseViewBuilderT() override = default; - Builder& CopyAddressTo(ViewClass_** view_address) { + template <typename View> + Builder& CopyAddressTo(View** view_address) { *view_address = view_ ? view_.get() : root_view_; return *static_cast<Builder*>(this); }
diff --git a/ui/views/metadata/view_factory_unittest.cc b/ui/views/metadata/view_factory_unittest.cc index 8d0f1d96..8432d9b 100644 --- a/ui/views/metadata/view_factory_unittest.cc +++ b/ui/views/metadata/view_factory_unittest.cc
@@ -12,6 +12,7 @@ #include "ui/views/border.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/scroll_view.h" +#include "ui/views/layout/fill_layout.h" #include "ui/views/test/widget_test.h" #include "ui/views/view.h" #include "ui/views/view_class_properties.h" @@ -24,6 +25,9 @@ views::LabelButton* button = nullptr; views::LabelButton* scroll_button = nullptr; views::ScrollView* scroll_view = nullptr; + views::View* view_with_layout_manager = nullptr; + auto layout_manager = std::make_unique<views::FillLayout>(); + auto* layout_manager_ptr = layout_manager.get(); auto view = views::Builder<views::View>() .CopyAddressTo(&parent) .SetEnabled(false) @@ -49,7 +53,10 @@ .SetContents(views::Builder<views::LabelButton>() .CopyAddressTo(&scroll_button) .SetText(u"ScrollTest")) - .SetHeader(views::Builder<views::View>().SetID(2))}) + .SetHeader(views::Builder<views::View>().SetID(2)), + views::Builder<views::LabelButton>() + .CopyAddressTo(&view_with_layout_manager) + .SetLayoutManager(std::move(layout_manager))}) .Build(); ASSERT_TRUE(view.get()); EXPECT_NE(parent, nullptr); @@ -65,6 +72,9 @@ EXPECT_NE(scroll_button, nullptr); EXPECT_EQ(scroll_button->GetText(), u"ScrollTest"); EXPECT_EQ(scroll_button, scroll_view->contents()); + EXPECT_NE(view_with_layout_manager, nullptr); + EXPECT_TRUE(views::IsViewClass<views::LabelButton>(view_with_layout_manager)); + EXPECT_EQ(view_with_layout_manager->GetLayoutManager(), layout_manager_ptr); } TEST_F(ViewFactoryTest, TestViewBuilderOwnerships) {
diff --git a/ui/views/view.h b/ui/views/view.h index df28d6bf..2c7cbb2 100644 --- a/ui/views/view.h +++ b/ui/views/view.h
@@ -2145,6 +2145,17 @@ }; BEGIN_VIEW_BUILDER(VIEWS_EXPORT, View, BaseView) +template <typename LayoutManager> +BuilderT& SetLayoutManager(std::unique_ptr<LayoutManager> layout_manager) { + auto setter = std::make_unique<::views::internal::PropertySetter< + ViewClass_, std::unique_ptr<LayoutManager>, + decltype((static_cast<LayoutManager* ( + ViewClass_::*)(std::unique_ptr<LayoutManager>)>( + &ViewClass_::SetLayoutManager))), + &ViewClass_::SetLayoutManager>>(std::move(layout_manager)); + ::views::internal::ViewBuilderCore::AddPropertySetter(std::move(setter)); + return *static_cast<BuilderT*>(this); +} VIEW_BUILDER_PROPERTY(std::unique_ptr<Background>, Background) VIEW_BUILDER_PROPERTY(std::unique_ptr<Border>, Border) VIEW_BUILDER_PROPERTY(gfx::Rect, BoundsRect)
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index 25a925b..48a3540 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -749,6 +749,16 @@ app_icon); } +const gfx::ImageSkia* DesktopNativeWidgetAura::GetWindowIcon() { + NOTIMPLEMENTED_LOG_ONCE(); + return nullptr; +} + +const gfx::ImageSkia* DesktopNativeWidgetAura::GetWindowAppIcon() { + NOTIMPLEMENTED_LOG_ONCE(); + return nullptr; +} + void DesktopNativeWidgetAura::InitModalType(ui::ModalType modal_type) { // 99% of the time, we should not be asked to create a // DesktopNativeWidgetAura that is modal. We only support window modal
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h index 4be3ddfb..9d847b51 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -138,6 +138,8 @@ bool SetWindowTitle(const std::u16string& title) override; void SetWindowIcons(const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) override; + const gfx::ImageSkia* GetWindowIcon() override; + const gfx::ImageSkia* GetWindowAppIcon() override; void InitModalType(ui::ModalType modal_type) override; gfx::Rect GetWindowBoundsInScreen() const override; gfx::Rect GetClientAreaBoundsInScreen() const override;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc index f6c41d83..4d986b92 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -66,6 +66,14 @@ namespace { +// While the mouse is locked we want the invisible mouse to stay within the +// confines of the screen so we keep it in a capture region the size of the +// screen. However, on windows when the mouse hits the edge of the screen some +// events trigger and cause strange issues to occur. To stop those events from +// occurring we add a small border around the edge of the capture region. +// This constant controls how many pixels wide that border is. +const int kMouseCaptureRegionBorder = 5; + gfx::Size GetExpandedWindowSize(bool is_translucent, gfx::Size size) { if (!is_translucent || !ui::win::IsAeroGlassEnabled()) return size; @@ -80,6 +88,24 @@ rect->Inset(0, 0, vector.x(), vector.y()); } +// Updates the cursor clip region. Used for mouse locking. +void UpdateMouseLockRegion(aura::Window* window, bool locked) { + if (!locked) { + ::ClipCursor(nullptr); + return; + } + + RECT window_rect = + display::Screen::GetScreen() + ->DIPToScreenRectInWindow(window, window->GetBoundsInScreen()) + .ToRECT(); + window_rect.left += kMouseCaptureRegionBorder; + window_rect.right -= kMouseCaptureRegionBorder; + window_rect.top += kMouseCaptureRegionBorder; + window_rect.bottom -= kMouseCaptureRegionBorder; + ::ClipCursor(&window_rect); +} + } // namespace DEFINE_UI_CLASS_PROPERTY_KEY(aura::Window*, kContentWindowForRootWindow, NULL) @@ -663,6 +689,16 @@ return message_handler_->RegisterUnadjustedMouseEvent(); } +void DesktopWindowTreeHostWin::LockMouse(aura::Window* window) { + UpdateMouseLockRegion(window, true /*locked*/); + WindowTreeHost::LockMouse(window); +} + +void DesktopWindowTreeHostWin::UnlockMouse(aura::Window* window) { + UpdateMouseLockRegion(window, false /*locked*/); + WindowTreeHost::UnlockMouse(window); +} + //////////////////////////////////////////////////////////////////////////////// // DesktopWindowTreeHostWin, wm::AnimationHost implementation:
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h index 07078cb..20bcac8 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -152,6 +152,8 @@ const gfx::Point& location_in_pixels) override; std::unique_ptr<aura::ScopedEnableUnadjustedMouseEvents> RequestUnadjustedMovement() override; + void LockMouse(aura::Window* window) override; + void UnlockMouse(aura::Window* window) override; // Overridden from aura::client::AnimationHost void SetHostTransitionOffsets(
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc index c5fb6a6..a8b4b0f 100644 --- a/ui/views/widget/native_widget_aura.cc +++ b/ui/views/widget/native_widget_aura.cc
@@ -456,6 +456,14 @@ AssignIconToAuraWindow(window_, window_icon, app_icon); } +const gfx::ImageSkia* NativeWidgetAura::GetWindowIcon() { + return window_->GetProperty(aura::client::kWindowIconKey); +} + +const gfx::ImageSkia* NativeWidgetAura::GetWindowAppIcon() { + return window_->GetProperty(aura::client::kAppIconKey); +} + void NativeWidgetAura::InitModalType(ui::ModalType modal_type) { if (modal_type != ui::MODAL_TYPE_NONE) window_->SetProperty(aura::client::kModalKey, modal_type);
diff --git a/ui/views/widget/native_widget_aura.h b/ui/views/widget/native_widget_aura.h index 7779011..648b11d 100644 --- a/ui/views/widget/native_widget_aura.h +++ b/ui/views/widget/native_widget_aura.h
@@ -97,6 +97,8 @@ bool SetWindowTitle(const std::u16string& title) override; void SetWindowIcons(const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) override; + const gfx::ImageSkia* GetWindowIcon() override; + const gfx::ImageSkia* GetWindowAppIcon() override; void InitModalType(ui::ModalType modal_type) override; gfx::Rect GetWindowBoundsInScreen() const override; gfx::Rect GetClientAreaBoundsInScreen() const override;
diff --git a/ui/views/widget/native_widget_mac.h b/ui/views/widget/native_widget_mac.h index b43425e..0b9c37a 100644 --- a/ui/views/widget/native_widget_mac.h +++ b/ui/views/widget/native_widget_mac.h
@@ -130,6 +130,8 @@ bool SetWindowTitle(const std::u16string& title) override; void SetWindowIcons(const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) override; + const gfx::ImageSkia* GetWindowIcon() override; + const gfx::ImageSkia* GetWindowAppIcon() override; void InitModalType(ui::ModalType modal_type) override; gfx::Rect GetWindowBoundsInScreen() const override; gfx::Rect GetClientAreaBoundsInScreen() const override;
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm index 668a7705..9451441 100644 --- a/ui/views/widget/native_widget_mac.mm +++ b/ui/views/widget/native_widget_mac.mm
@@ -413,6 +413,15 @@ // Everything happens upon show. } +const gfx::ImageSkia* NativeWidgetMac::GetWindowIcon() { + NOTIMPLEMENTED_LOG_ONCE(); + return nullptr; +} +const gfx::ImageSkia* NativeWidgetMac::GetWindowAppIcon() { + NOTIMPLEMENTED_LOG_ONCE(); + return nullptr; +} + gfx::Rect NativeWidgetMac::GetWindowBoundsInScreen() const { return ns_window_host_ ? ns_window_host_->GetWindowBoundsInScreen() : gfx::Rect();
diff --git a/ui/views/widget/native_widget_private.h b/ui/views/widget/native_widget_private.h index 8897a13..bb8c522 100644 --- a/ui/views/widget/native_widget_private.h +++ b/ui/views/widget/native_widget_private.h
@@ -160,6 +160,8 @@ // app switching UI. virtual void SetWindowIcons(const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) = 0; + virtual const gfx::ImageSkia* GetWindowIcon() = 0; + virtual const gfx::ImageSkia* GetWindowAppIcon() = 0; // Initializes the modal type of the window to |modal_type|. Called from // NativeWidgetDelegate::OnNativeWidgetCreated() before the widget is
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc index fc606d7..a742d7d 100644 --- a/ui/views/widget/widget.cc +++ b/ui/views/widget/widget.cc
@@ -956,11 +956,32 @@ void Widget::UpdateWindowIcon() { if (non_client_view_) non_client_view_->UpdateWindowIcon(); - native_widget_->SetWindowIcons( - GetImageSkiaFromImageModel(widget_delegate_->GetWindowIcon(), - GetNativeTheme()), - GetImageSkiaFromImageModel(widget_delegate_->GetWindowAppIcon(), - GetNativeTheme())); + + gfx::ImageSkia window_icon = GetImageSkiaFromImageModel( + widget_delegate_->GetWindowIcon(), GetNativeTheme()); + + // In general, icon information is read from a |widget_delegate_| and then + // passed to |native_widget_|. On ChromeOS, for lacros-chrome to support the + // initial window state as minimized state, a valid icon is added to + // |native_widget_| earlier stage of widget initialization. See + // https://crbug.com/1189981. As only lacros-chrome on ChromeOS supports this + // behavior other overrides of |native_widget_| will always have no icon + // information. This is also true for |app_icon| referred below. + if (window_icon.isNull()) { + const gfx::ImageSkia* icon = native_widget_->GetWindowIcon(); + if (icon && !icon->isNull()) + window_icon = *icon; + } + + gfx::ImageSkia app_icon = GetImageSkiaFromImageModel( + widget_delegate_->GetWindowAppIcon(), GetNativeTheme()); + if (app_icon.isNull()) { + const gfx::ImageSkia* icon = native_widget_->GetWindowAppIcon(); + if (icon && !icon->isNull()) + app_icon = *icon; + } + + native_widget_->SetWindowIcons(window_icon, app_icon); } FocusTraversable* Widget::GetFocusTraversable() {
diff --git a/url/url_idna_icu.cc b/url/url_idna_icu.cc index 48e53a9..c5fcc6f 100644 --- a/url/url_idna_icu.cc +++ b/url/url_idna_icu.cc
@@ -11,7 +11,6 @@ #include <ostream> #include "base/check_op.h" -#include "base/no_destructor.h" #include "third_party/icu/source/common/unicode/uidna.h" #include "third_party/icu/source/common/unicode/utypes.h" #include "url/url_canon_icu.h" @@ -19,10 +18,8 @@ namespace url { -namespace { - -// A wrapper to use base::NoDestructor with ICU's UIDNA, a C pointer to -// a UTS46/IDNA 2008 handling object opened with uidna_openUTS46(). +// Use UIDNA, a C pointer to a UTS46/IDNA 2008 handling object opened with +// uidna_openUTS46(). // // We use UTS46 with BiDiCheck to migrate from IDNA 2003 (with unassigned // code points allowed) to IDNA 2008 with @@ -42,12 +39,12 @@ // http://goo.gl/3XBhqw ). // See http://http://unicode.org/reports/tr46/ and references therein // for more details. -struct UIDNAWrapper { - UIDNAWrapper() { +UIDNA* GetUIDNA() { + static UIDNA* uidna = [] { UErrorCode err = U_ZERO_ERROR; // TODO(jungshik): Change options as different parties (browsers, // registrars, search engines) converge toward a consensus. - value = uidna_openUTS46(UIDNA_CHECK_BIDI, &err); + UIDNA* value = uidna_openUTS46(UIDNA_CHECK_BIDI, &err); if (U_FAILURE(err)) { CHECK(false) << "failed to open UTS46 data with error: " << u_errorName(err) @@ -56,16 +53,9 @@ << "tables for libicu. See https://crbug.com/778929."; value = nullptr; } - } - - UIDNA* value; -}; - -} // namespace - -UIDNA* GetUIDNA() { - static base::NoDestructor<UIDNAWrapper> uidna_wrapper; - return uidna_wrapper->value; + return value; + }(); + return uidna; } // Converts the Unicode input representing a hostname to ASCII using IDN rules.
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestServiceTest.java b/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestServiceTest.java index 1697d55..4d700aa 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestServiceTest.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestServiceTest.java
@@ -80,6 +80,10 @@ ShadowPaymentFeatureList.setFeatureEnabled( PaymentFeatureList.WEB_PAYMENTS_SINGLE_APP_UI_SKIP, true); + ShadowPaymentFeatureList.setFeatureEnabled( + PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION, true); + ShadowPaymentFeatureList.setFeatureEnabled( + PaymentFeatureList.WEB_PAYMENTS_EXPERIMENTAL_FEATURES, true); PaymentRequestService.resetShowingPaymentRequestForTest(); PaymentAppService.getInstance().resetForTest();
diff --git a/weblayer/browser/media/local_presentation_manager_factory.h b/weblayer/browser/media/local_presentation_manager_factory.h index 6002bb3..a426f44 100644 --- a/weblayer/browser/media/local_presentation_manager_factory.h +++ b/weblayer/browser/media/local_presentation_manager_factory.h
@@ -5,13 +5,9 @@ #ifndef WEBLAYER_BROWSER_MEDIA_LOCAL_PRESENTATION_MANAGER_FACTORY_H_ #define WEBLAYER_BROWSER_MEDIA_LOCAL_PRESENTATION_MANAGER_FACTORY_H_ +#include "base/no_destructor.h" #include "components/media_router/browser/presentation/local_presentation_manager_factory.h" -namespace base { -template <typename T> -class NoDestructor; -} - namespace content { class BrowserContext; }
diff --git a/weblayer/browser/media/media_router_factory.h b/weblayer/browser/media/media_router_factory.h index f66bd5d..030a29f 100644 --- a/weblayer/browser/media/media_router_factory.h +++ b/weblayer/browser/media/media_router_factory.h
@@ -5,13 +5,9 @@ #ifndef WEBLAYER_BROWSER_MEDIA_MEDIA_ROUTER_FACTORY_H_ #define WEBLAYER_BROWSER_MEDIA_MEDIA_ROUTER_FACTORY_H_ +#include "base/no_destructor.h" #include "components/media_router/browser/media_router_factory.h" -namespace base { -template <typename T> -class NoDestructor; -} - namespace content { class BrowserContext; }
diff --git a/weblayer/shell/app/shell_main_params.cc b/weblayer/shell/app/shell_main_params.cc index db4805e..0d6de8d 100644 --- a/weblayer/shell/app/shell_main_params.cc +++ b/weblayer/shell/app/shell_main_params.cc
@@ -99,9 +99,9 @@ } // namespace MainParams CreateMainParams() { - static const base::NoDestructor<MainDelegateImpl> weblayer_delegate; + static MainDelegateImpl weblayer_delegate; MainParams params; - params.delegate = const_cast<MainDelegateImpl*>(&(*weblayer_delegate)); + params.delegate = &weblayer_delegate; base::PathService::Get(base::DIR_EXE, ¶ms.log_filename); params.log_filename = params.log_filename.AppendASCII("weblayer_shell.log");