diff --git a/DEPS b/DEPS index 5a23107..bd8f3d5 100644 --- a/DEPS +++ b/DEPS
@@ -280,7 +280,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': 'f4087cb7c415e0fa8e1c27f6092d8e7ce335d711', + 'skia_revision': '23564bd50042bacd4d22c8ffcee0fd2fb9eaf877', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -288,7 +288,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '5a3e1dba8e6079f2c95493b52ad06c390ba6fe4a', + 'angle_revision': '1adf46a60a77be9f7fa940a98ad06cbe151b94c9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -307,7 +307,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Fuchsia sdk # and whatever else without interference from each other. - 'fuchsia_version': 'version:8.20220614.1.1', + 'fuchsia_version': 'version:8.20220614.2.1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling google-toolbox-for-mac # and whatever else without interference from each other. @@ -351,7 +351,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'd854027b5cff510baf7a712c900474d01b1c0701', + 'catapult_revision': '351bad3feafe6d2ff11b5a3ddc740e38e79f95b4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -846,7 +846,7 @@ 'packages': [ { 'package': 'chromium/rts/model/linux-amd64', - 'version': '2lgLyfFFn1giCzbCBxUtuCWlH8zMQfL7oPoda_slQ7gC', + 'version': 'fEF-m7iiUlPEMg0VIo-RTRPif-lBGJ0VTUzM_be56K8C', }, ], 'dep_type': 'cipd', @@ -1708,7 +1708,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '65ea407597c7781c92a87b6d7fac827ba2c5a478', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'bed8507b95710818e1a4642a269c59a1a5ea07de', + Var('webrtc_git') + '/src.git' + '@' + 'ea5a944921af4e1c31aa1e5f4ef28e4a8e942452', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1811,7 +1811,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': '2ofSj7tchb3b7Jor8ZSdo9gC44SSDFvWoIFO24DmY_0C', + 'version': 'J98AlfpF1UP6dn-WUiCIyYmt4jPVhKO20Ezm7AEeURQC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index b479043..8fa1491 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -801,7 +801,6 @@ "//components/network_session_configurator/android:network_session_configurator_java", "//components/variations:variations_java", "//components/viz:viz_java", - "//components/webrtc:components_webrtc_java", "//content/public/android:content_java", "//content/public/common:common_java", "//gpu/config:config_java",
diff --git a/android_webview/browser/gfx/output_surface_provider_webview.cc b/android_webview/browser/gfx/output_surface_provider_webview.cc index 12555ab..4e2c33f 100644 --- a/android_webview/browser/gfx/output_surface_provider_webview.cc +++ b/android_webview/browser/gfx/output_surface_provider_webview.cc
@@ -25,6 +25,7 @@ #include "gpu/ipc/single_task_sequence.h" #include "ui/base/ui_base_switches.h" #include "ui/gfx/geometry/size.h" +#include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_share_group.h" #include "ui/gl/gl_surface_egl.h" @@ -112,7 +113,7 @@ // If EGL supports EGL_ANGLE_external_context_and_surface, then we will create // an ANGLE context for the current native GL context. const bool is_angle = - !enable_vulkan_ && display->IsANGLEExternalContextAndSurfaceSupported(); + !enable_vulkan_ && display->ext->b_EGL_ANGLE_external_context_and_surface; GLSurfaceContextPair real_context; if (enable_vulkan_) {
diff --git a/android_webview/browser/gfx/scoped_app_gl_state_restore.cc b/android_webview/browser/gfx/scoped_app_gl_state_restore.cc index 1289f30..35305c1 100644 --- a/android_webview/browser/gfx/scoped_app_gl_state_restore.cc +++ b/android_webview/browser/gfx/scoped_app_gl_state_restore.cc
@@ -32,7 +32,7 @@ TRACE_EVENT0("android_webview", "AppGLStateSave"); if (gl::GLSurfaceEGL::GetGLDisplayEGL() - ->IsANGLEExternalContextAndSurfaceSupported()) { + ->ext->b_EGL_ANGLE_external_context_and_surface) { impl_ = std::make_unique<internal::ScopedAppGLStateRestoreImplAngle>( mode, save_restore); } else {
diff --git a/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc b/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc index 8490ffed..7c368a5 100644 --- a/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc +++ b/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc
@@ -95,9 +95,9 @@ // There is no way to access the gpu thread here, so leave it no-op for now. } -void SkiaOutputSurfaceDependencyWebView::PostTaskToClientThread( - base::OnceClosure closure) { - task_queue_->ScheduleClientTask(std::move(closure)); +scoped_refptr<base::TaskRunner> +SkiaOutputSurfaceDependencyWebView::GetClientTaskRunner() { + return task_queue_->GetClientTaskRunner(); } gpu::ImageFactory* SkiaOutputSurfaceDependencyWebView::GetGpuImageFactory() {
diff --git a/android_webview/browser/gfx/skia_output_surface_dependency_webview.h b/android_webview/browser/gfx/skia_output_surface_dependency_webview.h index 987cdf8..73dcc21 100644 --- a/android_webview/browser/gfx/skia_output_surface_dependency_webview.h +++ b/android_webview/browser/gfx/skia_output_surface_dependency_webview.h
@@ -49,7 +49,7 @@ gpu::ImageFactory* GetGpuImageFactory() override; void ScheduleGrContextCleanup() override; void ScheduleDelayedGPUTaskFromGPUThread(base::OnceClosure task) override; - void PostTaskToClientThread(base::OnceClosure closure) override; + scoped_refptr<base::TaskRunner> GetClientTaskRunner() override; bool IsOffscreen() override; gpu::SurfaceHandle GetSurfaceHandle() override; scoped_refptr<gl::GLSurface> CreateGLSurface(
diff --git a/android_webview/browser/gfx/task_queue_webview.cc b/android_webview/browser/gfx/task_queue_webview.cc index 424cd9e..06cfece 100644 --- a/android_webview/browser/gfx/task_queue_webview.cc +++ b/android_webview/browser/gfx/task_queue_webview.cc
@@ -42,7 +42,7 @@ void ScheduleTask(base::OnceClosure task, bool out_of_order) override; void ScheduleOrRetainTask(base::OnceClosure task) override; void ScheduleIdleTask(base::OnceClosure task) override; - void ScheduleClientTask(base::OnceClosure task) override; + scoped_refptr<base::TaskRunner> GetClientTaskRunner() override; void InitializeVizThread(const scoped_refptr<base::SingleThreadTaskRunner>& viz_task_runner) override; void ScheduleOnVizAndBlock(VizTask viz_task) override; @@ -111,9 +111,9 @@ EmplaceTask(std::move(task)); } -void TaskQueueViz::ScheduleClientTask(base::OnceClosure task) { +scoped_refptr<base::TaskRunner> TaskQueueViz::GetClientTaskRunner() { DCHECK(viz_task_runner_); - viz_task_runner_->PostTask(FROM_HERE, std::move(task)); + return viz_task_runner_; } void TaskQueueViz::InitializeVizThread(
diff --git a/android_webview/browser/gfx/task_queue_webview.h b/android_webview/browser/gfx/task_queue_webview.h index 85bb73f..9ceeb24e 100644 --- a/android_webview/browser/gfx/task_queue_webview.h +++ b/android_webview/browser/gfx/task_queue_webview.h
@@ -41,7 +41,10 @@ // Called by both DeferredGpuCommandService and // SkiaOutputSurfaceDisplayContext to post task to client thread. - virtual void ScheduleClientTask(base::OnceClosure task) = 0; + void ScheduleClientTask(base::OnceClosure task) { + GetClientTaskRunner()->PostTask(FROM_HERE, std::move(task)); + } + virtual scoped_refptr<base::TaskRunner> GetClientTaskRunner() = 0; protected: virtual ~TaskQueueWebView() = default;
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java index 0a3a5be3..9fe24a0 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java +++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -14,7 +14,6 @@ import org.chromium.components.network_session_configurator.NetworkSessionSwitches; import org.chromium.components.variations.VariationsSwitches; import org.chromium.components.viz.common.VizFeatures; -import org.chromium.components.webrtc.ComponentsWebRtcFeatures; import org.chromium.content_public.common.ContentFeatures; import org.chromium.content_public.common.ContentSwitches; import org.chromium.gpu.config.GpuFeatures; @@ -298,8 +297,6 @@ AwFeatures.WEBVIEW_SYNTHESIZE_PAGE_LOAD_ONLY_ON_INITIAL_MAIN_DOCUMENT_ACCESS, "Only synthesize page load for URL spoof prevention at most once," + " on initial main document access."), - Flag.baseFeature(ComponentsWebRtcFeatures.THREAD_WRAPPER_USES_METRONOME, - "Makes ThreadWrapper coalesce delayed tasks on metronome ticks."), Flag.baseFeature(WebRtcOverridesFeatures.WEB_RTC_TIMER_USES_METRONOME, "Makes WebRtcTimer coalesce delayed tasks on metronome ticks."), Flag.baseFeature(BlinkFeatures.VIEWPORT_HEIGHT_CLIENT_HINT_HEADER,
diff --git a/android_webview/javatests/PRESUBMIT.py b/android_webview/javatests/PRESUBMIT.py index 551251a..47b3dec 100644 --- a/android_webview/javatests/PRESUBMIT.py +++ b/android_webview/javatests/PRESUBMIT.py
@@ -14,6 +14,7 @@ results.extend(_CheckAwJUnitTestRunner(input_api, output_api)) results.extend(_CheckNoSkipCommandLineAnnotation(input_api, output_api)) results.extend(_CheckNoSandboxedRendererSwitch(input_api, output_api)) + results.extend(_CheckNoDomUtils(input_api, output_api)) return results @@ -123,3 +124,36 @@ """, errors)) return results + + +def _CheckNoDomUtils(input_api, output_api): + """Checks that tests prefer JSUtils.clickNodeWithUserGesture() over + DOMUtils.clickNode(). + """ + + dom_utils_pattern = input_api.re.compile(r'DOMUtils\.clickNode\(') + errors = [] + def _FilterFile(affected_file): + return input_api.FilterSourceFile( + affected_file, + files_to_skip=input_api.DEFAULT_FILES_TO_SKIP, + files_to_check=[r'.*\.java$']) + + for f in input_api.AffectedSourceFiles(_FilterFile): + for line_num, line in f.ChangedContents(): + m = dom_utils_pattern.search(line) + if m: + errors.append("%s:%d" % (f.LocalPath(), line_num)) + + results = [] + if errors: + results.append(output_api.PresubmitPromptWarning(""" +DOMUtils.clickNode() has been observed to cause flakiness in WebView tests. +Prefer using JSUtils.clickNodeWithUserGesture() as a more reliable replacement +where possible. This is a "soft" warning, so you can bypass this if +DOMUtils.clickNode() is the only way. +""", errors)) + + return results + +
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java index cd5ce83b..d9abf4f 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java
@@ -40,7 +40,6 @@ import org.chromium.components.policy.test.PolicyData; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationHistory; -import org.chromium.content_public.browser.test.util.DOMUtils; import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper; import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer.OnPageStartedHelper; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -713,7 +712,7 @@ Assert.assertEquals(indirectLoadCallCount, mShouldOverrideUrlLoadingHelper.getCallCount()); // Simulate touch, hasUserGesture must be true only on the first call. - DOMUtils.clickNode(mAwContents.getWebContents(), "link"); + JSUtils.clickNodeWithUserGesture(mAwContents.getWebContents(), "link"); mShouldOverrideUrlLoadingHelper.waitForCallback(indirectLoadCallCount, 1); Assert.assertEquals(
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java index 51bc664..4d0b52c 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
@@ -50,7 +50,6 @@ import org.chromium.components.embedder_support.util.WebResourceResponseInfo; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsObserver; -import org.chromium.content_public.browser.test.util.DOMUtils; import org.chromium.content_public.browser.test.util.HistoryUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.common.ContentSwitches; @@ -2595,7 +2594,7 @@ int count = callback.getCallCount(); mActivityTestRule.loadDataSync(awContents, contentClient.getOnPageFinishedHelper(), pageHtml, "text/html", false); - DOMUtils.clickNode(testContainer.getWebContents(), "play"); + JSUtils.clickNodeWithUserGesture(testContainer.getWebContents(), "play"); callback.waitForCallback(count, 1); Assert.assertEquals(0, webServer.getRequestCount(httpPath));
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java index 3f2f69c2..6ca3180e 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java
@@ -25,6 +25,7 @@ import org.chromium.android_webview.AwContentsClient; import org.chromium.android_webview.test.util.CommonResources; import org.chromium.android_webview.test.util.GraphicsTestUtils; +import org.chromium.android_webview.test.util.JSUtils; import org.chromium.android_webview.test.util.JavascriptEventObserver; import org.chromium.base.task.PostTask; import org.chromium.base.test.util.CallbackHelper; @@ -34,7 +35,6 @@ import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; -import org.chromium.content_public.browser.test.util.DOMUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import java.io.ByteArrayInputStream; @@ -314,7 +314,7 @@ Assert.assertTrue(readyToUpdateColor.await( AwActivityTestRule.SCALED_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); - DOMUtils.clickNode(webContents, UPDATE_COLOR_CONTROL_ID); + JSUtils.clickNodeWithUserGesture(webContents, UPDATE_COLOR_CONTROL_ID); Assert.assertTrue(jsObserver.waitForEvent(WAIT_TIMEOUT_MS)); InstrumentationRegistry.getInstrumentation().runOnMainSync( @@ -381,7 +381,7 @@ Assert.assertTrue(readyToEnterFullscreenSignal.await( AwActivityTestRule.SCALED_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); - DOMUtils.clickNode(webContents, ENTER_FULLSCREEN_CONTROL_ID); + JSUtils.clickNodeWithUserGesture(webContents, ENTER_FULLSCREEN_CONTROL_ID); Assert.assertTrue(jsObserver.waitForEvent(WAIT_TIMEOUT_MS)); InstrumentationRegistry.getInstrumentation().runOnMainSync(
diff --git a/ash/app_list/app_list_metrics.h b/ash/app_list/app_list_metrics.h index 058b5cd..368edd8 100644 --- a/ash/app_list/app_list_metrics.h +++ b/ash/app_list/app_list_metrics.h
@@ -223,6 +223,19 @@ kMaxValue = kOpenSuggestionChip, }; +// Whether and how user-entered search box text matches up with the first search +// result. These values are persisted to logs. Entries should not be renumbered +// and numeric values should never be reused. +enum class SearchBoxTextMatch { + // The user entered query is not a substring of the first search result. + kNoMatch = 0, + // The user entered query matches the prefix of the first search result. + kPrefixMatch = 1, + // The user entered query is a substring of the first search result. + kSubstringMatch = 2, + kMaxValue = kSubstringMatch, +}; + // Parameters to call RecordAppListAppLaunched. Passed to code that does not // directly have access to them, such ash AppListMenuModelAdapter. struct AppLaunchedMetricParams {
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index 6ce7ab60..cc8a64e 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -6,9 +6,11 @@ #include <algorithm> #include <memory> +#include <string> #include <utility> #include <vector> +#include "ash/app_list/app_list_metrics.h" #include "ash/app_list/app_list_util.h" #include "ash/app_list/app_list_view_delegate.h" #include "ash/app_list/model/search/search_box_model.h" @@ -30,6 +32,7 @@ #include "ash/search_box/search_box_view_delegate.h" #include "ash/strings/grit/ash_strings.h" #include "ash/style/ash_color_provider.h" +#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/notreached.h" @@ -112,6 +115,22 @@ return kDefaultPlaceholders[rand() % std::size(kDefaultPlaceholders)]; } +bool IsSubstringCaseInsensitive(std::u16string haystack_expr, + std::u16string needle_expr) { + // Convert complete given String to lower case + std::transform(haystack_expr.begin(), haystack_expr.end(), + haystack_expr.begin(), ::tolower); + // Convert complete given Sub String to lower case + std::transform(needle_expr.begin(), needle_expr.end(), needle_expr.begin(), + ::tolower); + // Find sub string in given string + return haystack_expr.find(needle_expr) != std::string::npos; +} + +void RecordAutocompleteMatchMetric(SearchBoxTextMatch match_type) { + base::UmaHistogramEnumeration("Apps.AppListSearchAutocomplete", match_type); +} + } // namespace class SearchBoxView::FocusRingLayer : public ui::Layer, ui::LayerDelegate { @@ -466,13 +485,14 @@ return; } - UMA_HISTOGRAM_ENUMERATION("Apps.AppListSearchBoxActivated", activation_type); + base::UmaHistogramEnumeration("Apps.AppListSearchBoxActivated", + activation_type); if (is_tablet_mode_) { - UMA_HISTOGRAM_ENUMERATION("Apps.AppListSearchBoxActivated.TabletMode", - activation_type); + base::UmaHistogramEnumeration("Apps.AppListSearchBoxActivated.TabletMode", + activation_type); } else { - UMA_HISTOGRAM_ENUMERATION("Apps.AppListSearchBoxActivated.ClamshellMode", - activation_type); + base::UmaHistogramEnumeration( + "Apps.AppListSearchBoxActivated.ClamshellMode", activation_type); } } @@ -669,21 +689,60 @@ const std::u16string& details = first_visible_result->details(); const std::u16string& search_text = first_visible_result->title(); + + // Don't set autocomplete text if it's the same as user typed text. + if (user_typed_text == details || user_typed_text == search_text) + return; + + auto is_valid_autocomplete_text = + [this](const std::u16string& autocomplete_text) { + // Don't set autocomplete text if it's the same as current search box + // text. + if (autocomplete_text == search_box()->GetText()) + return false; + // Don't set autocomplete text if the highlighted text is the same as + // before. + if (autocomplete_text.substr(highlight_range_.start()) == + search_box()->GetSelectedText()) { + return false; + } + return true; + }; + if (base::StartsWith(details, user_typed_text, - base::CompareCase::INSENSITIVE_ASCII)) { + base::CompareCase::INSENSITIVE_ASCII) && + is_valid_autocomplete_text(details)) { // Current text in the search_box matches the first result's url. SetAutocompleteText(details); + RecordAutocompleteMatchMetric(SearchBoxTextMatch::kPrefixMatch); return; } + if (base::StartsWith(search_text, user_typed_text, - base::CompareCase::INSENSITIVE_ASCII)) { + base::CompareCase::INSENSITIVE_ASCII) && + is_valid_autocomplete_text(search_text)) { // Current text in the search_box matches the first result's search result // text. SetAutocompleteText(search_text); + RecordAutocompleteMatchMetric(SearchBoxTextMatch::kPrefixMatch); return; } - // Current text in the search_box does not match the first result's url or - // search result text. + + // Record whether the user's query is a substring of the search result. Used + // to determine whether we should add substring matching to CrOS search + // autocomplete. + if (IsSubstringCaseInsensitive(details, user_typed_text) && + is_valid_autocomplete_text(details)) { + RecordAutocompleteMatchMetric(SearchBoxTextMatch::kSubstringMatch); + // TODO(crbug.com/1334821): Maybe enable substring match autocomplete. + } else if (IsSubstringCaseInsensitive(search_text, user_typed_text) && + is_valid_autocomplete_text(search_text)) { + RecordAutocompleteMatchMetric(SearchBoxTextMatch::kSubstringMatch); + // TODO(crbug.com/1334821): Maybe enable substring match autocomplete. + } else { + RecordAutocompleteMatchMetric(SearchBoxTextMatch::kNoMatch); + } + ClearAutocompleteText(); } @@ -863,16 +922,12 @@ // Currrent text is a prefix of autocomplete text. DCHECK(base::StartsWith(autocomplete_text, current_text, base::CompareCase::INSENSITIVE_ASCII)); - // Don't set autocomplete text if it's the same as current search box text. - if (autocomplete_text == current_text) - return; - + // Autocomplete text should not be the same as current search box text. + DCHECK(autocomplete_text != current_text); + // Autocomplete text should not be the same as highlighted text. const std::u16string& highlighted_text = autocomplete_text.substr(highlight_range_.start()); - - // Don't set autocomplete text if the highlighted text is the same as before. - if (highlighted_text == search_box()->GetSelectedText()) - return; + DCHECK(highlighted_text != current_text); highlight_range_.set_end(autocomplete_text.length()); ui::CompositionText composition_text;
diff --git a/ash/components/phonehub/phone_hub_metrics_recorder.cc b/ash/components/phonehub/phone_hub_metrics_recorder.cc index 80df3fbf..d9cd81d 100644 --- a/ash/components/phonehub/phone_hub_metrics_recorder.cc +++ b/ash/components/phonehub/phone_hub_metrics_recorder.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "ash/components/phonehub/phone_hub_metrics_recorder.h" +#include "ash/services/secure_channel/public/mojom/secure_channel.mojom.h" #include "base/metrics/histogram_functions.h" namespace ash::phonehub { @@ -14,13 +15,19 @@ base::UmaHistogramBoolean("PhoneHub.Connection.Result", success); } +void PhoneHubMetricsRecorder::RecordConnectionFailureReason( + secure_channel::mojom::ConnectionAttemptFailureReason reason) { + base::UmaHistogramEnumeration("PhoneHub.Connection.Result.FailureReason", + reason); +} + void PhoneHubMetricsRecorder::RecordConnectionLatency( - const base::TimeDelta& latency) { + const base::TimeDelta latency) { base::UmaHistogramTimes("PhoneHub.Connectivity.Latency", latency); } void PhoneHubMetricsRecorder::RecordConnectionDuration( - const base::TimeDelta& duration) { + const base::TimeDelta duration) { base::UmaHistogramLongTimes100("PhoneHub.Connection.Duration", duration); }
diff --git a/ash/components/phonehub/phone_hub_metrics_recorder.h b/ash/components/phonehub/phone_hub_metrics_recorder.h index f7849db..8e30a212 100644 --- a/ash/components/phonehub/phone_hub_metrics_recorder.h +++ b/ash/components/phonehub/phone_hub_metrics_recorder.h
@@ -20,8 +20,10 @@ // secure_channel::NearbyMetricsRecorder: void RecordConnectionResult(bool success) override; - void RecordConnectionLatency(const base::TimeDelta& latency) override; - void RecordConnectionDuration(const base::TimeDelta& duration) override; + void RecordConnectionFailureReason( + secure_channel::mojom::ConnectionAttemptFailureReason reason) override; + void RecordConnectionLatency(const base::TimeDelta latency) override; + void RecordConnectionDuration(const base::TimeDelta duration) override; }; } // namespace ash::phonehub
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 1fab77c..ec1a2e0 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -1298,6 +1298,10 @@ const base::Feature kScalableStatusArea{"ScalableStatusArea", base::FEATURE_ENABLED_BY_DEFAULT}; +// Enables the rounded corners for the internal display. +const base::Feature kRoundedDisplay{"RoundedDisplay", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Controls whether to enable kSecondaryGoogleAccountUsage policy. const base::Feature kSecondaryGoogleAccountUsage{ "SecondaryGoogleAccountUsage", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -2238,6 +2242,10 @@ return base::FeatureList::IsEnabled(kScalableStatusArea); } +bool IsRoundedDisplayEnabled() { + return base::FeatureList::IsEnabled(kRoundedDisplay); +} + bool IsSeparateNetworkIconsEnabled() { return base::FeatureList::IsEnabled(kSeparateNetworkIcons); }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 53b1f1f..568b28b 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -517,6 +517,8 @@ extern const base::Feature kReverseScrollGestures; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kScalableStatusArea; COMPONENT_EXPORT(ASH_CONSTANTS) +extern const base::Feature kRoundedDisplay; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kSecondaryGoogleAccountUsage; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kSemanticColorsDebugOverride; @@ -796,6 +798,8 @@ bool IsSamlReauthenticationOnLockscreenEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSavedDesksEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsScalableStatusAreaEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) +bool IsRoundedDisplayEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSeparateNetworkIconsEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSettingsAppNotificationSettingsEnabled();
diff --git a/ash/services/secure_channel/public/cpp/client/BUILD.gn b/ash/services/secure_channel/public/cpp/client/BUILD.gn index 5baab3b..77421935 100644 --- a/ash/services/secure_channel/public/cpp/client/BUILD.gn +++ b/ash/services/secure_channel/public/cpp/client/BUILD.gn
@@ -22,6 +22,7 @@ "connection_manager_impl.h", "nearby_connector.cc", "nearby_connector.h", + "nearby_metrics_recorder.cc", "nearby_metrics_recorder.h", "presence_monitor_client.h", "presence_monitor_client_impl.cc",
diff --git a/ash/services/secure_channel/public/cpp/client/connection_manager_impl.cc b/ash/services/secure_channel/public/cpp/client/connection_manager_impl.cc index f1d88fb5..f4fe288 100644 --- a/ash/services/secure_channel/public/cpp/client/connection_manager_impl.cc +++ b/ash/services/secure_channel/public/cpp/client/connection_manager_impl.cc
@@ -8,6 +8,7 @@ #include "ash/services/device_sync/public/cpp/device_sync_client.h" #include "ash/services/multidevice_setup/public/cpp/multidevice_setup_client.h" #include "ash/services/secure_channel/public/cpp/client/secure_channel_client.h" +#include "ash/services/secure_channel/public/mojom/secure_channel.mojom-shared.h" #include "ash/services/secure_channel/public/mojom/secure_channel.mojom.h" #include "ash/services/secure_channel/public/mojom/secure_channel_types.mojom.h" #include "base/callback.h" @@ -119,6 +120,10 @@ void ConnectionManagerImpl::Disconnect() { PA_LOG(INFO) << "ConnectionManager disconnecting connection."; + if (last_status_ == Status::kConnecting) { + metrics_recorder_->RecordConnectionFailure( + mojom::ConnectionAttemptFailureReason::CONNECTION_CANCELLED); + } TearDownConnection(); } @@ -167,6 +172,7 @@ << "error: " << reason << "."; timer_->Stop(); connection_attempt_.reset(); + metrics_recorder_->RecordConnectionFailure(reason); OnStatusChanged(); } @@ -177,6 +183,11 @@ timer_->Stop(); channel_ = std::move(channel); channel_->AddObserver(this); + if (last_status_ == Status::kConnecting) { + metrics_recorder_->RecordConnectionSuccess(clock_->Now() - + status_change_timestamp_); + } + OnStatusChanged(); } @@ -192,8 +203,8 @@ PA_LOG(WARNING) << "AttemptConnection() has timed out. Closing connection " << "attempt."; - connection_attempt_.reset(); - OnStatusChanged(); + OnConnectionAttemptFailure( + mojom::ConnectionAttemptFailureReason::TIMEOUT_FINDING_DEVICE); } void ConnectionManagerImpl::TearDownConnection() { @@ -203,39 +214,21 @@ if (channel_) channel_->RemoveObserver(this); channel_.reset(); + if (last_status_ == Status::kConnected) { + metrics_recorder_->RecordConnectionDuration(clock_->Now() - + status_change_timestamp_); + } OnStatusChanged(); } void ConnectionManagerImpl::OnStatusChanged() { NotifyStatusChanged(); - RecordMetrics(); -} -void ConnectionManagerImpl::RecordMetrics() { - const base::TimeDelta delta = clock_->Now() - status_change_timestamp_; - status_change_timestamp_ = clock_->Now(); - - const Status status = GetStatus(); - switch (status) { - case Status::kConnecting: - break; - - case ConnectionManager::Status::kDisconnected: - if (last_status_ == Status::kConnected) { - metrics_recorder_->RecordConnectionDuration(delta); - } else if (last_status_ == ConnectionManager::Status::kConnecting) { - metrics_recorder_->RecordConnectionResult(false); - } - break; - - case ConnectionManager::Status::kConnected: - if (last_status_ == Status::kConnecting) { - metrics_recorder_->RecordConnectionLatency(delta); - metrics_recorder_->RecordConnectionResult(true); - } - break; + Status status = GetStatus(); + if (last_status_ != status) { + status_change_timestamp_ = clock_->Now(); + last_status_ = status; } - last_status_ = status; } } // namespace ash::secure_channel
diff --git a/ash/services/secure_channel/public/cpp/client/connection_manager_impl_unittest.cc b/ash/services/secure_channel/public/cpp/client/connection_manager_impl_unittest.cc index 230e57e..6284455 100644 --- a/ash/services/secure_channel/public/cpp/client/connection_manager_impl_unittest.cc +++ b/ash/services/secure_channel/public/cpp/client/connection_manager_impl_unittest.cc
@@ -33,6 +33,8 @@ const char kSecureChannelFeatureName[] = "phone_hub"; const char kConnectionResultMetricName[] = "PhoneHub.Connection.Result"; +const char kConnectionFailureReasonMetricName[] = + "PhoneHub.Connection.Result.FailureReason"; const char kConnectionDurationMetricName[] = "PhoneHub.Connection.Duration"; const char kConnectionLatencyMetricName[] = "PhoneHub.Connectivity.Latency"; @@ -72,10 +74,14 @@ void RecordConnectionResult(bool success) override { base::UmaHistogramBoolean(kConnectionResultMetricName, success); } - void RecordConnectionLatency(const base::TimeDelta& latency) override { + void RecordConnectionFailureReason( + secure_channel::mojom::ConnectionAttemptFailureReason reason) override { + base::UmaHistogramEnumeration(kConnectionFailureReasonMetricName, reason); + } + void RecordConnectionLatency(const base::TimeDelta latency) override { base::UmaHistogramTimes(kConnectionLatencyMetricName, latency); } - void RecordConnectionDuration(const base::TimeDelta& duration) override { + void RecordConnectionDuration(const base::TimeDelta duration) override { base::UmaHistogramLongTimes100(kConnectionDurationMetricName, duration); } }; @@ -158,6 +164,13 @@ expected_count); } + void VerifyConnectionFailureReasonHistogram( + secure_channel::mojom::ConnectionAttemptFailureReason sample, + base::HistogramBase::Count expected_count) { + histogram_tester_.ExpectBucketCount(kConnectionResultMetricName, sample, + expected_count); + } + base::MockOneShotTimer* mock_timer_; multidevice::RemoteDeviceRef test_remote_device_; multidevice::RemoteDeviceRef test_local_device_; @@ -213,6 +226,8 @@ EXPECT_EQ(ConnectionManager::Status::kDisconnected, GetStatus()); VerifyConnectionResultHistogram(false, 1); + VerifyConnectionFailureReasonHistogram( + mojom::ConnectionAttemptFailureReason::AUTHENTICATION_ERROR, 1); } TEST_F(ConnectionManagerImplTest, SuccessfulAttemptConnectionButDisconnected) {
diff --git a/ash/services/secure_channel/public/cpp/client/nearby_metrics_recorder.cc b/ash/services/secure_channel/public/cpp/client/nearby_metrics_recorder.cc new file mode 100644 index 0000000..38bb4069 --- /dev/null +++ b/ash/services/secure_channel/public/cpp/client/nearby_metrics_recorder.cc
@@ -0,0 +1,25 @@ +// 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 "ash/services/secure_channel/public/cpp/client/nearby_metrics_recorder.h" + +namespace ash::secure_channel { + +NearbyMetricsRecorder::NearbyMetricsRecorder() = default; + +NearbyMetricsRecorder::~NearbyMetricsRecorder() = default; + +void NearbyMetricsRecorder::RecordConnectionSuccess( + const base::TimeDelta latency) { + RecordConnectionResult(true); + RecordConnectionLatency(latency); +} + +void NearbyMetricsRecorder::RecordConnectionFailure( + mojom::ConnectionAttemptFailureReason reason) { + RecordConnectionResult(false); + RecordConnectionFailureReason(reason); +} + +} // namespace ash::secure_channel
diff --git a/ash/services/secure_channel/public/cpp/client/nearby_metrics_recorder.h b/ash/services/secure_channel/public/cpp/client/nearby_metrics_recorder.h index c41d5c66..88628f6 100644 --- a/ash/services/secure_channel/public/cpp/client/nearby_metrics_recorder.h +++ b/ash/services/secure_channel/public/cpp/client/nearby_metrics_recorder.h
@@ -9,15 +9,31 @@ namespace ash::secure_channel { +namespace mojom { +enum class ConnectionAttemptFailureReason; +} + // Interface for recording connection metrics. class NearbyMetricsRecorder { public: - NearbyMetricsRecorder() = default; - virtual ~NearbyMetricsRecorder() = default; + NearbyMetricsRecorder(); + virtual ~NearbyMetricsRecorder(); + // Records connection success and the latency from the start of the + // connection attempt. + void RecordConnectionSuccess(const base::TimeDelta latency); + + // Records connection failure and the specific reason. + void RecordConnectionFailure(mojom::ConnectionAttemptFailureReason reason); + + // Records the length of time that we stayed connected. + virtual void RecordConnectionDuration(const base::TimeDelta duration) = 0; + + protected: + virtual void RecordConnectionLatency(const base::TimeDelta latency) = 0; virtual void RecordConnectionResult(bool success) = 0; - virtual void RecordConnectionLatency(const base::TimeDelta& latency) = 0; - virtual void RecordConnectionDuration(const base::TimeDelta& duration) = 0; + virtual void RecordConnectionFailureReason( + mojom::ConnectionAttemptFailureReason reason) = 0; }; } // namespace ash::secure_channel
diff --git a/ash/services/secure_channel/public/mojom/secure_channel.mojom b/ash/services/secure_channel/public/mojom/secure_channel.mojom index 45bcc10..37eb6223 100644 --- a/ash/services/secure_channel/public/mojom/secure_channel.mojom +++ b/ash/services/secure_channel/public/mojom/secure_channel.mojom
@@ -9,60 +9,65 @@ import "ash/services/secure_channel/public/mojom/secure_channel_types.mojom"; import "mojo/public/mojom/base/time.mojom"; +// Keep in sync with SecureChannelConnectionAttemptFailureReason in +// tools/metrics/histograms/enums.xml enum ConnectionAttemptFailureReason { // The local device could not authenticate with the remote device. This likely // means that one (or both) devices have not synced their keys recently. - AUTHENTICATION_ERROR, + AUTHENTICATION_ERROR = 0, // An advertisement could not be generated for this connection. This likely // means that one (or both) devices have not synced their BeaconSeeds // recently. - COULD_NOT_GENERATE_ADVERTISEMENT, + COULD_NOT_GENERATE_ADVERTISEMENT = 1, // GATT connections were attempted, but they failed. This could be caused by // errors creating GATT connections, dropped GATT connections, or an issue // relating to GATT services being unavailable. - GATT_CONNECTION_ERROR, + GATT_CONNECTION_ERROR = 2, // A Nearby Connection was attempted, but it failed. Potential causes include // internal API errors and flaky Bluetooth/WebRTC connections. - NEARBY_CONNECTION_ERROR, + NEARBY_CONNECTION_ERROR = 3, // The provided local device does not have a public key set. - LOCAL_DEVICE_INVALID_PUBLIC_KEY, + LOCAL_DEVICE_INVALID_PUBLIC_KEY = 4, // The provided local device does not have a persistent symmetric key set. - LOCAL_DEVICE_INVALID_PSK, + LOCAL_DEVICE_INVALID_PSK = 5, // The provided local device does not have a valid Bluetooth address. - LOCAL_DEVICE_INVALID_BLUETOOTH_ADDRESS, + LOCAL_DEVICE_INVALID_BLUETOOTH_ADDRESS = 6, // The provided remote device does not have a public key set. - REMOTE_DEVICE_INVALID_PUBLIC_KEY, + REMOTE_DEVICE_INVALID_PUBLIC_KEY = 7, // The provided remote device does not have a persistent symmetric key set. - REMOTE_DEVICE_INVALID_PSK, + REMOTE_DEVICE_INVALID_PSK = 8, // The provided remote device does not have a valid Bluetooth address. - REMOTE_DEVICE_INVALID_BLUETOOTH_ADDRESS, + REMOTE_DEVICE_INVALID_BLUETOOTH_ADDRESS = 9, // Timeouts occurred trying to contact the remote device. - TIMEOUT_FINDING_DEVICE, + TIMEOUT_FINDING_DEVICE = 10, // The local Bluetooth adapter is disabled (turned off). - ADAPTER_DISABLED, + ADAPTER_DISABLED = 11, // The local Bluetooth adapter is not present. - ADAPTER_NOT_PRESENT, + ADAPTER_NOT_PRESENT = 12, // Tried to connect using a role which is unsupported for the connection // medium (e.g., Nearby Connections only supports the listener role, not the // initiator role). - UNSUPPORTED_ROLE_FOR_MEDIUM, + UNSUPPORTED_ROLE_FOR_MEDIUM = 13, // Tried requesting a connection via Nearby Connections, but no // NearbyConnector was provided. - MISSING_NEARBY_CONNECTOR + MISSING_NEARBY_CONNECTOR = 14, + + // The attempt was intentionally interrupted. + CONNECTION_CANCELLED = 15, }; enum ConnectionCreationDetail {
diff --git a/ash/system/network/network_detailed_view_controller.cc b/ash/system/network/network_detailed_view_controller.cc index 0f92f76..4d1590c 100644 --- a/ash/system/network/network_detailed_view_controller.cc +++ b/ash/system/network/network_detailed_view_controller.cc
@@ -5,15 +5,108 @@ #include "ash/system/network/network_detailed_view_controller.h" #include "ash/constants/ash_features.h" +#include "ash/public/cpp/system_tray_client.h" +#include "ash/session/session_controller_impl.h" +#include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" +#include "ash/system/machine_learning/user_settings_event_logger.h" +#include "ash/system/model/system_tray_model.h" #include "ash/system/network/network_detailed_network_view.h" #include "ash/system/network/network_list_view_controller.h" +#include "ash/system/network/tray_network_state_model.h" #include "ash/system/tray/detailed_view_delegate.h" +#include "base/metrics/user_metrics.h" +#include "chromeos/network/network_connect.h" +#include "chromeos/services/network_config/public/cpp/cros_network_config_util.h" #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "ui/views/view.h" namespace ash { +namespace { + +using base::UserMetricsAction; + +using chromeos::network_config::NetworkTypeMatchesType; + +using chromeos::network_config::mojom::ActivationStateType; +using chromeos::network_config::mojom::CellularStateProperties; +using chromeos::network_config::mojom::ConnectionStateType; +using chromeos::network_config::mojom::NetworkStateProperties; +using chromeos::network_config::mojom::NetworkStatePropertiesPtr; +using chromeos::network_config::mojom::NetworkType; + +void LogUserNetworkEvent(const NetworkStateProperties& network) { + auto* const logger = ml::UserSettingsEventLogger::Get(); + if (logger) { + logger->LogNetworkUkmEvent(network); + } +} + +bool IsSecondaryUser() { + SessionControllerImpl* session_controller = + Shell::Get()->session_controller(); + return session_controller->IsActiveUserSessionStarted() && + !session_controller->IsUserPrimary(); +} + +bool NetworkTypeIsConfigurable(NetworkType type) { + switch (type) { + case NetworkType::kVPN: + case NetworkType::kWiFi: + return true; + case NetworkType::kAll: + case NetworkType::kCellular: + case NetworkType::kEthernet: + case NetworkType::kMobile: + case NetworkType::kTether: + case NetworkType::kWireless: + return false; + } + NOTREACHED(); + return false; +} + +bool IsNetworkConnectable(const NetworkStatePropertiesPtr& network_properties) { + // The network must not already be connected to be able to be connected to. + if (network_properties->connection_state != + ConnectionStateType::kNotConnected) { + return false; + } + + if (NetworkTypeMatchesType(network_properties->type, + NetworkType::kCellular)) { + // Cellular networks must be activated, uninhibited, and have an unlocked + // SIM to be able to be connected to. + const CellularStateProperties* cellular = + network_properties->type_state->get_cellular().get(); + + if (cellular->activation_state == ActivationStateType::kNotActivated && + !cellular->eid.empty()) { + return false; + } + + if (cellular->activation_state == ActivationStateType::kActivated) { + return true; + } + } + + // The network can be connected to if the network is connectable. + if (network_properties->connectable) { + return true; + } + + // Network can be connected to if the active user is the primary user and the + // network is configurable. + if (!IsSecondaryUser() && + NetworkTypeIsConfigurable(network_properties->type)) { + return true; + } + + return false; +} + +} // namespace NetworkDetailedViewController::NetworkDetailedViewController( UnifiedSystemTrayController* tray_controller) @@ -44,7 +137,36 @@ } void NetworkDetailedViewController::OnNetworkListItemSelected( - const chromeos::network_config::mojom::NetworkStatePropertiesPtr& network) { + const NetworkStatePropertiesPtr& network) { + if (Shell::Get()->session_controller()->login_status() == LoginStatus::LOCKED) + return; + + if (network) { + // If the network is locked and is cellular show SIM unlock dialog in OS + // Settings. + if (network->type == NetworkType::kCellular && + network->type_state->get_cellular()->sim_locked) { + if (!Shell::Get()->session_controller()->ShouldEnableSettings()) { + return; + } + Shell::Get()->system_tray_model()->client()->ShowSettingsSimUnlock(); + return; + } + + if (IsNetworkConnectable(network)) { + base::RecordAction( + UserMetricsAction("StatusArea_Network_ConnectConfigured")); + LogUserNetworkEvent(*network.get()); + chromeos::NetworkConnect::Get()->ConnectToNetworkId(network->guid); + return; + } + } + + // If the network is no longer available or not connectable or configurable, + // show the Settings UI. + base::RecordAction(UserMetricsAction("StatusArea_Network_ConnectionDetails")); + Shell::Get()->system_tray_model()->client()->ShowNetworkSettings( + network ? network->guid : std::string()); } void NetworkDetailedViewController::OnMobileToggleClicked(bool new_state) {}
diff --git a/ash/system/network/network_detailed_view_controller_unittest.cc b/ash/system/network/network_detailed_view_controller_unittest.cc index dab81ef..ff67cce 100644 --- a/ash/system/network/network_detailed_view_controller_unittest.cc +++ b/ash/system/network/network_detailed_view_controller_unittest.cc
@@ -7,14 +7,79 @@ #include <memory> #include "ash/constants/ash_features.h" +#include "ash/public/cpp/test/test_system_tray_client.h" +#include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "base/test/metrics/user_action_tester.h" #include "base/test/scoped_feature_list.h" +#include "chromeos/network/network_connect.h" +#include "chromeos/network/network_handler.h" +#include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h" +#include "third_party/cros_system_api/dbus/shill/dbus-constants.h" namespace ash { +using chromeos::network_config::mojom::ActivationStateType; +using chromeos::network_config::mojom::ConnectionStateType; +using chromeos::network_config::mojom::NetworkStatePropertiesPtr; +using chromeos::network_config::mojom::NetworkType; + +const std::string kCellular = "cellular"; +constexpr char kWifi[] = "WifiGuid"; + +const int kSignalStrength = 50; +constexpr char kUser1Email[] = "user1@quicksettings.com"; + +const char kNetworkConnectConfigured[] = "StatusArea_Network_ConnectConfigured"; +const char kNetworkConnectionDetails[] = "StatusArea_Network_ConnectionDetails"; + +class NetworkConnectTestDelegate : public chromeos::NetworkConnect::Delegate { + public: + NetworkConnectTestDelegate() {} + + NetworkConnectTestDelegate(const NetworkConnectTestDelegate&) = delete; + NetworkConnectTestDelegate& operator=(const NetworkConnectTestDelegate&) = + delete; + + ~NetworkConnectTestDelegate() override {} + + void ShowNetworkConfigure(const std::string& network_id) override {} + void ShowNetworkSettings(const std::string& network_id) override {} + bool ShowEnrollNetwork(const std::string& network_id) override { + return false; + } + void ShowMobileSetupDialog(const std::string& network_id) override {} + void ShowCarrierAccountDetail(const std::string& network_id) override {} + void ShowNetworkConnectError(const std::string& error_name, + const std::string& network_id) override {} + void ShowMobileActivationError(const std::string& network_id) override {} +}; + class NetworkDetailedViewControllerTest : public AshTestBase { public: void SetUp() override { + // Initialize CrosNetworkConfigTestHelper here, so we can initialize + // a unique network handler and also use NetworkConnectTestDelegate to + // initialize NetworkConnect. + network_config_helper_ = std::make_unique< + chromeos::network_config::CrosNetworkConfigTestHelper>(); + + chromeos::NetworkHandler::Initialize(); + base::RunLoop().RunUntilIdle(); + + // Creating a service here, since we would be testing that wifi, + // networks which can be connected to are actually connected to. This + // checks that chromeos::NetworkConnect eventually connects us to the + // network. + wifi_service_path_ = + network_state_helper()->ConfigureService(base::StringPrintf( + R"({"GUID": "%s", "Type": "wifi", + "State": "idle", "Strength": 100, + "Connectable": true})", + kWifi)); + + network_connect_delegate_ = std::make_unique<NetworkConnectTestDelegate>(); + chromeos::NetworkConnect::Initialize(network_connect_delegate_.get()); AshTestBase::SetUp(); feature_list_.InitAndEnableFeature(features::kQuickSettingsNetworkRevamp); @@ -26,18 +91,201 @@ void TearDown() override { network_detailed_view_controller_.reset(); - AshTestBase::TearDown(); + chromeos::NetworkConnect::Shutdown(); + chromeos::NetworkHandler::Shutdown(); + network_connect_delegate_.reset(); + } + + void SelectNetworkListItem(const NetworkStatePropertiesPtr& network) { + (static_cast<NetworkDetailedView::Delegate*>( + network_detailed_view_controller_.get())) + ->OnNetworkListItemSelected(mojo::Clone(network)); + } + + NetworkStatePropertiesPtr CreateStandaloneNetworkProperties( + const std::string& id, + NetworkType type, + ConnectionStateType connection_state) { + return network_config_helper_->CreateStandaloneNetworkProperties( + id, type, connection_state, kSignalStrength); + } + + std::string GetWifiNetworkState() { + return network_state_helper()->GetServiceStringProperty( + wifi_service_path_, shill::kStateProperty); + } + + void DisconnectWifiNetwork() { + network_state_helper()->SetServiceProperty( + wifi_service_path_, std::string(shill::kStateProperty), + base::Value(shill::kStateIdle)); + base::RunLoop().RunUntilIdle(); } private: + chromeos::NetworkStateTestHelper* network_state_helper() { + return &network_config_helper_->network_state_helper(); + } + base::test::ScopedFeatureList feature_list_; + std::unique_ptr<chromeos::network_config::CrosNetworkConfigTestHelper> + network_config_helper_; + std::unique_ptr<NetworkConnectTestDelegate> network_connect_delegate_; std::unique_ptr<NetworkDetailedViewController> network_detailed_view_controller_; + std::string wifi_service_path_; }; -TEST_F(NetworkDetailedViewControllerTest, CanConstruct) { - EXPECT_TRUE(true); +TEST_F(NetworkDetailedViewControllerTest, + NetworkListItemSelectedWithLockedScreen) { + base::UserActionTester user_action_tester; + + EXPECT_EQ(0, user_action_tester.GetActionCount(kNetworkConnectionDetails)); + EXPECT_EQ(0, user_action_tester.GetActionCount(kNetworkConnectConfigured)); + + NetworkStatePropertiesPtr cellular_network = + CreateStandaloneNetworkProperties(kCellular, NetworkType::kCellular, + ConnectionStateType::kConnected); + + EXPECT_EQ(0, GetSystemTrayClient()->show_network_settings_count()); + + // Set login status to locked. + GetSessionControllerClient()->SetSessionState( + session_manager::SessionState::LOCKED); + SelectNetworkListItem(cellular_network); + EXPECT_EQ(0, GetSystemTrayClient()->show_network_settings_count()); + EXPECT_EQ(0, GetSystemTrayClient()->show_sim_unlock_settings_count()); + + // Show network details page for a connected cellular network. + GetSessionControllerClient()->SetSessionState( + session_manager::SessionState::ACTIVE); + SelectNetworkListItem(cellular_network); + EXPECT_EQ(1, GetSystemTrayClient()->show_network_settings_count()); + EXPECT_EQ(0, GetSystemTrayClient()->show_sim_unlock_settings_count()); + EXPECT_EQ(1, user_action_tester.GetActionCount(kNetworkConnectionDetails)); + EXPECT_EQ(0, user_action_tester.GetActionCount(kNetworkConnectConfigured)); +} + +TEST_F(NetworkDetailedViewControllerTest, EmptyNetworkListItemSelected) { + base::UserActionTester user_action_tester; + + EXPECT_EQ(0, user_action_tester.GetActionCount(kNetworkConnectionDetails)); + EXPECT_EQ(0, user_action_tester.GetActionCount(kNetworkConnectConfigured)); + EXPECT_EQ(0, GetSystemTrayClient()->show_network_settings_count()); + EXPECT_EQ(0, GetSystemTrayClient()->show_sim_unlock_settings_count()); + + SelectNetworkListItem(/*network=*/nullptr); + EXPECT_EQ(1, GetSystemTrayClient()->show_network_settings_count()); + EXPECT_EQ(0, GetSystemTrayClient()->show_sim_unlock_settings_count()); + EXPECT_EQ(1, user_action_tester.GetActionCount(kNetworkConnectionDetails)); + EXPECT_EQ(0, user_action_tester.GetActionCount(kNetworkConnectConfigured)); +} + +TEST_F(NetworkDetailedViewControllerTest, CellularNetworkListItemSelected) { + base::UserActionTester user_action_tester; + + EXPECT_EQ(0, user_action_tester.GetActionCount(kNetworkConnectionDetails)); + EXPECT_EQ(0, user_action_tester.GetActionCount(kNetworkConnectConfigured)); + EXPECT_EQ(0, GetSystemTrayClient()->show_network_settings_count()); + EXPECT_EQ(0, GetSystemTrayClient()->show_sim_unlock_settings_count()); + + NetworkStatePropertiesPtr cellular_network = + CreateStandaloneNetworkProperties(kCellular, NetworkType::kCellular, + ConnectionStateType::kConnected); + + // When cellular eSIM network is not activated open network details page. + cellular_network->connection_state = ConnectionStateType::kNotConnected; + cellular_network->type_state->get_cellular()->activation_state = + ActivationStateType::kNotActivated; + cellular_network->type_state->get_cellular()->eid = "eid"; + SelectNetworkListItem(cellular_network); + EXPECT_EQ(1, GetSystemTrayClient()->show_network_settings_count()); + EXPECT_EQ(0, GetSystemTrayClient()->show_sim_unlock_settings_count()); + EXPECT_EQ(1, user_action_tester.GetActionCount(kNetworkConnectionDetails)); + EXPECT_EQ(0, user_action_tester.GetActionCount(kNetworkConnectConfigured)); + + // When cellular network is SIM locked, we show the SIM unlock settings page. + cellular_network->type_state->get_cellular()->sim_locked = true; + SelectNetworkListItem(cellular_network); + EXPECT_EQ(1, GetSystemTrayClient()->show_network_settings_count()); + EXPECT_EQ(1, GetSystemTrayClient()->show_sim_unlock_settings_count()); + EXPECT_EQ(1, user_action_tester.GetActionCount(kNetworkConnectionDetails)); + EXPECT_EQ(0, user_action_tester.GetActionCount(kNetworkConnectConfigured)); +} + +TEST_F(NetworkDetailedViewControllerTest, WifiNetworkListItemSelected) { + base::UserActionTester user_action_tester; + + EXPECT_EQ(0, user_action_tester.GetActionCount(kNetworkConnectionDetails)); + EXPECT_EQ(0, user_action_tester.GetActionCount(kNetworkConnectConfigured)); + EXPECT_EQ(0, GetSystemTrayClient()->show_network_settings_count()); + EXPECT_EQ(0, GetSystemTrayClient()->show_sim_unlock_settings_count()); + + // Clicking on an already connected network opens settings page. + // Since this network is already connected, selecting this network + // in network list vew should result in no change in NetworkState of + // the network service. + NetworkStatePropertiesPtr wifi_network = CreateStandaloneNetworkProperties( + kWifi, NetworkType::kWiFi, ConnectionStateType::kOnline); + + SelectNetworkListItem(wifi_network); + EXPECT_EQ(1, GetSystemTrayClient()->show_network_settings_count()); + EXPECT_EQ(0, GetSystemTrayClient()->show_sim_unlock_settings_count()); + EXPECT_EQ(1, user_action_tester.GetActionCount(kNetworkConnectionDetails)); + EXPECT_EQ(0, user_action_tester.GetActionCount(kNetworkConnectConfigured)); + EXPECT_EQ(shill::kStateIdle, GetWifiNetworkState()); + + // Set to be connectable and make sure network is connected to. + wifi_network->connection_state = ConnectionStateType::kNotConnected; + wifi_network->connectable = true; + SelectNetworkListItem(wifi_network); + + // Wait for Network to be connected to. + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, GetSystemTrayClient()->show_network_settings_count()); + EXPECT_EQ(0, GetSystemTrayClient()->show_sim_unlock_settings_count()); + EXPECT_EQ(1, user_action_tester.GetActionCount(kNetworkConnectionDetails)); + EXPECT_EQ(1, user_action_tester.GetActionCount(kNetworkConnectConfigured)); + EXPECT_EQ(shill::kStateOnline, GetWifiNetworkState()); + + // Reset network state to idle. + DisconnectWifiNetwork(); + EXPECT_EQ(shill::kStateIdle, GetWifiNetworkState()); + + /// Network can be connected to since active user is primary and the + // network is configurable. + wifi_network->connection_state = ConnectionStateType::kNotConnected; + wifi_network->connectable = false; + + SelectNetworkListItem(wifi_network); + + // Wait for network to be connected to. + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, GetSystemTrayClient()->show_network_settings_count()); + EXPECT_EQ(0, GetSystemTrayClient()->show_sim_unlock_settings_count()); + EXPECT_EQ(1, user_action_tester.GetActionCount(kNetworkConnectionDetails)); + EXPECT_EQ(2, user_action_tester.GetActionCount(kNetworkConnectConfigured)); + EXPECT_EQ(shill::kStateOnline, GetWifiNetworkState()); + + // Reset network to idle. + DisconnectWifiNetwork(); + EXPECT_EQ(shill::kStateIdle, GetWifiNetworkState()); + + // Login as secondary user, and make sure network is not connected to, + // but settings page is opened. + GetSessionControllerClient()->AddUserSession(kUser1Email); + SimulateUserLogin(kUser1Email); + GetSessionControllerClient()->SetSessionState( + session_manager::SessionState::LOGIN_SECONDARY); + base::RunLoop().RunUntilIdle(); + + SelectNetworkListItem(wifi_network); + EXPECT_EQ(2, GetSystemTrayClient()->show_network_settings_count()); + EXPECT_EQ(0, GetSystemTrayClient()->show_sim_unlock_settings_count()); + EXPECT_EQ(2, user_action_tester.GetActionCount(kNetworkConnectionDetails)); + EXPECT_EQ(2, user_action_tester.GetActionCount(kNetworkConnectConfigured)); + EXPECT_EQ(shill::kStateIdle, GetWifiNetworkState()); } } // namespace ash
diff --git a/ash/system/network/network_list_mobile_header_view_impl.cc b/ash/system/network/network_list_mobile_header_view_impl.cc index 685e727..8d53909e 100644 --- a/ash/system/network/network_list_mobile_header_view_impl.cc +++ b/ash/system/network/network_list_mobile_header_view_impl.cc
@@ -36,8 +36,8 @@ const DeviceStateProperties* cellular_device = Shell::Get()->system_tray_model()->network_state_model()->GetDevice( NetworkType::kCellular); - if (!cellular_device) - return 0; + + DCHECK(cellular_device); switch (cellular_device->inhibit_reason) { case chromeos::network_config::mojom::InhibitReason::kInstallingProfile:
diff --git a/ash/system/network/network_section_header_view.cc b/ash/system/network/network_section_header_view.cc index 5e5f060..2f8a2ad 100644 --- a/ash/system/network/network_section_header_view.cc +++ b/ash/system/network/network_section_header_view.cc
@@ -110,9 +110,8 @@ const DeviceStateProperties* cellular_device = Shell::Get()->system_tray_model()->network_state_model()->GetDevice( NetworkType::kCellular); - if (!cellular_device) { - return 0; - } + + DCHECK(cellular_device); switch (cellular_device->inhibit_reason) { case chromeos::network_config::mojom::InhibitReason::kInstallingProfile: @@ -370,6 +369,12 @@ void MobileSectionHeaderView::DeviceStateListChanged() { if (!add_esim_button_) return; + + if (!IsESimSupported()) { + add_esim_button_->SetVisible(/*visible=*/false); + return; + } + add_esim_button_->SetEnabled(can_add_esim_button_be_enabled_ && !IsCellularDeviceInhibited()); add_esim_button_->SetTooltipText(
diff --git a/ash/system/palette/tools/metalayer_mode.cc b/ash/system/palette/tools/metalayer_mode.cc index 62fd0821..73a1936 100644 --- a/ash/system/palette/tools/metalayer_mode.cc +++ b/ash/system/palette/tools/metalayer_mode.cc
@@ -19,6 +19,7 @@ #include "ash/system/tray/tray_constants.h" #include "ash/system/tray/tray_popup_utils.h" #include "base/bind.h" +#include "base/metrics/histogram_functions.h" #include "chromeos/services/assistant/public/cpp/assistant_prefs.h" #include "ui/base/l10n/l10n_util.h" #include "ui/events/event.h" @@ -38,6 +39,10 @@ // mode is deprecated. const char kDeprecateAssistantStylusToastId[] = "deprecate_assistant_stylus"; +// Histogram for Assistant stylus features deprecation toast events. +const char kDeprecateStylusFeaturesToastEvent[] = + "Ash.Shelf.Palette.Assistant.DeprecateStylusFeaturesToastEvent"; + // If the last stroke happened within this amount of time, // assume writing/sketching usage. const int kMaxStrokeGapWhenWritingMs = 1000; @@ -148,12 +153,15 @@ if (palette_utils::PaletteContainsPointInScreen(event->root_location())) return; + DeprecateStylusFeaturesToastEvent toast_event = kNotDeprecatedToastNotShown; + // Assistant stylus features are in the process of being deprecated. // After deprecation, which is currently gated by a feature flag, long // press stylus events will not trigger the metalayer mode. if (ash::features::IsDeprecateAssistantStylusFeaturesEnabled()) { // Only show the toast once when the metalayer is triggered for the first // time. + toast_event = kDeprecatedToastNotShown; if (!GetPrefs()->GetBoolean( chromeos::assistant::prefs::kAssistantDeprecateStylusToast)) { // Set the deprecate stylus toast assistant pref so that the toast doesn't @@ -168,10 +176,18 @@ ToastData::kDefaultToastDuration, /*visible_on_lock_screen=*/false, /*has_dismiss_button=*/true)); + toast_event = kDeprecatedToastShown; } + // Record toast event (feature is deprecated). + base::UmaHistogramEnumeration(kDeprecateStylusFeaturesToastEvent, + toast_event); return; } + // Record toast event (feature is not deprecated). + base::UmaHistogramEnumeration(kDeprecateStylusFeaturesToastEvent, + toast_event); + if (loading()) { // Repetitive presses will create toasts with the same id which will be // ignored.
diff --git a/ash/system/palette/tools/metalayer_mode.h b/ash/system/palette/tools/metalayer_mode.h index 3e0e3b0..ae01a04 100644 --- a/ash/system/palette/tools/metalayer_mode.h +++ b/ash/system/palette/tools/metalayer_mode.h
@@ -15,6 +15,24 @@ namespace ash { +// This will be used for the UMA stats to note deprecation toast events +// for Assistant stylus features. + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. Also remember to update the +// DeprecateStylusFeaturesToastEvent enum listing in +// tools/metrics/histograms/enums.xml. +enum DeprecateStylusFeaturesToastEvent { + // Features not deprecated, toast not shown. + kNotDeprecatedToastNotShown = 0, + // Features deprecated, toast shown (first time). + kDeprecatedToastShown = 1, + // Features deprecated, toast not shown (already shown). + kDeprecatedToastNotShown = 2, + + kMaxValue = kDeprecatedToastNotShown +}; + // A palette tool that lets the user select a screen region to be passed // to the Assistant framework. //
diff --git a/ash/webui/eche_app_ui/BUILD.gn b/ash/webui/eche_app_ui/BUILD.gn index f71a772..36e3237 100644 --- a/ash/webui/eche_app_ui/BUILD.gn +++ b/ash/webui/eche_app_ui/BUILD.gn
@@ -93,6 +93,7 @@ "//ash/services/multidevice_setup/public/cpp:prefs", "//ash/services/secure_channel/public/cpp/client", "//ash/services/secure_channel/public/cpp/shared", + "//ash/services/secure_channel/public/mojom", "//ash/webui/eche_app_ui/mojom", "//ash/webui/eche_app_ui/proto", "//ash/webui/resources:eche_app_resources",
diff --git a/ash/webui/eche_app_ui/eche_connection_metrics_recorder.cc b/ash/webui/eche_app_ui/eche_connection_metrics_recorder.cc index 19dde78..be2b350 100644 --- a/ash/webui/eche_app_ui/eche_connection_metrics_recorder.cc +++ b/ash/webui/eche_app_ui/eche_connection_metrics_recorder.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "ash/webui/eche_app_ui/eche_connection_metrics_recorder.h" +#include "ash/services/secure_channel/public/mojom/secure_channel.mojom.h" #include "base/metrics/histogram_functions.h" namespace ash::eche_app { @@ -14,13 +15,18 @@ base::UmaHistogramBoolean("Eche.Connection.Result", success); } +void EcheConnectionMetricsRecorder::RecordConnectionFailureReason( + secure_channel::mojom::ConnectionAttemptFailureReason reason) { + base::UmaHistogramEnumeration("Eche.Connection.Result.FailureReason", reason); +} + void EcheConnectionMetricsRecorder::RecordConnectionLatency( - const base::TimeDelta& latency) { + const base::TimeDelta latency) { base::UmaHistogramTimes("Eche.Connectivity.Latency", latency); } void EcheConnectionMetricsRecorder::RecordConnectionDuration( - const base::TimeDelta& duration) { + const base::TimeDelta duration) { base::UmaHistogramLongTimes100("Eche.Connection.Duration", duration); }
diff --git a/ash/webui/eche_app_ui/eche_connection_metrics_recorder.h b/ash/webui/eche_app_ui/eche_connection_metrics_recorder.h index 90504e2..ab14d62 100644 --- a/ash/webui/eche_app_ui/eche_connection_metrics_recorder.h +++ b/ash/webui/eche_app_ui/eche_connection_metrics_recorder.h
@@ -22,8 +22,10 @@ // secure_channel::NearbyMetricsRecorder: void RecordConnectionResult(bool success) override; - void RecordConnectionLatency(const base::TimeDelta& latency) override; - void RecordConnectionDuration(const base::TimeDelta& duration) override; + void RecordConnectionFailureReason( + secure_channel::mojom::ConnectionAttemptFailureReason reason) override; + void RecordConnectionLatency(const base::TimeDelta latency) override; + void RecordConnectionDuration(const base::TimeDelta duration) override; }; } // namespace ash::eche_app
diff --git a/base/json/json_parser.cc b/base/json/json_parser.cc index 91824d9e..c011e14 100644 --- a/base/json/json_parser.cc +++ b/base/json/json_parser.cc
@@ -5,6 +5,7 @@ #include "base/json/json_parser.h" #include <cmath> +#include <iterator> #include <utility> #include <vector> @@ -423,7 +424,7 @@ return absl::nullopt; } - std::vector<Value::DeprecatedDictStorage::value_type> dict_storage; + std::vector<std::pair<std::string, Value>> values; Token token = GetNextToken(); while (token != T_OBJECT_END) { @@ -453,7 +454,7 @@ return absl::nullopt; } - dict_storage.emplace_back(key.DestructiveAsString(), std::move(*value)); + values.emplace_back(key.DestructiveAsString(), std::move(*value)); token = GetNextToken(); if (token == T_LIST_SEPARATOR) { @@ -472,8 +473,9 @@ ConsumeChar(); // Closing '}'. // Reverse |dict_storage| to keep the last of elements with the same key in // the input. - ranges::reverse(dict_storage); - return Value(Value::DeprecatedDictStorage(std::move(dict_storage))); + ranges::reverse(values); + return Value(Value::Dict(std::make_move_iterator(values.begin()), + std::make_move_iterator(values.end()))); } absl::optional<Value> JSONParser::ConsumeList() {
diff --git a/base/message_loop/message_pump_mac.h b/base/message_loop/message_pump_mac.h index 4d38358..96881f96 100644 --- a/base/message_loop/message_pump_mac.h +++ b/base/message_loop/message_pump_mac.h
@@ -83,6 +83,8 @@ MessagePumpCFRunLoopBase(const MessagePumpCFRunLoopBase&) = delete; MessagePumpCFRunLoopBase& operator=(const MessagePumpCFRunLoopBase&) = delete; + static void InitializeFeatures(); + // MessagePump: void Run(Delegate* delegate) override; void Quit() override; @@ -157,10 +159,6 @@ // The maximum number of run loop modes that can be monitored. static constexpr int kNumModes = 4; - // All sources of delayed work scheduling converge to this, using TimeDelta - // avoids querying Now() for key callers. - void ScheduleDelayedWorkImpl(TimeDelta delta); - // Timer callback scheduled by ScheduleDelayedWork. This does not do any // work, but it signals |work_source_| so that delayed work can be performed // within the appropriate priority constraints. @@ -252,6 +250,9 @@ base::TimerSlack timer_slack_; + // Time at which `delayed_work_timer_` is set to fire. + base::TimeTicks delayed_work_scheduled_at_ = base::TimeTicks::Max(); + // The recursion depth of the currently-executing CFRunLoopRun loop on the // run loop's thread. 0 if no run loops are running inside of whatever scope // the object was created in.
diff --git a/base/message_loop/message_pump_mac.mm b/base/message_loop/message_pump_mac.mm index 8ce36eaa..1cf2edf 100644 --- a/base/message_loop/message_pump_mac.mm +++ b/base/message_loop/message_pump_mac.mm
@@ -6,6 +6,7 @@ #import <Foundation/Foundation.h> +#include <atomic> #include <limits> #include <memory> @@ -34,6 +35,18 @@ namespace { +// Enables two optimizations in MessagePumpCFRunLoop: +// - Skip calling CFRunLoopTimerSetNextFireDate if the next delayed wake up +// time hasn't changed. +// - Cancel an already scheduled timer wake up if there is no delayed work. +const base::Feature kMessagePumpMacDelayedWorkOptimizations{ + "MessagePumpMacDelayedWorkOptimizations", + base::FEATURE_DISABLED_BY_DEFAULT}; + +// Caches the state of the "MessagePumpMacDelayedWorkOptimizations" +// feature for efficiency. +std::atomic_bool g_enable_optimizations = false; + // Mask that determines which modes to use. enum { kCommonModeMask = 0x1, kAllModesMask = 0xf }; @@ -180,20 +193,38 @@ void MessagePumpCFRunLoopBase::ScheduleDelayedWork( const Delegate::NextWorkInfo& next_work_info) { DCHECK(!next_work_info.is_immediate()); - if (!next_work_info.delayed_run_time.is_max()) - ScheduleDelayedWorkImpl(next_work_info.remaining_delay()); -} -void MessagePumpCFRunLoopBase::ScheduleDelayedWorkImpl(TimeDelta delta) { - // The tolerance needs to be set before the fire date or it may be ignored. - - if (timer_slack_ == TIMER_SLACK_MAXIMUM) { - CFRunLoopTimerSetTolerance(delayed_work_timer_, delta.InSecondsF() * 0.5); + if (g_enable_optimizations.load(std::memory_order_relaxed)) { + // No-op if the delayed run time hasn't changed. + if (next_work_info.delayed_run_time == delayed_work_scheduled_at_) + return; } else { - CFRunLoopTimerSetTolerance(delayed_work_timer_, 0); + // Preserve the old behavior of not adjusting the timer when + // `delayed_run_time.is_max()`. + // + // TODO(crbug.com/1335524): Remove this once the + // "MessagePumpMacDelayedWorkOptimizations" feature is shipped. + if (next_work_info.delayed_run_time.is_max()) + return; } - CFRunLoopTimerSetNextFireDate( - delayed_work_timer_, CFAbsoluteTimeGetCurrent() + delta.InSecondsF()); + + if (next_work_info.delayed_run_time.is_max()) { + CFRunLoopTimerSetNextFireDate(delayed_work_timer_, kCFTimeIntervalMax); + } else { + const double delay_seconds = next_work_info.remaining_delay().InSecondsF(); + + // The tolerance needs to be set before the fire date or it may be ignored. + if (timer_slack_ == TIMER_SLACK_MAXIMUM) { + CFRunLoopTimerSetTolerance(delayed_work_timer_, delay_seconds * 0.5); + } else { + CFRunLoopTimerSetTolerance(delayed_work_timer_, 0); + } + + CFRunLoopTimerSetNextFireDate(delayed_work_timer_, + CFAbsoluteTimeGetCurrent() + delay_seconds); + } + + delayed_work_scheduled_at_ = next_work_info.delayed_run_time; } void MessagePumpCFRunLoopBase::SetTimerSlack(TimerSlack timer_slack) { @@ -293,6 +324,13 @@ CFRelease(run_loop_); } +// static +void MessagePumpCFRunLoopBase::InitializeFeatures() { + g_enable_optimizations.store( + base::FeatureList::IsEnabled(kMessagePumpMacDelayedWorkOptimizations), + std::memory_order_relaxed); +} + void MessagePumpCFRunLoopBase::OnAttach() { CHECK_EQ(nesting_level_, 0); // On iOS: the MessagePump is attached while it's already running. @@ -379,6 +417,8 @@ // The timer fired, assume we have work and let RunWork() figure out what to // do and what to schedule after. base::mac::CallWithEHFrame(^{ + DCHECK_GE(base::TimeTicks::Now(), self->delayed_work_scheduled_at_); + self->delayed_work_scheduled_at_ = base::TimeTicks::Max(); self->RunWork(); }); } @@ -423,11 +463,12 @@ if (next_work_info.is_immediate()) { CFRunLoopSourceSignal(work_source_); return true; + } else { + // This adjusts the next delayed wake up time (potentially cancels an + // already scheduled wake up if there is no delayed work). + ScheduleDelayedWork(next_work_info); + return false; } - - if (!next_work_info.delayed_run_time.is_max()) - ScheduleDelayedWorkImpl(next_work_info.remaining_delay()); - return false; } // Called from the run loop.
diff --git a/base/test/values_test_util.cc b/base/test/values_test_util.cc index c2c2dae..3a1b563b 100644 --- a/base/test/values_test_util.cc +++ b/base/test/values_test_util.cc
@@ -17,32 +17,34 @@ namespace base { void ExpectDictBooleanValue(bool expected_value, - const Value& value, - const std::string& key) { - EXPECT_EQ(value.FindBoolPath(key), absl::optional<bool>(expected_value)) - << key; + const Value::Dict& dict, + StringPiece path) { + EXPECT_EQ(dict.FindBoolByDottedPath(path), + absl::make_optional(expected_value)) + << path; } void ExpectDictIntegerValue(int expected_value, - const Value& value, - const std::string& key) { - EXPECT_EQ(value.FindIntPath(key), absl::optional<int>(expected_value)) << key; + const Value::Dict& dict, + StringPiece path) { + EXPECT_EQ(dict.FindIntByDottedPath(path), absl::make_optional(expected_value)) + << path; } -void ExpectDictStringValue(const std::string& expected_value, - const Value& value, - const std::string& key) { - EXPECT_EQ(OptionalFromPtr(value.FindStringPath(key)), - absl::optional<std::string>(expected_value)) - << key; +void ExpectDictStringValue(StringPiece expected_value, + const Value::Dict& dict, + StringPiece path) { + EXPECT_EQ(OptionalFromPtr(dict.FindStringByDottedPath(path)), + absl::make_optional(expected_value)) + << path; } void ExpectDictValue(const Value& expected_value, - const Value& value, - const std::string& key) { - const Value* found_value = value.FindPath(key); - EXPECT_TRUE(found_value) << key; - EXPECT_EQ(*found_value, expected_value) << key; + const Value::Dict& dict, + StringPiece path) { + const Value* found_value = dict.FindByDottedPath(path); + ASSERT_TRUE(found_value) << path; + EXPECT_EQ(*found_value, expected_value) << path; } void ExpectStringValue(const std::string& expected_str, const Value& actual) {
diff --git a/base/test/values_test_util.h b/base/test/values_test_util.h index da798bdb..0b36be7d 100644 --- a/base/test/values_test_util.h +++ b/base/test/values_test_util.h
@@ -15,24 +15,24 @@ namespace base { -// All the functions below expect that the value for the given key in +// All the functions below expect that the value for the given path in // the given dictionary equals the given expected value. void ExpectDictBooleanValue(bool expected_value, - const Value& value, - const std::string& key); + const Value::Dict& dict, + StringPiece path); void ExpectDictIntegerValue(int expected_value, - const Value& value, - const std::string& key); + const Value::Dict& dict, + StringPiece path); -void ExpectDictStringValue(const std::string& expected_value, - const Value& value, - const std::string& key); +void ExpectDictStringValue(StringPiece expected_value, + const Value::Dict& dict, + StringPiece path); void ExpectDictValue(const Value& expected_value, - const Value& value, - const std::string& key); + const Value::Dict& dict, + StringPiece path); void ExpectStringValue(const std::string& expected_str, const Value& actual);
diff --git a/base/values.cc b/base/values.cc index 42857cc..09f92b0 100644 --- a/base/values.cc +++ b/base/values.cc
@@ -231,24 +231,6 @@ Value::Value(List&& value) noexcept : data_(std::move(value)) {} -Value::Value(const DeprecatedDictStorage& value) - : data_(absl::in_place_type_t<Dict>()) { - dict().reserve(value.size()); - for (const auto& it : value) { - dict().try_emplace(dict().end(), it.first, - std::make_unique<Value>(it.second.Clone())); - } -} - -Value::Value(DeprecatedDictStorage&& value) - : data_(absl::in_place_type_t<Dict>()) { - dict().reserve(value.size()); - for (auto& it : value) { - dict().try_emplace(dict().end(), std::move(it.first), - std::make_unique<Value>(std::move(it.second))); - } -} - Value::Value(span<const Value> value) : data_(absl::in_place_type_t<List>()) { list().reserve(value.size()); for (const auto& val : value) @@ -1400,18 +1382,6 @@ return const_dict_iterator_proxy(&dict()); } -Value::DeprecatedDictStorage Value::TakeDictDeprecated() && { - DeprecatedDictStorage storage; - storage.reserve(dict().size()); - for (auto& pair : dict()) { - storage.try_emplace(storage.end(), std::move(pair.first), - std::move(*pair.second)); - } - - dict().clear(); - return storage; -} - size_t Value::DictSize() const { return GetDict().size(); }
diff --git a/base/values.h b/base/values.h index 727328f..ddab7ac 100644 --- a/base/values.h +++ b/base/values.h
@@ -11,6 +11,7 @@ #include <array> #include <initializer_list> #include <iosfwd> +#include <iterator> #include <memory> #include <string> #include <utility> @@ -206,13 +207,12 @@ using BlobStorage = std::vector<uint8_t>; using DeprecatedListStorage = std::vector<Value>; - using DeprecatedDictStorage = flat_map<std::string, Value>; // TODO(https://crbug.com/1291666): Make this private. using ListStorage = DeprecatedListStorage; // Like `DictStorage`, but with std::unique_ptr in the mapped type. This is - // due to legacy reasons, and should be replaced with a private version of - // DeprecatedDictStorage once no caller relies on stability of pointers + // due to legacy reasons, and should be replaced with + // flat_map<std::string, Value> once no caller relies on stability of pointers // anymore. using LegacyDictStorage = flat_map<std::string, std::unique_ptr<Value>>; @@ -302,10 +302,6 @@ // Constructor for `Value::Type::LIST`. explicit Value(List&& value) noexcept; - // DEPRECATED: prefer `Value(Dict&&)`. - explicit Value(const DeprecatedDictStorage& value); - explicit Value(DeprecatedDictStorage&& value); - // DEPRECATED: prefer `Value(List&&)`. explicit Value(span<const Value> value); explicit Value(ListStorage&& value) noexcept; @@ -376,6 +372,28 @@ Dict(const Dict&) = delete; Dict& operator=(const Dict&) = delete; + // Takes move_iterators iterators that return std::pair<std::string, Value>, + // and moves their values into a new Dict. Adding all entries at once + // results in a faster initial sort operation. Takes move iterators to avoid + // having to clone the input. + template <class IteratorType> + explicit Dict(std::move_iterator<IteratorType> first, + std::move_iterator<IteratorType> last) { + // Need to move into a vector first, since `storage_` currently uses + // unique_ptrs. + std::vector<std::pair<std::string, std::unique_ptr<Value>>> values; + for (auto current = first; current != last; ++current) { + // With move iterators, no need to call Clone(), but do need to move + // to a temporary first, as accessing either field individually will + // directly from the iterator will delete the other field. + auto value = *current; + values.emplace_back(std::move(value.first), + std::make_unique<Value>(std::move(value.second))); + } + storage_ = + flat_map<std::string, std::unique_ptr<Value>>(std::move(values)); + } + ~Dict(); // TODO(dcheng): Probably need to allow construction from a pair of @@ -997,13 +1015,6 @@ dict_iterator_proxy DictItems(); const_dict_iterator_proxy DictItems() const; - // Transfers ownership of the underlying dict to the caller. Subsequent - // calls to DictItems() will return an empty dict. - // - // DEPRECATED: prefer direct use of `base::Value::Dict` where possible, or - // `std::move(value.GetDict())` otherwise. - DeprecatedDictStorage TakeDictDeprecated() &&; - // DEPRECATED: prefer `Value::Dict::size()`. size_t DictSize() const;
diff --git a/base/values_unittest.cc b/base/values_unittest.cc index 8a518c2..df16e4a 100644 --- a/base/values_unittest.cc +++ b/base/values_unittest.cc
@@ -8,6 +8,7 @@ #include <algorithm> #include <functional> +#include <iterator> #include <limits> #include <memory> #include <string> @@ -214,25 +215,6 @@ } } -TEST(ValuesTest, ConstructDictFromDeprecatedDictStorage) { - Value::DeprecatedDictStorage storage; - storage.emplace("foo", "bar"); - { - Value value(storage); - EXPECT_EQ(Value::Type::DICTIONARY, value.type()); - EXPECT_EQ(Value::Type::STRING, value.FindKey("foo")->type()); - EXPECT_EQ("bar", value.FindKey("foo")->GetString()); - } - - storage["foo"] = base::Value("baz"); - { - Value value(std::move(storage)); - EXPECT_EQ(Value::Type::DICTIONARY, value.type()); - EXPECT_EQ(Value::Type::STRING, value.FindKey("foo")->type()); - EXPECT_EQ("baz", value.FindKey("foo")->GetString()); - } -} - TEST(ValuesTest, ConstructList) { ListValue value; EXPECT_EQ(Value::Type::LIST, value.type()); @@ -470,55 +452,17 @@ EXPECT_EQ(123, blank.FindKey("Int")->GetInt()); } -TEST(ValuesTest, MoveConstructDeprecatedDictStorage) { - Value::DeprecatedDictStorage storage; - storage.emplace("Int", 123); - - Value value(std::move(storage)); - Value moved_value(std::move(value)); - EXPECT_EQ(Value::Type::DICTIONARY, moved_value.type()); - EXPECT_EQ(123, moved_value.FindKey("Int")->GetInt()); -} - -TEST(ValuesTest, MoveAssignDeprecatedDictStorage) { - Value::DeprecatedDictStorage storage; - storage.emplace("Int", 123); +TEST(ValuesTest, ConstructDictWithIterators) { + std::vector<std::pair<std::string, Value>> values; + values.emplace_back(std::make_pair("Int", 123)); Value blank; - blank = Value(std::move(storage)); + blank = Value(Value::Dict(std::make_move_iterator(values.begin()), + std::make_move_iterator(values.end()))); EXPECT_EQ(Value::Type::DICTIONARY, blank.type()); EXPECT_EQ(123, blank.FindKey("Int")->GetInt()); } -TEST(ValuesTest, TakeDictDeprecated) { - // Prepare a dict with a value of each type. - Value::DeprecatedDictStorage storage; - storage.emplace("null", Value::Type::NONE); - storage.emplace("bool", Value::Type::BOOLEAN); - storage.emplace("int", Value::Type::INTEGER); - storage.emplace("double", Value::Type::DOUBLE); - storage.emplace("string", Value::Type::STRING); - storage.emplace("blob", Value::Type::BINARY); - storage.emplace("list", Value::Type::LIST); - storage.emplace("dict", Value::Type::DICTIONARY); - Value value(std::move(storage)); - - // Take ownership of the dict and make sure its contents are what we expect. - auto dict = std::move(value).TakeDictDeprecated(); - EXPECT_EQ(8u, dict.size()); - EXPECT_TRUE(dict["null"].is_none()); - EXPECT_TRUE(dict["bool"].is_bool()); - EXPECT_TRUE(dict["int"].is_int()); - EXPECT_TRUE(dict["double"].is_double()); - EXPECT_TRUE(dict["string"].is_string()); - EXPECT_TRUE(dict["blob"].is_blob()); - EXPECT_TRUE(dict["list"].is_list()); - EXPECT_TRUE(dict["dict"].is_dict()); - - // Validate that |value| no longer contains values. - EXPECT_TRUE(value.DictEmpty()); -} - TEST(ValuesTest, MoveList) { Value::ListStorage storage; storage.emplace_back(123);
diff --git a/build/config/compiler/pgo/pgo.gni b/build/config/compiler/pgo/pgo.gni index c053eb5..a5bb86b 100644 --- a/build/config/compiler/pgo/pgo.gni +++ b/build/config/compiler/pgo/pgo.gni
@@ -4,6 +4,7 @@ import("//build/config/chromecast_build.gni") import("//build/config/chromeos/ui_mode.gni") +import("//build/config/dcheck_always_on.gni") declare_args() { # Specify the current PGO phase. @@ -11,8 +12,12 @@ # 0 : Means that PGO is turned off. # 1 : Used during the PGI (instrumentation) phase. # 2 : Used during the PGO (optimization) phase. + # PGO profiles are generated from `dcheck_always_on = false` builds. Mixing + # those profiles with `dcheck_always_on = true` builds can cause the compiler + # to think some code is hotter than it actually is, potentially causing very + # bad compile times. chrome_pgo_phase = 0 - if (is_official_build && + if (!dcheck_always_on && is_official_build && # TODO(crbug.com/1052397): Remove chromeos_is_browser_only once # target_os switch for lacros-chrome is completed. (is_win || is_mac ||
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 6a51620..6f8ab04 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -1311,9 +1311,11 @@ testonly = true resources_package = "org.chromium.chrome.test" sources = [ + "javatests/src/org/chromium/chrome/browser/IntentFilterUnitTest.java", "javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRowTest.java", "javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkUtilsTest.java", "javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java", + "javatests/src/org/chromium/chrome/browser/crypto/CipherFactoryTest.java", "javatests/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManagerTest.java", "javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java", "javatests/src/org/chromium/chrome/browser/init/FirstDrawDetectorTest.java", @@ -1330,6 +1332,7 @@ "//base:base_java_test_support", "//chrome/android:chrome_java", "//chrome/android/features/autofill_assistant:unit_test_java", + "//chrome/browser/android/crypto:java", "//chrome/browser/contextmenu:java", "//chrome/browser/first_run/android:java", "//chrome/browser/flags:java", @@ -1628,7 +1631,6 @@ "//components/page_info/android:page_info_action_enum_java", "//components/page_info/core:proto_java", "//components/paint_preview/player/android:java", - "//components/paint_preview/player/android:javatests", "//components/password_manager/core/browser:password_manager_java_enums", "//components/payments/content/android:java", "//components/payments/content/android:javatests", @@ -3156,6 +3158,7 @@ "//chrome/browser/ui/messages/android:unit_device_javatests", "//chrome/browser/user_education:javatests", "//chrome/browser/video_tutorials/internal:javatests", + "//components/paint_preview/player/android:javatests", "//components/signin/public/android:javatests", ]
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index c260675..13e26c88 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -21,7 +21,6 @@ "javatests/src/org/chromium/chrome/browser/HTTPSTabsOpenedFromExternalAppTest.java", "javatests/src/org/chromium/chrome/browser/ImageFetcherIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/InstalledAppTest.java", - "javatests/src/org/chromium/chrome/browser/IntentFilterUnitTest.java", "javatests/src/org/chromium/chrome/browser/IntentHandlerBrowserTest.java", "javatests/src/org/chromium/chrome/browser/IntentHandlerUnitTest.java", "javatests/src/org/chromium/chrome/browser/JavaScriptEvalChromeTest.java", @@ -137,7 +136,6 @@ "javatests/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchFullUiTest.java", "javatests/src/org/chromium/chrome/browser/crash/LogcatExtractionRunnableTest.java", "javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java", - "javatests/src/org/chromium/chrome/browser/crypto/CipherFactoryTest.java", "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityAppMenuTest.java", "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoMetricTest.java", "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java", @@ -336,7 +334,6 @@ "javatests/src/org/chromium/chrome/browser/omnibox/suggestions/SwitchToTabTest.java", "javatests/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessorUnitTest.java", "javatests/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionProcessorTest.java", - "javatests/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorUnitTest.java", "javatests/src/org/chromium/chrome/browser/omnibox/suggestions/clipboard/ClipboardSuggestionProcessorTest.java", "javatests/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionUnitTest.java", "javatests/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionProcessorUnitTest.java",
diff --git a/chrome/android/features/start_surface/javatests/start_surface_test_java_sources.gni b/chrome/android/features/start_surface/javatests/start_surface_test_java_sources.gni index 2157dfc..5979c32c 100644 --- a/chrome/android/features/start_surface/javatests/start_surface_test_java_sources.gni +++ b/chrome/android/features/start_surface/javatests/start_surface_test_java_sources.gni
@@ -9,7 +9,6 @@ "//chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTabSwitcherTest.java", "//chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java", "//chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartToolbarTest.java", - "//chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinderTest.java", "//chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceBackButtonTest.java", "//chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceMVTilesTest.java", "//chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceNoTabsTest.java", @@ -18,7 +17,6 @@ "//chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java", "//chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayoutPerfTest.java", "//chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayoutTest.java", - "//chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinderTest.java", "//chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/tasks/SingleTabViewBinderTest.java", "//chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/tasks/TasksViewBinderTest.java", ]
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinderTest.java b/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinderUnitTest.java similarity index 74% rename from chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinderTest.java rename to chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinderUnitTest.java index 9e53515..229313a 100644 --- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinderTest.java +++ b/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinderUnitTest.java
@@ -12,6 +12,7 @@ import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_SECONDARY_SURFACE_VISIBLE; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.TOP_MARGIN; +import android.app.Activity; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.view.View; @@ -21,42 +22,43 @@ import androidx.test.filters.SmallTest; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.annotation.Config; +import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.UiThreadTest; -import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; -import org.chromium.ui.test.util.BlankUiTestActivityTestCase; /** Tests for {@link SecondaryTasksSurfaceViewBinder}. */ -@RunWith(ChromeJUnit4ClassRunner.class) -public class SecondaryTasksSurfaceViewBinderTest extends BlankUiTestActivityTestCase { +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class SecondaryTasksSurfaceViewBinderUnitTest { + private Activity mActivity; private ViewGroup mParentView; private View mTasksSurfaceView; private PropertyModel mPropertyModel; @SuppressWarnings({"FieldCanBeLocal", "unused"}) private PropertyModelChangeProcessor mPropertyModelChangeProcessor; - @Override - public void setUpTest() throws Exception { - super.setUpTest(); + @Before + public void setUp() throws Exception { + mActivity = Robolectric.buildActivity(Activity.class).setup().get(); - TestThreadUtils.runOnUiThreadBlocking(() -> { - // Note that the specific type of the parent view and tasks surface view do not matter - // for the SecondaryTasksSurfaceViewBinderTest. - mParentView = new FrameLayout(getActivity()); - mTasksSurfaceView = new View(getActivity()); - mTasksSurfaceView.setBackground(new ColorDrawable(Color.WHITE)); - getActivity().setContentView(mParentView); + // Note that the specific type of the parent view and tasks surface view do not matter for + // the SecondaryTasksSurfaceViewBinderTest. + mParentView = new FrameLayout(mActivity); + mTasksSurfaceView = new View(mActivity); + mTasksSurfaceView.setBackground(new ColorDrawable(Color.WHITE)); + mActivity.setContentView(mParentView); - mPropertyModel = new PropertyModel(StartSurfaceProperties.ALL_KEYS); - mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create(mPropertyModel, - new TasksSurfaceViewBinder.ViewHolder(mParentView, mTasksSurfaceView), - SecondaryTasksSurfaceViewBinder::bind); - }); + mPropertyModel = new PropertyModel(StartSurfaceProperties.ALL_KEYS); + mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create(mPropertyModel, + new TasksSurfaceViewBinder.ViewHolder(mParentView, mTasksSurfaceView), + SecondaryTasksSurfaceViewBinder::bind); } @Test
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinderTest.java b/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinderUnitTest.java similarity index 74% rename from chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinderTest.java rename to chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinderUnitTest.java index d017592..4d3b56e9d 100644 --- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinderTest.java +++ b/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinderUnitTest.java
@@ -13,6 +13,7 @@ import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_SHOWING_OVERVIEW; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.TOP_MARGIN; +import android.app.Activity; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.MarginLayoutParams; @@ -20,41 +21,42 @@ import androidx.test.filters.SmallTest; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.annotation.Config; +import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.UiThreadTest; -import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; -import org.chromium.ui.test.util.BlankUiTestActivityTestCase; /** Tests for {@link TasksSurfaceViewBinder}. */ -@RunWith(ChromeJUnit4ClassRunner.class) -public class TasksSurfaceViewBinderTest extends BlankUiTestActivityTestCase { +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class TasksSurfaceViewBinderUnitTest { + private Activity mActivity; private ViewGroup mParentView; private ViewGroup mTasksSurfaceView; private PropertyModel mPropertyModel; @SuppressWarnings({"FieldCanBeLocal", "unused"}) private PropertyModelChangeProcessor mPropertyModelChangeProcessor; - @Override - public void setUpTest() throws Exception { - super.setUpTest(); + @Before + public void setUp() { + mActivity = Robolectric.buildActivity(Activity.class).setup().get(); - TestThreadUtils.runOnUiThreadBlocking(() -> { - // Note that the specific type of the parent view and tasks surface view do not matter - // for the TasksSurfaceViewBinder. - mParentView = new FrameLayout(getActivity()); - mTasksSurfaceView = new FrameLayout(getActivity()); - getActivity().setContentView(mParentView); + // Note that the specific type of the parent view and tasks surface view do not matter for + // the TasksSurfaceViewBinder. + mParentView = new FrameLayout(mActivity); + mTasksSurfaceView = new FrameLayout(mActivity); + mActivity.setContentView(mParentView); - mPropertyModel = new PropertyModel(StartSurfaceProperties.ALL_KEYS); - mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create(mPropertyModel, - new TasksSurfaceViewBinder.ViewHolder(mParentView, mTasksSurfaceView), - TasksSurfaceViewBinder::bind); - }); + mPropertyModel = new PropertyModel(StartSurfaceProperties.ALL_KEYS); + mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create(mPropertyModel, + new TasksSurfaceViewBinder.ViewHolder(mParentView, mTasksSurfaceView), + TasksSurfaceViewBinder::bind); } @Test
diff --git a/chrome/android/features/start_surface/junit/start_surface_junit_java_sources.gni b/chrome/android/features/start_surface/junit/start_surface_junit_java_sources.gni index 622e98c..90ea96f 100644 --- a/chrome/android/features/start_surface/junit/start_surface_junit_java_sources.gni +++ b/chrome/android/features/start_surface/junit/start_surface_junit_java_sources.gni
@@ -3,7 +3,9 @@ # found in the LICENSE file. start_surface_junit_java_sources = [ + "//chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinderUnitTest.java", "//chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java", + "//chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinderUnitTest.java", "//chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/tasks/SingleTabSwitcherMediatorUnitTest.java", "//chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/tasks/TasksSurfaceMediatorUnitTest.java", ]
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index dfecfa80..ca7ad4b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -642,6 +642,7 @@ public void didAddTab( Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { if (type == TabLaunchType.FROM_LONGPRESS_BACKGROUND + || type == TabLaunchType.FROM_LONGPRESS_BACKGROUND_IN_GROUP || type == TabLaunchType.FROM_RECENT_TABS && !DeviceClassManager.enableAnimations()) { Toast.makeText(ChromeTabbedActivity.this, R.string.open_in_new_tab_toast, @@ -2335,6 +2336,7 @@ || type == TabLaunchType.FROM_LONGPRESS_FOREGROUND || type == TabLaunchType.FROM_LONGPRESS_INCOGNITO || type == TabLaunchType.FROM_LONGPRESS_BACKGROUND + || type == TabLaunchType.FROM_LONGPRESS_BACKGROUND_IN_GROUP || type == TabLaunchType.FROM_RECENT_TABS || (type == TabLaunchType.FROM_RESTORE && CriticalPersistedTabData.from(tab).getParentId() != Tab.INVALID_TAB_ID);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java index 5340fb22..5bee253 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -1988,11 +1988,6 @@ return mIsBottomSheetVisible || mIsAccessibilityModeEnabled; } - @VisibleForTesting - public void setVisibilityStateForTesting(boolean isVisible) { - getOverlayContentDelegate().onVisibilityChanged(isVisible); - } - @NativeMethods interface Natives { long init(ContextualSearchManager caller);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java index 02a5997c..e3cdc957 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
@@ -452,6 +452,11 @@ // CustomTabActivityNavigationController#FinishHandler. Pass the mode enum into // CustomTabActivityModule, so that it can provide the correct implementation. getComponent().resolveTwaFinishHandler().onFinish(defaultBehavior); + } else if (intentDataProvider.isPartialHeightCustomTab() + && intentDataProvider.shouldAnimateOnFinish()) { + // WebContents is missing during the close animation due to android:windowIsTranslucent. + // We let partial CCT handle the animation. + mBaseCustomTabRootUiCoordinator.handleCloseAnimation(defaultBehavior); } else { defaultBehavior.run(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java index 2a7879c..5f3c0e6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
@@ -55,7 +55,6 @@ * A {@link RootUiCoordinator} variant that controls UI for {@link BaseCustomTabActivity}. */ public class BaseCustomTabRootUiCoordinator extends RootUiCoordinator { - private final ObservableSupplier<CompositorViewHolder> mCompositorViewHolderSupplier; private final Supplier<CustomTabToolbarCoordinator> mToolbarCoordinator; private final Supplier<CustomTabActivityNavigationController> mNavigationController; private final Supplier<BrowserServicesIntentDataProvider> mIntentDataProvider; @@ -149,7 +148,6 @@ ephemeralTabCoordinatorSupplier, false, null, /* unblockDrawForOverviewPageRunnable= */ null); // clang-format on - mCompositorViewHolderSupplier = compositorViewHolderSupplier; mToolbarCoordinator = customTabToolbarCoordinator; mNavigationController = customTabNavigationController; mIntentDataProvider = intentDataProvider; @@ -205,14 +203,19 @@ != null : "IntentDataProvider needs to be non-null after preInflationStartup"; mCustomTabHeightStrategy = CustomTabHeightStrategy.createStrategy(mActivity, - mCompositorViewHolderSupplier, intentDataProvider.getInitialActivityHeight(), - mMultiWindowModeStateDispatcher, + intentDataProvider.getInitialActivityHeight(), mMultiWindowModeStateDispatcher, intentDataProvider.getColorProvider().getNavigationBarColor(), intentDataProvider.getColorProvider().getNavigationBarDividerColor(), CustomTabsConnection.getInstance(), intentDataProvider.getSession(), mActivityLifecycleDispatcher); } + @Override + public void onPostInflationStartup() { + super.onPostInflationStartup(); + mCustomTabHeightStrategy.onPostInflationStartup(); + } + /** * Delegates changing the background color to the {@link CustomTabHeightStrategy}. * Returns {@code true} if any action were taken, {@code false} if not. @@ -222,4 +225,12 @@ return mCustomTabHeightStrategy.changeBackgroundColorForResizing(); } + + /** + * Perform slide-down animation on closing. + * @param finishRunnable Runnable finishing the activity after the animation. + */ + void handleCloseAnimation(Runnable finishRunnable) { + mCustomTabHeightStrategy.handleCloseAnimation(finishRunnable); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabHeightStrategy.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabHeightStrategy.java index f3d06f6..f819ab5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabHeightStrategy.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabHeightStrategy.java
@@ -6,13 +6,11 @@ import android.app.Activity; import android.view.View; -import android.widget.FrameLayout; import androidx.annotation.Nullable; import androidx.annotation.Px; import androidx.browser.customtabs.CustomTabsSessionToken; -import org.chromium.base.supplier.ObservableSupplier; import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbar; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.multiwindow.MultiWindowModeStateDispatcher; @@ -21,8 +19,7 @@ * The default strategy for setting the height of the custom tab. */ public class CustomTabHeightStrategy { - public static CustomTabHeightStrategy createStrategy(Activity activity, - ObservableSupplier<? extends FrameLayout> parentViewSupplier, @Px int initialHeight, + public static CustomTabHeightStrategy createStrategy(Activity activity, @Px int initialHeight, MultiWindowModeStateDispatcher multiWindowModeStateDispatcher, Integer navigationBarColor, Integer navigationBarDividerColor, CustomTabsConnection connection, @Nullable CustomTabsSessionToken session, @@ -31,12 +28,17 @@ return new CustomTabHeightStrategy(); } - return new PartialCustomTabHeightStrategy(activity, parentViewSupplier, initialHeight, + return new PartialCustomTabHeightStrategy(activity, initialHeight, multiWindowModeStateDispatcher, navigationBarColor, navigationBarDividerColor, size -> connection.onResized(session, size), lifecycleDispatcher); } /** + * @see {@link org.chromium.chrome.browser.lifecycle.InflationObserver#onPostInflationStartup()} + */ + public void onPostInflationStartup() {} + + /** * Returns false if we didn't change the Window background color, true otherwise. */ public boolean changeBackgroundColorForResizing() { @@ -53,4 +55,12 @@ */ public void onToolbarInitialized( View coordinatorView, CustomTabToolbar toolbar, @Px int toolbarCornerRadius) {} + + /** + * @see {@link BaseCustomTabRootUiCoordinator#handleCloseAnimation()} + */ + public void handleCloseAnimation(Runnable finishRunnable) { + throw new IllegalStateException( + "Custom close animation should be performed only on partial CCT."); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index c6f7979..229cbc3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -637,8 +637,9 @@ @Override public int getAnimationExitRes() { - return shouldAnimateOnFinish() ? mAnimationBundle.getInt(BUNDLE_EXIT_ANIMATION_RESOURCE) - : 0; + return shouldAnimateOnFinish() && !isPartialHeightCustomTab() + ? mAnimationBundle.getInt(BUNDLE_EXIT_ANIMATION_RESOURCE) + : 0; } @Deprecated
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategy.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategy.java index d274372..0ee12c7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategy.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategy.java
@@ -14,25 +14,24 @@ import android.content.Context; import android.content.res.Configuration; import android.graphics.Color; -import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.GradientDrawable; import android.os.Build; import android.util.DisplayMetrics; -import android.view.Display; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewStub; +import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.WindowInsets; import android.view.WindowManager; -import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import androidx.annotation.IntDef; +import androidx.annotation.Nullable; import androidx.annotation.Px; import androidx.annotation.VisibleForTesting; import androidx.core.view.MotionEventCompat; @@ -44,7 +43,6 @@ import org.chromium.base.MathUtils; import org.chromium.base.SysUtils; import org.chromium.base.ThreadUtils; -import org.chromium.base.supplier.ObservableSupplier; import org.chromium.chrome.R; import org.chromium.chrome.browser.customtabs.features.CustomTabNavigationBarController; import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbar; @@ -88,7 +86,6 @@ } private final Activity mActivity; - private final @Px int mInitialHeight; private final @Px int mMaxHeight; private final @Px int mFullyExpandedAdjustmentHeight; @@ -97,6 +94,7 @@ private final OnResizedCallback mOnResizedCallback; private final AnimatorListener mSpinnerFadeoutAnimatorListener; private final int mHandleHeight; + private @Px int mInitialHeight; private ValueAnimator mAnimator; private int mShadowOffset; private boolean mDrawOutlineShadow; @@ -124,6 +122,11 @@ private CircularProgressDrawable mSpinner; private View mToolbarView; private View mToolbarCoordinator; + private Runnable mPositionUpdater; + + // Runnable finishing the activity after the exit animation. Non-null when PCCT is closing. + @Nullable + private Runnable mFinishRunnable; /** A callback to be called once the Custom Tab has been resized. */ interface OnResizedCallback { @@ -259,8 +262,7 @@ } } - public PartialCustomTabHeightStrategy(Activity activity, - ObservableSupplier<? extends FrameLayout> parentViewSupplier, @Px int initialHeight, + public PartialCustomTabHeightStrategy(Activity activity, @Px int initialHeight, MultiWindowModeStateDispatcher multiWindowModeStateDispatcher, Integer navigationBarColor, Integer navigationBarDividerColor, OnResizedCallback onResizedCallback, ActivityLifecycleDispatcher lifecycleDispatcher) { @@ -268,31 +270,6 @@ mMaxHeight = getMaximumPossibleHeight(); mInitialHeight = MathUtils.clamp( initialHeight, mMaxHeight, (int) (mMaxHeight * MINIMAL_HEIGHT_RATIO)); - - // Invoked twice - when populated/destroyed(null) - // TODO(jinsukkim): Obtain the CoordinatorLayout and ContentFrame directly, - // not through CompositorViewHolder which is not in use. - parentViewSupplier.addObserver(parentView -> { - if (parentView == null) { - mCoordinatorLayout = null; - mContentFrame = null; - return; - } - - mCoordinatorLayout = (ViewGroup) parentView.getParent(); - mContentFrame = (ViewGroup) mCoordinatorLayout.getParent(); - - // Elevate the main web contents area as high as the handle bar to have the shadow - // effect look right. - int ev = mActivity.getResources().getDimensionPixelSize(R.dimen.custom_tabs_elevation); - mCoordinatorLayout.setElevation(ev); - - // When the navigation bar on the right side (not at the bottom), no need to set - // contents height since it is fixed to the max height. - if (mNavbarHeight != 0) setContentsHeight(); - updateNavbarVisibility(true); - }); - mOnResizedCallback = onResizedCallback; // When the flag is enabled, we make the max snap point 10% shorter, so it will only occupy // 90% of the height. @@ -337,7 +314,49 @@ @Override public void onAnimationCancel(Animator animator) {} }; + + // On pre-R devices, We wait till the layout is complete and get the content + // |android.R.id.content| view height. See |getAppUsableScreenHeight|. + mPositionUpdater = + Build.VERSION.SDK_INT >= Build.VERSION_CODES.R ? this::updatePosition : () -> { + // Maybe invoked before layout inflation? Simply return here - postion update will be + // executed by |onPostInflationStartUp| anyway. + if (mContentFrame == null) return; + + mContentFrame.getViewTreeObserver().addOnGlobalLayoutListener( + new OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + mContentFrame.getViewTreeObserver().removeOnGlobalLayoutListener(this); + updatePosition(); + } + }); + }; + } + + @Override + public void onPostInflationStartup() { + mContentFrame = (ViewGroup) mActivity.findViewById(android.R.id.content); + mCoordinatorLayout = (ViewGroup) mActivity.findViewById(R.id.coordinator); + + // Elevate the main web contents area as high as the handle bar to have the shadow + // effect look right. + int ev = mActivity.getResources().getDimensionPixelSize(R.dimen.custom_tabs_elevation); + mCoordinatorLayout.setElevation(ev); + + mPositionUpdater.run(); + } + + private void updatePosition() { + if (mContentFrame == null) return; + initializeHeight(); + updateShadowOffset(); + + // When the navigation bar on the right side (not at the bottom), no need to + // set contents height since it is fixed to the max height. + if (mNavbarHeight != 0) setContentsHeight(); + updateNavbarVisibility(true); } private @Px int getNavbarHeight() { @@ -348,14 +367,19 @@ .getInsets(WindowInsets.Type.navigationBars()) .bottom; } + // On pre-R devices, there is no official way to get the navigation bar height. A common way + // was to get it from a resource definition('navigation_bar_height') but it fails on some + // vendor-customized devices. A workaround here is to subtract the app-usable height + // (client view height + status bar height) from the whole display height. return getDisplayHeight() - getAppUsableScreenHeight(); } private int getAppUsableScreenHeight() { - Display display = mActivity.getWindowManager().getDefaultDisplay(); - Point size = new Point(); - display.getSize(size); - return size.y; + // A correct way to get the client area height would be to use |decor_content_parent|, + // the parent of |content|, to make sure to include the top action bar dimension. But + // CCT (or Chrome for that matter) doesn't have the top action bar. So getting the height + // of |content| is enough. + return mContentFrame.getHeight() + getStatusBarHeight(); } @Override @@ -378,10 +402,12 @@ public void onConfigurationChanged(Configuration newConfig) { if (newConfig.orientation != mOrientation) { mOrientation = newConfig.orientation; - initializeHeight(); - updateShadowOffset(); - setContentsHeight(); - updateNavbarVisibility(true); + if (mOrientation == Configuration.ORIENTATION_LANDSCAPE) { + // We should update CCT position before Window#FLAG_LAYOUT_NO_LIMITS is set, + // otherwise it is not possible to get the correct content height. + mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + mPositionUpdater.run(); } } @@ -454,9 +480,9 @@ // TODO(jinsukkim): Handle multi-window mode. if (attributes.height == height) return; - // We do not resize Window but just translate its vertical offset, and resize the parent - // view of WebContents (CompositorViewHolder) instead. This helps us work around the round- - // corner bug in Android S. See b/223536648. + // We do not resize Window but just translate its vertical offset, and resize Coordinator- + // LayoutForPointer instead. This helps us work around the round-corner bug in Android S. + // See b/223536648. attributes.y = Math.max(maxExpandedY, maxHeight - height - mNavbarHeight); mActivity.getWindow().setAttributes(attributes); } @@ -488,8 +514,11 @@ mMaxHeight - mInitialHeight - mNavbarHeight); WindowManager.LayoutParams attributes = mActivity.getWindow().getAttributes(); if (attributes.y == y) return; + attributes.y = y; mActivity.getWindow().setAttributes(attributes); + if (mFinishRunnable != null) return; + assert mSpinnerView != null; centerSpinnerVertically((ViewGroup.LayoutParams) mSpinnerView.getLayoutParams()); } @@ -500,6 +529,10 @@ } private void onMoveEnd() { + if (mFinishRunnable != null) { + mFinishRunnable.run(); + return; + } setContentsHeight(); // TODO(crbug.com/1328555): Look into observing a view resize event to ensure the fade @@ -523,7 +556,6 @@ // Toolbar should not be hidden by spinner screen. ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(MATCH_PARENT, 0); lp.setMargins(0, mToolbarView.getHeight() + mHandleHeight + mShadowOffset, 0, 0); - mSpinner = new CircularProgressDrawable(mActivity); mSpinner.setStyle(CircularProgressDrawable.LARGE); mSpinnerView.setImageDrawable(mSpinner); @@ -571,9 +603,7 @@ // Show or hide our own navigation bar. private void updateNavbarVisibility(boolean show) { if (show) { - // No need draw its own navigation bar when it is located on the right side since - // the system navigation bar is visible and can handle API #setNavigationBarColor. - if (mNavbarHeight == 0) { + if (shouldShowSystemNavbar()) { setNavigationBarAndDividerColor(); if (mNavbar != null) mNavbar.setVisibility(View.GONE); return; @@ -599,6 +629,14 @@ showNavbarButtons(show); } + /** + * Return whether we need to show not its own custom navigation bar but the system-provided + * one that can handle the API |setNavigationBarColor()|. + */ + private boolean shouldShowSystemNavbar() { + return mNavbarHeight == 0 || mOrientation == Configuration.ORIENTATION_LANDSCAPE; + } + // Position our own navbar where the system navigation bar which is obscured by WebContents // rendered over it due to Window#FLAGS_LAYOUT_NO_LIMITS would be shown. private void setNavbarOffset() { @@ -616,7 +654,7 @@ // the bad contrast against buttons when they are both white. boolean needsDarkButtons = !ColorUtils.shouldUseLightForegroundOnBackground(color); if (needsDarkButtons) color = ColorUtils.getDarkenedColorForStatusBar(color); - if (mNavbarHeight == 0) { + if (shouldShowSystemNavbar()) { mActivity.getWindow().setNavigationBarColor(color); } else { // Use our own navbar where the system navigation bar which is obscured by WebContents @@ -629,7 +667,7 @@ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) return; Integer dividerColor = CustomTabNavigationBarController.getDividerColor( mActivity, mNavigationBarColor, mNavigationBarDividerColor, needsDarkButtons); - if (mNavbarHeight == 0) { + if (shouldShowSystemNavbar()) { if (dividerColor != null) { mActivity.getWindow().setNavigationBarDividerColor(dividerColor); } @@ -692,7 +730,7 @@ return displayMetrics.heightPixels; } - private @Px int getFullyExpandedYCoordinate() { + private @Px int getStatusBarHeight() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { return mActivity.getWindowManager() .getCurrentWindowMetrics() @@ -710,6 +748,10 @@ return statusBarHeight; } + private @Px int getFullyExpandedYCoordinate() { + return getStatusBarHeight(); + } + private @Px int getFullyExpandedYCoordinateWithAdjustment() { // Adding |mFullyExpandedAdjustmentHeight| to the y coordinate because the // coordinates system's origin is at the top left and y is growing in downward, larger y @@ -723,16 +765,36 @@ return true; } + @Override + public void handleCloseAnimation(Runnable finishRunnable) { + if (mFinishRunnable != null) return; + + mFinishRunnable = finishRunnable; + + int start = mActivity.getWindow().getAttributes().y; + int end = getDisplayHeight() - mNavbarHeight; + mInitialHeight = 0; + + if (mOrientation == Configuration.ORIENTATION_LANDSCAPE) { + mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + mAnimator.setDuration( + mActivity.getResources().getInteger(android.R.integer.config_mediumAnimTime)); + mAnimator.setIntValues(start, end); + mAnimator.start(); + } + @VisibleForTesting void setMockViewForTesting(LinearLayout navbar, ImageView spinnerView, - CircularProgressDrawable spinner, View toolbar, View toolbarCoordinator, - ViewGroup coordinatorLayout) { + CircularProgressDrawable spinner, View toolbar, View toolbarCoordinator) { mNavbar = navbar; mSpinnerView = spinnerView; mSpinner = spinner; mToolbarView = toolbar; mToolbarCoordinator = toolbarCoordinator; - mCoordinatorLayout = coordinatorLayout; + + mPositionUpdater = this::updatePosition; + onPostInflationStartup(); } @VisibleForTesting
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorCoordinator.java index eaf5a13..2c73dfd0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorCoordinator.java
@@ -11,6 +11,7 @@ import androidx.annotation.ColorInt; import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; import org.chromium.base.Callback; import org.chromium.base.supplier.Supplier; @@ -205,4 +206,9 @@ mResourceManager.getDynamicResourceLoader().unregisterResource(mResourceId); mResourceRegistered = false; } + + @VisibleForTesting + StatusIndicatorMediator getMediatorForTesting() { + return mMediator; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorMediator.java index 944f0a4..0c2e6a57 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorMediator.java
@@ -442,4 +442,20 @@ void updateVisibilityForTesting(boolean hiding) { updateVisibility(hiding); } -} + + @VisibleForTesting + void finishAnimationsForTesting() { + if (mStatusBarAnimation != null && mStatusBarAnimation.isRunning()) { + mStatusBarAnimation.end(); + } + if (mTextFadeInAnimation != null && mTextFadeInAnimation.isRunning()) { + mTextFadeInAnimation.end(); + } + if (mUpdateAnimatorSet != null && mUpdateAnimatorSet.isRunning()) { + mUpdateAnimatorSet.end(); + } + if (mHideAnimatorSet != null && mHideAnimatorSet.isRunning()) { + mHideAnimatorSet.end(); + } + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java index 919652f..caa3d27 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
@@ -134,6 +134,7 @@ * A {@link RootUiCoordinator} variant that controls tabbed-mode specific UI. */ public class TabbedRootUiCoordinator extends RootUiCoordinator { + private static boolean sDisableStatusIndicatorAnimations; private final RootUiTabObserver mRootUiTabObserver; private TabbedSystemUiCoordinator mSystemUiCoordinator; private @Nullable EmptyBackgroundViewWrapper mEmptyBackgroundViewWrapper; @@ -765,7 +766,8 @@ @Override public void onStatusIndicatorHeightChanged(int indicatorHeight) { mStatusIndicatorHeight = indicatorHeight; - updateTopControlsHeight(/*animate=*/true); + boolean animate = sDisableStatusIndicatorAnimations ? false : true; + updateTopControlsHeight(animate); } }; mStatusIndicatorCoordinator.addObserver(mStatusIndicatorObserver); @@ -933,4 +935,9 @@ } return LanguageAskPrompt.maybeShowLanguageAskPrompt(mActivity, mModalDialogManagerSupplier); } + + @VisibleForTesting + public static void setDisableStatusIndicatorAnimationsForTesting(boolean disable) { + sDisableStatusIndicatorAnimations = disable; + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java index 02660e6..09269e3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java
@@ -1388,7 +1388,7 @@ */ protected void expandPanelAndAssert() throws TimeoutException { TestThreadUtils.runOnUiThreadBlocking(() -> { - mManager.setVisibilityStateForTesting(true); + mPanel.notifyBarTouched(0); mFakeServer.getContentsObserver().wasShown(); mPanel.animatePanelToState(PanelState.EXPANDED, StateChangeReason.UNKNOWN, PANEL_INTERACTION_RETRY_DELAY_MS);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSystemTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSystemTest.java index 53ad5c2..3de909c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSystemTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSystemTest.java
@@ -155,7 +155,8 @@ @SmallTest @Feature({"ContextualSearch"}) @ParameterAnnotations.UseMethodParameter(FeatureParamProvider.class) - @FlakyTest(message = "Disabled 4/2021. https://crbug.com/1192285, /https://crbug.com/1192561") + // Revived 6/2022 based on reviver: https://crbug.com/1333277 + // Previously disabled: https://crbug.com/1192285, https://crbug.com/1192561 public void testContextualSearchNotDismissedOnBackgroundTabCrash( @EnabledFeature int enabledFeature) throws Exception { ChromeTabUtils.newTabFromMenu(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUnbatchedTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUnbatchedTest.java index 53b88bbf..a455e8f1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUnbatchedTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUnbatchedTest.java
@@ -18,9 +18,7 @@ import org.chromium.base.test.params.ParameterAnnotations; import org.chromium.base.test.params.ParameterizedRunner; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.RelatedSearchesControl; import org.chromium.chrome.browser.contextualsearch.ContextualSearchFakeServer.FakeResolveSearch; @@ -228,8 +226,7 @@ Assert.assertTrue("Related Searches results should have been returned but were not!", !resolvedSearchTerm.relatedSearchesJson().isEmpty()); // Expand the panel and assert that it ends up in the right place. - // TODO(crbug.com/1258165): switch to expandPanelAndAssert(); - tapPeekingBarToExpandAndAssert(); + expandPanelAndAssert(); // Don't select any Related Searches suggestion, and close the panel closePanel(); @@ -239,8 +236,6 @@ @Test @SmallTest @Feature({"ContextualSearch"}) - @FlakyTest(message = "https://crbug.com/1182040") - @DisableIf.Build(supported_abis_includes = "arm64-v8a", message = "crbug.com/1240342") public void testRelatedSearchesItemSelected() throws Exception { FeatureList.setTestFeatures(ENABLE_RELATED_SEARCHES_IN_BAR); mFakeServer.reset();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorTest.java index a29c145..6deaf21 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorTest.java
@@ -25,6 +25,7 @@ import org.hamcrest.Matcher; import org.hamcrest.Matchers; import org.hamcrest.TypeSafeMatcher; +import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -73,6 +74,7 @@ @Before public void setUp() throws InterruptedException { + TabbedRootUiCoordinator.setDisableStatusIndicatorAnimationsForTesting(true); mActivityTestRule.startMainActivityOnBlankPage(); mStatusIndicatorCoordinator = ((TabbedRootUiCoordinator) mActivityTestRule.getActivity() .getRootUiCoordinatorForTesting()) @@ -82,6 +84,11 @@ mBrowserControlsStateProvider = mActivityTestRule.getActivity().getBrowserControlsManager(); } + @After + public void tearDown() { + TabbedRootUiCoordinator.setDisableStatusIndicatorAnimationsForTesting(false); + } + @Test @MediumTest public void testInitialState() { @@ -106,9 +113,6 @@ "Status", null, Color.BLACK, Color.WHITE, Color.WHITE)); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - // TODO(sinansahin): Investigate setting the duration for the browser controls animations to - // 0 for testing. - // Wait until the status indicator finishes animating, or becomes fully visible. CriteriaHelper.pollUiThread(() -> { Criteria.checkThat(mBrowserControlsStateProvider.getTopControlsMinHeightOffset(), @@ -202,7 +206,7 @@ @CommandLineFlags.Add({"enable-features=" + ChromeFeatureList.START_SURFACE_ANDROID + "<Study", "force-fieldtrials=Study/Group", "force-fieldtrial-params=Study.Group:start_surface_variation/single"}) - @DisabledTest(message = "https://crbug.com/1109965") + @DisabledTest(message = "https://crbug.com/1331065") public void testShowAndHideOnStartSurface() { // clang-format on TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity()); @@ -215,8 +219,10 @@ Assert.assertFalse("Wrong initial composited view visibility.", mStatusIndicatorSceneLayer.isSceneOverlayTreeShowing()); - TestThreadUtils.runOnUiThreadBlocking(() -> mStatusIndicatorCoordinator.show( - "Status", null, Color.BLACK, Color.WHITE, Color.WHITE)); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mStatusIndicatorCoordinator.show("Status", null, Color.BLACK, Color.WHITE, Color.WHITE); + mStatusIndicatorCoordinator.getMediatorForTesting().finishAnimationsForTesting(); + }); // The status indicator will be immediately visible. onView(withId(R.id.status_indicator)).check(matches(withEffectiveVisibility(VISIBLE))); @@ -232,9 +238,11 @@ .check(matches( withTopMargin(mBrowserControlsStateProvider.getTopControlsHeight()))); - TestThreadUtils.runOnUiThreadBlocking( - () -> mStatusIndicatorCoordinator.updateContent("Exit status", null, - Color.WHITE, Color.BLACK, Color.BLACK, () -> {})); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mStatusIndicatorCoordinator.updateContent( + "Exit status", null, Color.WHITE, Color.BLACK, Color.BLACK, () -> {}); + mStatusIndicatorCoordinator.getMediatorForTesting().finishAnimationsForTesting(); + }); // #updateContent shouldn't change the layout. onView(withId(R.id.status_indicator)).check(matches(withEffectiveVisibility(VISIBLE))); @@ -244,7 +252,16 @@ .check(matches( withTopMargin(mBrowserControlsStateProvider.getTopControlsHeight()))); - TestThreadUtils.runOnUiThreadBlocking(() -> mStatusIndicatorCoordinator.hide()); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mStatusIndicatorCoordinator.hide(); + mStatusIndicatorCoordinator.getMediatorForTesting().finishAnimationsForTesting(); + }); + + // Wait until the status indicator finishes animating, or becomes fully hidden. + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat( + mBrowserControlsStateProvider.getTopControlsMinHeightOffset(), Matchers.is(0)); + }); onView(withId(R.id.status_indicator)).check(matches(withEffectiveVisibility(GONE))); onView(withId(R.id.control_container)).check(matches(withTopMargin(0))); @@ -255,7 +272,6 @@ @Test @MediumTest - @DisabledTest(message = "https://crbug.com/1109965") public void testShowAndHideOnNTP() { mActivityTestRule.loadUrl(UrlConstants.NTP_URL); Tab tab = mActivityTestRule.getActivity().getActivityTab(); @@ -272,8 +288,16 @@ Assert.assertFalse("Wrong initial composited view visibility.", mStatusIndicatorSceneLayer.isSceneOverlayTreeShowing()); - TestThreadUtils.runOnUiThreadBlocking(() -> mStatusIndicatorCoordinator.show( - "Status", null, Color.BLACK, Color.WHITE, Color.WHITE)); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mStatusIndicatorCoordinator.show("Status", null, Color.BLACK, Color.WHITE, Color.WHITE); + mStatusIndicatorCoordinator.getMediatorForTesting().finishAnimationsForTesting(); + }); + + // Wait until the status indicator finishes animating. + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat(mBrowserControlsStateProvider.getTopControlsMinHeightOffset(), + Matchers.is(getStatusIndicator().getHeight())); + }); // The status indicator will be immediately visible. onView(withId(R.id.status_indicator)).check(matches(withEffectiveVisibility(VISIBLE))); @@ -281,9 +305,11 @@ .check(matches(withTopMargin(getStatusIndicator().getHeight()))); onView(withId(viewId)).check(matches(withTopMargin(getStatusIndicator().getHeight()))); - TestThreadUtils.runOnUiThreadBlocking( - () -> mStatusIndicatorCoordinator.updateContent("Exit status", null, - Color.WHITE, Color.BLACK, Color.BLACK, () -> {})); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mStatusIndicatorCoordinator.updateContent( + "Exit status", null, Color.WHITE, Color.BLACK, Color.BLACK, () -> {}); + mStatusIndicatorCoordinator.getMediatorForTesting().finishAnimationsForTesting(); + }); // #updateContent shouldn't change the layout. onView(withId(R.id.status_indicator)).check(matches(withEffectiveVisibility(VISIBLE))); @@ -291,7 +317,16 @@ .check(matches(withTopMargin(getStatusIndicator().getHeight()))); onView(withId(viewId)).check(matches(withTopMargin(getStatusIndicator().getHeight()))); - TestThreadUtils.runOnUiThreadBlocking(() -> mStatusIndicatorCoordinator.hide()); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mStatusIndicatorCoordinator.hide(); + mStatusIndicatorCoordinator.getMediatorForTesting().finishAnimationsForTesting(); + }); + + // Wait until the status indicator finishes animating, or becomes fully hidden. + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat( + mBrowserControlsStateProvider.getTopControlsMinHeightOffset(), Matchers.is(0)); + }); onView(withId(R.id.status_indicator)).check(matches(withEffectiveVisibility(GONE))); onView(withId(R.id.control_container)).check(matches(withTopMargin(0))); @@ -300,7 +335,6 @@ @Test @MediumTest - @DisabledTest(message = "https://crbug.com/1109965") public void testShowAndHideOnRecentTabsPage() { mActivityTestRule.loadUrl(UrlConstants.RECENT_TABS_URL); final Tab tab = mActivityTestRule.getActivity().getActivityTab(); @@ -314,11 +348,17 @@ .check(matches( withTopMargin(mBrowserControlsStateProvider.getTopControlsHeight()))); - TestThreadUtils.runOnUiThreadBlocking( - () -> mStatusIndicatorCoordinator.show( - "Status", null, Color.BLACK, Color.WHITE, Color.WHITE)); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mStatusIndicatorCoordinator.show("Status", null, Color.BLACK, Color.WHITE, Color.WHITE); + mStatusIndicatorCoordinator.getMediatorForTesting().finishAnimationsForTesting(); + }); - // The status indicator will be immediately visible. + // Wait until the status indicator finishes animating. + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat(mBrowserControlsStateProvider.getTopControlsMinHeightOffset(), + Matchers.is(getStatusIndicator().getHeight())); + }); + onView(withId(R.id.status_indicator)).check(matches(withEffectiveVisibility(VISIBLE))); onView(withId(R.id.control_container)) .check(matches(withTopMargin(getStatusIndicator().getHeight()))); @@ -326,9 +366,11 @@ .check(matches( withTopMargin(mBrowserControlsStateProvider.getTopControlsHeight()))); - TestThreadUtils.runOnUiThreadBlocking( - () -> mStatusIndicatorCoordinator.updateContent("Exit status", null, - Color.WHITE, Color.BLACK, Color.BLACK, () -> {})); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mStatusIndicatorCoordinator.updateContent( + "Exit status", null, Color.WHITE, Color.BLACK, Color.BLACK, () -> {}); + mStatusIndicatorCoordinator.getMediatorForTesting().finishAnimationsForTesting(); + }); // #updateContent shouldn't change the layout. onView(withId(R.id.status_indicator)).check(matches(withEffectiveVisibility(VISIBLE))); @@ -338,7 +380,16 @@ .check(matches( withTopMargin(mBrowserControlsStateProvider.getTopControlsHeight()))); - TestThreadUtils.runOnUiThreadBlocking(() -> mStatusIndicatorCoordinator.hide()); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mStatusIndicatorCoordinator.hide(); + mStatusIndicatorCoordinator.getMediatorForTesting().finishAnimationsForTesting(); + }); + + // Wait until the status indicator finishes animating, or becomes fully hidden. + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat( + mBrowserControlsStateProvider.getTopControlsMinHeightOffset(), Matchers.is(0)); + }); onView(withId(R.id.status_indicator)).check(matches(withEffectiveVisibility(GONE))); onView(withId(R.id.control_container)).check(matches(withTopMargin(0)));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupUnitTest.java index f8abd7f8..119b326 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupUnitTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupUnitTest.java
@@ -43,6 +43,7 @@ import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.UiThreadTest; import org.chromium.base.test.util.Batch; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.browser.native_page.ContextMenuManager; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; @@ -201,6 +202,7 @@ @Test @UiThreadTest @SmallTest + @DisabledTest(message = "https://crbug.com/1330627, https://crbug.com/1293208") public void testReceiveNewTilesWithDataChanges_TrackLoad() { TileGroup tileGroup = initialiseTileGroup(/* deferLoad: */ true, URLS); @@ -294,6 +296,7 @@ @Test @UiThreadTest @SmallTest + @DisabledTest(message = "https://crbug.com/1330627, https://crbug.com/1293208") public void testRenderTileView() { SuggestionsUiDelegate uiDelegate = mSuggestionsUiDelegate; when(uiDelegate.getImageFetcher()).thenReturn(mImageFetcher); @@ -390,6 +393,7 @@ @Test @UiThreadTest @SmallTest + @DisabledTest(message = "https://crbug.com/1330627, https://crbug.com/1293208") public void testIconLoadingForInit() { TileGroup tileGroup = initialiseTileGroup(URLS); Tile tile = tileGroup.getTileSections().get(TileSectionType.PERSONALIZED).get(0); @@ -426,6 +430,7 @@ @Test @UiThreadTest @SmallTest + @DisabledTest(message = "https://crbug.com/1330627, https://crbug.com/1293208") public void testIconLoading_Sync() { TileGroup tileGroup = initialiseTileGroup(); mImageFetcher.fulfillLargeIconRequests(); @@ -445,6 +450,7 @@ @Test @UiThreadTest @SmallTest + @DisabledTest(message = "https://crbug.com/1330627, https://crbug.com/1293208") public void testIconLoading_AsyncNoTrack() { TileGroup tileGroup = initialiseTileGroup(/* deferLoad: */ true); mImageFetcher.fulfillLargeIconRequests(); @@ -465,6 +471,7 @@ @Test @UiThreadTest @SmallTest + @DisabledTest(message = "https://crbug.com/1330627, https://crbug.com/1293208") public void testIconLoading_AsyncTrack() { TileGroup tileGroup = initialiseTileGroup(/* deferLoad: */ true); mImageFetcher.fulfillLargeIconRequests();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategyTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategyTest.java index 5d6b065..fd4450c 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategyTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategyTest.java
@@ -20,7 +20,6 @@ import android.app.Activity; import android.content.res.Configuration; import android.content.res.Resources; -import android.graphics.Point; import android.os.Looper; import android.os.SystemClock; import android.util.DisplayMetrics; @@ -51,7 +50,6 @@ import org.robolectric.shadows.ShadowLog; import org.chromium.base.Callback; -import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -119,15 +117,12 @@ @Mock private View mToolbarCoordinator; @Mock - private FrameLayout mParentView; + private ViewGroup mContentFrame; @Mock private ViewGroup mCoordinatorLayout; private List<WindowManager.LayoutParams> mAttributeResults; private DisplayMetrics mRealMetrics; - private Point mDisplaySize; - private ObservableSupplierImpl<FrameLayout> mParentViewSupplier = - new ObservableSupplierImpl<>(); private Callback<Integer> mBottomInsetCallback = inset -> {}; private FrameLayout.LayoutParams mLayoutParams = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); @@ -141,6 +136,8 @@ when(mActivity.getWindowManager()).thenReturn(mWindowManager); when(mActivity.findViewById(R.id.custom_tabs_handle_view_stub)).thenReturn(mHandleViewStub); when(mActivity.findViewById(R.id.custom_tabs_handle_view)).thenReturn(mHandleView); + when(mActivity.findViewById(R.id.coordinator)).thenReturn(mCoordinatorLayout); + when(mActivity.findViewById(android.R.id.content)).thenReturn(mContentFrame); when(mHandleView.getLayoutParams()).thenReturn(mLayoutParams); when(mToolbarCoordinator.getLayoutParams()).thenReturn(mLayoutParams); mAttributes = new WindowManager.LayoutParams(); @@ -156,14 +153,12 @@ when(mViewAnimator.setDuration(anyLong())).thenReturn(mViewAnimator); when(mViewAnimator.setListener(anyObject())).thenReturn(mViewAnimator); when(mSpinnerView.getLayoutParams()).thenReturn(mLayoutParams); - when(mSpinnerView.getParent()).thenReturn(mParentView); + when(mSpinnerView.getParent()).thenReturn(mContentFrame); when(mSpinnerView.animate()).thenReturn(mViewAnimator); - when(mParentView.getLayoutParams()).thenReturn(mLayoutParams); - when(mParentView.getParent()).thenReturn(mCoordinatorLayout); + when(mContentFrame.getLayoutParams()).thenReturn(mLayoutParams); + when(mContentFrame.getHeight()).thenReturn(DEVICE_HEIGHT - NAVBAR_HEIGHT); when(mCoordinatorLayout.getLayoutParams()).thenReturn(mLayoutParams); - mParentViewSupplier.set(mParentView); - mConfiguration.orientation = Configuration.ORIENTATION_PORTRAIT; mAttributeResults = new ArrayList<>(); @@ -186,26 +181,20 @@ }) .when(mDisplay) .getRealMetrics(any(DisplayMetrics.class)); + } - mDisplaySize = new Point(); - mDisplaySize.x = DEVICE_WIDTH; - mDisplaySize.y = DEVICE_HEIGHT - NAVBAR_HEIGHT; - doAnswer(invocation -> { - Point point = invocation.getArgument(0); - point.x = mDisplaySize.x; - point.y = mDisplaySize.y; - return null; - }) - .when(mDisplay) - .getSize(any(Point.class)); + private PartialCustomTabHeightStrategy createPcctAtHeight(int heightPx) { + PartialCustomTabHeightStrategy pcct = new PartialCustomTabHeightStrategy(mActivity, + heightPx, mMultiWindowModeStateDispatcher, null, null, mOnResizedCallback, + mActivityLifecycleDispatcher); + pcct.setMockViewForTesting( + mNavbar, mSpinnerView, mSpinner, mToolbarView, mToolbarCoordinator); + return pcct; } @Test public void create_heightIsCappedToHalfOfDeviceHeight() { - new PartialCustomTabHeightStrategy(mActivity, mParentViewSupplier, 500, - mMultiWindowModeStateDispatcher, null, null, mOnResizedCallback, - mActivityLifecycleDispatcher); - + createPcctAtHeight(500); verifyWindowFlagsSet(); assertEquals(1, mAttributeResults.size()); @@ -214,10 +203,7 @@ @Test public void create_largeInitialHeight() { - new PartialCustomTabHeightStrategy(mActivity, mParentViewSupplier, 5000, - mMultiWindowModeStateDispatcher, null, null, mOnResizedCallback, - mActivityLifecycleDispatcher); - + createPcctAtHeight(5000); verifyWindowFlagsSet(); assertEquals(1, mAttributeResults.size()); @@ -226,10 +212,7 @@ @Test public void create_heightIsCappedToDeviceHeight() { - new PartialCustomTabHeightStrategy(mActivity, mParentViewSupplier, DEVICE_HEIGHT + 100, - mMultiWindowModeStateDispatcher, null, null, mOnResizedCallback, - mActivityLifecycleDispatcher); - + createPcctAtHeight(DEVICE_HEIGHT + 100); verifyWindowFlagsSet(); assertEquals(1, mAttributeResults.size()); @@ -241,12 +224,8 @@ mConfiguration.orientation = Configuration.ORIENTATION_LANDSCAPE; mRealMetrics.widthPixels = DEVICE_HEIGHT; mRealMetrics.heightPixels = DEVICE_WIDTH; - mDisplaySize.x = DEVICE_HEIGHT - NAVBAR_HEIGHT; - mDisplaySize.y = DEVICE_WIDTH; - new PartialCustomTabHeightStrategy(mActivity, mParentViewSupplier, 800, - mMultiWindowModeStateDispatcher, null, null, mOnResizedCallback, - mActivityLifecycleDispatcher); - + when(mContentFrame.getHeight()).thenReturn(DEVICE_WIDTH); + createPcctAtHeight(800); verifyWindowFlagsSet(); // Full height when in landscape mode. @@ -256,12 +235,7 @@ @Test public void moveUp() { - PartialCustomTabHeightStrategy strategy = new PartialCustomTabHeightStrategy(mActivity, - mParentViewSupplier, 500, mMultiWindowModeStateDispatcher, null, null, - mOnResizedCallback, mActivityLifecycleDispatcher); - strategy.setMockViewForTesting(mNavbar, mSpinnerView, mSpinner, mToolbarView, - mToolbarCoordinator, mCoordinatorLayout); - + PartialCustomTabHeightStrategy strategy = createPcctAtHeight(500); verifyWindowFlagsSet(); assertEquals(1, mAttributeResults.size()); @@ -299,9 +273,7 @@ mConfiguration.orientation = Configuration.ORIENTATION_LANDSCAPE; mRealMetrics.widthPixels = DEVICE_HEIGHT; mRealMetrics.heightPixels = DEVICE_WIDTH; - PartialCustomTabHeightStrategy strategy = new PartialCustomTabHeightStrategy(mActivity, - mParentViewSupplier, 800, mMultiWindowModeStateDispatcher, null, null, - mOnResizedCallback, mActivityLifecycleDispatcher); + PartialCustomTabHeightStrategy strategy = createPcctAtHeight(800); // Pass null because we have a mock Activity and we don't depend on the GestureDetector // inside as we test MotionEvents directly. @@ -317,9 +289,7 @@ @Test public void moveUp_multiwindowModeUnresizable() { when(mMultiWindowModeStateDispatcher.isInMultiWindowMode()).thenReturn(true); - PartialCustomTabHeightStrategy strategy = new PartialCustomTabHeightStrategy(mActivity, - mParentViewSupplier, 800, mMultiWindowModeStateDispatcher, null, null, - mOnResizedCallback, mActivityLifecycleDispatcher); + PartialCustomTabHeightStrategy strategy = createPcctAtHeight(800); // Pass null because we have a mock Activity and we don't depend on the GestureDetector // inside as we test MotionEvents directly. @@ -334,11 +304,7 @@ @Test public void rotateToLandescapeUnresizable() { - PartialCustomTabHeightStrategy strategy = new PartialCustomTabHeightStrategy(mActivity, - mParentViewSupplier, 800, mMultiWindowModeStateDispatcher, null, null, - mOnResizedCallback, mActivityLifecycleDispatcher); - strategy.setMockViewForTesting(mNavbar, mSpinnerView, mSpinner, mToolbarView, - mToolbarCoordinator, mCoordinatorLayout); + PartialCustomTabHeightStrategy strategy = createPcctAtHeight(800); // Pass null because we have a mock Activity and we don't depend on the GestureDetector // inside as we test MotionEvents directly. @@ -356,17 +322,12 @@ @Test public void rotateToLandescapeHideCustomNavbar() { - PartialCustomTabHeightStrategy strategy = new PartialCustomTabHeightStrategy(mActivity, - mParentViewSupplier, 800, mMultiWindowModeStateDispatcher, null, null, - mOnResizedCallback, mActivityLifecycleDispatcher); - strategy.setMockViewForTesting(mNavbar, mSpinnerView, mSpinner, mToolbarView, - mToolbarCoordinator, mCoordinatorLayout); + PartialCustomTabHeightStrategy strategy = createPcctAtHeight(800); mConfiguration.orientation = Configuration.ORIENTATION_LANDSCAPE; mRealMetrics.widthPixels = DEVICE_HEIGHT; mRealMetrics.heightPixels = DEVICE_WIDTH; - mDisplaySize.x = DEVICE_HEIGHT - NAVBAR_HEIGHT; - mDisplaySize.y = DEVICE_WIDTH; + when(mContentFrame.getHeight()).thenReturn(DEVICE_WIDTH); strategy.onConfigurationChanged(mConfiguration); @@ -376,9 +337,7 @@ @Test public void enterMultiwindowModeUnresizable() { - PartialCustomTabHeightStrategy strategy = new PartialCustomTabHeightStrategy(mActivity, - mParentViewSupplier, 800, mMultiWindowModeStateDispatcher, null, null, - mOnResizedCallback, mActivityLifecycleDispatcher); + PartialCustomTabHeightStrategy strategy = createPcctAtHeight(800); // Pass null because we have a mock Activity and we don't depend on the GestureDetector // inside as we test MotionEvents directly. @@ -395,11 +354,7 @@ @Test public void moveUpThenDown() { - PartialCustomTabHeightStrategy strategy = new PartialCustomTabHeightStrategy(mActivity, - mParentViewSupplier, 500, mMultiWindowModeStateDispatcher, null, null, - mOnResizedCallback, mActivityLifecycleDispatcher); - strategy.setMockViewForTesting(mNavbar, mSpinnerView, mSpinner, mToolbarView, - mToolbarCoordinator, mCoordinatorLayout); + PartialCustomTabHeightStrategy strategy = createPcctAtHeight(500); verify(mWindow).addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); verify(mWindow).clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); @@ -436,11 +391,7 @@ @Test public void moveToTopThenMoveDown() { - PartialCustomTabHeightStrategy strategy = new PartialCustomTabHeightStrategy(mActivity, - mParentViewSupplier, 500, mMultiWindowModeStateDispatcher, null, null, - mOnResizedCallback, mActivityLifecycleDispatcher); - strategy.setMockViewForTesting(mNavbar, mSpinnerView, mSpinner, mToolbarView, - mToolbarCoordinator, mCoordinatorLayout); + PartialCustomTabHeightStrategy strategy = createPcctAtHeight(500); verify(mWindow).addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); verify(mWindow).clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); @@ -499,12 +450,7 @@ @Test public void moveDownToDismiss() { - PartialCustomTabHeightStrategy strategy = new PartialCustomTabHeightStrategy(mActivity, - mParentViewSupplier, 500, mMultiWindowModeStateDispatcher, null, null, - mOnResizedCallback, mActivityLifecycleDispatcher); - strategy.setMockViewForTesting(mNavbar, mSpinnerView, mSpinner, mToolbarView, - mToolbarCoordinator, mCoordinatorLayout); - + PartialCustomTabHeightStrategy strategy = createPcctAtHeight(500); verifyWindowFlagsSet(); assertEquals(1, mAttributeResults.size());
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index 980f8730..97fabc4 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc
@@ -109,6 +109,7 @@ #if BUILDFLAG(IS_MAC) #include "base/mac/foundation_util.h" +#include "base/message_loop/message_pump_mac.h" #include "chrome/app/chrome_main_mac.h" #include "chrome/browser/chrome_browser_application_mac.h" #include "chrome/browser/mac/relauncher.h" @@ -794,6 +795,7 @@ base::sequence_manager::internal::SequenceManagerImpl::InitializeFeatures(); #if BUILDFLAG(IS_MAC) base::PlatformThread::InitializeOptimizedRealtimeThreadingFeature(); + base::MessagePumpCFRunLoopBase::InitializeFeatures(); #endif }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 31f4dd7c..b135144 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1883,6 +1883,9 @@ "//chrome/browser/devtools", "//chrome/browser/favicon", "//chrome/browser/profiling_host", + + # TODO(crbug.com/1335199): break this dep when favicon is in its own target + "//chrome/browser/share", "//chrome/browser/ui", "//chrome/browser/ui/webui/bluetooth_internals", "//chrome/browser/storage_access_api:permissions", @@ -3418,8 +3421,6 @@ "//url:origin_android", ] - allow_circular_includes_from += [ "//chrome/browser/share" ] - deps -= [ "//components/storage_monitor" ] if (enable_supervised_users) {
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 7f19cec..89ad5d4 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3521,6 +3521,9 @@ flag_descriptions::kAshEnableUnifiedDesktopName, flag_descriptions::kAshEnableUnifiedDesktopDescription, kOsCrOS, SINGLE_VALUE_TYPE(switches::kEnableUnifiedDesktop)}, + {"rounded-display", flag_descriptions::kRoundedDisplay, + flag_descriptions::kRoundedDisplayDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kRoundedDisplay)}, {"bluetooth-fix-a2dp-packet-size", flag_descriptions::kBluetoothFixA2dpPacketSizeName, flag_descriptions::kBluetoothFixA2dpPacketSizeDescription, kOsCrOS,
diff --git a/chrome/browser/app_controller_mac_browsertest.mm b/chrome/browser/app_controller_mac_browsertest.mm index 77cef98..b44a9a95a1 100644 --- a/chrome/browser/app_controller_mac_browsertest.mm +++ b/chrome/browser/app_controller_mac_browsertest.mm
@@ -1234,7 +1234,7 @@ content::TestActivationManager navigation_manager(GetActiveWebContents(), prerender_url); ASSERT_TRUE( - content::ExecJs(GetActiveWebContents()->GetMainFrame(), + content::ExecJs(GetActiveWebContents()->GetPrimaryMainFrame(), content::JsReplace("location = $1", prerender_url))); navigation_manager.WaitForNavigationFinished(); EXPECT_TRUE(navigation_manager.was_activated());
diff --git a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.cc b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.cc index 0d2988c..e986093 100644 --- a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.cc +++ b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.cc
@@ -224,10 +224,15 @@ } void ArcInputOverlayManager::RegisterWindow(aura::Window* window) { + // Only register the focused window that is not registered. if (!window || window != window->GetToplevelWindow() || registered_top_level_window_ == window) { return; } + DCHECK_EQ(ash::window_util::GetFocusedWindow()->GetToplevelWindow(), window); + if (ash::window_util::GetFocusedWindow()->GetToplevelWindow() != window) + return; + auto it = input_overlay_enabled_windows_.find(window); if (it == input_overlay_enabled_windows_.end()) return; @@ -327,8 +332,10 @@ } void ArcInputOverlayManager::OnWindowAddedToRootWindow(aura::Window* window) { - if (!window) + if (!window || + ash::window_util::GetFocusedWindow()->GetToplevelWindow() != window) { return; + } RegisterWindow(window); }
diff --git a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager_unittest.cc b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager_unittest.cc index 9f501641..62d7bbb 100644 --- a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager_unittest.cc +++ b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager_unittest.cc
@@ -6,6 +6,7 @@ #include "ash/shell.h" #include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h" +#include "ash/wm/window_util.h" #include "chrome/browser/ash/arc/input_overlay/test/arc_test_window.h" #include "chrome/browser/ash/arc/input_overlay/test/event_capturer.h" #include "components/exo/test/exo_test_base.h" @@ -75,10 +76,6 @@ return arc_test_input_overlay_manager_->display_overlay_controller_.get(); } - void WindowFocus(aura::Window* gain_focus, aura::Window* lost_focus) { - arc_test_input_overlay_manager_->OnWindowFocused(gain_focus, lost_focus); - } - // TODO(djacobo): Maybe move all tests inside input_overlay namespace. void DismissEducationalDialog(input_overlay::TouchInjector* injector) { injector->GetControllerForTesting()->DismissEducationalViewForTesting(); @@ -104,6 +101,8 @@ }; TEST_F(ArcInputOverlayManagerTest, TestPropertyChangeAndWindowDestroy) { + aura::client::FocusClient* focus_client = + aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); // Test app with input overlay data. auto arc_window = std::make_unique<input_overlay::test::ArcTestWindow>( exo_test_helper(), ash::Shell::GetPrimaryRootWindow(), @@ -114,7 +113,7 @@ // Input overlay registers the window after reading the data when the window // is still focused. In the test, the arc_window is considered as focused now. EXPECT_TRUE(GetRegisteredWindow()); - WindowFocus(arc_window->GetWindow(), nullptr); + focus_client->FocusWindow(arc_window->GetWindow()); EXPECT_TRUE(GetRegisteredWindow()); // Test app with input overlay data when window is destroyed. @@ -133,12 +132,14 @@ TEST_F(ArcInputOverlayManagerTest, TestInputMethodObsever) { ASSERT_FALSE(GetInputMethod()); ASSERT_FALSE(IsTextInputActive()); + aura::client::FocusClient* focus_client = + aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); auto arc_window = std::make_unique<input_overlay::test::ArcTestWindow>( exo_test_helper(), ash::Shell::GetPrimaryRootWindow(), kEnabledPackageName); // I/O takes time here. task_environment()->FastForwardBy(kIORead); - WindowFocus(arc_window->GetWindow(), nullptr); + focus_client->FocusWindow(arc_window->GetWindow()); ui::InputMethod* input_method = GetInputMethod(); EXPECT_TRUE(GetInputMethod()); input_method->SetFocusedTextInputClient(nullptr); @@ -154,6 +155,8 @@ } TEST_F(ArcInputOverlayManagerTest, TestWindowFocusChange) { + aura::client::FocusClient* focus_client = + aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); auto arc_window = std::make_unique<input_overlay::test::ArcTestWindow>( exo_test_helper(), ash::Shell::GetPrimaryRootWindow(), kEnabledPackageName); @@ -172,10 +175,10 @@ EXPECT_EQ(3, (int)injector->actions().size()); EXPECT_TRUE(!GetRegisteredWindow() && !GetDisplayOverlayController()); - WindowFocus(arc_window->GetWindow(), nullptr); + focus_client->FocusWindow(arc_window->GetWindow()); EXPECT_EQ(arc_window->GetWindow(), GetRegisteredWindow()); EXPECT_TRUE(GetDisplayOverlayController()); - WindowFocus(arc_window_no_data->GetWindow(), arc_window->GetWindow()); + focus_client->FocusWindow(arc_window_no_data->GetWindow()); EXPECT_TRUE(!GetRegisteredWindow() && !GetDisplayOverlayController()); } @@ -207,6 +210,8 @@ } TEST_F(ArcInputOverlayManagerTest, TestKeyEventSourceRewriterForMultiDisplay) { + aura::client::FocusClient* focus_client = + aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); UpdateDisplay("1000x900,1000x900"); aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); display::Display display0 = display::Screen::GetScreen()->GetDisplayMatching( @@ -226,7 +231,7 @@ // Make sure to dismiss the educational dialog in beforehand. auto* injector = GetTouchInjector(arc_window->GetWindow()); EXPECT_TRUE(injector); - WindowFocus(arc_window->GetWindow(), nullptr); + focus_client->FocusWindow(arc_window->GetWindow()); DismissEducationalDialog(injector); EXPECT_TRUE(GetKeyEventSourceRewriter()); // Simulate the fact that key events are only sent to primary root window @@ -264,7 +269,7 @@ arc_window->SetBounds(display1, gfx::Rect(10, 10, 100, 100)); EXPECT_TRUE(GetKeyEventSourceRewriter()); // When losing focus, |key_event_source_rewriter_| should be destroyed too. - WindowFocus(nullptr, arc_window->GetWindow()); + focus_client->FocusWindow(nullptr); EXPECT_FALSE(GetKeyEventSourceRewriter()); arc_window.reset(); @@ -273,7 +278,7 @@ auto arc_window_no_data = std::make_unique<input_overlay::test::ArcTestWindow>( exo_test_helper(), root_windows[1], kRandomPackageName); - WindowFocus(arc_window_no_data->GetWindow(), nullptr); + focus_client->FocusWindow(arc_window_no_data->GetWindow()); EXPECT_FALSE(GetKeyEventSourceRewriter()); arc_window_no_data.reset(); @@ -289,13 +294,13 @@ arc_window_no_data = std::make_unique<input_overlay::test::ArcTestWindow>( exo_test_helper(), root_windows[0], kRandomPackageName); // Focus on window without input overlay. - WindowFocus(arc_window_no_data->GetWindow(), nullptr); + focus_client->FocusWindow(arc_window_no_data->GetWindow()); event_generator->PressKey(ui::VKEY_A, ui::EF_NONE, 1 /* keyboard id */); event_generator->ReleaseKey(ui::VKEY_A, ui::EF_NONE, 1 /* keyboard id */); EXPECT_EQ(2u, event_capturer.key_events().size()); event_capturer.Clear(); // Focus input overlay window. - WindowFocus(arc_window->GetWindow(), arc_window_no_data->GetWindow()); + focus_client->FocusWindow(arc_window->GetWindow()); EXPECT_TRUE(GetKeyEventSourceRewriter()); event_generator->PressKey(ui::VKEY_A, ui::EF_NONE, 1 /* keyboard id */); event_generator->ReleaseKey(ui::VKEY_A, ui::EF_NONE, 1 /* keyboard id */);
diff --git a/chrome/browser/ash/dbus/ash_dbus_helper.cc b/chrome/browser/ash/dbus/ash_dbus_helper.cc index 1fe45e1..4b8f5973 100644 --- a/chrome/browser/ash/dbus/ash_dbus_helper.cc +++ b/chrome/browser/ash/dbus/ash_dbus_helper.cc
@@ -53,6 +53,7 @@ #include "chromeos/dbus/hermes/hermes_clients.h" #include "chromeos/dbus/human_presence/human_presence_dbus_client.h" #include "chromeos/dbus/init/initialize_dbus_client.h" +#include "chromeos/dbus/lorgnette_manager/lorgnette_manager_client.h" #include "chromeos/dbus/machine_learning/machine_learning_client.h" #include "chromeos/dbus/missive/missive_client.h" #include "chromeos/dbus/permission_broker/permission_broker_client.h" @@ -139,6 +140,7 @@ InitializeDBusClient<chromeos::InstallAttributesClient>(bus); InitializeDBusClient<IpPeripheralServiceClient>(bus); InitializeDBusClient<KerberosClient>(bus); + InitializeDBusClient<chromeos::LorgnetteManagerClient>(bus); InitializeDBusClient<chromeos::MachineLearningClient>(bus); InitializeDBusClient<MediaAnalyticsClient>(bus); InitializeDBusClient<chromeos::MissiveClient>(bus); @@ -238,6 +240,7 @@ chromeos::MissiveClient::Shutdown(); MediaAnalyticsClient::Shutdown(); chromeos::MachineLearningClient::Shutdown(); + chromeos::LorgnetteManagerClient::Shutdown(); KerberosClient::Shutdown(); IpPeripheralServiceClient::Shutdown(); chromeos::InstallAttributesClient::Shutdown();
diff --git a/chrome/browser/ash/events/OWNERS b/chrome/browser/ash/events/OWNERS index 3b4e32e6..637480f 100644 --- a/chrome/browser/ash/events/OWNERS +++ b/chrome/browser/ash/events/OWNERS
@@ -1,3 +1,2 @@ -sadrul@chromium.org per-file *event_rewriter* = kpschoedel@chromium.org
diff --git a/chrome/browser/ash/printing/bulk_printers_calculator.cc b/chrome/browser/ash/printing/bulk_printers_calculator.cc index 7a85e54..d077d0e 100644 --- a/chrome/browser/ash/printing/bulk_printers_calculator.cc +++ b/chrome/browser/ash/printing/bulk_printers_calculator.cc
@@ -79,14 +79,12 @@ auto parsed_printers = std::make_unique<PrinterCache>(); parsed_printers->reserve(printer_list.size()); for (const base::Value& val : printer_list) { - // TODO(skau): Convert to the new Value APIs. - const base::DictionaryValue* printer_dict; - if (!val.GetAsDictionary(&printer_dict)) { + if (!val.is_dict()) { LOG(WARNING) << "Entry in printers policy skipped. Not a dictionary."; continue; } - auto printer = chromeos::RecommendedPrinterToPrinter(*printer_dict); + auto printer = chromeos::RecommendedPrinterToPrinter(val.GetDict()); if (!printer) { LOG(WARNING) << "Failed to parse printer configuration. Skipped."; continue;
diff --git a/chrome/browser/ash/printing/enterprise_printers_provider.cc b/chrome/browser/ash/printing/enterprise_printers_provider.cc index ca0484f..32b25a5 100644 --- a/chrome/browser/ash/printing/enterprise_printers_provider.cc +++ b/chrome/browser/ash/printing/enterprise_printers_provider.cc
@@ -135,10 +135,9 @@ recommended_printers_.clear(); std::vector<std::string> data = FromPrefs(prefs::kRecommendedPrinters); for (const auto& printer_json : data) { - absl::optional<base::Value> printer_dictionary = base::JSONReader::Read( + absl::optional<base::Value> printer_value = base::JSONReader::Read( printer_json, base::JSON_ALLOW_TRAILING_COMMAS); - if (!printer_dictionary.has_value() || - !printer_dictionary.value().is_dict()) { + if (!printer_value.has_value() || !printer_value.value().is_dict()) { LOG(WARNING) << "Ignoring invalid printer. Invalid JSON object: " << printer_json; continue; @@ -148,10 +147,11 @@ // unique so we'll hash the record. This will not collide with the // UUIDs generated for user entries. std::string id = base::MD5String(printer_json); - printer_dictionary.value().SetStringKey(chromeos::kPrinterId, id); + base::Value::Dict& printer_dictionary = printer_value.value().GetDict(); + printer_dictionary.Set(chromeos::kPrinterId, id); - auto new_printer = chromeos::RecommendedPrinterToPrinter( - base::Value::AsDictionaryValue(printer_dictionary.value())); + auto new_printer = + chromeos::RecommendedPrinterToPrinter(printer_dictionary); if (!new_printer) { LOG(WARNING) << "Recommended printer is malformed."; continue;
diff --git a/chrome/browser/ash/printing/oauth2/http_exchange.cc b/chrome/browser/ash/printing/oauth2/http_exchange.cc index 640757c..e7a256c 100644 --- a/chrome/browser/ash/printing/oauth2/http_exchange.cc +++ b/chrome/browser/ash/printing/oauth2/http_exchange.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ash/printing/oauth2/http_exchange.h" #include <string> +#include <utility> #include "base/bind.h" #include "base/json/json_reader.h" @@ -42,13 +43,12 @@ HttpExchange::HttpExchange( scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) - : url_loader_factory_(url_loader_factory), - content_(base::Value::Type::DICTIONARY) {} + : url_loader_factory_(url_loader_factory) {} HttpExchange::~HttpExchange() {} void HttpExchange::Clear() { - content_ = base::Value(base::Value::Type::DICTIONARY); + content_.clear(); error_msg_.clear(); url_loader_.reset(); } @@ -56,17 +56,17 @@ void HttpExchange::AddParamString(const std::string& name, const std::string& value) { DCHECK(!name.empty()); - content_.SetStringKey(name, value); + content_.Set(name, value); } void HttpExchange::AddParamArrayString(const std::string& name, const std::vector<std::string>& value) { DCHECK(!name.empty()); - base::Value* list_node = - content_.SetKey(name, base::Value(base::Value::Type::LIST)); - for (auto& value_element : value) { - list_node->Append(value_element); + base::Value::List list_node; + for (const auto& value_element : value) { + list_node.Append(value_element); } + content_.Set(name, std::move(list_node)); } void HttpExchange::Exchange( @@ -86,7 +86,7 @@ return; } } else if (request_format == ContentFormat::kXWwwFormUrlencoded) { - for (const auto kv : content_.DictItems()) { + for (const auto kv : content_) { if (!data.empty()) { data += "&"; } @@ -221,7 +221,7 @@ std::move(callback).Run(StatusCode::kInvalidResponse); return; } - content_ = std::move(parsed.value()); + content_ = std::move(parsed->GetDict()); // Exits if success. if (http_status == success_http_status) { @@ -406,7 +406,7 @@ } base::Value* HttpExchange::FindNode(const std::string& name, bool required) { - base::Value* value = content_.FindKey(name); + base::Value* value = content_.Find(name); if (required && !value) { error_msg_ = "Field " + name + " is missing"; }
diff --git a/chrome/browser/ash/printing/oauth2/http_exchange.h b/chrome/browser/ash/printing/oauth2/http_exchange.h index 1c5bbf8..17d92e2 100644 --- a/chrome/browser/ash/printing/oauth2/http_exchange.h +++ b/chrome/browser/ash/printing/oauth2/http_exchange.h
@@ -185,7 +185,7 @@ std::unique_ptr<network::SimpleURLLoader> url_loader_; // Stores parameters for a request or parameters parsed from a response. - base::Value content_; + base::Value::Dict content_; // Error message. std::string error_msg_;
diff --git a/chrome/browser/ash/scanning/lorgnette_scanner_manager.cc b/chrome/browser/ash/scanning/lorgnette_scanner_manager.cc index 446c34c..79ce87c 100644 --- a/chrome/browser/ash/scanning/lorgnette_scanner_manager.cc +++ b/chrome/browser/ash/scanning/lorgnette_scanner_manager.cc
@@ -89,8 +89,7 @@ // Returns a pointer to LorgnetteManagerClient, which is used to detect and // interact with scanners via the lorgnette D-Bus service. chromeos::LorgnetteManagerClient* GetLorgnetteManagerClient() { - DCHECK(DBusThreadManager::IsInitialized()); - return DBusThreadManager::Get()->GetLorgnetteManagerClient(); + return chromeos::LorgnetteManagerClient::Get(); } // Creates a base name by concatenating the manufacturer and model, if the
diff --git a/chrome/browser/ash/scanning/lorgnette_scanner_manager_unittest.cc b/chrome/browser/ash/scanning/lorgnette_scanner_manager_unittest.cc index af275c53..da43179 100644 --- a/chrome/browser/ash/scanning/lorgnette_scanner_manager_unittest.cc +++ b/chrome/browser/ash/scanning/lorgnette_scanner_manager_unittest.cc
@@ -23,6 +23,7 @@ #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/lorgnette/lorgnette_service.pb.h" #include "chromeos/dbus/lorgnette_manager/fake_lorgnette_manager_client.h" +#include "chromeos/dbus/lorgnette_manager/lorgnette_manager_client.h" #include "net/base/ip_address.h" #include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gtest/include/gtest/gtest.h" @@ -166,6 +167,7 @@ LorgnetteScannerManagerTest() { run_loop_ = std::make_unique<base::RunLoop>(); DBusThreadManager::Initialize(); + chromeos::LorgnetteManagerClient::InitializeFake(); auto fake_zeroconf_scanner_detector = std::make_unique<FakeZeroconfScannerDetector>(); fake_zeroconf_scanner_detector_ = fake_zeroconf_scanner_detector.get(); @@ -176,13 +178,16 @@ GetLorgnetteManagerClient()->SetScannerCapabilitiesResponse(capabilities); } - ~LorgnetteScannerManagerTest() override { DBusThreadManager::Shutdown(); } + ~LorgnetteScannerManagerTest() override { + chromeos::LorgnetteManagerClient::Shutdown(); + DBusThreadManager::Shutdown(); + } // Returns a FakeLorgnetteManagerClient with an empty but successful // GetCapabilities response by default. FakeLorgnetteManagerClient* GetLorgnetteManagerClient() { return static_cast<FakeLorgnetteManagerClient*>( - DBusThreadManager::Get()->GetLorgnetteManagerClient()); + chromeos::LorgnetteManagerClient::Get()); } // Calls LorgnetteScannerManager::GetScannerNames() and binds a callback to
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc index 7612355..45d6d4b 100644 --- a/chrome/browser/banners/app_banner_manager_browsertest.cc +++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -789,7 +789,7 @@ } content::RenderFrameHost* current_frame_host() { - return web_contents()->GetMainFrame(); + return web_contents()->GetPrimaryMainFrame(); } GURL Get2ndInstallableURL() {
diff --git a/chrome/browser/chrome_browser_main_mac.mm b/chrome/browser/chrome_browser_main_mac.mm index 341458a..7ef669d5 100644 --- a/chrome/browser/chrome_browser_main_mac.mm +++ b/chrome/browser/chrome_browser_main_mac.mm
@@ -37,7 +37,6 @@ #include "components/version_info/channel.h" #include "content/public/common/main_function_params.h" #include "content/public/common/result_codes.h" -#include "net/base/features.h" #include "net/cert/internal/system_trust_store.h" #include "services/network/public/cpp/features.h" #include "ui/base/cocoa/permissions_utils.h" @@ -139,10 +138,7 @@ MacStartupProfiler::POST_MAIN_MESSAGE_LOOP_START); ChromeBrowserMainPartsPosix::PostCreateMainMessageLoop(); - if (base::FeatureList::IsEnabled( - net::features::kCertVerifierBuiltinFeature)) { - net::InitializeTrustStoreMacCache(); - } + net::InitializeTrustStoreMacCache(); } void ChromeBrowserMainPartsMac::PreProfileInit() {
diff --git a/chrome/browser/dips/dips_bounce_detector_browsertest.cc b/chrome/browser/dips/dips_bounce_detector_browsertest.cc index 3eda0022..5123d0f9 100644 --- a/chrome/browser/dips/dips_bounce_detector_browsertest.cc +++ b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
@@ -202,7 +202,8 @@ void CreateImageAndWaitForCookieAccess(const GURL& image_url) { WebContents* web_contents = GetActiveWebContents(); - CookieAccessObserver observer(web_contents, web_contents->GetMainFrame()); + CookieAccessObserver observer(web_contents, + web_contents->GetPrimaryMainFrame()); ASSERT_TRUE(content::ExecJs(web_contents, content::JsReplace( R"( @@ -445,7 +446,7 @@ // Visit initial page ASSERT_TRUE(content::NavigateToURL(web_contents, initial_url)); - frame = web_contents->GetMainFrame(); + frame = web_contents->GetPrimaryMainFrame(); // Wait for navigation to finish to initial page EXPECT_TRUE(content::WaitForLoadStop(web_contents)); // Wait until we can click. @@ -461,7 +462,7 @@ // Wait for navigation to finish to interstitial page EXPECT_TRUE(content::WaitForLoadStop(web_contents)); - frame = web_contents->GetMainFrame(); + frame = web_contents->GetPrimaryMainFrame(); // Advance TimeTicks by 1 second AdvanceDIPSTime(base::TimeDelta(base::Seconds(1))); // Write Cookie via JS on bounce page @@ -564,7 +565,7 @@ // Wait for navigation to finish to bounce page (b.test). EXPECT_TRUE(content::WaitForLoadStop(web_contents)); - frame = web_contents->GetMainFrame(); + frame = web_contents->GetPrimaryMainFrame(); // Advance TimeTicks by 1 second. AdvanceDIPSTime(base::TimeDelta(base::Seconds(1))); // Write Cookie via JS on bounce page. @@ -632,7 +633,7 @@ ASSERT_TRUE(content::NavigateToURL(web_contents, initial_url)); // Wait for navigation to finish to initial page. EXPECT_TRUE(content::WaitForLoadStop(web_contents)); - frame = web_contents->GetMainFrame(); + frame = web_contents->GetPrimaryMainFrame(); // Wait until we can click. content::WaitForHitTestData(frame); // Advance TimeTicks 10 seconds. @@ -646,7 +647,7 @@ // Wait for navigation to finish to bounce page 1. EXPECT_TRUE(content::WaitForLoadStop(web_contents)); - frame = web_contents->GetMainFrame(); + frame = web_contents->GetPrimaryMainFrame(); // Wait until we can click. content::WaitForHitTestData(frame); // simulate mouse click @@ -667,7 +668,7 @@ // Wait for navigation to finish to bounce page 2. EXPECT_TRUE(content::WaitForLoadStop(web_contents)); - frame = web_contents->GetMainFrame(); + frame = web_contents->GetPrimaryMainFrame(); // Advance TimeTicks by 1 second. AdvanceDIPSTime(base::TimeDelta(base::Seconds(1))); // Write Cookie via JS on bounce page 2. @@ -682,7 +683,7 @@ // Wait for navigation to finish to bounce page 3. EXPECT_TRUE(content::WaitForLoadStop(web_contents)); - frame = web_contents->GetMainFrame(); + frame = web_contents->GetPrimaryMainFrame(); // Advance TimeTicks by 1 second. AdvanceDIPSTime(base::TimeDelta(base::Seconds(1))); // Write Cookie via JS on bounce page 3. @@ -810,14 +811,14 @@ // Set cookies on c.test without of user engagement signal. ASSERT_TRUE(NavigateToURLFromRendererWithoutUserGesture( - web_contents->GetMainFrame(), + web_contents->GetPrimaryMainFrame(), embedded_test_server()->GetURL("c.test", "/set-cookie?name=value"))); // Visit initial page. ASSERT_TRUE(content::NavigateToURL(web_contents, initial_url)); // Wait for navigation to finish to initial page. EXPECT_TRUE(content::WaitForLoadStop(web_contents)); - frame = web_contents->GetMainFrame(); + frame = web_contents->GetPrimaryMainFrame(); // Wait until we can click. content::WaitForHitTestData(frame); // Advance TimeTicks 10 seconds. @@ -832,7 +833,7 @@ // Wait for navigation to finish to bounce page 1. EXPECT_TRUE(content::WaitForLoadStop(web_contents)); - frame = web_contents->GetMainFrame(); + frame = web_contents->GetPrimaryMainFrame(); // Wait until we can click. content::WaitForHitTestData(frame); // Advance TimeTicks by 1 second @@ -844,7 +845,7 @@ // Wait for navigation to finish to bounce page 2. EXPECT_TRUE(content::WaitForLoadStop(web_contents)); - frame = web_contents->GetMainFrame(); + frame = web_contents->GetPrimaryMainFrame(); // Advance TimeTicks by 1 second. AdvanceDIPSTime(base::TimeDelta(base::Seconds(1))); // Write Cookie via JS on bounce page 2 (c.test).
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index a917514..b4aa473 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -5317,6 +5317,14 @@ "expiry_milestone": 96 }, { + "name": "rounded-display", + "owners": [ + "zoraiznaeem", + "chromeos-foundations@google.com" + ], + "expiry_milestone": 110 + }, + { "name": "run-video-capture-service-in-browser", "owners": [ "agpalak", "herre" ], "expiry_milestone": 110
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 4a6e7c9..c3dbc99 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -2260,6 +2260,10 @@ "Enables Permissions Policy and Secure Context restrictions on the Gamepad " "API"; +const char kRoundedDisplay[] = "Rounded display"; +const char kRoundedDisplayDescription[] = + "Enables rounded corners for the display"; + const char kMBIModeName[] = "MBI Scheduling Mode"; const char kMBIModeDescription[] = "Enables independent agent cluster scheduling, via the "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index d77b9088..f33362c 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1270,6 +1270,9 @@ extern const char kRestrictGamepadAccessName[]; extern const char kRestrictGamepadAccessDescription[]; +extern const char kRoundedDisplay[]; +extern const char kRoundedDisplayDescription[]; + extern const char kMBIModeName[]; extern const char kMBIModeDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 282db210..2f9f858 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -194,6 +194,7 @@ &kCCTResourcePrefetch, &kCCTToolbarCustomizations, &kDontAutoHideBrowserControls, + &kCacheDeprecatedSystemLocationSetting, &kChromeNewDownloadTab, &kChromeShareLongScreenshot, &kChromeSharingHub, @@ -531,6 +532,9 @@ const base::Feature kDontAutoHideBrowserControls{ "DontAutoHideBrowserControls", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kCacheDeprecatedSystemLocationSetting{ + "CacheDeprecatedSystemLocationSetting", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kChromeNewDownloadTab{"ChromeNewDownloadTab", 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 5fe378d..53d9d25 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -51,6 +51,7 @@ extern const base::Feature kCCTRetainingState; extern const base::Feature kCCTToolbarCustomizations; extern const base::Feature kDontAutoHideBrowserControls; +extern const base::Feature kCacheDeprecatedSystemLocationSetting; extern const base::Feature kChromeNewDownloadTab; extern const base::Feature kChromeShareLongScreenshot; extern const base::Feature kChromeShareScreenshot;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 656431a9..06001f5 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -240,6 +240,8 @@ public static final String BACK_GESTURE_REFACTOR = "BackGestureRefactorAndroid"; public static final String BIOMETRIC_TOUCH_TO_FILL = "BiometricTouchToFill"; public static final String BULK_TAB_RESTORE = "BulkTabRestore"; + public static final String CACHE_DEPRECATED_SYSTEM_LOCATION_SETTING = + "CacheDeprecatedSystemLocationSetting"; public static final String CAPTIVE_PORTAL_CERTIFICATE_LIST = "CaptivePortalCertificateList"; public static final String CCT_BACKGROUND_TAB = "CCTBackgroundTab"; public static final String CCT_CLIENT_DATA_HEADER = "CCTClientDataHeader";
diff --git a/chrome/browser/media/webrtc/region_capture_browsertest.cc b/chrome/browser/media/webrtc/region_capture_browsertest.cc index 5760f2b3..70b12bfc 100644 --- a/chrome/browser/media/webrtc/region_capture_browsertest.cc +++ b/chrome/browser/media/webrtc/region_capture_browsertest.cc
@@ -114,7 +114,7 @@ void SetUpMailman(const GURL& url) { std::string script_result; EXPECT_TRUE(content::ExecuteScriptAndExtractString( - web_contents->GetMainFrame(), + web_contents->GetPrimaryMainFrame(), base::StringPrintf("setUpMailman('%s');", url.spec().c_str()), &script_result)); EXPECT_EQ(script_result, "mailman-ready"); @@ -198,7 +198,7 @@ bool CloneTrack() { std::string script_result = "error-not-modified"; EXPECT_TRUE(content::ExecuteScriptAndExtractString( - web_contents->GetMainFrame(), "clone();", &script_result)); + web_contents->GetPrimaryMainFrame(), "clone();", &script_result)); DCHECK(script_result == "clone-track-success" || script_result == "clone-track-failure"); return script_result == "clone-track-success"; @@ -207,7 +207,7 @@ bool Deallocate(Track track) { std::string script_result = "error-not-modified"; EXPECT_TRUE(content::ExecuteScriptAndExtractString( - web_contents->GetMainFrame(), + web_contents->GetPrimaryMainFrame(), base::StringPrintf("deallocate('%s');", ToString(track)), &script_result)); DCHECK(script_result == "deallocate-failure" ||
diff --git a/chrome/browser/navigation_predictor/anchor_element_preloader_browsertest.cc b/chrome/browser/navigation_predictor/anchor_element_preloader_browsertest.cc index 74a2f8b..c2000ff 100644 --- a/chrome/browser/navigation_predictor/anchor_element_preloader_browsertest.cc +++ b/chrome/browser/navigation_predictor/anchor_element_preloader_browsertest.cc
@@ -158,7 +158,7 @@ ukm::SourceId ukm_source_id = browser() ->tab_strip_model() ->GetActiveWebContents() - ->GetMainFrame() + ->GetPrimaryMainFrame() ->GetPageUkmSourceId(); // First link with mousedown event should get preconnected.
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc index a30846e..e32919d 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -3480,7 +3480,8 @@ ASSERT_EQ(all_frames_value, main_frame_value); } -#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS) // crbug.com/1277391 +// Test is flaky. https://crbug.com/1260953 +#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) #define MAYBE_PageLCPAnimatedImage DISABLED_PageLCPAnimatedImage #else #define MAYBE_PageLCPAnimatedImage PageLCPAnimatedImage
diff --git a/chrome/browser/policy/test/renderer_app_container_enabled_win_browsertest.cc b/chrome/browser/policy/test/renderer_app_container_enabled_win_browsertest.cc index 74ce25e..75b95bc 100644 --- a/chrome/browser/policy/test/renderer_app_container_enabled_win_browsertest.cc +++ b/chrome/browser/policy/test/renderer_app_container_enabled_win_browsertest.cc
@@ -95,7 +95,7 @@ base::ProcessId renderer_process_id = browser() ->tab_strip_model() ->GetActiveWebContents() - ->GetMainFrame() + ->GetPrimaryMainFrame() ->GetProcess() ->GetProcess() .Pid();
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc index d0b89aea..af129f8 100644 --- a/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc +++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc
@@ -928,7 +928,7 @@ history.replaceState(null, "", url.toString()); )"; - content::RenderFrameHost* frame = GetWebContents()->GetMainFrame(); + content::RenderFrameHost* frame = GetWebContents()->GetPrimaryMainFrame(); EXPECT_TRUE(content::ExecuteScript(frame, script)); // The prefetch should be served, and only 1 request should be issued.
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 60d1819..1d873735 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -150,6 +150,7 @@ #include "components/sync_device_info/device_info_prefs.h" #include "components/sync_preferences/pref_service_syncable.h" #include "components/sync_sessions/session_sync_prefs.h" +#include "components/tracing/common/pref_names.h" #include "components/translate/core/browser/translate_prefs.h" #include "components/update_client/update_client.h" #include "components/variations/service/variations_service.h" @@ -742,6 +743,9 @@ const char kTokenServiceDiceCompatible[] = "token_service.dice_compatible"; #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) +// Deprecated 06/2022. +const char kBackgroundTracingLastUpload[] = "background_tracing.last_upload"; + // Register local state used only for migration (clearing or moving to a new // key). void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) { @@ -795,6 +799,9 @@ registry->RegisterBooleanPref(kNativeBridge64BitSupportExperimentEnabled, false); #endif // BUILDFLAG(IS_CHROMEOS_ASH) + + // Deprecated 06/2022. + registry->RegisterInt64Pref(kBackgroundTracingLastUpload, 0); } // Register prefs used only for migration (clearing or moving to a new key). @@ -980,7 +987,6 @@ chrome_labs_prefs::RegisterLocalStatePrefs(registry); #endif ChromeMetricsServiceClient::RegisterPrefs(registry); - ChromeTracingDelegate::RegisterPrefs(registry); chrome::enterprise_util::RegisterLocalStatePrefs(registry); component_updater::RegisterPrefs(registry); embedder_support::OriginTrialPrefs::RegisterPrefs(registry); @@ -1019,6 +1025,7 @@ SSLConfigServiceManager::RegisterPrefs(registry); subresource_filter::IndexedRulesetVersion::RegisterPrefs(registry); SystemNetworkContextManager::RegisterPrefs(registry); + tracing::RegisterPrefs(registry); update_client::RegisterPrefs(registry); variations::VariationsService::RegisterPrefs(registry); @@ -1646,6 +1653,9 @@ local_state->ClearPref(kNativeBridge64BitSupportExperimentEnabled); #endif // BUILDFLAG(IS_CHROMEOS_ASH) + // Added 06/2022. + local_state->ClearPref(kBackgroundTracingLastUpload); + // Please don't delete the following line. It is used by PRESUBMIT.py. // END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS
diff --git a/chrome/browser/renderer_context_menu/link_to_text_menu_observer.h b/chrome/browser/renderer_context_menu/link_to_text_menu_observer.h index 8ab2d0b..d93bbc5 100644 --- a/chrome/browser/renderer_context_menu/link_to_text_menu_observer.h +++ b/chrome/browser/renderer_context_menu/link_to_text_menu_observer.h
@@ -109,6 +109,7 @@ raw_ptr<RenderViewContextMenuProxy> proxy_; GURL url_; GURL raw_url_; + raw_ptr<content::RenderFrameHost> render_frame_host_; std::unordered_map<content::GlobalRenderFrameHostId, std::vector<std::string>,
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn index e5527d1..561f3bb 100644 --- a/chrome/browser/resources/BUILD.gn +++ b/chrome/browser/resources/BUILD.gn
@@ -126,7 +126,6 @@ "inline_login:closure_compile", "ntp4:closure_compile", "omnibox:closure_compile", - "settings:closure_compile", ] } if (is_chromeos_ash) { @@ -135,6 +134,7 @@ "nearby_internals:closure_compile", "nearby_share:closure_compile", "nearby_share/shared:closure_compile_module", + "settings:closure_compile", ] } if (is_android) {
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html index ddf1e4f..8afc8c9 100644 --- a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html +++ b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html
@@ -53,6 +53,7 @@ <network-siminfo class="flex" network-state="[[getNetworkState_(managedProperties_)]]" device-state="[[deviceState_]]" + global-policy="[[globalPolicy_]]" disabled="[[disabled_]]"> </network-siminfo> </div>
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js index 4c508e7..52b83caa 100644 --- a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js +++ b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js
@@ -96,6 +96,9 @@ value: false, computed: 'computeDisabled_(deviceState_.*)' }, + + /** @private {!chromeos.networkConfig.mojom.GlobalPolicy|undefined} */ + globalPolicy_: Object, }, /** @@ -152,6 +155,9 @@ this.managedProperties_ = OncMojo.getDefaultManagedProperties( OncMojo.getNetworkTypeFromString(type), this.guid, name); this.getNetworkDetails_(); + + // Fetch global policies. + this.onPoliciesApplied(/*userhash=*/ ''); }, /** @private */ @@ -176,6 +182,16 @@ /** * CrosNetworkConfigObserver impl + * @param {!string} userhash + */ + onPoliciesApplied(userhash) { + this.networkConfig_.getGlobalPolicy().then(response => { + this.globalPolicy_ = response.result; + }); + }, + + /** + * CrosNetworkConfigObserver impl * @param {!Array<OncMojo.NetworkStateProperties>} networks */ onActiveNetworksChanged(networks) {
diff --git a/chrome/browser/resources/feed_internals/feed_internals.html b/chrome/browser/resources/feed_internals/feed_internals.html index 5b84305..eee1ee2 100644 --- a/chrome/browser/resources/feed_internals/feed_internals.html +++ b/chrome/browser/resources/feed_internals/feed_internals.html
@@ -30,9 +30,9 @@ </p> <p> <label> - <input type="checkbox" id="use-feed-query-requests-for-web-feeds" - name="use-feed-query-requests-for-web-feeds"> - Use legacy endpoint for Web Feed content fetches + <input type="checkbox" id="use-feed-query-requests" + name="use-feed-query-requests"> + Use legacy endpoint for content fetches </label> </p> <p>
diff --git a/chrome/browser/resources/feed_internals/feed_internals.js b/chrome/browser/resources/feed_internals/feed_internals.js index cbff9da..bb51f60b 100644 --- a/chrome/browser/resources/feed_internals/feed_internals.js +++ b/chrome/browser/resources/feed_internals/feed_internals.js
@@ -29,8 +29,7 @@ $('enable-webfeed-follow-intro-debug').checked = properties.isWebFeedFollowIntroDebugEnabled; $('enable-webfeed-follow-intro-debug').disabled = false; - $('use-feed-query-requests-for-web-feeds').checked = - properties.useFeedQueryRequestsForWebFeeds; + $('use-feed-query-requests').checked = properties.useFeedQueryRequests; switch (properties.followingFeedOrder) { case FeedOrder.kUnspecified: @@ -148,11 +147,9 @@ $('enable-webfeed-follow-intro-debug').disabled = true; }); - $('use-feed-query-requests-for-web-feeds') - .addEventListener('click', function() { - pageHandler.setUseFeedQueryRequestsForWebFeeds( - $('use-feed-query-requests-for-web-feeds').checked); - }); + $('use-feed-query-requests').addEventListener('click', function() { + pageHandler.setUseFeedQueryRequests($('use-feed-query-requests').checked); + }); const orderRadioClickListener = function(order) { $('following-feed-order-grouped').disabled = true;
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn index e163e3e..e60915c0 100644 --- a/chrome/browser/resources/settings/BUILD.gn +++ b/chrome/browser/resources/settings/BUILD.gn
@@ -183,79 +183,78 @@ output_dir = "$root_gen_dir/chrome" } -group("closure_compile") { - deps = [ ":closure_compile_local" ] - - if (is_chromeos_ash) { - deps += [ "chromeos:closure_compile_module" ] +if (is_chromeos_ash) { + group("closure_compile") { + deps = [ + ":closure_compile_local", + "chromeos:closure_compile_module", + ] } -} -js_type_check("closure_compile_local") { - is_polymer3 = true - closure_flags = settings_closure_flags - deps = [ - ":extension_control_browser_proxy", - ":i18n_setup", - ":lifetime_browser_proxy", - ":router", - ":setting_id_param_util", - ":settings", - ] -} + js_type_check("closure_compile_local") { + is_polymer3 = true + closure_flags = settings_closure_flags + deps = [ + ":extension_control_browser_proxy", + ":i18n_setup", + ":lifetime_browser_proxy", + ":router", + ":setting_id_param_util", + ":settings", + ] + } -js_library("settings") { - sources = - [ "$root_gen_dir/chrome/browser/resources/settings/tsc/settings.js" ] - deps = [ - ":i18n_setup", - ":lifetime_browser_proxy", - ] - extra_deps = [ ":build_ts" ] -} + js_library("settings") { + sources = + [ "$root_gen_dir/chrome/browser/resources/settings/tsc/settings.js" ] + deps = [ + ":i18n_setup", + ":lifetime_browser_proxy", + ] + extra_deps = [ ":build_ts" ] + } -js_library("extension_control_browser_proxy") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/tsc/extension_control_browser_proxy.js" ] - deps = [ "//ui/webui/resources/js:cr.m" ] - externs_list = [ "$externs_path/chrome_send.js" ] - extra_deps = [ ":build_ts" ] -} + js_library("extension_control_browser_proxy") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/tsc/extension_control_browser_proxy.js" ] + deps = [ "//ui/webui/resources/js:cr.m" ] + externs_list = [ "$externs_path/chrome_send.js" ] + extra_deps = [ ":build_ts" ] + } -js_library("i18n_setup") { - sources = - [ "$root_gen_dir/chrome/browser/resources/settings/tsc/i18n_setup.js" ] - deps = [ "//ui/webui/resources/js:load_time_data.m" ] - extra_deps = [ ":build_ts" ] -} + js_library("i18n_setup") { + sources = + [ "$root_gen_dir/chrome/browser/resources/settings/tsc/i18n_setup.js" ] + deps = [ "//ui/webui/resources/js:load_time_data.m" ] + extra_deps = [ ":build_ts" ] + } -js_library("lifetime_browser_proxy") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/tsc/lifetime_browser_proxy.js" ] - deps = [ "//ui/webui/resources/js:cr.m" ] - extra_deps = [ ":build_ts" ] -} + js_library("lifetime_browser_proxy") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/tsc/lifetime_browser_proxy.js" ] + deps = [ "//ui/webui/resources/js:cr.m" ] + extra_deps = [ ":build_ts" ] + } -js_library("open_window_proxy") { - sources = [ - "$root_gen_dir/chrome/browser/resources/settings/tsc/open_window_proxy.js", - ] - extra_deps = [ ":build_ts" ] -} + js_library("open_window_proxy") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/tsc/open_window_proxy.js" ] + extra_deps = [ ":build_ts" ] + } -js_library("router") { - deps = [ - "//ui/webui/resources/js:assert.m", - "//ui/webui/resources/js:load_time_data.m", - ] - externs_list = [ "$externs_path/metrics_private.js" ] -} + js_library("router") { + deps = [ + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:load_time_data.m", + ] + externs_list = [ "$externs_path/metrics_private.js" ] + } -js_library("setting_id_param_util") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/tsc/setting_id_param_util.js" ] - deps = [ - ":router", - "//ui/webui/resources/js:load_time_data.m", - ] - extra_deps = [ ":build_ts" ] + js_library("setting_id_param_util") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/tsc/setting_id_param_util.js" ] + deps = [ + ":router", + "//ui/webui/resources/js:load_time_data.m", + ] + extra_deps = [ ":build_ts" ] + } } html_to_js("css_wrapper_files_old") {
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.html index 8f97314..3863f08 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.html +++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.html
@@ -297,6 +297,7 @@ <network-siminfo id="cellularSimInfoAdvanced" network-state="[[getNetworkState_(managedProperties_)]]" device-state="[[deviceState_]]" + global-policy="[[globalPolicy]]" disabled="[[disabled_]]"> </network-siminfo> </div>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/network_summary.html b/chrome/browser/resources/settings/chromeos/internet_page/network_summary.html index acee8c4..afed1f6 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/network_summary.html +++ b/chrome/browser/resources/settings/chromeos/internet_page/network_summary.html
@@ -8,6 +8,7 @@ <network-summary-item id="[[getTypeString_(item)]]" active-network-state="[[item]]" device-state="[[get(item.type, deviceStates)]]" + global-policy="[[globalPolicy_]]" network-state-list="[[get(item.type, networkStateLists_)]]" tether-device-state="[[getTetherDeviceState_(deviceStates)]]"> </network-summary-item>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/network_summary.js b/chrome/browser/resources/settings/chromeos/internet_page/network_summary.js index 963f5ae..4173664a 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/network_summary.js +++ b/chrome/browser/resources/settings/chromeos/internet_page/network_summary.js
@@ -90,6 +90,9 @@ return result; }, }, + + /** @private {!chromeos.networkConfig.mojom.GlobalPolicy|undefined} */ + globalPolicy_: Object, }; } @@ -113,6 +116,18 @@ super.connectedCallback(); this.getNetworkLists_(); + + // Fetch global policies. + this.onPoliciesApplied(/*userhash=*/ ''); + } + /** + * CrosNetworkConfigObserver impl + * @param {!string} userhash + */ + onPoliciesApplied(userhash) { + this.networkConfig_.getGlobalPolicy().then(response => { + this.globalPolicy_ = response.result; + }); } /**
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.html b/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.html index 461dc50..9988342 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.html +++ b/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.html
@@ -56,6 +56,7 @@ <network-siminfo on-click="doNothing_" network-state="[[activeNetworkState]]" + global-policy="[[globalPolicy]]"" device-state="[[deviceState]]"> </network-siminfo> </template>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.js b/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.js index 80128d7..5c95d97 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.js +++ b/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.js
@@ -99,6 +99,9 @@ loadTimeData.getBoolean('showTechnologyBadge'); } }, + + /** @private {!chromeos.networkConfig.mojom.GlobalPolicy|undefined} */ + globalPolicy: Object, }; }
diff --git a/chrome/browser/resources/settings/chromeos/settings_scheduler_slider/settings_scheduler_slider.js b/chrome/browser/resources/settings/chromeos/settings_scheduler_slider/settings_scheduler_slider.js index ad380c9..8cbdad5 100644 --- a/chrome/browser/resources/settings/chromeos/settings_scheduler_slider/settings_scheduler_slider.js +++ b/chrome/browser/resources/settings/chromeos/settings_scheduler_slider/settings_scheduler_slider.js
@@ -10,12 +10,34 @@ import '../../settings_shared_css.js'; -import {I18nBehavior} from '//resources/js/i18n_behavior.m.js'; -import {IronResizableBehavior} from '//resources/polymer/v3_0/iron-resizable-behavior/iron-resizable-behavior.js'; -import {PaperRippleBehavior} from '//resources/polymer/v3_0/paper-behaviors/paper-ripple-behavior.js'; -import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js'; +import {IronResizableBehavior} from 'chrome://resources/polymer/v3_0/iron-resizable-behavior/iron-resizable-behavior.js'; +import {PaperRippleBehavior} from 'chrome://resources/polymer/v3_0/paper-behaviors/paper-ripple-behavior.js'; +import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {PrefsBehavior} from '../prefs_behavior.js'; +import {PrefsBehavior, PrefsBehaviorInterface} from '../prefs_behavior.js'; + +/** @interface */ +class PaperRippleBehaviorInterface { + constructor() { + /** + * @type {?Object} + * @protected + */ + this._ripple; + + /** + * @type {?Element} + * @protected + */ + this._rippleContainer; + } + + /** @return {boolean} */ + hasRipple() {} + + ensureRipple() {} +} const HOURS_PER_DAY = 24; const MIN_KNOBS_DISTANCE_MINUTES = 60; @@ -45,95 +67,120 @@ return ((x % y) + y) % y; } -Polymer({ +/** + * @constructor + * @extends {PolymerElement} + * @implements {I18nBehaviorInterface} + * @implements {PrefsBehaviorInterface} + * @implements {PaperRippleBehaviorInterface} + */ +const SettingsSchedulerSliderElementBase = mixinBehaviors( + [I18nBehavior, PrefsBehavior, IronResizableBehavior, PaperRippleBehavior], + PolymerElement); - _template: html`{__html_template__}`, +/** @polymer */ +class SettingsSchedulerSliderElement extends + SettingsSchedulerSliderElementBase { + static get is() { + return 'settings-scheduler-slider'; + } - is: 'settings-scheduler-slider', + static get template() { + return html`{__html_template__}`; + } - behaviors: [ - I18nBehavior, - PrefsBehavior, - IronResizableBehavior, - PaperRippleBehavior, - ], - - properties: { - - /** - * The start time pref object being tracked. - * @type {!chrome.settingsPrivate.PrefObject} - */ - prefStartTime: { - type: Object, - notify: true, - value() { - return { - key: 'ash.fake_feature.custom_start_time', - type: chrome.settingsPrivate.PrefType.NUMBER, - value: DEFAULT_CUSTOM_START_TIME, - }; + static get properties() { + return { + /** + * The start time pref object being tracked. + * @type {!chrome.settingsPrivate.PrefObject} + */ + prefStartTime: { + type: Object, + notify: true, + value() { + return { + key: 'ash.fake_feature.custom_start_time', + type: chrome.settingsPrivate.PrefType.NUMBER, + value: DEFAULT_CUSTOM_START_TIME, + }; + }, }, - }, - /** - * The end time pref object being tracked. - * @type {!chrome.settingsPrivate.PrefObject} - */ - prefEndTime: { - type: Object, - notify: true, - value() { - return { - key: 'ash.fake_feature.custom_start_time', - type: chrome.settingsPrivate.PrefType.NUMBER, - value: DEFAULT_CUSTOM_END_TIME, - }; + /** + * The end time pref object being tracked. + * @type {!chrome.settingsPrivate.PrefObject} + */ + prefEndTime: { + type: Object, + notify: true, + value() { + return { + key: 'ash.fake_feature.custom_start_time', + type: chrome.settingsPrivate.PrefType.NUMBER, + value: DEFAULT_CUSTOM_END_TIME, + }; + }, }, - }, + + /** + * Whether the element is ready and fully rendered. + * @private + */ + isReady_: Boolean, + + /** + * Whether the window is in RTL locales. + * @private + */ + isRTL_: Boolean, + + /** + * Whether to use the 24-hour format for the time shown in the label + * bubbles. + * @private + */ + shouldUse24Hours_: Boolean, + }; + } + + static get observers() { + return [ + 'updateKnobs_(prefs.*, isRTL_, isReady_)', + 'hourFormatChanged_(prefs.settings.clock.use_24hour_clock.*)', + 'updateMarkers_(prefs.*, isRTL_, isReady_)', + ]; + } + + constructor() { + super(); /** - * Whether the element is ready and fully rendered. + * The object currently being dragged. Either the start or end knobs. + * @type {Element} * @private */ - isReady_: Boolean, + this.dragObject_ = null; /** - * Whether the window is in RTL locales. - * @private + * @private {number} */ - isRTL_: Boolean, + this.valueAtDragStart_; + } - /** - * Whether to use the 24-hour format for the time shown in the label - * bubbles. - * @private - */ - shouldUse24Hours_: Boolean, - }, + ready() { + super.ready(); - listeners: { - 'iron-resize': 'onResize_', - focus: 'onFocus_', - blur: 'onBlur_', - keydown: 'onKeyDown_', - }, - - observers: [ - 'updateKnobs_(prefs.*, isRTL_, isReady_)', - 'hourFormatChanged_(prefs.settings.clock.use_24hour_clock.*)', - 'updateMarkers_(prefs.*, isRTL_, isReady_)', - ], - - /** - * The object currently being dragged. Either the start or end knobs. - * @type {Element} - * @private - */ - dragObject_: null, + this.addEventListener('iron-resize', this.onResize_); + this.addEventListener('focus', this.onFocus_); + this.addEventListener('blur', this.onBlur_); + this.addEventListener('keydown', this.onKeyDown_); + } /** @override */ - attached() { + connectedCallback() { + super.connectedCallback(); + this.isRTL_ = window.getComputedStyle(this).direction === 'rtl'; this.$.sliderContainer.addEventListener('contextmenu', function(e) { // Prevent the context menu from interfering with dragging the knobs using @@ -149,7 +196,7 @@ // rendered. this.isReady_ = true; }); - }, + } /** * @return {boolean} @@ -158,7 +205,7 @@ prefsAvailable() { return [this.prefStartTime, this.prefEndTime].every( pref => pref !== undefined); - }, + } /** @private */ updateMarkers_() { @@ -189,7 +236,7 @@ markersContainer.appendChild(marker); marker.style.left = (i * 100 / HOURS_PER_DAY) + '%'; } - }, + } /** * Return true if the start knob is focused. @@ -198,7 +245,7 @@ */ isStartKnobFocused_() { return (this.shadowRoot.activeElement === this.$.startKnob); - }, + } /** * Return true if the end knob is focused. @@ -207,7 +254,7 @@ */ isEndKnobFocused_() { return (this.shadowRoot.activeElement === this.$.endKnob); - }, + } /** * Invoked when the element is resized and the knobs positions need to be @@ -216,7 +263,7 @@ */ onResize_() { this.updateKnobs_(); - }, + } /** * Called when the value of the pref associated with whether to use the @@ -226,7 +273,7 @@ hourFormatChanged_() { this.shouldUse24Hours_ = /** @type {boolean} */ ( this.getPref('settings.clock.use_24hour_clock').value); - }, + } /** * Gets the style of legend div determining its absolute left position. @@ -238,7 +285,7 @@ getLegendStyle_(percent, isRTL) { percent = isRTL ? 100 - percent : percent; return 'left: ' + percent + '%'; - }, + } /** * Gets the aria label for the start time knob. @@ -251,7 +298,7 @@ this.getTimeString_( /** @type {number} */ (this.prefStartTime.value), this.shouldUse24Hours_)); - }, + } /** * Gets the aria label for the end time knob. @@ -264,7 +311,7 @@ this.getTimeString_( /** @type {number} */ (this.prefEndTime.value), this.shouldUse24Hours_)); - }, + } /** @@ -275,7 +322,7 @@ if (this.isEitherKnobFocused_()) { this.shadowRoot.activeElement.blur(); } - }, + } /** * Start dragging the target knob. @@ -290,18 +337,18 @@ if (event.target === this.$.startKnob || event.target === this.$.startKnob.firstElementChild) { this.dragObject_ = this.$.startKnob; - this.valueAtDragStart_ = this.prefStartTime.value; + this.valueAtDragStart_ = /** @type {number} */ (this.prefStartTime.value); } else if ( event.target === this.$.endKnob || event.target === this.$.endKnob.firstElementChild) { this.dragObject_ = this.$.endKnob; - this.valueAtDragStart_ = this.prefEndTime.value; + this.valueAtDragStart_ = /** @type {number} */ (this.prefEndTime.value); } else { return; } this.handleKnobEvent_(event, this.dragObject_); - }, + } /** * Continues dragging the selected knob if any. @@ -325,7 +372,7 @@ this.endDrag_(event); break; } - }, + } /** * Converts horizontal pixels into number of minutes. @@ -337,7 +384,7 @@ return (this.isRTL_ ? -1 : 1) * Math.floor( TOTAL_MINUTES_PER_DAY * deltaX / this.$.sliderBar.offsetWidth); - }, + } /** * Updates the knob's corresponding pref value in response to dragging, which @@ -359,7 +406,7 @@ // pixel movement due to rounding. this.updatePref_( this.valueAtDragStart_ + this.getDeltaMinutes_(event.detail.dx), true); - }, + } /** * Ends the dragging. @@ -370,7 +417,7 @@ event.preventDefault(); this.dragObject_ = null; this.removeRipple_(); - }, + } /** * Gets the given knob's offset ratio with respect to its parent element @@ -381,7 +428,7 @@ */ getKnobRatio_(knob) { return parseFloat(knob.style.left) / this.$.sliderBar.offsetWidth; - }, + } /** * Converts the time of day, given as |hour| and |minutes|, to its language- @@ -402,7 +449,7 @@ return d.toLocaleTimeString( navigator.language, {hour: 'numeric', minute: 'numeric', hour12: !shouldUse24Hours}); - }, + } /** * Converts the |offsetMinutes| value (which the number of minutes since @@ -417,7 +464,7 @@ const hour = Math.floor(offsetMinutes / 60); const minute = Math.floor(offsetMinutes % 60); return this.getLocaleTimeString_(hour, minute, shouldUse24Hours); - }, + } /** * Using the current start and end times prefs, this function updates the @@ -441,7 +488,7 @@ this.updateKnobLeft_(this.$.endKnob, endOffsetMinutes); this.refresh_(); - }, + } /** * Updates the absolute left coordinate of the given |knob| based on the time @@ -468,7 +515,7 @@ ratio = this.isRTL_ ? (1.0 - ratio) : ratio; } knob.style.left = (ratio * this.$.sliderBar.offsetWidth) + 'px'; - }, + } /** * Refreshes elements of the slider other than the knobs (the label bubbles, @@ -509,7 +556,7 @@ 'px'; this.fixLabelsOverlapIfAny_(); - }, + } /** * If the label bubbles overlap, this function fixes them by moving the end @@ -529,7 +576,7 @@ } else { endLabel.classList.remove('end-label-overlap'); } - }, + } /** * Return the value of the pref that corresponds to the other knob than @@ -542,7 +589,7 @@ return /** @type {number} */ (this.prefEndTime.value); } return /** @type {number} */ (this.prefStartTime.value); - }, + } /** * Updates the value of the pref and wraps around if necessary. @@ -591,7 +638,7 @@ this.set( 'prefEndTime.value', modulo(updatedValue, TOTAL_MINUTES_PER_DAY)); } - }, + } /** * @param {Element} knob @@ -606,7 +653,7 @@ } else { return null; } - }, + } /** * @return {boolean} Whether either of the two knobs is focused. @@ -614,7 +661,7 @@ */ isEitherKnobFocused_() { return this.isStartKnobFocused_() || this.isEndKnobFocused_(); - }, + } /** * Overrides _createRipple() from PaperRippleBehavior to create the ripple @@ -637,7 +684,7 @@ ripple.setAttribute('recenters', ''); ripple.classList.add('circle', 'toggle-ink'); return ripple; - }, + } /** * @param {!Event} event @@ -645,7 +692,7 @@ */ onFocus_(event) { this.handleKnobEvent_(event); - }, + } /** * Handles focus, drag and key events on the start and end knobs. @@ -675,7 +722,7 @@ this._ripple.style.display = ''; this._ripple.holdDown = true; } - }, + } /** * Handles blur events on the start and end knobs. @@ -683,7 +730,7 @@ */ onBlur_() { this.removeRipple_(); - }, + } /** * Removes ripple if one exists. @@ -694,7 +741,7 @@ this._ripple.remove(); this._ripple = null; } - }, + } /** * @param {!Event} event @@ -741,5 +788,8 @@ const delta = deltaKeyMap[event.key]; this.updatePref_(value + delta, false); } - }, -}); + } +} + +customElements.define( + SettingsSchedulerSliderElement.is, SettingsSchedulerSliderElement);
diff --git a/chrome/browser/resources/settings/people_page/sync_page.ts b/chrome/browser/resources/settings/people_page/sync_page.ts index ae720dfd..e20ad76 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.ts +++ b/chrome/browser/resources/settings/people_page/sync_page.ts
@@ -55,6 +55,7 @@ SYNC: Route, SYNC_ADVANCED: Route, OS_SYNC: Route, + OS_PEOPLE: Route, }; function getSyncRoutes(): SyncRoutes { @@ -372,6 +373,17 @@ return getSyncRoutes().SYNC_ADVANCED; } + private getPeoplePageRoute_(): Route { + // <if expr="chromeos_ash"> + if (loadTimeData.getBoolean('isOSSettings')) { + // In OS settings on ChromeOS a different page is used as a people page. + return getSyncRoutes().OS_PEOPLE; + } + // </if> + + return getSyncRoutes().PEOPLE; + } + private onFocusConfigChange_() { this.focusConfig.set(this.getSyncAdvancedPageRoute_().path, () => { const toFocus = this.shadowRoot!.querySelector('#sync-advanced-row'); @@ -637,7 +649,7 @@ return; case PageStatus.DONE: if (router.getCurrentRoute() === getSyncRoutes().SYNC) { - router.navigateTo(getSyncRoutes().PEOPLE); + router.navigateTo(this.getPeoplePageRoute_()); } return; case PageStatus.PASSPHRASE_FAILED:
diff --git a/chrome/browser/safe_browsing/client_side_detection_service_browsertest.cc b/chrome/browser/safe_browsing/client_side_detection_service_browsertest.cc index 30d1ab5..30f98554 100644 --- a/chrome/browser/safe_browsing/client_side_detection_service_browsertest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_service_browsertest.cc
@@ -98,7 +98,7 @@ GURL url(embedded_test_server()->GetURL("/empty.html")); ASSERT_TRUE(content::NavigateToURL(web_contents(), url)); - content::RenderFrameHost* rfh = web_contents()->GetMainFrame(); + content::RenderFrameHost* rfh = web_contents()->GetPrimaryMainFrame(); content::RenderProcessHost* rph = rfh->GetProcess(); // Update the model and wait for confirmation @@ -159,7 +159,7 @@ GURL url(embedded_test_server()->GetURL("/empty.html")); ASSERT_TRUE(content::NavigateToURL(web_contents(), url)); - content::RenderFrameHost* rfh = web_contents()->GetMainFrame(); + content::RenderFrameHost* rfh = web_contents()->GetPrimaryMainFrame(); content::RenderProcessHost* rph = rfh->GetProcess(); // Update the model and wait for confirmation
diff --git a/chrome/browser/share/BUILD.gn b/chrome/browser/share/BUILD.gn index a9bd452..38d8d04 100644 --- a/chrome/browser/share/BUILD.gn +++ b/chrome/browser/share/BUILD.gn
@@ -22,6 +22,7 @@ deps = [ "//base", + "//chrome/browser/favicon", "//chrome/browser/profiles:profile", "//chrome/browser/share/proto:proto", "//chrome/services/qrcode_generator/public/cpp",
diff --git a/chrome/browser/share/share_attempt.cc b/chrome/browser/share/share_attempt.cc index 5c26d81..8abd1dc3 100644 --- a/chrome/browser/share/share_attempt.cc +++ b/chrome/browser/share/share_attempt.cc
@@ -4,16 +4,25 @@ #include "chrome/browser/share/share_attempt.h" +#include "chrome/browser/favicon/favicon_utils.h" #include "content/public/browser/web_contents.h" +#include "ui/base/models/image_model.h" namespace share { ShareAttempt::ShareAttempt(content::WebContents* contents) - : ShareAttempt(contents, contents->GetTitle(), contents->GetVisibleURL()) {} + : ShareAttempt(contents, + contents->GetTitle(), + contents->GetVisibleURL(), + ui::ImageModel::FromImage(favicon::GetDefaultFavicon())) {} ShareAttempt::ShareAttempt(content::WebContents* contents, std::u16string title, - GURL url) - : web_contents(contents->GetWeakPtr()), title(title), url(url) {} + GURL url, + ui::ImageModel preview_image) + : web_contents(contents->GetWeakPtr()), + title(title), + url(url), + preview_image(preview_image) {} ShareAttempt::~ShareAttempt() = default;
diff --git a/chrome/browser/share/share_attempt.h b/chrome/browser/share/share_attempt.h index bf9bb1ca..6110016 100644 --- a/chrome/browser/share/share_attempt.h +++ b/chrome/browser/share/share_attempt.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_SHARE_SHARE_ATTEMPT_H_ #include "base/memory/weak_ptr.h" +#include "ui/base/models/image_model.h" #include "url/gurl.h" namespace content { @@ -18,7 +19,10 @@ // content - a whole page, a link, an image, or perhaps (later on) other types. struct ShareAttempt { explicit ShareAttempt(content::WebContents* contents); - ShareAttempt(content::WebContents* contents, std::u16string title, GURL url); + ShareAttempt(content::WebContents* contents, + std::u16string title, + GURL url, + ui::ImageModel preview_image); ~ShareAttempt(); ShareAttempt(const ShareAttempt&); @@ -27,6 +31,11 @@ base::WeakPtr<content::WebContents> web_contents; const std::u16string title; const GURL url; + + // The initial preview image to use for the share - note that this may get + // replaced if a better preview image becomes available. See + // SharingHubBubbleController::RegisterPreviewImageChangedCallback(). + ui::ImageModel preview_image; }; } // namespace share
diff --git a/chrome/browser/spellchecker/spellcheck_mac_view_interactive_uitest.mm b/chrome/browser/spellchecker/spellcheck_mac_view_interactive_uitest.mm index 093f20e..dd37cfa 100644 --- a/chrome/browser/spellchecker/spellcheck_mac_view_interactive_uitest.mm +++ b/chrome/browser/spellchecker/spellcheck_mac_view_interactive_uitest.mm
@@ -40,7 +40,7 @@ test_helper.RunUntilBind(); spellcheck::SpellCheckMockPanelHost* host = test_helper.GetSpellCheckMockPanelHostForProcess( - web_contents->GetMainFrame()->GetProcess()); + web_contents->GetPrimaryMainFrame()->GetProcess()); EXPECT_TRUE(host->SpellingPanelVisible()); } #endif
diff --git a/chrome/browser/tracing/chrome_tracing_delegate.cc b/chrome/browser/tracing/chrome_tracing_delegate.cc index 271d647c..4ba6f3d 100644 --- a/chrome/browser/tracing/chrome_tracing_delegate.cc +++ b/chrome/browser/tracing/chrome_tracing_delegate.cc
@@ -28,11 +28,9 @@ #include "chrome/browser/ui/browser_otr_state.h" #include "chrome/common/pref_names.h" #include "components/metrics/metrics_pref_names.h" -#include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/tracing/common/background_tracing_state_manager.h" #include "components/tracing/common/background_tracing_utils.h" -#include "components/tracing/common/pref_names.h" #include "components/variations/active_field_trials.h" #include "components/version_info/version_info.h" #include "content/public/browser/background_tracing_config.h" @@ -108,13 +106,6 @@ } // namespace -void ChromeTracingDelegate::RegisterPrefs(PrefRegistrySimple* registry) { - // TODO(ssid): This is no longer used, remove the pref once the new one is - // stable. - registry->RegisterInt64Pref(prefs::kBackgroundTracingLastUpload, 0); - tracing::RegisterPrefs(registry); -} - ChromeTracingDelegate::ChromeTracingDelegate() { // Ensure that this code is called on the UI thread, except for // tests where a UI thread might not have been initialized at this point.
diff --git a/chrome/browser/tracing/chrome_tracing_delegate.h b/chrome/browser/tracing/chrome_tracing_delegate.h index 2db2911..2b9730bd 100644 --- a/chrome/browser/tracing/chrome_tracing_delegate.h +++ b/chrome/browser/tracing/chrome_tracing_delegate.h
@@ -18,8 +18,6 @@ #include "chrome/browser/ui/browser_list_observer.h" #endif -class PrefRegistrySimple; - namespace base { class Value; } @@ -35,8 +33,6 @@ ChromeTracingDelegate(); ~ChromeTracingDelegate() override; - static void RegisterPrefs(PrefRegistrySimple* registry); - // Returns if the tracing session is allowed to begin. Also updates the // background tracing state in prefs using BackgroundTracingStateManager. So, // this is required to be called exactly once per background tracing session
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 0cf9e837..48e4deb 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -4764,8 +4764,6 @@ "views/sharing_hub/sharing_hub_bubble_action_button.h", "views/sharing_hub/sharing_hub_bubble_util.cc", "views/sharing_hub/sharing_hub_bubble_util.h", - "views/sharing_hub/sharing_hub_bubble_view_impl.cc", - "views/sharing_hub/sharing_hub_bubble_view_impl.h", "views/sharing_hub/sharing_hub_icon_view.cc", "views/sharing_hub/sharing_hub_icon_view.h", "views/shopping_bubble/shopping_prompt_impl.cc", @@ -5229,6 +5227,8 @@ "views/frame/opaque_browser_frame_view_layout.h", "views/frame/opaque_browser_frame_view_layout_delegate.cc", "views/frame/opaque_browser_frame_view_layout_delegate.h", + "views/sharing_hub/sharing_hub_bubble_view_impl.cc", + "views/sharing_hub/sharing_hub_bubble_view_impl.h", ] deps += [ "//ui/views/window/vector_icons" ] }
diff --git a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuTest.java b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuTest.java index 9699adf..13f85d0 100644 --- a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuTest.java +++ b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuTest.java
@@ -6,7 +6,6 @@ import static org.mockito.ArgumentMatchers.eq; -import android.app.Activity; import android.graphics.Canvas; import android.graphics.Rect; import android.view.KeyEvent; @@ -20,18 +19,14 @@ import androidx.test.filters.MediumTest; import androidx.test.filters.SmallTest; -import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; -import org.junit.Before; import org.junit.BeforeClass; -import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.chromium.base.test.BaseActivityTestRule; import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; @@ -47,6 +42,7 @@ import org.chromium.components.browser_ui.widget.highlight.ViewHighlighterTestUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.BlankUiTestActivity; +import org.chromium.ui.test.util.BlankUiTestActivityTestCase; import org.chromium.ui.test.util.UiDisableIf; import java.util.ArrayList; @@ -60,13 +56,8 @@ */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -@Batch(Batch.UNIT_TESTS) -public class AppMenuTest { - @ClassRule - public static BaseActivityTestRule<BlankUiTestActivity> sActivityTestRule = - new BaseActivityTestRule<>(BlankUiTestActivity.class); - - private Activity mActivity; +@Batch(Batch.PER_CLASS) +public class AppMenuTest extends BlankUiTestActivityTestCase { private AppMenuCoordinatorImpl mAppMenuCoordinator; private AppMenuHandlerImpl mAppMenuHandler; private TestAppMenuPropertiesDelegate mPropertiesDelegate; @@ -84,38 +75,28 @@ @BeforeClass public static void setUpBeforeActivityLaunched() { BlankUiTestActivity.setTestLayout(R.layout.test_app_menu_activity_layout); - sActivityTestRule.launchActivity(null); } - @Before + @Override public void setUpTest() throws Exception { + super.setUpTest(); mCanvas = Mockito.mock(Canvas.class); TestThreadUtils.runOnUiThreadBlocking(this::setUpTestOnUiThread); mLifecycleDispatcher.observerRegisteredCallbackHelper.waitForCallback(0); } - @After - public void teardownTest() { - TestThreadUtils.runOnUiThreadBlocking(() -> { - mAppMenuHandler.hideAppMenu(); - mTestMenuButtonDelegate.getMenuButtonView().setPressed(false); - mAppMenuCoordinator.destroy(); - }); - } - @AfterClass public static void tearDownAfterActivityDestroyed() { AppMenuCoordinatorImpl.setHasPermanentMenuKeyForTesting(null); } private void setUpTestOnUiThread() { - mActivity = sActivityTestRule.getActivity(); mLifecycleDispatcher = new TestActivityLifecycleDispatcher(); mDelegate = new TestAppMenuDelegate(); mTestMenuButtonDelegate = new TestMenuButtonDelegate(); - mAppMenuCoordinator = new AppMenuCoordinatorImpl(mActivity, mLifecycleDispatcher, - mTestMenuButtonDelegate, mDelegate, mActivity.getWindow().getDecorView(), - mActivity.findViewById(R.id.menu_anchor_stub)); + mAppMenuCoordinator = new AppMenuCoordinatorImpl(getActivity(), mLifecycleDispatcher, + mTestMenuButtonDelegate, mDelegate, getActivity().getWindow().getDecorView(), + getActivity().findViewById(R.id.menu_anchor_stub)); mAppMenuHandler = mAppMenuCoordinator.getAppMenuHandlerImplForTesting(); mMenuObserver = new TestAppMenuObserver(); mAppMenuCoordinator.getAppMenuHandler().addObserver(mMenuObserver); @@ -161,7 +142,7 @@ AppMenuCoordinatorImpl.setHasPermanentMenuKeyForTesting(false); showMenuAndAssert(); - View topAnchor = mActivity.findViewById(R.id.top_button); + View topAnchor = getActivity().findViewById(R.id.top_button); Rect viewRect = getViewLocationRect(topAnchor); Rect popupRect = getPopupLocationRect(); @@ -186,7 +167,7 @@ AppMenuCoordinatorImpl.setHasPermanentMenuKeyForTesting(true); showMenuAndAssert(); - View anchorStub = mActivity.findViewById(R.id.menu_anchor_stub); + View anchorStub = getActivity().findViewById(R.id.menu_anchor_stub); Rect viewRect = getViewLocationRect(anchorStub); Rect popupRect = getPopupLocationRect(); @@ -255,7 +236,7 @@ showMenuAndAssert(); AppMenu spiedMenu = Mockito.spy(mAppMenuHandler.getAppMenu()); - View dummyView = new View(mActivity); + View dummyView = new View(getActivity()); TestThreadUtils.runOnUiThreadBlocking(() -> { spiedMenu.onItemLongClick( mAppMenuHandler.getAppMenu().getMenuItemPropertyModel(R.id.icon_one), @@ -272,7 +253,7 @@ showMenuAndAssert(); AppMenu spiedMenu = Mockito.spy(mAppMenuHandler.getAppMenu()); - View dummyView = new View(mActivity); + View dummyView = new View(getActivity()); TestThreadUtils.runOnUiThreadBlocking(() -> { spiedMenu.onItemLongClick( mAppMenuHandler.getAppMenu().getMenuItemPropertyModel(R.id.icon_two), @@ -289,7 +270,7 @@ showMenuAndAssert(); AppMenu spiedMenu = Mockito.spy(mAppMenuHandler.getAppMenu()); - View dummyView = new View(mActivity); + View dummyView = new View(getActivity()); TestThreadUtils.runOnUiThreadBlocking(() -> { spiedMenu.onItemLongClick( mAppMenuHandler.getAppMenu().getMenuItemPropertyModel(R.id.icon_three), @@ -892,7 +873,7 @@ @Nullable @Override public View getMenuButtonView() { - return mActivity.findViewById(R.id.top_button); + return getActivity().findViewById(R.id.top_button); } }
diff --git a/chrome/browser/ui/android/omnibox/BUILD.gn b/chrome/browser/ui/android/omnibox/BUILD.gn index d3254c8b..b0b5cec4 100644 --- a/chrome/browser/ui/android/omnibox/BUILD.gn +++ b/chrome/browser/ui/android/omnibox/BUILD.gn
@@ -356,6 +356,7 @@ "java/src/org/chromium/chrome/browser/omnibox/KeyboardHideHelperUnitTest.java", "java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java", "java/src/org/chromium/chrome/browser/omnibox/SearchEngineLogoUtilsUnitTest.java", + "java/src/org/chromium/chrome/browser/omnibox/ShadowUrlBarData.java", "java/src/org/chromium/chrome/browser/omnibox/SpannableAutocompleteEditTextModelUnitTest.java", "java/src/org/chromium/chrome/browser/omnibox/UrlBarDataTest.java", "java/src/org/chromium/chrome/browser/omnibox/UrlBarMediatorUnitTest.java", @@ -371,6 +372,7 @@ "java/src/org/chromium/chrome/browser/omnibox/suggestions/base/SimpleHorizontalLayoutViewTest.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/base/SimpleVerticalLayoutViewTest.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/base/SuggestionSpannableUnitTest.java", + "java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorUnitTest.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/carousel/BaseCarouselSuggestionSelectionManagerUnitTest.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/carousel/BaseCarouselSuggestionViewBinderUnitTest.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/header/HeaderViewBinderUnitTest.java", @@ -430,6 +432,7 @@ "//ui/android:ui_no_recycler_view_java", "//ui/android:ui_recycler_view_java", "//url:gurl_java", + "//url:gurl_junit_shadows", "//url:gurl_junit_test_support", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/ShadowUrlBarData.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/ShadowUrlBarData.java new file mode 100644 index 0000000..0e44fe7 --- /dev/null +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/ShadowUrlBarData.java
@@ -0,0 +1,23 @@ +// Copyright 2022 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.omnibox; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +/** + * Shadow of the UrlBarData, that permits stubbing/mocking static methods for testing. + */ +@Implements(UrlBarData.class) +public class ShadowUrlBarData { + public static boolean sShouldShowNextUrl = true; + + @Implementation + public static boolean shouldShowUrl(String url, boolean isIncognito) { + boolean res = sShouldShowNextUrl; + sShouldShowNextUrl = true; + return res; + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorUnitTest.java similarity index 82% rename from chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorUnitTest.java rename to chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorUnitTest.java index a9fce94..e78ca07 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorUnitTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorUnitTest.java
@@ -10,10 +10,8 @@ import static org.mockito.Mockito.verify; import android.graphics.Bitmap; -import android.graphics.Bitmap.Config; import android.graphics.drawable.BitmapDrawable; -import androidx.collection.ArrayMap; import androidx.test.filters.SmallTest; import org.junit.Assert; @@ -24,39 +22,45 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.annotation.Config; import org.chromium.base.ContextUtils; -import org.chromium.base.test.BaseJUnit4ClassRunner; -import org.chromium.base.test.UiThreadTest; -import org.chromium.base.test.util.Batch; +import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.R; import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType; +import org.chromium.chrome.browser.omnibox.ShadowUrlBarData; import org.chromium.chrome.browser.omnibox.UrlBarEditingTextStateProvider; import org.chromium.chrome.browser.omnibox.suggestions.SuggestionHost; import org.chromium.chrome.browser.omnibox.suggestions.base.BaseSuggestionViewProperties; import org.chromium.chrome.browser.omnibox.suggestions.base.SuggestionDrawableState; import org.chromium.chrome.browser.omnibox.suggestions.basic.SuggestionViewProperties.SuggestionIcon; import org.chromium.chrome.test.util.browser.Features; -import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.favicon.LargeIconBridge; import org.chromium.components.favicon.LargeIconBridge.LargeIconCallback; import org.chromium.components.omnibox.AutocompleteMatch; import org.chromium.components.omnibox.AutocompleteMatchBuilder; -import org.chromium.content_public.browser.test.NativeLibraryTestUtils; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.url.GURL; +import org.chromium.url.JUnitTestGURLs; +import org.chromium.url.ShadowGURL; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Tests for {@link BasicSuggestionProcessor}. */ -@RunWith(BaseJUnit4ClassRunner.class) -@Batch(Batch.UNIT_TESTS) +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE, shadows = {ShadowGURL.class, ShadowUrlBarData.class}) public class BasicSuggestionProcessorUnitTest { - private static final ArrayMap<Integer, String> ICON_TYPE_NAMES = - new ArrayMap<Integer, String>(SuggestionIcon.TOTAL_COUNT) { + private static final GURL EXTERNAL_URL = JUnitTestGURLs.getGURL(JUnitTestGURLs.URL_1); + private static final GURL INTERNAL_URL = JUnitTestGURLs.getGURL(JUnitTestGURLs.NTP_URL); + + private static final Map<Integer, String> ICON_TYPE_NAMES = + new HashMap<Integer, String>(SuggestionIcon.TOTAL_COUNT) { { put(SuggestionIcon.UNSET, "UNSET"); put(SuggestionIcon.BOOKMARK, "BOOKMARK"); @@ -68,43 +72,39 @@ } }; - private static final ArrayMap<Integer, String> SUGGESTION_TYPE_NAMES = - new ArrayMap<Integer, String>(OmniboxSuggestionType.NUM_TYPES) { - { - put(OmniboxSuggestionType.URL_WHAT_YOU_TYPED, "URL_WHAT_YOU_TYPED"); - put(OmniboxSuggestionType.HISTORY_URL, "HISTORY_URL"); - put(OmniboxSuggestionType.HISTORY_TITLE, "HISTORY_TITLE"); - put(OmniboxSuggestionType.HISTORY_BODY, "HISTORY_BODY"); - put(OmniboxSuggestionType.HISTORY_KEYWORD, "HISTORY_KEYWORD"); - put(OmniboxSuggestionType.NAVSUGGEST, "NAVSUGGEST"); - put(OmniboxSuggestionType.SEARCH_WHAT_YOU_TYPED, "SEARCH_WHAT_YOU_TYPED"); - put(OmniboxSuggestionType.SEARCH_HISTORY, "SEARCH_HISTORY"); - put(OmniboxSuggestionType.SEARCH_SUGGEST, "SEARCH_SUGGEST"); - put(OmniboxSuggestionType.SEARCH_SUGGEST_ENTITY, "SEARCH_SUGGEST_ENTITY"); - put(OmniboxSuggestionType.SEARCH_SUGGEST_TAIL, "SEARCH_SUGGEST_TAIL"); - put(OmniboxSuggestionType.SEARCH_SUGGEST_PERSONALIZED, - "SEARCH_SUGGEST_PERSONALIZED"); - put(OmniboxSuggestionType.SEARCH_SUGGEST_PROFILE, "SEARCH_SUGGEST_PROFILE"); - put(OmniboxSuggestionType.SEARCH_OTHER_ENGINE, "SEARCH_OTHER_ENGINE"); - put(OmniboxSuggestionType.NAVSUGGEST_PERSONALIZED, "NAVSUGGEST_PERSONALIZED"); - put(OmniboxSuggestionType.VOICE_SUGGEST, "VOICE_SUGGEST"); - put(OmniboxSuggestionType.DOCUMENT_SUGGESTION, "DOCUMENT_SUGGESTION"); - // Note: CALCULATOR suggestions are not handled by basic suggestion processor. - // These suggestions are now processed by AnswerSuggestionProcessor instead. - } - }; + private static final Map<Integer, String> SUGGESTION_TYPE_NAMES = new HashMap<Integer, String>( + OmniboxSuggestionType.NUM_TYPES) { + { + put(OmniboxSuggestionType.URL_WHAT_YOU_TYPED, "URL_WHAT_YOU_TYPED"); + put(OmniboxSuggestionType.HISTORY_URL, "HISTORY_URL"); + put(OmniboxSuggestionType.HISTORY_TITLE, "HISTORY_TITLE"); + put(OmniboxSuggestionType.HISTORY_BODY, "HISTORY_BODY"); + put(OmniboxSuggestionType.HISTORY_KEYWORD, "HISTORY_KEYWORD"); + put(OmniboxSuggestionType.NAVSUGGEST, "NAVSUGGEST"); + put(OmniboxSuggestionType.SEARCH_WHAT_YOU_TYPED, "SEARCH_WHAT_YOU_TYPED"); + put(OmniboxSuggestionType.SEARCH_HISTORY, "SEARCH_HISTORY"); + put(OmniboxSuggestionType.SEARCH_SUGGEST, "SEARCH_SUGGEST"); + put(OmniboxSuggestionType.SEARCH_SUGGEST_ENTITY, "SEARCH_SUGGEST_ENTITY"); + put(OmniboxSuggestionType.SEARCH_SUGGEST_TAIL, "SEARCH_SUGGEST_TAIL"); + put(OmniboxSuggestionType.SEARCH_SUGGEST_PERSONALIZED, "SEARCH_SUGGEST_PERSONALIZED"); + put(OmniboxSuggestionType.SEARCH_SUGGEST_PROFILE, "SEARCH_SUGGEST_PROFILE"); + put(OmniboxSuggestionType.SEARCH_OTHER_ENGINE, "SEARCH_OTHER_ENGINE"); + put(OmniboxSuggestionType.NAVSUGGEST_PERSONALIZED, "NAVSUGGEST_PERSONALIZED"); + put(OmniboxSuggestionType.VOICE_SUGGEST, "VOICE_SUGGEST"); + put(OmniboxSuggestionType.DOCUMENT_SUGGESTION, "DOCUMENT_SUGGESTION"); + // Note: CALCULATOR suggestions are not handled by basic suggestion processor. + // These suggestions are now processed by AnswerSuggestionProcessor instead. + } + }; - @Rule - public TestRule mFeaturesProcessor = new Features.JUnitProcessor(); + public @Rule TestRule mFeaturesProcessor = new Features.JUnitProcessor(); + public @Rule MockitoRule mMockitoRule = MockitoJUnit.rule(); - @Mock - SuggestionHost mSuggestionHost; - @Mock - LargeIconBridge mIconBridge; - @Mock - UrlBarEditingTextStateProvider mUrlBarText; + private @Mock SuggestionHost mSuggestionHost; + private @Mock LargeIconBridge mIconBridge; + private @Mock UrlBarEditingTextStateProvider mUrlBarText; + private @Mock Bitmap mBitmap; - private Bitmap mBitmap; private BasicSuggestionProcessor mProcessor; private AutocompleteMatch mSuggestion; private PropertyModel mModel; @@ -122,10 +122,7 @@ @Before public void setUp() { - MockitoAnnotations.initMocks(this); - NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess(); doReturn("").when(mUrlBarText).getTextWithoutAutocomplete(); - mBitmap = Bitmap.createBitmap(1, 1, Config.ALPHA_8); mProcessor = new BasicSuggestionProcessor(ContextUtils.getApplicationContext(), mSuggestionHost, mUrlBarText, () -> mIconBridge, mIsBookmarked); } @@ -175,7 +172,6 @@ @Test @SmallTest - @UiThreadTest public void getSuggestionIconTypeForSearch_Default() { int[][] testCases = { {OmniboxSuggestionType.URL_WHAT_YOU_TYPED, SuggestionIcon.MAGNIFIER}, @@ -207,7 +203,6 @@ @Test @SmallTest - @UiThreadTest public void getSuggestionIconTypeForUrl_Default() { int[][] testCases = { {OmniboxSuggestionType.URL_WHAT_YOU_TYPED, SuggestionIcon.GLOBE}, @@ -239,7 +234,6 @@ @Test @SmallTest - @UiThreadTest public void getSuggestionIconTypeForBookmarks_Default() { int[][] testCases = { {OmniboxSuggestionType.URL_WHAT_YOU_TYPED, SuggestionIcon.BOOKMARK}, @@ -273,7 +267,6 @@ @Test @SmallTest - @UiThreadTest public void getSuggestionIconTypeForTrendingQueries() { int[][] testCases = { {OmniboxSuggestionType.URL_WHAT_YOU_TYPED, SuggestionIcon.TRENDS}, @@ -296,7 +289,6 @@ @Test @SmallTest - @UiThreadTest public void refineIconNotShownForWhatYouTypedSuggestions() { final String typed = "Typed content"; doReturn(typed).when(mUrlBarText).getTextWithoutAutocomplete(); @@ -312,7 +304,6 @@ @Test @SmallTest - @UiThreadTest public void refineIconShownForRefineSuggestions() { final String typed = "Typed conte"; final String refined = "Typed content"; @@ -335,7 +326,6 @@ @Test @SmallTest - @UiThreadTest public void switchTabIconShownForSwitchToTabSuggestions() { final String tabMatch = "tab match"; createSwitchToTabSuggestion(OmniboxSuggestionType.URL_WHAT_YOU_TYPED, tabMatch); @@ -352,7 +342,6 @@ @Test @SmallTest - @UiThreadTest public void suggestionFavicons_showFaviconWhenAvailable() { final ArgumentCaptor<LargeIconCallback> callback = ArgumentCaptor.forClass(LargeIconCallback.class); @@ -373,7 +362,6 @@ @Test @SmallTest - @UiThreadTest public void suggestionFavicons_doNotReplaceFallbackIconWhenNoFaviconIsAvailable() { final ArgumentCaptor<LargeIconCallback> callback = ArgumentCaptor.forClass(LargeIconCallback.class); @@ -393,7 +381,6 @@ @Test @SmallTest - @UiThreadTest public void searchSuggestions_searchQueriesCanWrapAroundWithFeatureEnabled() { mProcessor.onNativeInitialized(); createSearchSuggestion(OmniboxSuggestionType.SEARCH_WHAT_YOU_TYPED, ""); @@ -405,17 +392,12 @@ @Test @SmallTest - @UiThreadTest public void internalUrlSuggestions_doNotPresentInternalScheme() { mProcessor.onNativeInitialized(); - // chrome://newtab and such should have no URL in the suggestions list. - createUrlSuggestion(OmniboxSuggestionType.URL_WHAT_YOU_TYPED, "", - new GURL(UrlConstants.NTP_NON_NATIVE_URL)); - Assert.assertNull(mModel.get(SuggestionViewProperties.TEXT_LINE_2_TEXT)); - - // Similarly, internal (eg. chrome-intenal://) URLs should not be shown. + // URLs that are rejected by UrlBarData should not be presented to the User. + ShadowUrlBarData.sShouldShowNextUrl = false; createUrlSuggestion( - OmniboxSuggestionType.URL_WHAT_YOU_TYPED, "", new GURL(UrlConstants.DOWNLOADS_URL)); + OmniboxSuggestionType.URL_WHAT_YOU_TYPED, "", new GURL(JUnitTestGURLs.URL_1)); Assert.assertNull(mModel.get(SuggestionViewProperties.TEXT_LINE_2_TEXT)); } }
diff --git a/chrome/browser/ui/cocoa/applescript/tab_applescript.mm b/chrome/browser/ui/cocoa/applescript/tab_applescript.mm index 1bc4a58..d1ddc0e 100644 --- a/chrome/browser/ui/cocoa/applescript/tab_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/tab_applescript.mm
@@ -236,7 +236,7 @@ - (void)handlesPrintScriptCommand:(NSScriptCommand*)command { AppleScript::LogAppleScriptUMA(AppleScript::AppleScriptCommand::TAB_PRINT); bool initiated = printing::PrintViewManager::FromWebContents(_webContents) - ->PrintNow(_webContents->GetMainFrame()); + ->PrintNow(_webContents->GetPrimaryMainFrame()); if (!initiated) { AppleScript::SetError(AppleScript::errInitiatePrinting); } @@ -306,7 +306,7 @@ return nil; } - content::RenderFrameHost* frame = _webContents->GetMainFrame(); + content::RenderFrameHost* frame = _webContents->GetPrimaryMainFrame(); if (!frame) { NOTREACHED(); return nil;
diff --git a/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_unittest.mm b/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_unittest.mm index 0d76c2b..c8a49ad4 100644 --- a/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_unittest.mm +++ b/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_unittest.mm
@@ -31,7 +31,7 @@ content::ContextMenuParams params; params.selection_text = base::UTF8ToUTF16(text); auto menu = std::make_unique<RenderViewContextMenuMac>( - *contents_->GetMainFrame(), params); + *contents_->GetPrimaryMainFrame(), params); menu->InitToolkitMenu(); return menu; }
diff --git a/chrome/browser/ui/content_settings/content_setting_media_image_model_unittest.mm b/chrome/browser/ui/content_settings/content_setting_media_image_model_unittest.mm index 5f41ec0..98d90ac 100644 --- a/chrome/browser/ui/content_settings/content_setting_media_image_model_unittest.mm +++ b/chrome/browser/ui/content_settings/content_setting_media_image_model_unittest.mm
@@ -87,8 +87,8 @@ web_contents(), std::make_unique<chrome::PageSpecificContentSettingsDelegate>( web_contents())); - auto* content_settings = - PageSpecificContentSettings::GetForFrame(web_contents()->GetMainFrame()); + auto* content_settings = PageSpecificContentSettings::GetForFrame( + web_contents()->GetPrimaryMainFrame()); const GURL kTestOrigin("https://www.example.com"); auto content_setting_image_model = ContentSettingImageModel::CreateForContentType(
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h index 73f95d0..5c5b1823 100644 --- a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h +++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_UI_SHARING_HUB_SHARING_HUB_BUBBLE_CONTROLLER_H_ #include "chrome/browser/share/share_attempt.h" +#include "chrome/browser/sharing_hub/sharing_hub_model.h" namespace content { class WebContents; @@ -33,6 +34,39 @@ virtual SharingHubBubbleView* sharing_hub_bubble_view() const = 0; // Returns true if the omnibox icon should be shown. virtual bool ShouldOfferOmniboxIcon() = 0; + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_FUCHSIA) + // These two methods return the sets of first- and third-party actions; + // first-party actions are internal to Chrome and third-party actions are + // other websites or apps. + // + // TODO(ellyjones): Could we feasibly pass these in when we construct + // ShareAttempt? Does that make sense, even? + virtual std::vector<SharingHubAction> GetFirstPartyActions() = 0; + virtual std::vector<SharingHubAction> GetThirdPartyActions() = 0; + + // Returns whether the sharing hub should show a preview section or not. + // TODO(ellyjones): Remove this once the preview section is launched. + virtual bool ShouldUsePreview() = 0; + + // The sharing hub can load images asynchronously under some circumstances; to + // allow for that, the controller allows clients to register a callback to be + // notified when a new image is loaded. + using PreviewImageChangedCallback = + base::RepeatingCallback<void(ui::ImageModel)>; + virtual base::CallbackListSubscription RegisterPreviewImageChangedCallback( + PreviewImageChangedCallback callback) = 0; + + virtual base::WeakPtr<SharingHubBubbleController> GetWeakPtr() = 0; + + // Client code should call these when the corresponding things happen in the + // View. + virtual void OnBubbleClosed() = 0; + virtual void OnActionSelected(int command_id, + bool is_first_party, + std::string feature_name_for_metrics) = 0; +#endif }; } // namespace sharing_hub
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.cc b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.cc index 66bf082a..3209025 100644 --- a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.cc +++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.cc
@@ -162,28 +162,17 @@ share::DesktopSharePreviewVariant::kDisabled; } -std::u16string SharingHubBubbleControllerDesktopImpl::GetPreviewTitle() { - // TODO(https://crbug.com/1312524): get passed this state from the omnibox - // instead. - return GetWebContents().GetTitle(); -} - -GURL SharingHubBubbleControllerDesktopImpl::GetPreviewUrl() { - // TODO(https://crbug.com/1312524): get passed this state from the omnibox - // instead. - return GetWebContents().GetVisibleURL(); -} - -ui::ImageModel SharingHubBubbleControllerDesktopImpl::GetPreviewImage() { - return ui::ImageModel::FromImage(favicon::GetDefaultFavicon()); -} - base::CallbackListSubscription SharingHubBubbleControllerDesktopImpl::RegisterPreviewImageChangedCallback( PreviewImageChangedCallback callback) { return preview_image_changed_callbacks_.Add(callback); } +base::WeakPtr<SharingHubBubbleController> +SharingHubBubbleControllerDesktopImpl::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + void SharingHubBubbleControllerDesktopImpl::OnActionSelected( int command_id, bool is_first_party, @@ -261,7 +250,7 @@ GetWebContents().GetPrimaryPage().GetMainDocument(); main_frame.GetOpenGraphMetadata(base::BindOnce( &SharingHubBubbleControllerDesktopImpl::OnGetOpenGraphMetadata, - AsWeakPtr())); + internal_weak_factory_.GetWeakPtr())); } void SharingHubBubbleControllerDesktopImpl::OnGetOpenGraphMetadata( @@ -288,7 +277,7 @@ image_fetcher_->FetchImage( *metadata->image, base::BindOnce(&SharingHubBubbleControllerDesktopImpl::OnGetHQImage, - AsWeakPtr()), + internal_weak_factory_.GetWeakPtr()), image_fetcher::ImageFetcherParams(kPreviewImageNetworkAnnotationTag, kPreviewUmaClient)); }
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.h b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.h index 9db0026..2268617 100644 --- a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.h +++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.h
@@ -38,12 +38,8 @@ : public SharingHubBubbleController, public content::WebContentsObserver, public content::WebContentsUserData< - SharingHubBubbleControllerDesktopImpl>, - public base::SupportsWeakPtr<SharingHubBubbleControllerDesktopImpl> { + SharingHubBubbleControllerDesktopImpl> { public: - using PreviewImageChangedCallback = - base::RepeatingCallback<void(ui::ImageModel)>; - SharingHubBubbleControllerDesktopImpl( const SharingHubBubbleControllerDesktopImpl&) = delete; SharingHubBubbleControllerDesktopImpl& operator=( @@ -62,27 +58,17 @@ // Returns the current profile. Profile* GetProfile() const; - // Returns the list of Sharing Hub first party actions. - virtual std::vector<SharingHubAction> GetFirstPartyActions(); - // Returns the list of Sharing Hub third party actions. - virtual std::vector<SharingHubAction> GetThirdPartyActions(); - - virtual bool ShouldUsePreview(); - virtual std::u16string GetPreviewTitle(); - virtual GURL GetPreviewUrl(); - virtual ui::ImageModel GetPreviewImage(); - + // SharingHubBubbleController: + std::vector<SharingHubAction> GetFirstPartyActions() override; + std::vector<SharingHubAction> GetThirdPartyActions() override; + bool ShouldUsePreview() override; base::CallbackListSubscription RegisterPreviewImageChangedCallback( - PreviewImageChangedCallback callback); - - // Handles when the user clicks on a Sharing Hub action. If this is a first - // party action, executes the appropriate browser command. If this is a third - // party action, navigates to an external webpage. - virtual void OnActionSelected(int command_id, - bool is_first_party, - std::string feature_name_for_metrics); - // Handler for when the bubble is closed. - void OnBubbleClosed(); + PreviewImageChangedCallback callback) override; + base::WeakPtr<SharingHubBubbleController> GetWeakPtr() override; + void OnActionSelected(int command_id, + bool is_first_party, + std::string feature_name_for_metrics) override; + void OnBubbleClosed() override; protected: explicit SharingHubBubbleControllerDesktopImpl( @@ -124,6 +110,17 @@ std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher_; + base::WeakPtrFactory<SharingHubBubbleController> weak_factory_{this}; + + // This is a bit ugly: SharingHubBubbleController's interface requires it to + // be able to create WeakPtr<SharingHubBubbleController>, but this class + // internally also needs to be able to bind weak pointers to itself for use + // with the image fetching state machine. Those internal weak pointers need to + // be to an instance of *this class*, not of the parent interface, so that we + // can bind them to methods on this class rather than the parent interface. + base::WeakPtrFactory<SharingHubBubbleControllerDesktopImpl> + internal_weak_factory_{this}; + WEB_CONTENTS_USER_DATA_KEY_DECL(); };
diff --git a/chrome/browser/ui/toolbar/location_bar_model_unittest.cc b/chrome/browser/ui/toolbar/location_bar_model_unittest.cc index 1410d00..91ae52d 100644 --- a/chrome/browser/ui/toolbar/location_bar_model_unittest.cc +++ b/chrome/browser/ui/toolbar/location_bar_model_unittest.cc
@@ -46,12 +46,19 @@ { GURL("view-source:http://www.google.com"), "view-source:www.google.com", - "view-source:www.google.com", }, { GURL(chrome::kChromeUINewTabURL), "", }, + // After executing the associated JS code, the "javascript:" scheme + // will cause the address in the location bar to revert to whatever + // it was prior to execution of the JS code (i.e. the URL of the + // previous test case) + { + GURL("javascript:alert(1);"), + "", + }, { GURL(std::string("view-source:") + chrome::kChromeUINewTabURL), "view-source:" + @@ -75,10 +82,54 @@ "google.com/search?q=tractor+supply", }, { + GURL("https://www.google.com/search?q=tractor+supply"), + "https://www.google.com/search?q=tractor+supply", + "google.com/search?q=tractor+supply", + }, + { GURL("https://m.google.ca/search?q=tractor+supply"), "https://m.google.ca/search?q=tractor+supply", "m.google.ca/search?q=tractor+supply", }, + { + GURL("http://m.google.ca/search?q=tractor+supply"), + "m.google.ca/search?q=tractor+supply", + }, + { + GURL("http://en.wikipedia.org"), + "en.wikipedia.org", + }, + { + GURL("https://en.wikipedia.org"), + "https://en.wikipedia.org", + "en.wikipedia.org", + }, + { + GURL("http://www3.nhk.or.jp/nhkworld"), + "www3.nhk.or.jp/nhkworld", + }, + { + GURL("https://www3.nhk.or.jp/nhkworld"), + "https://www3.nhk.or.jp/nhkworld", + "www3.nhk.or.jp/nhkworld", + }, +#if BUILDFLAG(IS_WIN) + { + GURL("file:///c:/path/to/file"), + "file:///C:/path/to/file", + "C:/path/to/file", + }, +#else + { + GURL("file:///path/to/file"), + "file:///path/to/file", + "/path/to/file", + }, +#endif + { + GURL("data:text/plain;base64,SGVsbG8sIFdvcmxkIQ=="), + "data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==", + }, }}; return *items; }
diff --git a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.cc b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.cc index f0aef18..1d1201d 100644 --- a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.cc
@@ -735,7 +735,8 @@ requests_access_.container->SetVisible(false); site_settings_button_->SetVisible(false); } else { - url::Origin origin = web_contents->GetMainFrame()->GetLastCommittedOrigin(); + url::Origin origin = + web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin(); extensions::PermissionsManager::UserSiteSetting site_setting = extensions::PermissionsManager::Get(browser_->profile()) ->GetUserSiteSetting(origin); @@ -833,8 +834,8 @@ extensions::PermissionsManager::UserSiteSetting site_setting; site_setting = extensions::PermissionsManager::Get(browser_->profile()) - ->GetUserSiteSetting( - web_contents->GetMainFrame()->GetLastCommittedOrigin()); + ->GetUserSiteSetting(web_contents->GetPrimaryMainFrame() + ->GetLastCommittedOrigin()); if (site_setting == UserSiteSetting::kGrantAllExtensions) return &has_access_; return &requests_access_; @@ -871,7 +872,7 @@ void ExtensionsTabbedMenuView::OnSiteSettingSelected( extensions::PermissionsManager::UserSiteSetting site_settings) { auto current_origin = - GetActiveWebContents()->GetMainFrame()->GetLastCommittedOrigin(); + GetActiveWebContents()->GetPrimaryMainFrame()->GetLastCommittedOrigin(); auto* permissions_manager = extensions::PermissionsManager::Get(browser_->profile()); switch (site_settings) {
diff --git a/chrome/browser/ui/views/sharing_hub/preview_view.cc b/chrome/browser/ui/views/sharing_hub/preview_view.cc index eb10a318..aea78548 100644 --- a/chrome/browser/ui/views/sharing_hub/preview_view.cc +++ b/chrome/browser/ui/views/sharing_hub/preview_view.cc
@@ -91,7 +91,7 @@ // View [FlexLayout, vertical] // Label (title) // Label (URL) -PreviewView::PreviewView(share::ShareAttempt attempt, ui::ImageModel image) { +PreviewView::PreviewView(share::ShareAttempt attempt) { auto variant = LayoutVariant::FromFeatureConfig(); auto* layout = SetLayoutManager(std::make_unique<views::FlexLayout>()); @@ -102,7 +102,8 @@ .SetDefault(views::kMarginsKey, variant.default_margin) .SetCollapseMargins(true); - image_ = AddChildView(std::make_unique<views::ImageView>(image)); + image_ = + AddChildView(std::make_unique<views::ImageView>(attempt.preview_image)); image_->SetPreferredSize(variant.image_size); auto* labels_container = AddChildView(std::make_unique<views::View>());
diff --git a/chrome/browser/ui/views/sharing_hub/preview_view.h b/chrome/browser/ui/views/sharing_hub/preview_view.h index adf318f2..06faebd 100644 --- a/chrome/browser/ui/views/sharing_hub/preview_view.h +++ b/chrome/browser/ui/views/sharing_hub/preview_view.h
@@ -30,11 +30,7 @@ // trial. class PreviewView : public views::View { public: - // Taking an initial image here, instead of requiring the caller to call - // OnImageChanged() after construction to set the initial image, means that - // this class always has a valid image to display and does not have a - // "half-initialized" state to worry about. - explicit PreviewView(share::ShareAttempt attempt, ui::ImageModel image); + explicit PreviewView(share::ShareAttempt attempt); ~PreviewView() override; // This seemingly-odd method allows for PreviewView to be uncoupled from the
diff --git a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc index 58a8cf8..8f9e433 100644 --- a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc +++ b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc
@@ -50,7 +50,7 @@ static_cast<SharingHubBubbleControllerDesktopImpl*>( SharingHubBubbleController::CreateOrGetFromWebContents( attempt.web_contents.get())); - controller_ = controller->AsWeakPtr(); + controller_ = controller->GetWeakPtr(); } SharingHubBubbleViewImpl::~SharingHubBubbleViewImpl() = default; @@ -129,8 +129,7 @@ auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>()); layout->SetOrientation(views::BoxLayout::Orientation::kVertical); if (controller_->ShouldUsePreview()) { - auto* preview = AddChildView(std::make_unique<PreviewView>( - attempt_, controller_->GetPreviewImage())); + auto* preview = AddChildView(std::make_unique<PreviewView>(attempt_)); preview->TakeCallbackSubscription( controller_->RegisterPreviewImageChangedCallback(base::BindRepeating( &PreviewView::OnImageChanged, base::Unretained(preview))));
diff --git a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h index 96757cd..7d068dc 100644 --- a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h +++ b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h
@@ -18,7 +18,7 @@ namespace sharing_hub { -class SharingHubBubbleControllerDesktopImpl; +class SharingHubBubbleController; class SharingHubBubbleActionButton; struct SharingHubAction; @@ -77,7 +77,7 @@ // the bubble during the window close path, since the bubble will be closed // asynchronously during browser window teardown but the controller will be // destroyed synchronously. - base::WeakPtr<SharingHubBubbleControllerDesktopImpl> controller_; + base::WeakPtr<SharingHubBubbleController> controller_; // ScrollView containing the list of share/save actions. raw_ptr<views::ScrollView> scroll_view_ = nullptr;
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_mac_win_linux.cc b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_mac_win_linux.cc index 09492721..93d6cd5 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_mac_win_linux.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_mac_win_linux.cc
@@ -65,6 +65,20 @@ helper_.CheckPlatformShortcutAndIcon(Site::kSiteA); } +IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTestMacWinLinux, + CheckSiteHandlesFile) { + helper_.InstallCreateShortcutWindowed(Site::kSiteB); + helper_.CheckSiteHandlesFile(Site::kSiteB, "qux"); + helper_.CheckSiteHandlesFile(Site::kSiteB, "quux"); +} + +IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTestMacWinLinux, + CheckSiteNotHandlesFile) { + helper_.InstallCreateShortcutWindowed(Site::kSiteA); + helper_.CheckSiteNotHandlesFile(Site::kSiteA, "qux"); + helper_.CheckSiteNotHandlesFile(Site::kSiteA, "quux"); +} + // Generated tests: IN_PROC_BROWSER_TEST_F(
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc index 3bcac7a..e2919a3 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
@@ -32,6 +32,7 @@ #include "chrome/browser/banners/test_app_banner_manager_desktop.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/shell_integration.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_dialogs.h" @@ -97,6 +98,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/manifest/display_mode.mojom-shared.h" #include "third_party/re2/src/re2/re2.h" #include "ui/accessibility/ax_action_data.h" @@ -120,13 +122,18 @@ #if BUILDFLAG(IS_MAC) #include <ImageIO/ImageIO.h> #include "chrome/browser/apps/app_shim/app_shim_manager_mac.h" +#include "chrome/browser/shell_integration.h" #include "chrome/browser/web_applications/app_shim_registry_mac.h" +#include "net/base/filename_util.h" #include "skia/ext/skia_utils_mac.h" #endif #if BUILDFLAG(IS_WIN) +#include "base/test/test_reg_util_win.h" #include "base/win/shortcut.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/web_applications/os_integration/web_app_handler_registration_utils_win.h" +#include "chrome/installer/util/shell_util.h" #endif namespace web_app::integration_tests { @@ -293,6 +300,23 @@ } #if BUILDFLAG(IS_WIN) +std::vector<std::wstring> GetFileExtensionsForProgId( + const std::wstring& file_handler_prog_id) { + const std::wstring prog_id_path = + base::StrCat({ShellUtil::kRegClasses, L"\\", file_handler_prog_id}); + + // Get list of handled file extensions from value FileExtensions at + // HKEY_CURRENT_USER\Software\Classes\<file_handler_prog_id>. + base::win::RegKey file_extensions_key(HKEY_CURRENT_USER, prog_id_path.c_str(), + KEY_QUERY_VALUE); + std::wstring handled_file_extensions; + EXPECT_EQ(file_extensions_key.ReadValue(L"FileExtensions", + &handled_file_extensions), + ERROR_SUCCESS); + return base::SplitString(handled_file_extensions, std::wstring(L";"), + base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); +} + base::FilePath GetShortcutProfile(base::FilePath shortcut_path) { base::FilePath shortcut_profile; std::wstring cmd_line_string; @@ -544,7 +568,7 @@ } void WebAppIntegrationTestDriver::SetUpOnMainThread() { - shortcut_override_ = OverrideShortcutsForTesting(); + shortcut_override_ = OverrideShortcutsForTesting(base::GetHomeDir()); // Only support manifest updates on non-sync tests, as the current // infrastructure here only supports listening on one profile. @@ -1831,6 +1855,26 @@ AfterStateCheckAction(); } +void WebAppIntegrationTestDriver::CheckSiteHandlesFile( + Site site, + std::string file_extension) { +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) + BeforeStateCheckAction(__FUNCTION__); + ASSERT_TRUE(IsFileHandledBySite(site, file_extension)); + AfterStateCheckAction(); +#endif +} + +void WebAppIntegrationTestDriver::CheckSiteNotHandlesFile( + Site site, + std::string file_extension) { +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) + BeforeStateCheckAction(__FUNCTION__); + ASSERT_FALSE(IsFileHandledBySite(site, file_extension)); + AfterStateCheckAction(); +#endif +} + void WebAppIntegrationTestDriver::CheckUserCannotSetRunOnOsLogin(Site site) { #if !BUILDFLAG(IS_CHROMEOS) BeforeStateCheckAction(__FUNCTION__); @@ -2468,6 +2512,49 @@ return is_shortcut_and_icon_correct; } +bool WebAppIntegrationTestDriver::IsFileHandledBySite( + Site site, + std::string file_extension) { + base::ScopedAllowBlockingForTesting allow_blocking; + bool is_file_handled = false; +#if BUILDFLAG(IS_WIN) + AppId app_id = GetAppIdBySiteMode(site); + const std::wstring prog_id = + GetProgIdForApp(browser()->profile()->GetPath(), app_id); + const std::vector<std::wstring> file_handler_prog_ids = + ShellUtil::GetFileHandlerProgIdsForAppId(prog_id); + + base::win::RegKey key; + std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; + for (const auto& file_handler_prog_id : file_handler_prog_ids) { + const std::vector<std::wstring> supported_file_extensions = + GetFileExtensionsForProgId(file_handler_prog_id); + std::wstring extension = converter.from_bytes("." + file_extension); + if (std::find(supported_file_extensions.begin(), + supported_file_extensions.end(), + extension) != supported_file_extensions.end()) { + const std::wstring reg_key = + L"Software\\Classes\\" + extension + L"\\OpenWithProgids"; + EXPECT_EQ(ERROR_SUCCESS, + key.Open(HKEY_CURRENT_USER, reg_key.data(), KEY_READ)); + return key.HasValue(file_handler_prog_id.data()); + } + } +#elif BUILDFLAG(IS_MAC) + std::string app_name = g_site_to_app_name.find(site)->second; + const base::FilePath test_file_path = + shortcut_override_->chrome_apps_folder.GetPath().AppendASCII( + "test." + file_extension); + const base::File test_file( + test_file_path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); + const GURL test_file_url = net::FilePathToFileURL(test_file_path); + is_file_handled = + (base::UTF8ToUTF16(app_name) == + shell_integration::GetApplicationNameForProtocol(test_file_url)); +#endif + return is_file_handled; +} + void WebAppIntegrationTestDriver::SetRunOnOsLoginMode( Site site, apps::RunOnOsLoginMode login_mode) { @@ -2542,6 +2629,7 @@ enabled_features.push_back(features::kPwaUpdateDialogForName); enabled_features.push_back(features::kDesktopPWAsEnforceWebAppSettingsPolicy); enabled_features.push_back(features::kWebAppWindowControlsOverlay); + enabled_features.push_back(blink::features::kFileHandlingAPI); #if BUILDFLAG(IS_CHROMEOS_ASH) disabled_features.push_back(features::kWebAppsCrosapi); disabled_features.push_back(chromeos::features::kLacrosPrimary);
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h index b68a41d..30a283fc 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h +++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h
@@ -261,6 +261,8 @@ void CheckPlatformShortcutNotExists(Site site); void CheckRunOnOsLoginEnabled(Site site); void CheckRunOnOsLoginDisabled(Site site); + void CheckSiteHandlesFile(Site site, std::string file_extension); + void CheckSiteNotHandlesFile(Site site, std::string file_extension); void CheckUserCannotSetRunOnOsLogin(Site site); void CheckUserDisplayModeInternal(UserDisplayMode user_display_mode); void CheckWindowClosed(); @@ -332,6 +334,8 @@ const std::string& name, const AppId& id); + bool IsFileHandledBySite(Site site, std::string file_extension); + void SetRunOnOsLoginMode(Site site, apps::RunOnOsLoginMode login_mode); void LaunchAppStartupBrowserCreator(const AppId& app_id);
diff --git a/chrome/browser/ui/webui/feed_internals/feed_internals.mojom b/chrome/browser/ui/webui/feed_internals/feed_internals.mojom index e26aed51..a842b1d 100644 --- a/chrome/browser/ui/webui/feed_internals/feed_internals.mojom +++ b/chrome/browser/ui/webui/feed_internals/feed_internals.mojom
@@ -31,9 +31,8 @@ // Whether debugging the WebFeed follow intro is enabled. bool is_web_feed_follow_intro_debug_enabled; - // Whether the legacy feed endpoint should be used for Web Feed content - // fetches. - bool use_feed_query_requests_for_web_feeds; + // Whether the legacy feed endpoint should be used. + bool use_feed_query_requests; // Last load stream status, human readable. string load_stream_status; @@ -117,7 +116,7 @@ // Sets whether the legacy feed endpoint should be used for Web Feed content // fetches. - SetUseFeedQueryRequestsForWebFeeds(bool use_legacy); + SetUseFeedQueryRequests(bool use_legacy); // Sets the Following feed order in local preferences. SetFollowingFeedOrder(FeedOrder order);
diff --git a/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.cc b/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.cc index 7641e07..90edb76 100644 --- a/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.cc +++ b/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.cc
@@ -64,8 +64,7 @@ offline_pages::prefetch_prefs::IsEnabled(pref_service_); properties->is_web_feed_follow_intro_debug_enabled = IsWebFeedFollowIntroDebugEnabled(); - properties->use_feed_query_requests_for_web_feeds = - ShouldUseFeedQueryRequestsForWebFeeds(); + properties->use_feed_query_requests = ShouldUseFeedQueryRequests(); if (debug_data.fetch_info) properties->feed_fetch_url = debug_data.fetch_info->base_request_url; if (debug_data.upload_info) @@ -157,13 +156,13 @@ enabled); } -bool FeedV2InternalsPageHandler::ShouldUseFeedQueryRequestsForWebFeeds() { - return feed::GetFeedConfig().use_feed_query_requests_for_web_feeds; +bool FeedV2InternalsPageHandler::ShouldUseFeedQueryRequests() { + return feed::GetFeedConfig().use_feed_query_requests; } -void FeedV2InternalsPageHandler::SetUseFeedQueryRequestsForWebFeeds( +void FeedV2InternalsPageHandler::SetUseFeedQueryRequests( const bool use_legacy) { - feed::SetUseFeedQueryRequestsForWebFeeds(use_legacy); + feed::SetUseFeedQueryRequests(use_legacy); } feed_internals::mojom::FeedOrder
diff --git a/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.h b/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.h index 35d759b9..34efba4c 100644 --- a/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.h +++ b/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.h
@@ -46,14 +46,14 @@ void OverrideDiscoverApiEndpoint(const GURL& endpoint_url) override; void OverrideFeedStreamData(const std::vector<uint8_t>& data) override; void SetWebFeedFollowIntroDebugEnabled(const bool enabled) override; - void SetUseFeedQueryRequestsForWebFeeds(const bool use_legacy) override; + void SetUseFeedQueryRequests(const bool use_legacy) override; void SetFollowingFeedOrder( const feed_internals::mojom::FeedOrder new_order) override; private: bool IsFeedAllowed(); bool IsWebFeedFollowIntroDebugEnabled(); - bool ShouldUseFeedQueryRequestsForWebFeeds(); + bool ShouldUseFeedQueryRequests(); feed_internals::mojom::FeedOrder GetFollowingFeedOrder(); mojo::Receiver<feed_internals::mojom::PageHandler> receiver_;
diff --git a/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc b/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc index 7db11fbc..18cab3a 100644 --- a/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc +++ b/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc
@@ -156,7 +156,7 @@ PrintBackend::CreateInstance(locale)); PrinterList printer_list; - mojom::ResultCode result = print_backend->EnumeratePrinters(&printer_list); + mojom::ResultCode result = print_backend->EnumeratePrinters(printer_list); if (result != mojom::ResultCode::kSuccess) { PRINTER_LOG(ERROR) << "Failure enumerating local printers, result: " << result;
diff --git a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc index 17c3374..af094de 100644 --- a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
@@ -102,16 +102,16 @@ } // Returns the list of |printers| formatted as a CupsPrintersList. -base::Value BuildCupsPrintersList(const std::vector<Printer>& printers) { - base::Value printers_list(base::Value::Type::LIST); +base::Value::Dict BuildCupsPrintersList(const std::vector<Printer>& printers) { + base::Value::List printers_list; for (const Printer& printer : printers) { // Some of these printers could be invalid but we want to allow the user // to edit them. crbug.com/778383 printers_list.Append(GetCupsPrinterInfo(printer)); } - base::Value response(base::Value::Type::DICTIONARY); - response.SetKey("printerList", std::move(printers_list)); + base::Value::Dict response; + response.Set("printerList", std::move(printers_list)); return response; } @@ -383,8 +383,8 @@ std::vector<Printer> printers = printers_manager_->GetPrinters(PrinterClass::kSaved); - auto response = BuildCupsPrintersList(printers); - ResolveJavascriptCallback(base::Value(callback_id), response); + ResolveJavascriptCallback(base::Value(callback_id), + base::Value(BuildCupsPrintersList(printers))); } void CupsPrintersHandler::HandleGetCupsEnterprisePrintersList( @@ -397,8 +397,8 @@ std::vector<Printer> printers = printers_manager_->GetPrinters(PrinterClass::kEnterprise); - auto response = BuildCupsPrintersList(printers); - ResolveJavascriptCallback(base::Value(callback_id), response); + ResolveJavascriptCallback(base::Value(callback_id), + base::Value(BuildCupsPrintersList(printers))); } void CupsPrintersHandler::HandleUpdateCupsPrinter( @@ -551,7 +551,7 @@ // the rest. PRINTER_LOG(EVENT) << "Could not query printer. Fallback to asking the user"; RejectJavascriptCallback(base::Value(callback_id), - GetCupsPrinterInfo(printer)); + base::Value(GetCupsPrinterInfo(printer))); } void CupsPrintersHandler::OnAutoconfQueried( @@ -812,7 +812,7 @@ "Fall back to manual."; // Could not set up printer. Asking user for manufacturer data. RejectJavascriptCallback(base::Value(callback_id), - GetCupsPrinterInfo(printer)); + base::Value(GetCupsPrinterInfo(printer))); } } @@ -1029,14 +1029,14 @@ UpdateDiscoveredPrinters(); break; case PrinterClass::kSaved: { - auto printers_list = BuildCupsPrintersList(printers); - FireWebUIListener("on-saved-printers-changed", printers_list); + FireWebUIListener("on-saved-printers-changed", + base::Value(BuildCupsPrintersList(printers))); break; } case PrinterClass::kEnterprise: - auto enterprise_printers_list = BuildCupsPrintersList(printers); FireWebUIListener("on-enterprise-printers-changed", - enterprise_printers_list); + base::Value(BuildCupsPrintersList(printers))); + break; } } @@ -1107,7 +1107,7 @@ // directly, so we have to fall back to manual configuration here. if (printer->IsUsbProtocol()) { RejectJavascriptCallback(base::Value(callback_id), - GetCupsPrinterInfo(*printer)); + base::Value(GetCupsPrinterInfo(*printer))); return; } @@ -1235,7 +1235,7 @@ PRINTER_LOG(EVENT) << "Request make and model from user"; // If it's not an IPP printer, the user must choose a PPD. RejectJavascriptCallback(base::Value(callback_id), - GetCupsPrinterInfo(printer)); + base::Value(GetCupsPrinterInfo(printer))); } void CupsPrintersHandler::HandleQueryPrintServer( @@ -1315,8 +1315,8 @@ server_printers_fetcher_.reset(); // Create result value and finish the callback. - base::Value result_dict = BuildCupsPrintersList(printers); - ResolveJavascriptCallback(base::Value(callback_id), result_dict); + ResolveJavascriptCallback(base::Value(callback_id), + base::Value(BuildCupsPrintersList(printers))); } void CupsPrintersHandler::HandleOpenPrintManagementApp(
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 81a87a5..d080325 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1655207804-0abcd90f44ccd89ac51f969b2567acb48919e9c0.profdata +chrome-linux-main-1655229557-36aeb1dcde852e0e6daabaedec9aed25e8446d58.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 49c6a6d3..9dab6e3 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1655207804-b62733c21a998e4abe9ff8b80ba2710e67e7784a.profdata +chrome-mac-main-1655229557-2e41633d7cf2398cd102dfca76172e280ea23daa.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index eaeb71a..f04ed15 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1655207804-26d325bfbe5071d5ca06e216b4cf2331aaf34b13.profdata +chrome-win32-main-1655229557-066d5add5fce3d3ed8e49b23efab1500633c1555.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 688dc9d..3a36d5a 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1655207804-ffdc848710727fd771a04d10cb14690d174a60e4.profdata +chrome-win64-main-1655229557-734cbdd8045e65c1312bc314b73ee12f3fafdbb4.profdata
diff --git a/chrome/common/net/x509_certificate_model.cc b/chrome/common/net/x509_certificate_model.cc index b93adb2..bc7faee 100644 --- a/chrome/common/net/x509_certificate_model.cc +++ b/chrome/common/net/x509_certificate_model.cc
@@ -277,13 +277,42 @@ constexpr auto kNameStringHandling = net::X509NameAttribute::PrintableStringHandling::kAsUTF8Hack; -std::string ProcessRawBytes(net::der::Input data) { - return x509_certificate_model::ProcessRawBytes(data.UnsafeData(), - data.Length()); +std::string ProcessRawBytesWithSeparators(const unsigned char* data, + size_t data_length, + char hex_separator, + char line_separator) { + static const char kHexChars[] = "0123456789ABCDEF"; + + // Each input byte creates two output hex characters + a space or newline, + // except for the last byte. + std::string ret; + size_t kMin = 0U; + + if (!data_length) + return std::string(); + + ret.reserve(std::max(kMin, data_length * 3 - 1)); + + for (size_t i = 0; i < data_length; ++i) { + unsigned char b = data[i]; + ret.push_back(kHexChars[(b >> 4) & 0xf]); + ret.push_back(kHexChars[b & 0xf]); + if (i + 1 < data_length) { + if ((i + 1) % 16 == 0) + ret.push_back(line_separator); + else + ret.push_back(hex_separator); + } + } + return ret; } std::string ProcessRawBytes(base::span<const uint8_t> data) { - return x509_certificate_model::ProcessRawBytes(data.data(), data.size()); + return ProcessRawBytesWithSeparators(data.data(), data.size(), ' ', '\n'); +} + +std::string ProcessRawBytes(net::der::Input data) { + return ProcessRawBytes(data.AsSpan()); } OptionalStringOrError FindAttributeOfType( @@ -1213,13 +1242,13 @@ std::string X509CertificateModel::HashCertSHA256WithSeparators() const { auto hash = crypto::SHA256Hash(net::x509_util::CryptoBufferAsSpan(cert_data_.get())); - return ProcessRawBytes(hash.data(), hash.size()); + return ProcessRawBytes(hash); } std::string X509CertificateModel::HashCertSHA1WithSeparators() const { auto hash = base::SHA1HashSpan(net::x509_util::CryptoBufferAsSpan(cert_data_.get())); - return ProcessRawBytes(hash.data(), hash.size()); + return ProcessRawBytes(hash); } std::string X509CertificateModel::GetTitle() const { @@ -1512,50 +1541,6 @@ output16); } -// TODO(https://crbug.com/953425): move to anonymous namespace once -// x509_certificate_model_nss is removed. -std::string ProcessRawBytesWithSeparators(const unsigned char* data, - size_t data_length, - char hex_separator, - char line_separator) { - static const char kHexChars[] = "0123456789ABCDEF"; - - // Each input byte creates two output hex characters + a space or newline, - // except for the last byte. - std::string ret; - size_t kMin = 0U; - - if (!data_length) - return std::string(); - - ret.reserve(std::max(kMin, data_length * 3 - 1)); - - for (size_t i = 0; i < data_length; ++i) { - unsigned char b = data[i]; - ret.push_back(kHexChars[(b >> 4) & 0xf]); - ret.push_back(kHexChars[b & 0xf]); - if (i + 1 < data_length) { - if ((i + 1) % 16 == 0) - ret.push_back(line_separator); - else - ret.push_back(hex_separator); - } - } - return ret; -} - -// TODO(https://crbug.com/953425): move to anonymous namespace once -// x509_certificate_model_nss is removed. -std::string ProcessRawBytes(const unsigned char* data, size_t data_length) { - return ProcessRawBytesWithSeparators(data, data_length, ' ', '\n'); -} - -// TODO(https://crbug.com/953425): move to anonymous namespace once -// x509_certificate_model_nss is removed. -std::string ProcessRawBits(const unsigned char* data, size_t data_length) { - return ProcessRawBytes(data, (data_length + 7) / 8); -} - std::string ProcessRawSubjectPublicKeyInfo(base::span<const uint8_t> spki_der) { bssl::UniquePtr<EVP_PKEY> public_key; if (!net::ParsePublicKey(net::der::Input(spki_der.data(), spki_der.size()),
diff --git a/chrome/common/net/x509_certificate_model.h b/chrome/common/net/x509_certificate_model.h index 3a52e58..caf27fcb 100644 --- a/chrome/common/net/x509_certificate_model.h +++ b/chrome/common/net/x509_certificate_model.h
@@ -142,20 +142,6 @@ // decoded U-label form. Otherwise, the string will be returned as is. std::string ProcessIDN(const std::string& input); -// Format a buffer as |hex_separator| separated string, with 16 bytes on each -// line separated using |line_separator|. -std::string ProcessRawBytesWithSeparators(const unsigned char* data, - size_t data_length, - char hex_separator, - char line_separator); - -// Format a buffer as a space separated string, with 16 bytes on each line. -std::string ProcessRawBytes(const unsigned char* data, size_t data_length); - -// Format a buffer as a space separated string, with 16 bytes on each line. -// |data_length| is the length in bits. -std::string ProcessRawBits(const unsigned char* data, size_t data_length); - // Parses |public_key_spki_der| as a DER-encoded X.509 SubjectPublicKeyInfo, // then formats the public key as a string for displaying. Returns an empty // string on error.
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 5d33e8a..a90f742 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -3043,8 +3043,6 @@ "lacros.settings.a11y.virtual_keyboard"; #endif -const char kBackgroundTracingLastUpload[] = "background_tracing.last_upload"; - const char kAllowDinosaurEasterEgg[] = "allow_dinosaur_easter_egg"; #if BUILDFLAG(IS_ANDROID)
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index a10a186..9fb77863 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -1022,8 +1022,6 @@ extern const char kLacrosDockedMagnifierEnabled[]; #endif -extern const char kBackgroundTracingLastUpload[]; - extern const char kAllowDinosaurEasterEgg[]; #if BUILDFLAG(IS_ANDROID)
diff --git a/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc b/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc index 214ff93..b0177ef 100644 --- a/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc +++ b/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc
@@ -4,6 +4,7 @@ #include "chrome/renderer/printing/chrome_print_render_frame_helper_delegate.h" +#include <utility> #include <vector> #include "base/check.h" @@ -60,9 +61,9 @@ // instructs the PDF plugin to print. This is to make window.print() on a // PDF plugin document correctly print the PDF. See // https://crbug.com/448720. - base::DictionaryValue message; - message.SetStringKey("type", "print"); - post_message_support->PostMessageFromValue(message); + base::Value::Dict message; + message.Set("type", "print"); + post_message_support->PostMessageFromValue(base::Value(std::move(message))); return true; } #endif // BUILDFLAG(ENABLE_PDF)
diff --git a/chrome/services/printing/print_backend_service_impl.cc b/chrome/services/printing/print_backend_service_impl.cc index 48c8592..596ff08 100644 --- a/chrome/services/printing/print_backend_service_impl.cc +++ b/chrome/services/printing/print_backend_service_impl.cc
@@ -412,7 +412,7 @@ } PrinterList printer_list; - mojom::ResultCode result = print_backend_->EnumeratePrinters(&printer_list); + mojom::ResultCode result = print_backend_->EnumeratePrinters(printer_list); if (result != mojom::ResultCode::kSuccess) { std::move(callback).Run(mojom::PrinterListResult::NewResultCode(result)); return;
diff --git a/chrome/test/data/web_apps/site_b/basic.json b/chrome/test/data/web_apps/site_b/basic.json index 36a63d10..8cefecfe 100644 --- a/chrome/test/data/web_apps/site_b/basic.json +++ b/chrome/test/data/web_apps/site_b/basic.json
@@ -20,7 +20,8 @@ "action": "/web_apps/site_b/text_handler.html", "name": "Plain Text", "accept": { - "text/plain": [".txt", ".md", ".csv", ".text"] + "text/plain": [".txt", ".md", ".csv", ".text"], + "application/octet-stream": [".qux", ".quux"] } }, {
diff --git a/chrome/test/data/webrtc/region_capture_embedded.html b/chrome/test/data/webrtc/region_capture_embedded.html index 3f1cdce1..03591155 100644 --- a/chrome/test/data/webrtc/region_capture_embedded.html +++ b/chrome/test/data/webrtc/region_capture_embedded.html
@@ -19,11 +19,17 @@ } </script> </head> - <body onload="reportEmbeddingSuccess();"> + <body onload="onLoad();"> <div id="div"> <!-- This DIV is just a convenient target for cropTargetFromElement. --> - <h1>Region Capture Test - Page 1 (Embedded)</h1> + <p id="p_id">0</p> </div> - <iframe id="mailman_frame"></iframe> + <iframe id="mailman_frame" hidden></iframe> + <script> + function onLoad() { + animate(document.getElementById('p_id')); + reportEmbeddingSuccess(); + } + </script> </body> </html>
diff --git a/chrome/test/data/webrtc/region_capture_helpers.js b/chrome/test/data/webrtc/region_capture_helpers.js index 4e888f69..2ccdcd1 100644 --- a/chrome/test/data/webrtc/region_capture_helpers.js +++ b/chrome/test/data/webrtc/region_capture_helpers.js
@@ -65,6 +65,12 @@ } } +function animate(element) { + const animationCallback = function() { + element.innerHTML = parseInt(element.innerHTML) + 1; + }; + setInterval(animationCallback, 20); +} ///////////////////////////////////////// // Main actions from C++ test fixture. //
diff --git a/chrome/test/data/webrtc/region_capture_main.html b/chrome/test/data/webrtc/region_capture_main.html index e521ac3..50b7b6bc3 100644 --- a/chrome/test/data/webrtc/region_capture_main.html +++ b/chrome/test/data/webrtc/region_capture_main.html
@@ -54,13 +54,18 @@ } </script> </head> - <body> + <body onload="onLoad();"> <div id="div"> <!-- This DIV is just a convenient target for cropTargetFromElement. --> - <h1>Region Capture Test - Page 1 (Main)</h1> - <br/> + <p id="p_id">0</p> </div> + <br /> <iframe id="embedded_frame" allow="display-capture *"></iframe> - <iframe id="mailman_frame"></iframe> + <iframe id="mailman_frame" hidden></iframe> + <script> + function onLoad() { + animate(document.getElementById('p_id')); + } + </script> </body> </html>
diff --git a/chrome/test/data/webrtc/region_capture_other_embedded.html b/chrome/test/data/webrtc/region_capture_other_embedded.html index 3c1e6f4..ae0f488 100644 --- a/chrome/test/data/webrtc/region_capture_other_embedded.html +++ b/chrome/test/data/webrtc/region_capture_other_embedded.html
@@ -14,11 +14,17 @@ } </script> </head> - <body onload="reportEmbeddingSuccess();"> + <body onload="onLoad();"> <div id="div"> <!-- This DIV is just a convenient target for cropTargetFromElement. --> - <h1>Region Capture Test - Page 2 (Embedded)</h1> + <p id="p_id">0</p> </div> - <iframe id="mailman_frame"></iframe> + <iframe id="mailman_frame" hidden></iframe> + <script> + function onLoad() { + animate(document.getElementById('p_id')); + reportEmbeddingSuccess(); + } + </script> </body> </html>
diff --git a/chrome/test/data/webrtc/region_capture_other_main.html b/chrome/test/data/webrtc/region_capture_other_main.html index 8ad30d5e..0b69455 100644 --- a/chrome/test/data/webrtc/region_capture_other_main.html +++ b/chrome/test/data/webrtc/region_capture_other_main.html
@@ -10,13 +10,18 @@ setRole("top-level"); </script> </head> - <body> + <body onload="onLoad();"> <div id="div"> <!-- This DIV is just a convenient target for cropTargetFromElement. --> - <h1>Region Capture Test - Page 2 (Main)</h1> - <br/> + <p id="p_id">0</p> + <br /> <iframe id="embedded_frame" allow="display-capture *"></iframe> </div> - <iframe id="mailman_frame"></iframe> + <iframe id="mailman_frame" hidden></iframe> + <script> + function onLoad() { + animate(document.getElementById('p_id')); + } + </script> </body> </html>
diff --git a/chrome/test/data/webui/chromeos/scanning/scanning_app_browsertest.js b/chrome/test/data/webui/chromeos/scanning/scanning_app_browsertest.js index 8f21bff..1c518ec 100644 --- a/chrome/test/data/webui/chromeos/scanning/scanning_app_browsertest.js +++ b/chrome/test/data/webui/chromeos/scanning/scanning_app_browsertest.js
@@ -45,7 +45,7 @@ ]; // Flaky. See crbug.com/1334465 -TEST_F('ScanningAppBrowserTest', 'DISABLED_All', function() { +TEST_F('ScanningAppBrowserTest', 'All', function() { assertDeepEquals( debug_suites_list, test_suites_list, 'List of registered tests suites and debug suites do not match.\n' +
diff --git a/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js b/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js index 88a7fd3..4213078 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js +++ b/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js
@@ -109,6 +109,7 @@ enabled: [ 'chromeos::features::kCellularUseAttachApn', 'chromeos::features::kESimPolicy', + 'chromeos::features::kSimLockPolicy', 'ash::features::kBluetoothRevamp', ], };
diff --git a/chrome/test/data/webui/cr_components/chromeos/network/network_siminfo_test.js b/chrome/test/data/webui/cr_components/chromeos/network/network_siminfo_test.js index ee002506..c508041 100644 --- a/chrome/test/data/webui/cr_components/chromeos/network/network_siminfo_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/network/network_siminfo_test.js
@@ -142,6 +142,55 @@ verifyExistsAndClickOpensDialog('changePinButton'); }); + test('Policy controlled SIM lock setting', async () => { + const getChangePinButton = () => simInfo.$$('#changePinButton'); + const getSimLockButton = () => simInfo.$$('#simLockButton'); + const getSimLockButtonTooltip = () => simInfo.$$('#inActiveSimLockTooltip'); + + simInfo.globalPolicy = { + allowCellularSimLock: false, + }; + await flushAsync(); + + // Unlocked primary SIM with lock setting enabled. Change button should not + // be visible, and toggle should be visible, on, and enabled to allow users + // to turn off the SIM Lock setting. + updateDeviceState( + /*isPrimary=*/ true, /*lockEnabled=*/ true, /*isLocked=*/ false); + assertTrue(getChangePinButton().hidden); + assertFalse(getSimLockButton().disabled); + assertTrue(getSimLockButton().checked); + assertFalse(!!getSimLockButtonTooltip()); + + // Unlocked primary SIM with lock setting disabled. Change button should not + // be visible, and toggle should be visible, off, and disabled to prevent + // users to turn on the SIM Lock setting. + updateDeviceState( + /*isPrimary=*/ true, /*lockEnabled=*/ false, /*isLocked=*/ false); + assertTrue(getChangePinButton().hidden); + assertTrue(getSimLockButton().disabled); + assertFalse(getSimLockButton().checked); + assertFalse(!!getSimLockButtonTooltip()); + + // Non-primary unlocked SIM with lock setting enabled. Change button should + // be hidden, and toggle should be visible, off, and disabled. + updateDeviceState( + /*isPrimary=*/ false, /*lockEnabled=*/ true, /*isLocked=*/ false); + assertTrue(getChangePinButton().hidden); + assertTrue(getSimLockButton().disabled); + assertFalse(getSimLockButton().checked); + assertTrue(!!getSimLockButtonTooltip()); + + // Non-primary unlocked SIM with lock setting disabled. Change button should + // be hidden, and toggle should be visible, off, and disabled. + updateDeviceState( + /*isPrimary=*/ false, /*lockEnabled=*/ false, /*isLocked=*/ false); + assertTrue(getChangePinButton().hidden); + assertTrue(getSimLockButton().disabled); + assertFalse(getSimLockButton().checked); + assertTrue(!!getSimLockButtonTooltip()); + }); + test('Primary vs. non-primary SIM', function() { const getChangePinButton = () => simInfo.$$('#changePinButton'); const getSimLockButton = () => simInfo.$$('#simLockButton');
diff --git a/chrome/test/data/webui/settings/chromeos/settings_scheduler_slider_test.js b/chrome/test/data/webui/settings/chromeos/settings_scheduler_slider_test.js index 5d65dc1..51f7569 100644 --- a/chrome/test/data/webui/settings/chromeos/settings_scheduler_slider_test.js +++ b/chrome/test/data/webui/settings/chromeos/settings_scheduler_slider_test.js
@@ -61,15 +61,15 @@ test.skip('pref value update time string', function() { // Test that the slider time string is updated after the pref is // saved. - assertTrue(!!slider.$$('#startLabel')); - assertTrue(!!slider.$$('#endLabel')); + assertTrue(!!slider.shadowRoot.querySelector('#startLabel')); + assertTrue(!!slider.shadowRoot.querySelector('#endLabel')); const getStartTimeString = () => { - return slider.$$('#startLabel').innerHTML.trim(); + return slider.shadowRoot.querySelector('#startLabel').innerHTML.trim(); }; const getEndTimeString = () => { - return slider.$$('#endLabel').innerHTML.trim(); + return slider.shadowRoot.querySelector('#endLabel').innerHTML.trim(); }; assertEquals('1:00 AM', getStartTimeString()); @@ -109,15 +109,15 @@ // daylight savings is active. test.skip('pref value update aria label', function() { // Test that the aria label is updated after the pref is saved. - assertTrue(!!slider.$$('#startKnob')); - assertTrue(!!slider.$$('#endKnob')); + assertTrue(!!slider.shadowRoot.querySelector('#startKnob')); + assertTrue(!!slider.shadowRoot.querySelector('#endKnob')); const getStartTimeAriaLabel = () => { - return slider.$$('#startKnob').ariaLabel.trim(); + return slider.shadowRoot.querySelector('#startKnob').ariaLabel.trim(); }; const getEndTimeAriaLabel = () => { - return slider.$$('#endKnob').ariaLabel.trim(); + return slider.shadowRoot.querySelector('#endKnob').ariaLabel.trim(); }; assertEquals(slider.i18n('startTime', '1:00 AM'), getStartTimeAriaLabel());
diff --git a/chrome/test/data/webui/settings/safety_check_page_test.ts b/chrome/test/data/webui/settings/safety_check_page_test.ts index add7586..0fbeb7b 100644 --- a/chrome/test/data/webui/settings/safety_check_page_test.ts +++ b/chrome/test/data/webui/settings/safety_check_page_test.ts
@@ -4,6 +4,7 @@ // clang-format off import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {HatsBrowserProxyImpl, LifetimeBrowserProxyImpl, MetricsBrowserProxyImpl, OpenWindowProxyImpl, PasswordCheckReferrer, PasswordManagerImpl, Router, routes, SafetyCheckBrowserProxy, SafetyCheckBrowserProxyImpl, SafetyCheckCallbackConstants, SafetyCheckChromeCleanerStatus, SafetyCheckExtensionsStatus, SafetyCheckIconStatus, SafetyCheckInteractions, SafetyCheckParentStatus, SafetyCheckPasswordsStatus, SafetyCheckSafeBrowsingStatus, SafetyCheckUpdatesStatus, SettingsSafetyCheckChildElement, SettingsSafetyCheckExtensionsChildElement, SettingsSafetyCheckPageElement, SettingsSafetyCheckPasswordsChildElement, SettingsSafetyCheckSafeBrowsingChildElement, SettingsSafetyCheckUpdatesChildElement, TrustSafetyInteraction} from 'chrome://settings/settings.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; @@ -18,6 +19,10 @@ // clang-format on const testDisplayString = 'Test display string'; +const passwordsString = + loadTimeData.getBoolean('unifiedPasswordManagerEnabled') ? + 'Password Manager' : + 'Passwords'; /** * Fire a safety check parent event. @@ -539,7 +544,7 @@ assertSafetyCheckChild({ page: page, iconStatus: SafetyCheckIconStatus.RUNNING, - label: 'Passwords', + label: passwordsString, }); }); @@ -549,7 +554,7 @@ assertSafetyCheckChild({ page: page, iconStatus: SafetyCheckIconStatus.SAFE, - label: 'Passwords', + label: passwordsString, rowClickable: true, }); @@ -576,7 +581,7 @@ assertSafetyCheckChild({ page: page, iconStatus: SafetyCheckIconStatus.WARNING, - label: 'Passwords', + label: passwordsString, buttonLabel: 'Review', buttonAriaLabel: 'Review passwords', buttonClass: 'action-button', @@ -614,7 +619,7 @@ assertSafetyCheckChild({ page: page, iconStatus: SafetyCheckIconStatus.INFO, - label: 'Passwords', + label: passwordsString, rowClickable: true, }); @@ -651,7 +656,7 @@ assertSafetyCheckChild({ page: page, iconStatus: SafetyCheckIconStatus.INFO, - label: 'Passwords', + label: passwordsString, }); break; case SafetyCheckPasswordsStatus.QUOTA_LIMIT: @@ -659,7 +664,7 @@ assertSafetyCheckChild({ page: page, iconStatus: SafetyCheckIconStatus.INFO, - label: 'Passwords', + label: passwordsString, rowClickable: true, }); break;
diff --git a/chrome/updater/win/win_util.cc b/chrome/updater/win/win_util.cc index 9ede349..b0f7a0e9 100644 --- a/chrome/updater/win/win_util.cc +++ b/chrome/updater/win/win_util.cc
@@ -168,6 +168,28 @@ return foreground_parent.Detach(); } +// Compares the OS, service pack, and build numbers using `::VerifyVersionInfo`, +// in accordance with `type_mask` and `oper`. +bool CompareOSVersionsInternal(const OSVERSIONINFOEX& os, + DWORD type_mask, + BYTE oper) { + DCHECK(type_mask); + DCHECK(oper); + + ULONGLONG cond_mask = 0; + cond_mask = ::VerSetConditionMask(cond_mask, VER_MAJORVERSION, oper); + cond_mask = ::VerSetConditionMask(cond_mask, VER_MINORVERSION, oper); + cond_mask = ::VerSetConditionMask(cond_mask, VER_SERVICEPACKMAJOR, oper); + cond_mask = ::VerSetConditionMask(cond_mask, VER_SERVICEPACKMINOR, oper); + cond_mask = ::VerSetConditionMask(cond_mask, VER_BUILDNUMBER, oper); + + // `::VerifyVersionInfo` could return `FALSE` due to an error other than + // `ERROR_OLD_WIN_VERSION`. We do not handle that case here. + // https://msdn.microsoft.com/ms725492. + OSVERSIONINFOEX os_in = os; + return !!::VerifyVersionInfo(&os_in, type_mask, cond_mask); +} + } // namespace NamedObjectAttributes::NamedObjectAttributes() = default; @@ -772,4 +794,18 @@ return os_out; } +bool CompareOSVersions(const OSVERSIONINFOEX& os_version, BYTE oper) { + DCHECK(oper); + + const DWORD os_sp_type_mask = VER_MAJORVERSION | VER_MINORVERSION | + VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR; + const DWORD build_number_type_mask = VER_BUILDNUMBER; + + // If the OS and the service pack match, return the build number comparison. + return CompareOSVersionsInternal(os_version, os_sp_type_mask, VER_EQUAL) + ? CompareOSVersionsInternal(os_version, build_number_type_mask, + oper) + : CompareOSVersionsInternal(os_version, os_sp_type_mask, oper); +} + } // namespace updater
diff --git a/chrome/updater/win/win_util.h b/chrome/updater/win/win_util.h index 70a9d1c..85fa5c5 100644 --- a/chrome/updater/win/win_util.h +++ b/chrome/updater/win/win_util.h
@@ -259,6 +259,12 @@ // Returns an OSVERSIONINFOEX for the current OS version. absl::optional<OSVERSIONINFOEX> GetOSVersion(); +// Compares the current OS to the supplied version. The value of `oper` should +// be one of the predicate values from `::VerSetConditionMask()`, for example, +// `VER_GREATER` or `VER_GREATER_EQUAL`. `os_version` is usually from a prior +// call to `::GetVersionEx` or `::RtlGetVersion`. +bool CompareOSVersions(const OSVERSIONINFOEX& os, BYTE oper); + } // namespace updater #endif // CHROME_UPDATER_WIN_WIN_UTIL_H_
diff --git a/chrome/updater/win/win_util_unittest.cc b/chrome/updater/win/win_util_unittest.cc index 9bcb6f66..00610051 100644 --- a/chrome/updater/win/win_util_unittest.cc +++ b/chrome/updater/win/win_util_unittest.cc
@@ -159,4 +159,100 @@ EXPECT_EQ(rtl_os_version->wReserved, os.wReserved); } +TEST(WinUtil, CompareOSVersions_SameAsCurrent) { + absl::optional<OSVERSIONINFOEX> this_os = GetOSVersion(); + ASSERT_NE(this_os, absl::nullopt); + + EXPECT_TRUE(CompareOSVersions(this_os.value(), VER_EQUAL)); + EXPECT_TRUE(CompareOSVersions(this_os.value(), VER_GREATER_EQUAL)); + EXPECT_FALSE(CompareOSVersions(this_os.value(), VER_GREATER)); + EXPECT_FALSE(CompareOSVersions(this_os.value(), VER_LESS)); + EXPECT_TRUE(CompareOSVersions(this_os.value(), VER_LESS_EQUAL)); +} + +TEST(WinUtil, CompareOSVersions_NewBuildNumber) { + absl::optional<OSVERSIONINFOEX> prior_os = GetOSVersion(); + ASSERT_NE(prior_os, absl::nullopt); + ASSERT_GT(prior_os->dwBuildNumber, 0UL); + --prior_os->dwBuildNumber; + + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_EQUAL)); + EXPECT_TRUE(CompareOSVersions(prior_os.value(), VER_GREATER_EQUAL)); + EXPECT_TRUE(CompareOSVersions(prior_os.value(), VER_GREATER)); + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_LESS)); + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_LESS_EQUAL)); +} + +TEST(WinUtil, CompareOSVersions_NewMajor) { + absl::optional<OSVERSIONINFOEX> prior_os = GetOSVersion(); + ASSERT_NE(prior_os, absl::nullopt); + ASSERT_GT(prior_os->dwMajorVersion, 0UL); + --prior_os->dwMajorVersion; + + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_EQUAL)); + EXPECT_TRUE(CompareOSVersions(prior_os.value(), VER_GREATER_EQUAL)); + EXPECT_TRUE(CompareOSVersions(prior_os.value(), VER_GREATER)); + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_LESS)); + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_LESS_EQUAL)); +} + +TEST(WinUtil, CompareOSVersions_NewMinor) { + absl::optional<OSVERSIONINFOEX> prior_os = GetOSVersion(); + ASSERT_NE(prior_os, absl::nullopt); + + // This test only runs if the current OS has a minor version. + if (prior_os->dwMinorVersion >= 1) { + --prior_os->dwMinorVersion; + + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_EQUAL)); + EXPECT_TRUE(CompareOSVersions(prior_os.value(), VER_GREATER_EQUAL)); + EXPECT_TRUE(CompareOSVersions(prior_os.value(), VER_GREATER)); + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_LESS)); + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_LESS_EQUAL)); + } +} + +TEST(WinUtil, CompareOSVersions_NewMajorWithLowerMinor) { + absl::optional<OSVERSIONINFOEX> prior_os = GetOSVersion(); + ASSERT_NE(prior_os, absl::nullopt); + ASSERT_GT(prior_os->dwMajorVersion, 0UL); + --prior_os->dwMajorVersion; + ++prior_os->dwMinorVersion; + + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_EQUAL)); + EXPECT_TRUE(CompareOSVersions(prior_os.value(), VER_GREATER_EQUAL)); + EXPECT_TRUE(CompareOSVersions(prior_os.value(), VER_GREATER)); + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_LESS)); + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_LESS_EQUAL)); +} + +TEST(WinUtil, CompareOSVersions_OldMajor) { + absl::optional<OSVERSIONINFOEX> prior_os = GetOSVersion(); + ASSERT_NE(prior_os, absl::nullopt); + ++prior_os->dwMajorVersion; + + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_EQUAL)); + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_GREATER_EQUAL)); + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_GREATER)); + EXPECT_TRUE(CompareOSVersions(prior_os.value(), VER_LESS)); + EXPECT_TRUE(CompareOSVersions(prior_os.value(), VER_LESS_EQUAL)); +} + +TEST(WinUtil, CompareOSVersions_OldMajorWithHigherMinor) { + absl::optional<OSVERSIONINFOEX> prior_os = GetOSVersion(); + ASSERT_NE(prior_os, absl::nullopt); + + // This test only runs if the current OS has a minor version. + if (prior_os->dwMinorVersion >= 1) { + ++prior_os->dwMajorVersion; + --prior_os->dwMinorVersion; + + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_EQUAL)); + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_GREATER_EQUAL)); + EXPECT_FALSE(CompareOSVersions(prior_os.value(), VER_GREATER)); + EXPECT_TRUE(CompareOSVersions(prior_os.value(), VER_LESS)); + EXPECT_TRUE(CompareOSVersions(prior_os.value(), VER_LESS_EQUAL)); + } +} + } // namespace updater
diff --git a/chromecast/browser/accessibility/accessibility_service_impl.cc b/chromecast/browser/accessibility/accessibility_service_impl.cc index 767d263..4423b53 100644 --- a/chromecast/browser/accessibility/accessibility_service_impl.cc +++ b/chromecast/browser/accessibility/accessibility_service_impl.cc
@@ -103,7 +103,7 @@ for (chromecast::CastWebContents* webview : webviews) { mojo::Remote<mojom::CastAccessibilityClient> accessibility_client; content::RenderFrameHost* render_frame_host = - webview->web_contents()->GetMainFrame(); + webview->web_contents()->GetPrimaryMainFrame(); if (!render_frame_host) continue;
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index 03136bb..43c890d 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc
@@ -630,8 +630,8 @@ base::BindOnce( &CastContentBrowserClient::SelectClientCertificateOnIOThread, base::Unretained(this), requesting_url, session_id, - web_contents->GetMainFrame()->GetProcess()->GetID(), - web_contents->GetMainFrame()->GetRoutingID(), + web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(), + web_contents->GetPrimaryMainFrame()->GetRoutingID(), base::SequencedTaskRunnerHandle::Get(), base::BindOnce( &content::ClientCertificateDelegate::ContinueWithCertificate,
diff --git a/chromecast/browser/cast_web_contents_browsertest.cc b/chromecast/browser/cast_web_contents_browsertest.cc index 73f04b6..b41e09d 100644 --- a/chromecast/browser/cast_web_contents_browsertest.cc +++ b/chromecast/browser/cast_web_contents_browsertest.cc
@@ -473,11 +473,11 @@ ASSERT_TRUE(ExecJs(web_contents_.get(), script)); ASSERT_EQ(2, (int)render_frames_.size()); - auto it = - std::find_if(render_frames_.begin(), render_frames_.end(), - [this](content::RenderFrameHost* frame) { - return frame->GetParent() == web_contents_->GetMainFrame(); - }); + auto it = std::find_if(render_frames_.begin(), render_frames_.end(), + [this](content::RenderFrameHost* frame) { + return frame->GetParent() == + web_contents_->GetPrimaryMainFrame(); + }); ASSERT_NE(render_frames_.end(), it); content::RenderFrameHost* sub_frame = *it; ASSERT_NE(nullptr, sub_frame); @@ -490,8 +490,9 @@ EXPECT_CALL(mock_cast_wc_observer_, PageStateChanged(_)).Times(0); EXPECT_CALL(mock_cast_wc_observer_, PageStopped(_, _)).Times(0); cast_web_contents_->DidFailLoad( - web_contents_->GetMainFrame(), - web_contents_->GetMainFrame()->GetLastCommittedURL(), net::ERR_ABORTED); + web_contents_->GetPrimaryMainFrame(), + web_contents_->GetPrimaryMainFrame()->GetLastCommittedURL(), + net::ERR_ABORTED); // =========================================================================== // Test: If main frame fails to load, page should enter ERROR state. @@ -501,8 +502,9 @@ PageStopped(PageState::ERROR, net::ERR_FAILED)) .WillOnce(InvokeWithoutArgs([&]() { QuitRunLoop(); })); cast_web_contents_->DidFailLoad( - web_contents_->GetMainFrame(), - web_contents_->GetMainFrame()->GetLastCommittedURL(), net::ERR_FAILED); + web_contents_->GetPrimaryMainFrame(), + web_contents_->GetPrimaryMainFrame()->GetLastCommittedURL(), + net::ERR_FAILED); run_loop_->Run(); }
diff --git a/chromecast/browser/cast_web_contents_impl.cc b/chromecast/browser/cast_web_contents_impl.cc index 9710040..98968cf 100644 --- a/chromecast/browser/cast_web_contents_impl.cc +++ b/chromecast/browser/cast_web_contents_impl.cc
@@ -162,9 +162,9 @@ DCHECK(web_contents_); DCHECK(web_contents_->GetController().IsInitialNavigation()); DCHECK(!web_contents_->IsLoading()); - DCHECK(web_contents_->GetMainFrame()); + DCHECK(web_contents_->GetPrimaryMainFrame()); - main_process_host_ = web_contents_->GetMainFrame()->GetProcess(); + main_process_host_ = web_contents_->GetPrimaryMainFrame()->GetProcess(); DCHECK(main_process_host_); main_process_host_->AddObserver(this); @@ -201,7 +201,7 @@ switches::kCastAppBackgroundColor, SK_ColorBLACK)); if (params_->enable_webui_bindings_permission) { - web_contents_->GetMainFrame()->AllowBindings( + web_contents_->GetPrimaryMainFrame()->AllowBindings( content::BINDINGS_POLICY_WEB_UI | content::BINDINGS_POLICY_MOJO_WEB_UI); } } @@ -407,11 +407,11 @@ base::OnceCallback<void(base::Value)> callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!web_contents_ || closing_ || !main_frame_loaded_ || - !web_contents_->GetMainFrame()) + !web_contents_->GetPrimaryMainFrame()) return; - web_contents_->GetMainFrame()->ExecuteJavaScript(javascript, - std::move(callback)); + web_contents_->GetPrimaryMainFrame()->ExecuteJavaScript(javascript, + std::move(callback)); } void CastWebContentsImpl::ConnectToBindingsService( @@ -450,12 +450,12 @@ } void CastWebContentsImpl::GetMainFramePid(GetMainFramePidCallback cb) { - if (!web_contents_ || !web_contents_->GetMainFrame()) { + if (!web_contents_ || !web_contents_->GetPrimaryMainFrame()) { std::move(cb).Run(base::kNullProcessHandle); return; } - auto* rph = web_contents_->GetMainFrame()->GetProcess(); + auto* rph = web_contents_->GetPrimaryMainFrame()->GetProcess(); if (!rph || rph->GetProcess().Handle() == base::kNullProcessHandle) { std::move(cb).Run(base::kNullProcessHandle); return; @@ -747,7 +747,7 @@ const GURL& validated_url) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (page_state_ != PageState::LOADING || !web_contents_ || - render_frame_host != web_contents_->GetMainFrame()) { + render_frame_host != web_contents_->GetPrimaryMainFrame()) { return; } @@ -884,7 +884,8 @@ content::RenderFrameHost* render_frame_host, const content::GlobalRequestID& request_id, const blink::mojom::ResourceLoadInfo& resource_load_info) { - if (!web_contents_ || render_frame_host != web_contents_->GetMainFrame()) + if (!web_contents_ || + render_frame_host != web_contents_->GetPrimaryMainFrame()) return; int net_error = resource_load_info.net_error; if (net_error == net::OK)
diff --git a/chromecast/browser/webview/cast_app_controller.cc b/chromecast/browser/webview/cast_app_controller.cc index 0d785a93..52581b4 100644 --- a/chromecast/browser/webview/cast_app_controller.cc +++ b/chromecast/browser/webview/cast_app_controller.cc
@@ -23,7 +23,7 @@ std::unique_ptr<webview::WebviewResponse> response = std::make_unique<webview::WebviewResponse>(); - auto ax_id = contents->GetMainFrame()->GetAXTreeID().ToString(); + auto ax_id = contents->GetPrimaryMainFrame()->GetAXTreeID().ToString(); response->mutable_create_response() ->mutable_accessibility_info() ->set_ax_tree_id(ax_id);
diff --git a/chromecast/browser/webview/web_content_controller.cc b/chromecast/browser/webview/web_content_controller.cc index be6334ab..53f8459f 100644 --- a/chromecast/browser/webview/web_content_controller.cc +++ b/chromecast/browser/webview/web_content_controller.cc
@@ -448,7 +448,7 @@ void WebContentController::HandleEvaluateJavascript( int64_t id, const webview::EvaluateJavascriptRequest& request) { - GetWebContents()->GetMainFrame()->ExecuteJavaScript( + GetWebContents()->GetPrimaryMainFrame()->ExecuteJavaScript( base::UTF8ToUTF16(request.javascript_blob()), base::BindOnce(&WebContentController::JavascriptCallback, weak_ptr_factory_.GetWeakPtr(), id));
diff --git a/chromeos/dbus/dbus_clients_browser.cc b/chromeos/dbus/dbus_clients_browser.cc index a8fc24e..cb65bfc9 100644 --- a/chromeos/dbus/dbus_clients_browser.cc +++ b/chromeos/dbus/dbus_clients_browser.cc
@@ -35,8 +35,6 @@ #include "chromeos/dbus/image_burner/image_burner_client.h" #include "chromeos/dbus/image_loader/fake_image_loader_client.h" #include "chromeos/dbus/image_loader/image_loader_client.h" -#include "chromeos/dbus/lorgnette_manager/fake_lorgnette_manager_client.h" -#include "chromeos/dbus/lorgnette_manager/lorgnette_manager_client.h" #include "chromeos/dbus/oobe_config/fake_oobe_configuration_client.h" #include "chromeos/dbus/oobe_config/oobe_configuration_client.h" #include "chromeos/dbus/runtime_probe/fake_runtime_probe_client.h" @@ -90,8 +88,6 @@ CREATE_DBUS_CLIENT(ImageBurnerClient, use_real_clients); image_loader_client_ = CREATE_DBUS_CLIENT(ImageLoaderClient, use_real_clients); - lorgnette_manager_client_ = - CREATE_DBUS_CLIENT(LorgnetteManagerClient, use_real_clients); oobe_configuration_client_ = CREATE_DBUS_CLIENT(OobeConfigurationClient, use_real_clients); runtime_probe_client_ = @@ -128,7 +124,6 @@ gnubby_client_->Init(system_bus); image_burner_client_->Init(system_bus); image_loader_client_->Init(system_bus); - lorgnette_manager_client_->Init(system_bus); oobe_configuration_client_->Init(system_bus); runtime_probe_client_->Init(system_bus); smb_provider_client_->Init(system_bus);
diff --git a/chromeos/dbus/dbus_clients_browser.h b/chromeos/dbus/dbus_clients_browser.h index 82e589f..0e1bb471 100644 --- a/chromeos/dbus/dbus_clients_browser.h +++ b/chromeos/dbus/dbus_clients_browser.h
@@ -28,7 +28,6 @@ class GnubbyClient; class ImageBurnerClient; class ImageLoaderClient; -class LorgnetteManagerClient; class OobeConfigurationClient; class RuntimeProbeClient; class SmbProviderClient; @@ -70,7 +69,6 @@ std::unique_ptr<GnubbyClient> gnubby_client_; std::unique_ptr<ImageBurnerClient> image_burner_client_; std::unique_ptr<ImageLoaderClient> image_loader_client_; - std::unique_ptr<LorgnetteManagerClient> lorgnette_manager_client_; std::unique_ptr<OobeConfigurationClient> oobe_configuration_client_; std::unique_ptr<RuntimeProbeClient> runtime_probe_client_; std::unique_ptr<SmbProviderClient> smb_provider_client_;
diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc index edcace9..8d699bc 100644 --- a/chromeos/dbus/dbus_thread_manager.cc +++ b/chromeos/dbus/dbus_thread_manager.cc
@@ -24,7 +24,6 @@ #include "chromeos/dbus/gnubby/gnubby_client.h" #include "chromeos/dbus/image_burner/image_burner_client.h" #include "chromeos/dbus/image_loader/image_loader_client.h" -#include "chromeos/dbus/lorgnette_manager/lorgnette_manager_client.h" #include "chromeos/dbus/oobe_config/oobe_configuration_client.h" #include "chromeos/dbus/runtime_probe/runtime_probe_client.h" #include "chromeos/dbus/shill/shill_clients.h" @@ -104,11 +103,6 @@ RETURN_DBUS_CLIENT(image_loader_client_); } -LorgnetteManagerClient* DBusThreadManager::GetLorgnetteManagerClient() { - return clients_browser_ ? clients_browser_->lorgnette_manager_client_.get() - : nullptr; -} - OobeConfigurationClient* DBusThreadManager::GetOobeConfigurationClient() { return clients_browser_->oobe_configuration_client_.get(); }
diff --git a/chromeos/dbus/dbus_thread_manager.h b/chromeos/dbus/dbus_thread_manager.h index e50e35d..8e7f3cf 100644 --- a/chromeos/dbus/dbus_thread_manager.h +++ b/chromeos/dbus/dbus_thread_manager.h
@@ -29,7 +29,6 @@ class GnubbyClient; class ImageBurnerClient; class ImageLoaderClient; -class LorgnetteManagerClient; class OobeConfigurationClient; class RuntimeProbeClient; class SmbProviderClient; @@ -84,7 +83,6 @@ GnubbyClient* GetGnubbyClient(); ImageBurnerClient* GetImageBurnerClient(); ImageLoaderClient* GetImageLoaderClient(); - LorgnetteManagerClient* GetLorgnetteManagerClient(); OobeConfigurationClient* GetOobeConfigurationClient(); RuntimeProbeClient* GetRuntimeProbeClient(); SmbProviderClient* GetSmbProviderClient();
diff --git a/chromeos/dbus/dbus_thread_manager_unittest.cc b/chromeos/dbus/dbus_thread_manager_unittest.cc index 85bf784..a518edd 100644 --- a/chromeos/dbus/dbus_thread_manager_unittest.cc +++ b/chromeos/dbus/dbus_thread_manager_unittest.cc
@@ -26,7 +26,6 @@ EXPECT_TRUE(manager->GetDebugDaemonClient()); EXPECT_TRUE(manager->GetEasyUnlockClient()); EXPECT_TRUE(manager->GetImageBurnerClient()); - EXPECT_TRUE(manager->GetLorgnetteManagerClient()); EXPECT_TRUE(manager->GetUpdateEngineClient()); DBusThreadManager::Shutdown();
diff --git a/chromeos/dbus/lorgnette_manager/lorgnette_manager_client.cc b/chromeos/dbus/lorgnette_manager/lorgnette_manager_client.cc index a0d58f5e..dc6b046 100644 --- a/chromeos/dbus/lorgnette_manager/lorgnette_manager_client.cc +++ b/chromeos/dbus/lorgnette_manager/lorgnette_manager_client.cc
@@ -21,6 +21,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "chromeos/dbus/common/pipe_reader.h" #include "chromeos/dbus/lorgnette/lorgnette_service.pb.h" +#include "chromeos/dbus/lorgnette_manager/fake_lorgnette_manager_client.h" #include "dbus/bus.h" #include "dbus/message.h" #include "dbus/object_path.h" @@ -29,6 +30,9 @@ #include "third_party/cros_system_api/dbus/service_constants.h" namespace chromeos { +namespace { + +LorgnetteManagerClient* g_instance = nullptr; // The LorgnetteManagerClient implementation used in production. class LorgnetteManagerClientImpl : public LorgnetteManagerClient { @@ -105,7 +109,6 @@ std::move(cancel_callback))); } - protected: void Init(dbus::Bus* bus) override { lorgnette_daemon_proxy_ = bus->GetObjectProxy(lorgnette::kManagerServiceName, @@ -524,13 +527,38 @@ base::WeakPtrFactory<LorgnetteManagerClientImpl> weak_ptr_factory_{this}; }; -LorgnetteManagerClient::LorgnetteManagerClient() = default; - -LorgnetteManagerClient::~LorgnetteManagerClient() = default; +} // namespace // static -std::unique_ptr<LorgnetteManagerClient> LorgnetteManagerClient::Create() { - return std::make_unique<LorgnetteManagerClientImpl>(); +void LorgnetteManagerClient::Initialize(dbus::Bus* bus) { + CHECK(bus); + (new LorgnetteManagerClientImpl())->Init(bus); +} + +// static +void LorgnetteManagerClient::InitializeFake() { + new FakeLorgnetteManagerClient(); +} + +// static +void LorgnetteManagerClient::Shutdown() { + CHECK(g_instance); + delete g_instance; +} + +// static +LorgnetteManagerClient* LorgnetteManagerClient::Get() { + return g_instance; +} + +LorgnetteManagerClient::LorgnetteManagerClient() { + CHECK(!g_instance); + g_instance = this; +} + +LorgnetteManagerClient::~LorgnetteManagerClient() { + CHECK_EQ(g_instance, this); + g_instance = nullptr; } } // namespace chromeos
diff --git a/chromeos/dbus/lorgnette_manager/lorgnette_manager_client.h b/chromeos/dbus/lorgnette_manager/lorgnette_manager_client.h index 274d80a..cfea4f8 100644 --- a/chromeos/dbus/lorgnette_manager/lorgnette_manager_client.h +++ b/chromeos/dbus/lorgnette_manager/lorgnette_manager_client.h
@@ -29,9 +29,20 @@ int resolution_dpi = 0; }; + // Creates and initializes the global instance. |bus| must not be null. + static void Initialize(dbus::Bus* bus); + + // Creates and initializes a fake global instance. + static void InitializeFake(); + + // Destroys the global instance if it has been initialized. + static void Shutdown(); + + // Returns the global instance if initialized. May return null. + static LorgnetteManagerClient* Get(); + LorgnetteManagerClient(const LorgnetteManagerClient&) = delete; LorgnetteManagerClient& operator=(const LorgnetteManagerClient&) = delete; - ~LorgnetteManagerClient() override; // Gets a list of scanners from the lorgnette manager. virtual void ListScanners( @@ -70,15 +81,12 @@ // scan running at a time. virtual void CancelScan(VoidDBusMethodCallback cancel_callback) = 0; - // Factory function, creates a new instance and returns ownership. - // For normal usage, access the singleton via DBusThreadManager::Get(). - static std::unique_ptr<LorgnetteManagerClient> Create(); - protected: friend class LorgnetteManagerClientTest; - // Create() should be used instead. + // Initialize() should be used instead. LorgnetteManagerClient(); + ~LorgnetteManagerClient() override; }; } // namespace chromeos
diff --git a/chromeos/dbus/lorgnette_manager/lorgnette_manager_client_unittest.cc b/chromeos/dbus/lorgnette_manager/lorgnette_manager_client_unittest.cc index f1cafeb..788a5e2 100644 --- a/chromeos/dbus/lorgnette_manager/lorgnette_manager_client_unittest.cc +++ b/chromeos/dbus/lorgnette_manager/lorgnette_manager_client_unittest.cc
@@ -224,7 +224,7 @@ mock_bus_.get(), lorgnette::kManagerServiceName, dbus::ObjectPath(lorgnette::kManagerServicePath)); - // |client_|'s Init() method should request a proxy for communicating with + // The client's Init() method should request a proxy for communicating with // the lorgnette daemon. EXPECT_CALL( *mock_bus_.get(), @@ -232,7 +232,7 @@ dbus::ObjectPath(lorgnette::kManagerServicePath))) .WillOnce(Return(mock_proxy_.get())); - // Save |client_|'s scan status changed signal callback. + // Save the client's scan status changed signal callback. EXPECT_CALL(*mock_proxy_.get(), DoConnectToSignal(lorgnette::kManagerServiceInterface, lorgnette::kScanStatusChangedSignal, _, _)) @@ -252,16 +252,21 @@ EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return()); // Create and initialize a client with the mock bus. - client_ = LorgnetteManagerClient::Create(); - client_->Init(mock_bus_.get()); + LorgnetteManagerClient::Initialize(mock_bus_.get()); // Execute callbacks posted by Init(). base::RunLoop().RunUntilIdle(); } - void TearDown() override { mock_bus_->ShutdownAndBlock(); } + void TearDown() override { + LorgnetteManagerClient::Shutdown(); + mock_bus_->ShutdownAndBlock(); + } - LorgnetteManagerClient* client() { return client_.get(); } + // A shorter name to return the LorgnetteManagerClient under test. + static LorgnetteManagerClient* GetClient() { + return LorgnetteManagerClient::Get(); + } // Adds an expectation to |mock_proxy_| that kListScannersMethod will be // called. When called, |mock_proxy_| will respond with |response|. @@ -442,12 +447,10 @@ // A message loop to emulate asynchronous behavior. base::test::TaskEnvironment task_environment_; - // Mock D-Bus objects for |client_| to interact with. + // Mock D-Bus objects for the client to interact with. scoped_refptr<dbus::MockBus> mock_bus_; scoped_refptr<dbus::MockObjectProxy> mock_proxy_; - // The client to be tested. - std::unique_ptr<LorgnetteManagerClient> client_; - // Holds |client_|'s kScanStatusChangedSignal callback. + // Holds the client's kScanStatusChangedSignal callback. dbus::ObjectProxy::SignalCallback scan_status_changed_signal_callback_; // Used to respond to kListScannersMethod D-Bus calls. dbus::Response* list_scanners_response_ = nullptr; @@ -477,7 +480,7 @@ SetListScannersExpectation(response.get()); base::RunLoop run_loop; - client()->ListScanners(base::BindLambdaForTesting( + GetClient()->ListScanners(base::BindLambdaForTesting( [&](absl::optional<lorgnette::ListScannersResponse> result) { ASSERT_TRUE(result.has_value()); EXPECT_THAT(result.value(), ProtobufEquals(kExpectedResponse)); @@ -493,7 +496,7 @@ SetListScannersExpectation(nullptr); base::RunLoop run_loop; - client()->ListScanners(base::BindLambdaForTesting( + GetClient()->ListScanners(base::BindLambdaForTesting( [&](absl::optional<lorgnette::ListScannersResponse> result) { EXPECT_EQ(result, absl::nullopt); run_loop.Quit(); @@ -509,7 +512,7 @@ SetListScannersExpectation(response.get()); base::RunLoop run_loop; - client()->ListScanners(base::BindLambdaForTesting( + GetClient()->ListScanners(base::BindLambdaForTesting( [&](absl::optional<lorgnette::ListScannersResponse> result) { EXPECT_EQ(result, absl::nullopt); run_loop.Quit(); @@ -528,7 +531,7 @@ SetGetScannerCapabilitiesExpectation(response.get()); base::RunLoop run_loop; - client()->GetScannerCapabilities( + GetClient()->GetScannerCapabilities( kScannerDeviceName, base::BindLambdaForTesting( [&](absl::optional<lorgnette::ScannerCapabilities> result) { @@ -546,7 +549,7 @@ SetGetScannerCapabilitiesExpectation(nullptr); base::RunLoop run_loop; - client()->GetScannerCapabilities( + GetClient()->GetScannerCapabilities( kScannerDeviceName, base::BindLambdaForTesting( [&](absl::optional<lorgnette::ScannerCapabilities> result) { @@ -564,7 +567,7 @@ SetGetScannerCapabilitiesExpectation(response.get()); base::RunLoop run_loop; - client()->GetScannerCapabilities( + GetClient()->GetScannerCapabilities( kScannerDeviceName, base::BindLambdaForTesting( [&](absl::optional<lorgnette::ScannerCapabilities> result) { @@ -585,7 +588,7 @@ base::RunLoop run_loop; lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan( + GetClient()->StartScan( request.device_name(), request.settings(), base::NullCallback(), base::NullCallback(), base::BindLambdaForTesting([&](uint32_t progress, uint32_t page_num) { @@ -616,7 +619,7 @@ base::RunLoop page_run_loop; uint8_t num_pages_scanned = 0; lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan( + GetClient()->StartScan( request.device_name(), request.settings(), base::BindLambdaForTesting([&](lorgnette::ScanFailureMode failure_mode) { EXPECT_EQ(failure_mode, lorgnette::SCAN_FAILURE_MODE_NO_FAILURE); @@ -661,7 +664,7 @@ base::RunLoop page_run_loop; uint8_t num_pages_scanned = 0; lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan( + GetClient()->StartScan( request.device_name(), request.settings(), base::BindLambdaForTesting([&](lorgnette::ScanFailureMode failure_mode) { EXPECT_EQ(failure_mode, lorgnette::SCAN_FAILURE_MODE_NO_FAILURE); @@ -708,7 +711,7 @@ base::RunLoop second_page_run_loop; uint8_t num_pages_scanned = 0; lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan( + GetClient()->StartScan( request.device_name(), request.settings(), base::BindLambdaForTesting([&](lorgnette::ScanFailureMode failure_mode) { EXPECT_EQ(failure_mode, lorgnette::SCAN_FAILURE_MODE_NO_FAILURE); @@ -763,7 +766,7 @@ base::RunLoop run_loop; lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan( + GetClient()->StartScan( request.device_name(), request.settings(), base::BindLambdaForTesting([&](lorgnette::ScanFailureMode failure_mode) { EXPECT_EQ(failure_mode, lorgnette::SCAN_FAILURE_MODE_DEVICE_BUSY); @@ -788,7 +791,7 @@ base::RunLoop run_loop; lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan( + GetClient()->StartScan( request.device_name(), request.settings(), base::BindLambdaForTesting([&](lorgnette::ScanFailureMode failure_mode) { EXPECT_EQ(failure_mode, lorgnette::SCAN_FAILURE_MODE_UNKNOWN); @@ -807,7 +810,7 @@ base::RunLoop run_loop; lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan( + GetClient()->StartScan( request.device_name(), request.settings(), base::BindLambdaForTesting([&](lorgnette::ScanFailureMode failure_mode) { EXPECT_EQ(failure_mode, lorgnette::SCAN_FAILURE_MODE_UNKNOWN); @@ -828,7 +831,7 @@ base::RunLoop run_loop; lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan( + GetClient()->StartScan( request.device_name(), request.settings(), base::BindLambdaForTesting([&](lorgnette::ScanFailureMode failure_mode) { EXPECT_EQ(failure_mode, lorgnette::SCAN_FAILURE_MODE_ADF_JAMMED); @@ -849,7 +852,7 @@ base::RunLoop run_loop; lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan( + GetClient()->StartScan( request.device_name(), request.settings(), base::BindLambdaForTesting([&](lorgnette::ScanFailureMode failure_mode) { EXPECT_EQ(failure_mode, lorgnette::SCAN_FAILURE_MODE_UNKNOWN); @@ -872,7 +875,7 @@ base::RunLoop run_loop; lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan( + GetClient()->StartScan( request.device_name(), request.settings(), base::BindLambdaForTesting([&](lorgnette::ScanFailureMode failure_mode) { EXPECT_EQ(failure_mode, lorgnette::SCAN_FAILURE_MODE_UNKNOWN); @@ -895,7 +898,7 @@ base::RunLoop run_loop; lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan( + GetClient()->StartScan( request.device_name(), request.settings(), base::BindLambdaForTesting([&](lorgnette::ScanFailureMode failure_mode) { EXPECT_EQ(failure_mode, lorgnette::SCAN_FAILURE_MODE_IO_ERROR); @@ -931,14 +934,14 @@ SetCancelScanExpectation(cancel_scan_response.get()); lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan(request.device_name(), request.settings(), - base::NullCallback(), base::NullCallback(), - base::NullCallback()); + GetClient()->StartScan(request.device_name(), request.settings(), + base::NullCallback(), base::NullCallback(), + base::NullCallback()); base::RunLoop().RunUntilIdle(); base::RunLoop run_loop; - client()->CancelScan(base::BindLambdaForTesting([&](bool success) { + GetClient()->CancelScan(base::BindLambdaForTesting([&](bool success) { EXPECT_TRUE(success); run_loop.Quit(); })); @@ -955,7 +958,7 @@ // Test that the client handles a cancel call with no existing scan jobs. TEST_F(LorgnetteManagerClientTest, CancelScanJobNoExistingJobs) { base::RunLoop run_loop; - client()->CancelScan(base::BindLambdaForTesting([&](bool success) { + GetClient()->CancelScan(base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); run_loop.Quit(); })); @@ -972,9 +975,9 @@ SetGetNextImageExpectation(get_next_image_response.get()); lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan(request.device_name(), request.settings(), - base::NullCallback(), base::NullCallback(), - base::NullCallback()); + GetClient()->StartScan(request.device_name(), request.settings(), + base::NullCallback(), base::NullCallback(), + base::NullCallback()); base::RunLoop().RunUntilIdle(); @@ -982,14 +985,14 @@ lorgnette::ScanState::SCAN_STATE_IN_PROGRESS, kSecondScanUuid); SetStartScanExpectation(start_scan_response.get()); SetGetNextImageExpectation(get_next_image_response.get(), kSecondScanUuid); - client()->StartScan(request.device_name(), request.settings(), - base::NullCallback(), base::NullCallback(), - base::NullCallback()); + GetClient()->StartScan(request.device_name(), request.settings(), + base::NullCallback(), base::NullCallback(), + base::NullCallback()); base::RunLoop().RunUntilIdle(); base::RunLoop run_loop; - client()->CancelScan(base::BindLambdaForTesting([&](bool success) { + GetClient()->CancelScan(base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); run_loop.Quit(); })); @@ -1008,14 +1011,14 @@ SetCancelScanExpectation(nullptr); lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan(request.device_name(), request.settings(), - base::NullCallback(), base::NullCallback(), - base::NullCallback()); + GetClient()->StartScan(request.device_name(), request.settings(), + base::NullCallback(), base::NullCallback(), + base::NullCallback()); base::RunLoop().RunUntilIdle(); base::RunLoop run_loop; - client()->CancelScan(base::BindLambdaForTesting([&](bool success) { + GetClient()->CancelScan(base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); run_loop.Quit(); })); @@ -1035,14 +1038,14 @@ SetCancelScanExpectation(cancel_scan_response.get()); lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan(request.device_name(), request.settings(), - base::NullCallback(), base::NullCallback(), - base::NullCallback()); + GetClient()->StartScan(request.device_name(), request.settings(), + base::NullCallback(), base::NullCallback(), + base::NullCallback()); base::RunLoop().RunUntilIdle(); base::RunLoop run_loop; - client()->CancelScan(base::BindLambdaForTesting([&](bool success) { + GetClient()->CancelScan(base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); run_loop.Quit(); })); @@ -1061,14 +1064,14 @@ SetCancelScanExpectation(cancel_scan_response.get()); lorgnette::StartScanRequest request = CreateStartScanRequest(); - client()->StartScan(request.device_name(), request.settings(), - base::NullCallback(), base::NullCallback(), - base::NullCallback()); + GetClient()->StartScan(request.device_name(), request.settings(), + base::NullCallback(), base::NullCallback(), + base::NullCallback()); base::RunLoop().RunUntilIdle(); base::RunLoop run_loop; - client()->CancelScan(base::BindLambdaForTesting([&](bool success) { + GetClient()->CancelScan(base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); run_loop.Quit(); }));
diff --git a/chromeos/printing/printer_translator.cc b/chromeos/printing/printer_translator.cc index 49ab79b..56e232d 100644 --- a/chromeos/printing/printer_translator.cc +++ b/chromeos/printing/printer_translator.cc
@@ -39,35 +39,34 @@ // Populates the |printer| object with corresponding fields from |value|. // Returns false if |value| is missing a required field. -bool DictionaryToPrinter(const base::Value& value, Printer* printer) { +bool DictionaryToPrinter(const base::Value::Dict& value, Printer* printer) { // Mandatory fields - const std::string* display_name = value.FindStringKey(kDisplayName); - if (display_name) { - printer->set_display_name(*display_name); - } else { + const std::string* display_name = value.FindString(kDisplayName); + if (!display_name) { LOG(WARNING) << "Display name required"; return false; } + printer->set_display_name(*display_name); - const std::string* uri = value.FindStringKey(kUri); - if (uri) { - std::string message; - if (!printer->SetUri(*uri, &message)) { - LOG(WARNING) << message; - return false; - } - } else { + const std::string* uri = value.FindString(kUri); + if (!uri) { LOG(WARNING) << "Uri required"; return false; } + std::string message; + if (!printer->SetUri(*uri, &message)) { + LOG(WARNING) << message; + return false; + } + // Optional fields - const std::string* description = value.FindStringKey(kDescription); + const std::string* description = value.FindString(kDescription); if (description) printer->set_description(*description); - const std::string* manufacturer = value.FindStringKey(kManufacturer); - const std::string* model = value.FindStringKey(kModel); + const std::string* manufacturer = value.FindString(kManufacturer); + const std::string* model = value.FindString(kModel); std::string make_and_model = manufacturer ? *manufacturer : std::string(); if (!make_and_model.empty() && model && !model->empty()) @@ -76,7 +75,7 @@ make_and_model.append(*model); printer->set_make_and_model(make_and_model); - const std::string* uuid = value.FindStringKey(kUUID); + const std::string* uuid = value.FindString(kUUID); if (uuid) printer->set_uuid(*uuid); @@ -86,21 +85,21 @@ // Create an empty CupsPrinterInfo dictionary value. It should be consistent // with the fields in js side. See cups_printers_browser_proxy.js for the // definition of CupsPrintersInfo. -base::Value CreateEmptyPrinterInfo() { - base::Value printer_info(base::Value::Type::DICTIONARY); - printer_info.SetBoolKey("isManaged", false); - printer_info.SetStringKey("ppdManufacturer", ""); - printer_info.SetStringKey("ppdModel", ""); - printer_info.SetStringKey("printerAddress", ""); - printer_info.SetBoolPath("printerPpdReference.autoconf", false); - printer_info.SetStringKey("printerDescription", ""); - printer_info.SetStringKey("printerId", ""); - printer_info.SetStringKey("printerMakeAndModel", ""); - printer_info.SetStringKey("printerName", ""); - printer_info.SetStringKey("printerPPDPath", ""); - printer_info.SetStringKey("printerProtocol", "ipp"); - printer_info.SetStringKey("printerQueue", ""); - printer_info.SetStringKey("printerStatus", ""); +base::Value::Dict CreateEmptyPrinterInfo() { + base::Value::Dict printer_info; + printer_info.Set("isManaged", false); + printer_info.Set("ppdManufacturer", ""); + printer_info.Set("ppdModel", ""); + printer_info.Set("printerAddress", ""); + printer_info.SetByDottedPath("printerPpdReference.autoconf", false); + printer_info.Set("printerDescription", ""); + printer_info.Set("printerId", ""); + printer_info.Set("printerMakeAndModel", ""); + printer_info.Set("printerName", ""); + printer_info.Set("printerPPDPath", ""); + printer_info.Set("printerProtocol", "ipp"); + printer_info.Set("printerQueue", ""); + printer_info.Set("printerStatus", ""); return printer_info; } @@ -118,11 +117,12 @@ const char kPrinterId[] = "id"; -std::unique_ptr<Printer> RecommendedPrinterToPrinter(const base::Value& pref) { +std::unique_ptr<Printer> RecommendedPrinterToPrinter( + const base::Value::Dict& pref) { std::string id; // Printer id comes from the id or guid field depending on the source. - const std::string* printer_id = pref.FindStringKey(kPrinterId); - const std::string* printer_guid = pref.FindStringKey(kGuid); + const std::string* printer_id = pref.FindString(kPrinterId); + const std::string* printer_guid = pref.FindString(kGuid); if (printer_id) { id = *printer_id; } else if (printer_guid) { @@ -140,13 +140,13 @@ printer->set_source(Printer::SRC_POLICY); - const base::Value* ppd = pref.FindDictKey(kPpdResource); + const base::Value::Dict* ppd = pref.FindDict(kPpdResource); if (ppd) { Printer::PpdReference* ppd_reference = printer->mutable_ppd_reference(); - const std::string* make_and_model = ppd->FindStringKey(kEffectiveModel); + const std::string* make_and_model = ppd->FindString(kEffectiveModel); if (make_and_model) ppd_reference->effective_make_and_model = *make_and_model; - absl::optional<bool> autoconf = ppd->FindBoolKey(kAutoconf); + absl::optional<bool> autoconf = ppd->FindBool(kAutoconf); if (autoconf.has_value()) ppd_reference->autoconf = *autoconf; } @@ -168,70 +168,65 @@ return printer; } -base::Value GetCupsPrinterInfo(const Printer& printer) { - base::Value printer_info = CreateEmptyPrinterInfo(); +base::Value::Dict GetCupsPrinterInfo(const Printer& printer) { + base::Value::Dict printer_info = CreateEmptyPrinterInfo(); - printer_info.SetBoolKey("isManaged", - printer.source() == Printer::Source::SRC_POLICY); - printer_info.SetStringKey("printerId", printer.id()); - printer_info.SetStringKey("printerName", printer.display_name()); - printer_info.SetStringKey("printerDescription", printer.description()); - printer_info.SetStringKey("printerMakeAndModel", printer.make_and_model()); + printer_info.Set("isManaged", + printer.source() == Printer::Source::SRC_POLICY); + printer_info.Set("printerId", printer.id()); + printer_info.Set("printerName", printer.display_name()); + printer_info.Set("printerDescription", printer.description()); + printer_info.Set("printerMakeAndModel", printer.make_and_model()); // NOTE: This assumes the the function IsIppEverywhere() simply returns // |printer.ppd_reference_.autoconf|. If the implementation of // IsIppEverywhere() changes this will need to be changed as well. - printer_info.SetBoolPath("printerPpdReference.autoconf", - printer.IsIppEverywhere()); - printer_info.SetStringKey("printerPPDPath", - printer.ppd_reference().user_supplied_ppd_url); - printer_info.SetStringKey("printServerUri", printer.print_server_uri()); + printer_info.SetByDottedPath("printerPpdReference.autoconf", + printer.IsIppEverywhere()); + printer_info.Set("printerPPDPath", + printer.ppd_reference().user_supplied_ppd_url); + printer_info.Set("printServerUri", printer.print_server_uri()); if (!printer.HasUri()) { // Uri is invalid so we set default values. LOG(WARNING) << "Could not parse uri. Defaulting values"; - printer_info.SetStringKey("printerAddress", ""); - printer_info.SetStringKey("printerQueue", ""); - printer_info.SetStringKey("printerProtocol", - "ipp"); // IPP is our default protocol. + printer_info.Set("printerAddress", ""); + printer_info.Set("printerQueue", ""); + printer_info.Set("printerProtocol", "ipp"); // IPP is our default protocol. return printer_info; } if (printer.IsUsbProtocol()) - printer_info.SetStringKey("ppdManufacturer", - printer.usb_printer_manufacturer()); - printer_info.SetStringKey("printerProtocol", printer.uri().GetScheme()); - printer_info.SetStringKey("printerAddress", PrinterAddress(printer.uri())); + printer_info.Set("ppdManufacturer", printer.usb_printer_manufacturer()); + printer_info.Set("printerProtocol", printer.uri().GetScheme()); + printer_info.Set("printerAddress", PrinterAddress(printer.uri())); std::string printer_queue = printer.uri().GetPathEncodedAsString(); if (!printer_queue.empty()) printer_queue = printer_queue.substr(1); // removes the leading '/' if (!printer.uri().GetQueryEncodedAsString().empty()) printer_queue += "?" + printer.uri().GetQueryEncodedAsString(); - printer_info.SetStringKey("printerQueue", printer_queue); + printer_info.Set("printerQueue", printer_queue); return printer_info; } -base::Value CreateCupsPrinterStatusDictionary( +base::Value::Dict CreateCupsPrinterStatusDictionary( const CupsPrinterStatus& cups_printer_status) { - base::Value printer_status(base::Value::Type::DICTIONARY); + base::Value::Dict printer_status; - printer_status.SetKey("printerId", - base::Value(cups_printer_status.GetPrinterId())); - printer_status.SetKey( - "timestamp", - base::Value(cups_printer_status.GetTimestamp().ToJsTimeIgnoringNull())); + printer_status.Set("printerId", cups_printer_status.GetPrinterId()); + printer_status.Set("timestamp", + cups_printer_status.GetTimestamp().ToJsTimeIgnoringNull()); - base::Value status_reasons(base::Value::Type::LIST); - for (auto reason : cups_printer_status.GetStatusReasons()) { - base::Value status_reason(base::Value::Type::DICTIONARY); - status_reason.SetKey("reason", - base::Value(static_cast<int>(reason.GetReason()))); - status_reason.SetKey("severity", - base::Value(static_cast<int>(reason.GetSeverity()))); + base::Value::List status_reasons; + for (const auto& reason : cups_printer_status.GetStatusReasons()) { + base::Value::Dict status_reason; + status_reason.Set("reason", static_cast<int>(reason.GetReason())); + status_reason.Set("severity", static_cast<int>(reason.GetSeverity())); status_reasons.Append(std::move(status_reason)); } - printer_status.SetKey("statusReasons", std::move(status_reasons)); + printer_status.Set("statusReasons", std::move(status_reasons)); return printer_status; } + } // namespace chromeos
diff --git a/chromeos/printing/printer_translator.h b/chromeos/printing/printer_translator.h index 25f46f65..993cb62a 100644 --- a/chromeos/printing/printer_translator.h +++ b/chromeos/printing/printer_translator.h
@@ -8,12 +8,9 @@ #include <memory> #include "base/component_export.h" +#include "base/values.h" #include "chromeos/printing/printer_configuration.h" -namespace base { -class Value; -} - namespace chromeos { class CupsPrinterStatus; @@ -23,18 +20,20 @@ // Returns a new printer populated with the fields from |pref|. Processes // dictionaries from policy. COMPONENT_EXPORT(CHROMEOS_PRINTING) -std::unique_ptr<Printer> RecommendedPrinterToPrinter(const base::Value& pref); +std::unique_ptr<Printer> RecommendedPrinterToPrinter( + const base::Value::Dict& pref); // Returns a JSON representation of |printer| as a CupsPrinterInfo. If the // printer uri cannot be parsed, the relevant fields are populated with default // values. CupsPrinterInfo is defined in cups_printers_browser_proxy.js. COMPONENT_EXPORT(CHROMEOS_PRINTING) -base::Value GetCupsPrinterInfo(const Printer& printer); +base::Value::Dict GetCupsPrinterInfo(const Printer& printer); // Returns a JSON representation of a CupsPrinterStatus COMPONENT_EXPORT(CHROMEOS_PRINTING) -base::Value CreateCupsPrinterStatusDictionary( +base::Value::Dict CreateCupsPrinterStatusDictionary( const CupsPrinterStatus& cups_printer_status); + } // namespace chromeos #endif // CHROMEOS_PRINTING_PRINTER_TRANSLATOR_H_
diff --git a/chromeos/printing/printer_translator_unittest.cc b/chromeos/printing/printer_translator_unittest.cc index c3795763..8d1c30f 100644 --- a/chromeos/printing/printer_translator_unittest.cc +++ b/chromeos/printing/printer_translator_unittest.cc
@@ -55,7 +55,7 @@ // Check the values populated in |printer_info| match the values of |printer|. void CheckGenericPrinterInfo(const Printer& printer, - const base::Value& printer_info) { + const base::Value::Dict& printer_info) { ExpectDictStringValue(printer.id(), printer_info, "printerId"); ExpectDictStringValue(printer.display_name(), printer_info, "printerName"); ExpectDictStringValue(printer.description(), printer_info, @@ -66,7 +66,7 @@ // Check that the corresponding values in |printer_info| match the given URI // components of |address|, |queue|, and |protocol|. -void CheckPrinterInfoUri(const base::Value& printer_info, +void CheckPrinterInfoUri(const base::Value::Dict& printer_info, const std::string& protocol, const std::string& address, const std::string& queue) { @@ -78,41 +78,41 @@ } // anonymous namespace TEST(PrinterTranslatorTest, RecommendedPrinterToPrinterMissingId) { - base::Value value(base::Value::Type::DICTIONARY); + base::Value::Dict value; std::unique_ptr<Printer> printer = RecommendedPrinterToPrinter(value); EXPECT_FALSE(printer); } TEST(PrinterTranslatorTest, MissingDisplayNameFails) { - base::Value preference(base::Value::Type::DICTIONARY); - preference.SetStringKey("id", kHash); + base::Value::Dict preference; + preference.Set("id", kHash); // display name omitted - preference.SetStringKey("uri", kUri); - preference.SetStringPath("ppd_resource.effective_model", - kEffectiveMakeAndModel); + preference.Set("uri", kUri); + preference.SetByDottedPath("ppd_resource.effective_model", + kEffectiveMakeAndModel); std::unique_ptr<Printer> printer = RecommendedPrinterToPrinter(preference); EXPECT_FALSE(printer); } TEST(PrinterTranslatorTest, MissingUriFails) { - base::Value preference(base::Value::Type::DICTIONARY); - preference.SetStringKey("id", kHash); - preference.SetStringKey("display_name", kName); + base::Value::Dict preference; + preference.Set("id", kHash); + preference.Set("display_name", kName); // uri omitted - preference.SetStringPath("ppd_resource.effective_model", - kEffectiveMakeAndModel); + preference.SetByDottedPath("ppd_resource.effective_model", + kEffectiveMakeAndModel); std::unique_ptr<Printer> printer = RecommendedPrinterToPrinter(preference); EXPECT_FALSE(printer); } TEST(PrinterTranslatorTest, MissingPpdResourceFails) { - base::Value preference(base::Value::Type::DICTIONARY); - preference.SetStringKey("id", kHash); - preference.SetStringKey("display_name", kName); - preference.SetStringKey("uri", kUri); + base::Value::Dict preference; + preference.Set("id", kHash); + preference.Set("display_name", kName); + preference.Set("uri", kUri); // ppd resource omitted std::unique_ptr<Printer> printer = RecommendedPrinterToPrinter(preference); @@ -120,11 +120,11 @@ } TEST(PrinterTranslatorTest, MissingEffectiveMakeModelFails) { - base::Value preference(base::Value::Type::DICTIONARY); - preference.SetStringKey("id", kHash); - preference.SetStringKey("display_name", kName); - preference.SetStringKey("uri", kUri); - preference.SetStringPath("ppd_resource.foobarwrongfield", "gibberish"); + base::Value::Dict preference; + preference.Set("id", kHash); + preference.Set("display_name", kName); + preference.Set("uri", kUri); + preference.SetByDottedPath("ppd_resource.foobarwrongfield", "gibberish"); std::unique_ptr<Printer> printer = RecommendedPrinterToPrinter(preference); EXPECT_FALSE(printer); @@ -133,39 +133,39 @@ // The test verifies that setting both true autoconf flag and non-empty // effective_model properties is not considered as the valid policy. TEST(PrinterTranslatorTest, AutoconfAndMakeModelSet) { - base::Value preference(base::Value::Type::DICTIONARY); - preference.SetStringKey("id", kHash); - preference.SetStringKey("display_name", kName); - preference.SetStringKey("uri", kUri); - preference.SetStringPath("ppd_resource.effective_model", - kEffectiveMakeAndModel); - preference.SetBoolPath("ppd_resource.autoconf", true); + base::Value::Dict preference; + preference.Set("id", kHash); + preference.Set("display_name", kName); + preference.Set("uri", kUri); + preference.SetByDottedPath("ppd_resource.effective_model", + kEffectiveMakeAndModel); + preference.SetByDottedPath("ppd_resource.autoconf", true); std::unique_ptr<Printer> printer = RecommendedPrinterToPrinter(preference); EXPECT_FALSE(printer); } TEST(PrinterTranslatorTest, InvalidUriFails) { - base::Value preference(base::Value::Type::DICTIONARY); - preference.SetStringKey("id", kHash); - preference.SetStringKey("display_name", kName); - preference.SetStringPath("ppd_resource.effective_model", - kEffectiveMakeAndModel); + base::Value::Dict preference; + preference.Set("id", kHash); + preference.Set("display_name", kName); + preference.SetByDottedPath("ppd_resource.effective_model", + kEffectiveMakeAndModel); // uri with incorrect port - preference.SetStringKey("uri", "ipp://hostname.tld:-1"); + preference.Set("uri", "ipp://hostname.tld:-1"); std::unique_ptr<Printer> printer = RecommendedPrinterToPrinter(preference); EXPECT_FALSE(printer); } TEST(PrinterTranslatorTest, RecommendedPrinterMinimalSetup) { - base::Value preference(base::Value::Type::DICTIONARY); - preference.SetStringKey("id", kHash); - preference.SetStringKey("display_name", kName); - preference.SetStringKey("uri", kUri); - preference.SetStringPath("ppd_resource.effective_model", - kEffectiveMakeAndModel); + base::Value::Dict preference; + preference.Set("id", kHash); + preference.Set("display_name", kName); + preference.Set("uri", kUri); + preference.SetByDottedPath("ppd_resource.effective_model", + kEffectiveMakeAndModel); std::unique_ptr<Printer> printer = RecommendedPrinterToPrinter(preference); ASSERT_TRUE(printer); @@ -176,18 +176,18 @@ } TEST(PrinterTranslatorTest, RecommendedPrinterToPrinter) { - base::Value preference(base::Value::Type::DICTIONARY); - preference.SetStringKey("id", kHash); - preference.SetStringKey("display_name", kName); - preference.SetStringKey("description", kDescription); - preference.SetStringKey("manufacturer", kMake); - preference.SetStringKey("model", kModel); - preference.SetStringKey("uri", kUri); - preference.SetStringKey("uuid", kUUID); + base::Value::Dict preference; + preference.Set("id", kHash); + preference.Set("display_name", kName); + preference.Set("description", kDescription); + preference.Set("manufacturer", kMake); + preference.Set("model", kModel); + preference.Set("uri", kUri); + preference.Set("uuid", kUUID); - preference.SetBoolPath("ppd_resource.autoconf", false); - preference.SetStringPath("ppd_resource.effective_model", - kEffectiveMakeAndModel); + preference.SetByDottedPath("ppd_resource.autoconf", false); + preference.SetByDottedPath("ppd_resource.effective_model", + kEffectiveMakeAndModel); std::unique_ptr<Printer> printer = RecommendedPrinterToPrinter(preference); EXPECT_TRUE(printer); @@ -205,12 +205,12 @@ } TEST(PrinterTranslatorTest, RecommendedPrinterToPrinterAutoconf) { - base::Value preference(base::Value::Type::DICTIONARY); - preference.SetStringKey("id", kHash); - preference.SetStringKey("display_name", kName); - preference.SetStringKey("uri", kUri); + base::Value::Dict preference; + preference.Set("id", kHash); + preference.Set("display_name", kName); + preference.Set("uri", kUri); - preference.SetBoolPath("ppd_resource.autoconf", true); + preference.SetByDottedPath("ppd_resource.autoconf", true); std::unique_ptr<Printer> printer = RecommendedPrinterToPrinter(preference); EXPECT_TRUE(printer); @@ -223,13 +223,13 @@ } TEST(PrinterTranslatorTest, RecommendedPrinterToPrinterBlankManufacturer) { - base::Value preference(base::Value::Type::DICTIONARY); - preference.SetStringKey("id", kHash); - preference.SetStringKey("display_name", kName); - preference.SetStringKey("model", kModel); - preference.SetStringKey("uri", kUri); - preference.SetStringPath("ppd_resource.effective_model", - kEffectiveMakeAndModel); + base::Value::Dict preference; + preference.Set("id", kHash); + preference.Set("display_name", kName); + preference.Set("model", kModel); + preference.Set("uri", kUri); + preference.SetByDottedPath("ppd_resource.effective_model", + kEffectiveMakeAndModel); std::unique_ptr<Printer> printer = RecommendedPrinterToPrinter(preference); EXPECT_TRUE(printer); @@ -238,13 +238,13 @@ } TEST(PrinterTranslatorTest, RecommendedPrinterToPrinterBlankModel) { - base::Value preference(base::Value::Type::DICTIONARY); - preference.SetStringKey("id", kHash); - preference.SetStringKey("display_name", kName); - preference.SetStringKey("manufacturer", kMake); - preference.SetStringKey("uri", kUri); - preference.SetStringPath("ppd_resource.effective_model", - kEffectiveMakeAndModel); + base::Value::Dict preference; + preference.Set("id", kHash); + preference.Set("display_name", kName); + preference.Set("manufacturer", kMake); + preference.Set("uri", kUri); + preference.SetByDottedPath("ppd_resource.effective_model", + kEffectiveMakeAndModel); std::unique_ptr<Printer> printer = RecommendedPrinterToPrinter(preference); EXPECT_TRUE(printer); @@ -253,12 +253,12 @@ } TEST(PrinterTranslatorTest, BulkPrinterJson) { - base::Value preference(base::Value::Type::DICTIONARY); - preference.SetStringKey("guid", kGUID); - preference.SetStringKey("display_name", kName); - preference.SetStringKey("uri", kUri); - preference.SetStringPath("ppd_resource.effective_model", - kEffectiveMakeAndModel); + base::Value::Dict preference; + preference.Set("guid", kGUID); + preference.Set("display_name", kName); + preference.Set("uri", kUri); + preference.SetByDottedPath("ppd_resource.effective_model", + kEffectiveMakeAndModel); std::unique_ptr<Printer> printer = RecommendedPrinterToPrinter(preference); EXPECT_TRUE(printer); @@ -268,7 +268,7 @@ TEST(PrinterTranslatorTest, GetCupsPrinterInfoGenericPrinter) { Printer printer = CreateGenericPrinter(); - base::Value printer_info = GetCupsPrinterInfo(printer); + base::Value::Dict printer_info = GetCupsPrinterInfo(printer); CheckGenericPrinterInfo(CreateGenericPrinter(), printer_info); // We expect the default values to be set for the URI components since the @@ -282,7 +282,7 @@ Printer printer = CreateGenericPrinter(); ASSERT_TRUE(printer.SetUri(kUri)); - base::Value printer_info = GetCupsPrinterInfo(printer); + base::Value::Dict printer_info = GetCupsPrinterInfo(printer); CheckGenericPrinterInfo(CreateGenericPrinter(), printer_info); CheckPrinterInfoUri(printer_info, "ipp", "printy.domain.co:555", "ipp/print"); @@ -294,7 +294,7 @@ Printer printer = CreateGenericPrinter(); ASSERT_TRUE(printer.SetUri(kUsbUri)); - base::Value printer_info = GetCupsPrinterInfo(printer); + base::Value::Dict printer_info = GetCupsPrinterInfo(printer); CheckGenericPrinterInfo(CreateGenericPrinter(), printer_info); CheckPrinterInfoUri(printer_info, "usb", "1234", "af9d?serial=ink1"); @@ -304,7 +304,7 @@ TEST(PrinterTranslatorTest, GetCupsPrinterInfoAutoconfPrinter) { Printer printer = CreateAutoconfPrinter(); - base::Value printer_info = GetCupsPrinterInfo(printer); + base::Value::Dict printer_info = GetCupsPrinterInfo(printer); CheckGenericPrinterInfo(CreateGenericPrinter(), printer_info); // We expect the default values to be set for the URI components since the @@ -322,22 +322,24 @@ CupsPrinterStatusReason::Reason::kDoorOpen, CupsPrinterStatusReason::Severity::kError); - base::Value printer_status_dict = + base::Value::Dict printer_status_dict = CreateCupsPrinterStatusDictionary(cups_printer_status); - EXPECT_EQ("id", *printer_status_dict.FindStringPath("printerId")); + EXPECT_EQ("id", *printer_status_dict.FindString("printerId")); EXPECT_EQ(cups_printer_status.GetTimestamp().ToJsTimeIgnoringNull(), - *printer_status_dict.FindDoublePath("timestamp")); + *printer_status_dict.FindDouble("timestamp")); - const base::Value* status_reasons = - printer_status_dict.FindListPath("statusReasons"); - EXPECT_EQ(1u, status_reasons->GetList().size()); + const base::Value::List* status_reasons = + printer_status_dict.FindList("statusReasons"); + ASSERT_TRUE(status_reasons); + EXPECT_EQ(1u, status_reasons->size()); - for (const base::Value& status_reason : status_reasons->GetList()) { + for (const base::Value& status_reason : *status_reasons) { + ASSERT_TRUE(status_reason.is_dict()); EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Reason::kDoorOpen), - *status_reason.FindIntPath("reason")); + status_reason.GetDict().FindInt("reason")); EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Severity::kError), - *status_reason.FindIntPath("severity")); + status_reason.GetDict().FindInt("severity")); } } @@ -350,33 +352,34 @@ CupsPrinterStatusReason::Reason::kPaperJam, CupsPrinterStatusReason::Severity::kError); - base::Value printer_status_dict = + base::Value::Dict printer_status_dict = CreateCupsPrinterStatusDictionary(cups_printer_status); - EXPECT_EQ("id", *printer_status_dict.FindStringPath("printerId")); + EXPECT_EQ("id", *printer_status_dict.FindString("printerId")); EXPECT_EQ(cups_printer_status.GetTimestamp().ToJsTimeIgnoringNull(), - *printer_status_dict.FindDoublePath("timestamp")); + *printer_status_dict.FindDouble("timestamp")); - const base::Value* status_reasons = - printer_status_dict.FindListPath("statusReasons"); + const base::Value::List* status_reasons = + printer_status_dict.FindList("statusReasons"); + ASSERT_TRUE(status_reasons); - const auto& status_reasons_list = status_reasons->GetList(); + const auto& status_reasons_list = *status_reasons; ASSERT_EQ(2u, status_reasons_list.size()); EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Reason::kLowOnPaper), - status_reasons_list[0].FindIntPath("reason")); + status_reasons_list[0].GetDict().FindInt("reason")); EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Severity::kWarning), - status_reasons_list[0].FindIntPath("severity")); + status_reasons_list[0].GetDict().FindInt("severity")); EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Reason::kPaperJam), - status_reasons_list[1].FindIntPath("reason")); + status_reasons_list[1].GetDict().FindInt("reason")); EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Severity::kError), - status_reasons_list[1].FindIntPath("severity")); + status_reasons_list[1].GetDict().FindInt("severity")); } TEST(PrinterTranslatorTest, GetCupsPrinterInfoManagedPrinter) { Printer printer = CreateGenericPrinter(); printer.set_source(Printer::Source::SRC_USER_PREFS); - base::Value printer_info = GetCupsPrinterInfo(printer); + base::Value::Dict printer_info = GetCupsPrinterInfo(printer); ExpectDictBooleanValue(false, printer_info, "isManaged"); printer.set_source(Printer::Source::SRC_POLICY);
diff --git a/components/exo/wayland/clients/client_base.cc b/components/exo/wayland/clients/client_base.cc index 50f1a59f..430f0b8 100644 --- a/components/exo/wayland/clients/client_base.cc +++ b/components/exo/wayland/clients/client_base.cc
@@ -556,8 +556,9 @@ ui::OzonePlatform::InitParams ozone_params; ozone_params.single_process = true; ui::OzonePlatform::InitializeForGPU(ozone_params); - bool gl_initialized = gl::init::InitializeGLOneOff(/*system_device_id=*/0); - DCHECK(gl_initialized); + gl::GLDisplayEGL* display = static_cast<gl::GLDisplayEGL*>( + gl::init::InitializeGLOneOff(/*system_device_id=*/0)); + DCHECK(display); gl_surface_ = gl::init::CreateOffscreenGLSurface(gfx::Size()); gl_context_ = gl::init::CreateGLContext(nullptr, // share_group @@ -566,14 +567,11 @@ make_current_ = std::make_unique<ui::ScopedMakeCurrent>(gl_context_.get(), gl_surface_.get()); - if (gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( - "EGL_EXT_image_flush_external") || - gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( - "EGL_ARM_implicit_external_sync")) { + if (display->ext->b_EGL_EXT_image_flush_external || + display->ext->b_EGL_ARM_implicit_external_sync) { egl_sync_type_ = EGL_SYNC_FENCE_KHR; } - if (gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( - "EGL_ANDROID_native_fence_sync")) { + if (display->ext->b_EGL_ANDROID_native_fence_sync) { egl_sync_type_ = EGL_SYNC_NATIVE_FENCE_ANDROID; }
diff --git a/components/feed/core/v2/api_test/feed_api_stream_unittest.cc b/components/feed/core/v2/api_test/feed_api_stream_unittest.cc index bc108e6..06d79de 100644 --- a/components/feed/core/v2/api_test/feed_api_stream_unittest.cc +++ b/components/feed/core/v2/api_test/feed_api_stream_unittest.cc
@@ -322,6 +322,22 @@ ModelStateFor(GetStreamType(), store_.get())); } +TEST_P(FeedStreamTestForAllStreamTypes, UseFeedQueryOverride) { + Config config = GetFeedConfig(); + config.use_feed_query_requests = true; + SetFeedConfigForTesting(config); + + response_translator_.InjectResponse(MakeTypicalInitialModelState()); + TestSurface surface(stream_.get()); + WaitForIdleTaskQueue(); + ASSERT_TRUE(network_.query_request_sent); + // There should be no API refresh requests when using use_feed_query_requests. + auto api_request_counts = network_.GetApiRequestCounts(); + api_request_counts.erase(NetworkRequestType::kListWebFeeds); // ignore + EXPECT_EQ((std::map<NetworkRequestType, int>()), api_request_counts); + EXPECT_EQ("loading -> [user@foo] 2 slices", surface.DescribeUpdates()); +} + TEST_F(FeedApiTest, OnboardingFetchAfterStartup) { // Enable WebFeed and WebFeedOnboarding flags. base::test::ScopedFeatureList features; @@ -439,7 +455,7 @@ } TEST_P(FeedNetworkEndpointTest, TestAllNetworkEndpointConfigs) { - SetUseFeedQueryRequestsForWebFeeds(GetWebFeedUsesFeedQueryRequests()); + SetUseFeedQueryRequests(GetUseFeedQueryRequests()); // Enable WebFeed and subscribe to a page, so that we can check if the WebFeed // is refreshed by ForceRefreshForDebugging. @@ -470,10 +486,10 @@ // Total 2 queries (Web + For You). EXPECT_EQ(2, network_.send_query_call_count); // API request to DiscoFeed (For You) - if enabled by feature - EXPECT_EQ(GetDiscoFeedEnabled() ? 1 : 0, + EXPECT_EQ((!GetUseFeedQueryRequests() && GetDiscoFeedEnabled()) ? 1 : 0, network_.GetApiRequestCount<QueryInteractiveFeedDiscoverApi>()); // API request to WebFeedList if FeedQuery not enabled by config. - EXPECT_EQ(GetWebFeedUsesFeedQueryRequests() ? 0 : 1, + EXPECT_EQ(GetUseFeedQueryRequests() ? 0 : 1, network_.GetApiRequestCount<WebFeedListContentsDiscoverApi>()); }
diff --git a/components/feed/core/v2/api_test/feed_api_test.cc b/components/feed/core/v2/api_test/feed_api_test.cc index 5a2261f9..34b5e846 100644 --- a/components/feed/core/v2/api_test/feed_api_test.cc +++ b/components/feed/core/v2/api_test/feed_api_test.cc
@@ -840,9 +840,9 @@ // Disable fetching of recommended web feeds at startup to // avoid a delayed task in tests that don't need it. config.fetch_web_feed_info_delay = base::TimeDelta(); - // `use_feed_query_requests_for_web_feeds` is a temporary option for + // `use_feed_query_requests` is a temporary option for // debugging, setting it to false tests the preferred endpoint. - config.use_feed_query_requests_for_web_feeds = false; + config.use_feed_query_requests = false; SetFeedConfigForTesting(config); feed::prefs::RegisterFeedSharedProfilePrefs(profile_prefs_.registry());
diff --git a/components/feed/core/v2/api_test/feed_api_test.h b/components/feed/core/v2/api_test/feed_api_test.h index 0ef006e..59406c5 100644 --- a/components/feed/core/v2/api_test/feed_api_test.h +++ b/components/feed/core/v2/api_test/feed_api_test.h
@@ -304,6 +304,10 @@ auto iter = api_request_count_.find(request_type); return iter == api_request_count_.end() ? 0 : iter->second; } + std::map<NetworkRequestType, int> GetApiRequestCounts() const { + return api_request_count_; + } + int GetActionRequestCount() const; int GetFollowRequestCount() const { return GetApiRequestCount<FollowWebFeedDiscoverApi>(); @@ -553,7 +557,8 @@ public ::testing::WithParamInterface<::testing::tuple<bool, bool>> { public: static bool GetDiscoFeedEnabled() { return ::testing::get<0>(GetParam()); } - static bool GetWebFeedUsesFeedQueryRequests() { + // Whether Feed-Query is used instead, as request in snippets-internals. + static bool GetUseFeedQueryRequests() { return ::testing::get<1>(GetParam()); } };
diff --git a/components/feed/core/v2/config.cc b/components/feed/core/v2/config.cc index 462813c..876b50b9 100644 --- a/components/feed/core/v2/config.cc +++ b/components/feed/core/v2/config.cc
@@ -171,9 +171,8 @@ } void OverrideWithSwitches(Config& config) { - config.use_feed_query_requests_for_web_feeds = - base::CommandLine::ForCurrentProcess()->HasSwitch( - "webfeed-legacy-feedquery"); + config.use_feed_query_requests = + base::CommandLine::ForCurrentProcess()->HasSwitch("use-legacy-feedquery"); } } // namespace @@ -189,10 +188,9 @@ } // This is a dev setting that updates Config, which is supposed to be constant. -// TODO(crbug/1152592): remove when not needed anymore. -void SetUseFeedQueryRequestsForWebFeeds(const bool use_legacy) { +void SetUseFeedQueryRequests(const bool use_legacy) { Config& config = const_cast<Config&>(GetFeedConfig()); - config.use_feed_query_requests_for_web_feeds = use_legacy; + config.use_feed_query_requests = use_legacy; } void SetFeedConfigForTesting(const Config& config) {
diff --git a/components/feed/core/v2/config.h b/components/feed/core/v2/config.h index 456b081..f295219 100644 --- a/components/feed/core/v2/config.h +++ b/components/feed/core/v2/config.h
@@ -102,7 +102,7 @@ // Until we get the new list contents API working, keep using FeedQuery. // TODO(crbug/1152592): remove this when new endpoint is tested enough. // Set using snippets-internals, or the --webfeed-legacy-feedquery switch. - bool use_feed_query_requests_for_web_feeds = false; + bool use_feed_query_requests = false; // Set of optional capabilities included in requests. See // CreateFeedQueryRequest() for required capabilities. @@ -124,7 +124,7 @@ // Sets whether the legacy feed endpoint should be used for Web Feed content // fetches. -void SetUseFeedQueryRequestsForWebFeeds(const bool use_legacy); +void SetUseFeedQueryRequests(const bool use_legacy); void SetFeedConfigForTesting(const Config& config); void OverrideConfigWithFinchForTesting();
diff --git a/components/feed/core/v2/tasks/load_more_task.cc b/components/feed/core/v2/tasks/load_more_task.cc index 07f73cb..dc89ec2 100644 --- a/components/feed/core/v2/tasks/load_more_task.cc +++ b/components/feed/core/v2/tasks/load_more_task.cc
@@ -15,6 +15,7 @@ #include "components/feed/core/proto/v2/wire/client_info.pb.h" #include "components/feed/core/proto/v2/wire/feed_request.pb.h" #include "components/feed/core/proto/v2/wire/request.pb.h" +#include "components/feed/core/v2/config.h" #include "components/feed/core/v2/enums.h" #include "components/feed/core/v2/feed_network.h" #include "components/feed/core/v2/feed_stream.h" @@ -94,9 +95,8 @@ request_metadata, stream_.GetMetadata().consistency_token(), stream_.GetModel(stream_type_)->GetNextPageToken()); - // TODO(crbug/1152592): Send a different network request type for - // WebFeeds. - if (base::FeatureList::IsEnabled(kDiscoFeedEndpoint)) { + if (base::FeatureList::IsEnabled(kDiscoFeedEndpoint) && + !GetFeedConfig().use_feed_query_requests) { stream_.GetNetwork().SendApiRequest<QueryNextPageDiscoverApi>( request, account_info, std::move(request_metadata), base::BindOnce(&LoadMoreTask::QueryApiRequestComplete, GetWeakPtr()));
diff --git a/components/feed/core/v2/tasks/load_stream_task.cc b/components/feed/core/v2/tasks/load_stream_task.cc index 9ab3ccb70..04a75fb 100644 --- a/components/feed/core/v2/tasks/load_stream_task.cc +++ b/components/feed/core/v2/tasks/load_stream_task.cc
@@ -304,16 +304,16 @@ options_.stream_type, request_metadata.content_order); FeedNetwork& network = stream_.GetNetwork(); - - if (options_.stream_type.IsWebFeed() && - !GetFeedConfig().use_feed_query_requests_for_web_feeds) { + const bool force_feed_query = GetFeedConfig().use_feed_query_requests; + if (options_.stream_type.IsWebFeed() && !force_feed_query) { // Special case: web feed that is not using Feed Query requests go to // WebFeedListContentsDiscoverApi. network.SendApiRequest<WebFeedListContentsDiscoverApi>( std::move(request), account_info, std::move(request_metadata), base::BindOnce(&LoadStreamTask::QueryApiRequestComplete, GetWeakPtr())); } else if (options_.stream_type.IsForYou() && - base::FeatureList::IsEnabled(kDiscoFeedEndpoint)) { + base::FeatureList::IsEnabled(kDiscoFeedEndpoint) && + !force_feed_query) { // Special case: For You feed using the DiscoFeedEndpoint call // Query*FeedDiscoverApi. switch (options_.load_type) {
diff --git a/components/omnibox/OWNERS b/components/omnibox/OWNERS index c01d941..d59becaf 100644 --- a/components/omnibox/OWNERS +++ b/components/omnibox/OWNERS
@@ -1,7 +1,8 @@ +ender@google.com jdonnelly@chromium.org mahmadi@chromium.org manukh@chromium.org mpearson@chromium.org orinj@chromium.org tommycli@chromium.org -yoangela@chromium.org +yoangela@chromium.org \ No newline at end of file
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index 7f1e2bb..90221ff 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn
@@ -466,6 +466,7 @@ "//components/query_tiles:query_tile_java", "//third_party/androidx:androidx_collection_collection_java", "//url:gurl_java", + "//url:gurl_junit_test_support", ] }
diff --git a/components/omnibox/browser/android/javatests/src/org/chromium/components/omnibox/AutocompleteMatchBuilder.java b/components/omnibox/browser/android/javatests/src/org/chromium/components/omnibox/AutocompleteMatchBuilder.java index e31e064..456bfaa 100644 --- a/components/omnibox/browser/android/javatests/src/org/chromium/components/omnibox/AutocompleteMatchBuilder.java +++ b/components/omnibox/browser/android/javatests/src/org/chromium/components/omnibox/AutocompleteMatchBuilder.java
@@ -11,6 +11,7 @@ import org.chromium.components.omnibox.action.OmniboxPedal; import org.chromium.components.query_tiles.QueryTile; import org.chromium.url.GURL; +import org.chromium.url.JUnitTestGURLs; import java.util.ArrayList; import java.util.List; @@ -56,7 +57,8 @@ .setIsSearch(true) .setDisplayText("Dummy Suggestion") .setDescription("Dummy Description") - .setUrl(new GURL("http://dummy-website.com/test")); + // Use either JUnitTest or actual GURL (depends on whether ShadowGURL is applied). + .setUrl(new GURL(JUnitTestGURLs.SEARCH_URL)); } public AutocompleteMatchBuilder(@OmniboxSuggestionType int type) {
diff --git a/components/safe_browsing/core/common/features.cc b/components/safe_browsing/core/common/features.cc index e4e8f99..1309a829 100644 --- a/components/safe_browsing/core/common/features.cc +++ b/components/safe_browsing/core/common/features.cc
@@ -116,6 +116,9 @@ const base::Feature kSimplifiedUrlDisplay{"SimplifiedUrlDisplay", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kTailoredSecurityDesktopNotice{ + "TailoredSecurityDesktopNotice", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kTailoredSecurityIntegration{ "TailoredSecurityIntegration", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/components/safe_browsing/core/common/features.h b/components/safe_browsing/core/common/features.h index a6eea513..63b5960 100644 --- a/components/safe_browsing/core/common/features.h +++ b/components/safe_browsing/core/common/features.h
@@ -141,6 +141,12 @@ // default and control groups of the experiment. extern const base::Feature kSimplifiedUrlDisplay; +// Controls whether to automatically enable Enhanced Protection for desktop +// tailored security users. If not enabled, users of tailored security are +// notified that they can enable Enhanced Protection through an operating system +// notification. +extern const base::Feature kTailoredSecurityDesktopNotice; + // Controls whether the integration of tailored security settings is enabled. extern const base::Feature kTailoredSecurityIntegration;
diff --git a/components/sync/engine/cycle/sync_cycle_snapshot_unittest.cc b/components/sync/engine/cycle/sync_cycle_snapshot_unittest.cc index d33ffe2..1c740ae 100644 --- a/components/sync/engine/cycle/sync_cycle_snapshot_unittest.cc +++ b/components/sync/engine/cycle/sync_cycle_snapshot_unittest.cc
@@ -51,24 +51,25 @@ /*has_remaining_local_changes=*/false); std::unique_ptr<base::DictionaryValue> value(snapshot.ToValue()); EXPECT_EQ(14u, value->DictSize()); - ExpectDictStringValue(kBirthday, *value, "birthday"); + const base::Value::Dict& dict = value->GetDict(); + ExpectDictStringValue(kBirthday, dict, "birthday"); // Base64-encoded version of |kBagOfChips|. - ExpectDictStringValue("YmFnb2ZjaGlwcwE=", *value, "bagOfChips"); - ExpectDictIntegerValue(model_neutral.num_successful_commits, *value, + ExpectDictStringValue("YmFnb2ZjaGlwcwE=", dict, "bagOfChips"); + ExpectDictIntegerValue(model_neutral.num_successful_commits, dict, "numSuccessfulCommits"); - ExpectDictIntegerValue(model_neutral.num_successful_bookmark_commits, *value, + ExpectDictIntegerValue(model_neutral.num_successful_bookmark_commits, dict, "numSuccessfulBookmarkCommits"); - ExpectDictIntegerValue(model_neutral.num_updates_downloaded_total, *value, + ExpectDictIntegerValue(model_neutral.num_updates_downloaded_total, dict, "numUpdatesDownloadedTotal"); ExpectDictIntegerValue(model_neutral.num_tombstone_updates_downloaded_total, - *value, "numTombstoneUpdatesDownloadedTotal"); - ExpectDictValue(*expected_download_progress_markers_value, *value, + dict, "numTombstoneUpdatesDownloadedTotal"); + ExpectDictValue(*expected_download_progress_markers_value, dict, "downloadProgressMarkers"); - ExpectDictBooleanValue(kIsSilenced, *value, "isSilenced"); - ExpectDictIntegerValue(kNumServerConflicts, *value, "numServerConflicts"); - ExpectDictBooleanValue(false, *value, "notificationsEnabled"); - ExpectDictBooleanValue(false, *value, "hasRemainingLocalChanges"); - ExpectDictStringValue("0h 30m", *value, "poll_interval"); + ExpectDictBooleanValue(kIsSilenced, dict, "isSilenced"); + ExpectDictIntegerValue(kNumServerConflicts, dict, "numServerConflicts"); + ExpectDictBooleanValue(false, dict, "notificationsEnabled"); + ExpectDictBooleanValue(false, dict, "hasRemainingLocalChanges"); + ExpectDictStringValue("0h 30m", dict, "poll_interval"); // poll_finish_time includes the local time zone, so simply verify its // existence. EXPECT_TRUE(
diff --git a/components/ui_devtools/OWNERS b/components/ui_devtools/OWNERS index 3b961a1d..b8580f13 100644 --- a/components/ui_devtools/OWNERS +++ b/components/ui_devtools/OWNERS
@@ -1,2 +1,2 @@ -sadrul@chromium.org +kerenzhu@chromium.org lgrey@chromium.org
diff --git a/components/ui_devtools/views/OWNERS b/components/ui_devtools/views/OWNERS index 3b961a1d..b8580f13 100644 --- a/components/ui_devtools/views/OWNERS +++ b/components/ui_devtools/views/OWNERS
@@ -1,2 +1,2 @@ -sadrul@chromium.org +kerenzhu@chromium.org lgrey@chromium.org
diff --git a/components/viz/service/display_embedder/compositor_gpu_thread.cc b/components/viz/service/display_embedder/compositor_gpu_thread.cc index 06e2cb2..e3a72cb 100644 --- a/components/viz/service/display_embedder/compositor_gpu_thread.cc +++ b/components/viz/service/display_embedder/compositor_gpu_thread.cc
@@ -20,6 +20,7 @@ #include "gpu/ipc/common/gpu_client_ids.h" #include "gpu/ipc/service/gpu_channel_manager.h" #include "gpu/vulkan/buildflags.h" +#include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_surface_egl.h" #include "ui/gl/init/gl_factory.h" @@ -48,7 +49,7 @@ // that instead of enabling/disabling DrDc based on the extension. if (gl::GetGLImplementation() == gl::kGLImplementationEGLANGLE) DCHECK(gl::GLSurfaceEGL::GetGLDisplayEGL() - ->IsANGLEContextVirtualizationSupported()); + ->ext->b_EGL_ANGLE_context_virtualization); #endif scoped_refptr<VulkanContextProvider> vulkan_context_provider;
diff --git a/components/viz/service/display_embedder/skia_output_surface_dependency.h b/components/viz/service/display_embedder/skia_output_surface_dependency.h index 43dadb7..0683b7e 100644 --- a/components/viz/service/display_embedder/skia_output_surface_dependency.h +++ b/components/viz/service/display_embedder/skia_output_surface_dependency.h
@@ -89,9 +89,13 @@ gl::GLSurfaceFormat format) = 0; // Hold a ref of the given surface until the returned closure is fired. virtual base::ScopedClosureRunner CacheGLSurface(gl::GLSurface* surface) = 0; - virtual void PostTaskToClientThread(base::OnceClosure closure) = 0; virtual void ScheduleGrContextCleanup() = 0; + void PostTaskToClientThread(base::OnceClosure closure) { + GetClientTaskRunner()->PostTask(FROM_HERE, std::move(closure)); + } + virtual scoped_refptr<base::TaskRunner> GetClientTaskRunner() = 0; + // This function schedules delayed task to be run on GPUThread. It can be // called only from GPU Thread. virtual void ScheduleDelayedGPUTaskFromGPUThread(base::OnceClosure task) = 0;
diff --git a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc index 342f27f9..8a7a0354 100644 --- a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc
@@ -127,9 +127,9 @@ return base::ScopedClosureRunner(std::move(release_callback)); } -void SkiaOutputSurfaceDependencyImpl::PostTaskToClientThread( - base::OnceClosure closure) { - client_thread_task_runner_->PostTask(FROM_HERE, std::move(closure)); +scoped_refptr<base::TaskRunner> +SkiaOutputSurfaceDependencyImpl::GetClientTaskRunner() { + return client_thread_task_runner_; } void SkiaOutputSurfaceDependencyImpl::ScheduleGrContextCleanup() {
diff --git a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h index d8d90af..1d65c148 100644 --- a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h +++ b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h
@@ -52,7 +52,7 @@ base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub, gl::GLSurfaceFormat format) override; base::ScopedClosureRunner CacheGLSurface(gl::GLSurface* surface) override; - void PostTaskToClientThread(base::OnceClosure closure) override; + scoped_refptr<base::TaskRunner> GetClientTaskRunner() override; void ScheduleGrContextCleanup() override; void ScheduleDelayedGPUTaskFromGPUThread(base::OnceClosure task) override;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index 74fd2601..2ca903a 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -10,6 +10,7 @@ #include <vector> #include "base/bind.h" +#include "base/callback_forward.h" #include "base/callback_helpers.h" #include "base/no_destructor.h" #include "base/observer_list.h" @@ -32,6 +33,7 @@ #include "components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h" #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" #include "gpu/command_buffer/common/swap_buffers_complete_params.h" +#include "gpu/command_buffer/common/sync_token.h" #include "gpu/command_buffer/service/scheduler.h" #include "gpu/command_buffer/service/shared_image_factory.h" #include "gpu/command_buffer/service/shared_image_representation.h" @@ -852,13 +854,15 @@ base::BindRepeating(&SkiaOutputSurfaceImpl::BufferPresented, weak_ptr_); auto context_lost_callback = base::BindOnce(&SkiaOutputSurfaceImpl::ContextLost, weak_ptr_); + auto schedule_gpu_task = base::BindRepeating( + &SkiaOutputSurfaceImpl::ScheduleOrRetainGpuTask, weak_ptr_); impl_on_gpu_ = SkiaOutputSurfaceImplOnGpu::Create( dependency_, renderer_settings_, gpu_task_scheduler_->GetSequenceId(), display_compositor_controller_->controller_on_gpu(), std::move(did_swap_buffer_complete_callback), std::move(buffer_presented_callback), std::move(context_lost_callback), - std::move(vsync_callback_runner)); + std::move(schedule_gpu_task), std::move(vsync_callback_runner)); if (!impl_on_gpu_) { *result = false; } else { @@ -1252,6 +1256,13 @@ observer.OnContextLost(); } +void SkiaOutputSurfaceImpl::ScheduleOrRetainGpuTask( + base::OnceClosure callback, + std::vector<gpu::SyncToken> tokens) { + gpu_task_scheduler_->ScheduleOrRetainGpuTask(std::move(callback), + std::move(tokens)); +} + gfx::Rect SkiaOutputSurfaceImpl::GetCurrentFramebufferDamage() const { if (use_damage_area_from_skia_output_device_) { DCHECK(damage_of_current_buffer_);
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h index 685a700..2bf5bd4 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -8,6 +8,7 @@ #include <memory> #include <vector> +#include "base/callback_forward.h" #include "base/callback_helpers.h" #include "base/containers/circular_deque.h" #include "base/memory/raw_ptr.h" @@ -195,6 +196,8 @@ std::vector<gpu::SyncToken> sync_tokens, bool make_current, bool need_framebuffer); + void ScheduleOrRetainGpuTask(base::OnceClosure callback, + std::vector<gpu::SyncToken> tokens); enum class SyncMode { kNoWait = 0,
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 dcca5fa9..702b77f 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
@@ -9,12 +9,14 @@ #include "base/atomic_sequence_num.h" #include "base/bind.h" +#include "base/callback_forward.h" #include "base/callback_helpers.h" #include "base/debug/crash_logging.h" #include "base/memory/raw_ptr.h" #include "base/memory/scoped_refptr.h" #include "base/notreached.h" #include "base/task/bind_post_task.h" +#include "base/threading/thread_checker.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/trace_event.h" @@ -24,6 +26,7 @@ #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_util.h" #include "components/viz/common/gpu/vulkan_context_provider.h" +#include "components/viz/common/resources/release_callback.h" #include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/skia_helper.h" #include "components/viz/common/viz_utils.h" @@ -39,6 +42,7 @@ #include "components/viz/service/display_embedder/skia_output_device_webview.h" #include "components/viz/service/display_embedder/skia_output_surface_dependency.h" #include "components/viz/service/display_embedder/skia_render_copy_results.h" +#include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/common/mailbox_holder.h" #include "gpu/command_buffer/common/swap_buffers_complete_params.h" #include "gpu/command_buffer/common/sync_token.h" @@ -264,6 +268,7 @@ DidSwapBufferCompleteCallback did_swap_buffer_complete_callback, BufferPresentedCallback buffer_presented_callback, ContextLostCallback context_lost_callback, + ScheduleGpuTaskCallback schedule_gpu_task, GpuVSyncCallback gpu_vsync_callback) { TRACE_EVENT0("viz", "SkiaOutputSurfaceImplOnGpu::Create"); @@ -286,7 +291,7 @@ context_state->feature_info(), renderer_settings, sequence_id, shared_gpu_deps, std::move(did_swap_buffer_complete_callback), std::move(buffer_presented_callback), std::move(context_lost_callback), - std::move(gpu_vsync_callback)); + std::move(schedule_gpu_task), std::move(gpu_vsync_callback)); if (!impl_on_gpu->Initialize()) return nullptr; @@ -303,6 +308,7 @@ DidSwapBufferCompleteCallback did_swap_buffer_complete_callback, BufferPresentedCallback buffer_presented_callback, ContextLostCallback context_lost_callback, + ScheduleGpuTaskCallback schedule_gpu_task, GpuVSyncCallback gpu_vsync_callback) : dependency_(std::move(deps)), shared_gpu_deps_(shared_gpu_deps), @@ -324,6 +330,7 @@ did_swap_buffer_complete_callback_( std::move(did_swap_buffer_complete_callback)), context_lost_callback_(std::move(context_lost_callback)), + schedule_gpu_task_(std::move(schedule_gpu_task)), gpu_vsync_callback_(std::move(gpu_vsync_callback)), gpu_preferences_(dependency_->GetGpuPreferences()), display_context_(std::make_unique<DisplayContext>(deps, this)), @@ -355,8 +362,9 @@ } } - for (auto& callback : release_on_gpu_callbacks_) - std::move(*callback).Run(gpu::SyncToken(), /*is_lost=*/true); + DCHECK(copy_output_images_.empty() || context_state_) + << "We must have a valid context if copy requests were serviced"; + copy_output_images_.clear(); // |output_device_| may still need |shared_image_factory_|, so release it // first. @@ -1310,18 +1318,45 @@ ReleaseCallback SkiaOutputSurfaceImplOnGpu::CreateDestroyCopyOutputResourcesOnGpuThreadCallback( std::unique_ptr<gpu::SharedImageRepresentationSkia> representation) { - auto gpu_callback = std::make_unique<ReleaseCallback>(base::BindOnce( + copy_output_images_.push_back(std::move(representation)); + + auto closure_on_gpu_thread = base::BindOnce( &SkiaOutputSurfaceImplOnGpu::DestroyCopyOutputResourcesOnGpuThread, - weak_ptr_factory_.GetWeakPtr(), std::move(representation), - context_state_)); - release_on_gpu_callbacks_.push_back(std::move(gpu_callback)); + weak_ptr_, copy_output_images_.back()->mailbox()); - auto run_gpu_callback = base::BindOnce( - &SkiaOutputSurfaceImplOnGpu::RunDestroyCopyOutputResourcesOnGpuThread, - weak_ptr_factory_.GetWeakPtr(), release_on_gpu_callbacks_.back().get()); + // The destruction sequence for the textures cached by |copy_output_images_| + // is as follows: + // 1) The ReleaseCallback returned here can be invoked on any thread. When + // invoked, we post a task to the client thread with sync token + // dependencies that must be met before the texture can be released. + // 2) When this task runs on the Viz thread, it will retain the closure above + // until the next draw (for WebView). At the next draw, the Viz thread + // synchronously waits to satisfy the sync token dependencies. + // 3) Once the step above finishes, the closure is dispatched on the GPU + // thread (or render thread on WebView). + ReleaseCallback release_callback = base::BindOnce( + [](ScheduleGpuTaskCallback schedule_gpu_task, base::OnceClosure callback, + const gpu::SyncToken& sync_token, + bool) { schedule_gpu_task.Run(std::move(callback), {sync_token}); }, + schedule_gpu_task_, std::move(closure_on_gpu_thread)); - return base::BindPostTask(base::ThreadTaskRunnerHandle::Get(), - std::move(run_gpu_callback)); + return base::BindPostTask(dependency_->GetClientTaskRunner(), + std::move(release_callback)); +} + +void SkiaOutputSurfaceImplOnGpu::DestroyCopyOutputResourcesOnGpuThread( + const gpu::Mailbox& mailbox) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + for (size_t i = 0; i < copy_output_images_.size(); ++i) { + if (copy_output_images_[i]->mailbox() == mailbox) { + context_state_->MakeCurrent(nullptr); + copy_output_images_.erase(copy_output_images_.begin() + i); + return; + } + } + NOTREACHED() << "The Callback returned by GetDeleteCallback() was called " + << "more than once."; } void SkiaOutputSurfaceImplOnGpu::CopyOutput( @@ -1479,30 +1514,6 @@ ScheduleCheckReadbackCompletion(); } -void SkiaOutputSurfaceImplOnGpu::RunDestroyCopyOutputResourcesOnGpuThread( - ReleaseCallback* callback, - const gpu::SyncToken& sync_token, - bool is_lost) { - for (size_t i = 0; i < release_on_gpu_callbacks_.size(); ++i) { - if (release_on_gpu_callbacks_[i].get() == callback) { - std::move(*release_on_gpu_callbacks_[i]).Run(sync_token, is_lost); - release_on_gpu_callbacks_.erase(release_on_gpu_callbacks_.begin() + i); - return; - } - } - NOTREACHED() << "The Callback returned by GetDeleteCallback() was called " - << "more than once."; -} - -void SkiaOutputSurfaceImplOnGpu::DestroyCopyOutputResourcesOnGpuThread( - std::unique_ptr<gpu::SharedImageRepresentationSkia> representation, - scoped_refptr<gpu::SharedContextState> context_state, - const gpu::SyncToken& sync_token, - bool is_lost) { - context_state_->MakeCurrent(nullptr); - representation.reset(); -} - void SkiaOutputSurfaceImplOnGpu::BeginAccessImages( const std::vector<ImageContextImpl*>& image_contexts, std::vector<GrBackendSemaphore>* begin_semaphores,
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index 204eebd..9b27550 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -11,6 +11,7 @@ #include <utility> #include <vector> +#include "base/callback_forward.h" #include "base/containers/span.h" #include "base/memory/raw_ptr.h" #include "base/threading/thread_checker.h" @@ -94,6 +95,10 @@ base::RepeatingCallback<void(const gfx::PresentationFeedback& feedback)>; using ContextLostCallback = base::OnceClosure; + using ScheduleGpuTaskCallback = + base::RepeatingCallback<void(base::OnceClosure, + std::vector<gpu::SyncToken>)>; + // |gpu_vsync_callback| must be safe to call on any thread. The other // callbacks will only be called via |deps->PostTaskToClientThread|. static std::unique_ptr<SkiaOutputSurfaceImplOnGpu> Create( @@ -104,6 +109,7 @@ DidSwapBufferCompleteCallback did_swap_buffer_complete_callback, BufferPresentedCallback buffer_presented_callback, ContextLostCallback context_lost_callback, + ScheduleGpuTaskCallback schedule_gpu_task, GpuVSyncCallback gpu_vsync_callback); SkiaOutputSurfaceImplOnGpu( @@ -116,6 +122,7 @@ DidSwapBufferCompleteCallback did_swap_buffer_complete_callback, BufferPresentedCallback buffer_presented_callback, ContextLostCallback context_lost_callback, + ScheduleGpuTaskCallback schedule_gpu_task, GpuVSyncCallback gpu_vsync_callback); SkiaOutputSurfaceImplOnGpu(const SkiaOutputSurfaceImplOnGpu&) = delete; @@ -278,16 +285,7 @@ void MarkContextLost(ContextLostReason reason); - void RunDestroyCopyOutputResourcesOnGpuThread( - ReleaseCallback* callback, - const gpu::SyncToken& sync_token, - bool is_lost); - - void DestroyCopyOutputResourcesOnGpuThread( - std::unique_ptr<gpu::SharedImageRepresentationSkia> representation, - scoped_refptr<gpu::SharedContextState> context_state, - const gpu::SyncToken& sync_token, - bool is_lost); + void DestroyCopyOutputResourcesOnGpuThread(const gpu::Mailbox& mailbox); void SwapBuffersInternal(absl::optional<OutputSurfaceFrame> frame); void PostSubmit(absl::optional<OutputSurfaceFrame> frame); @@ -431,15 +429,17 @@ DidSwapBufferCompleteCallback did_swap_buffer_complete_callback_; BufferPresentedCallback buffer_presented_callback_; ContextLostCallback context_lost_callback_; + ScheduleGpuTaskCallback schedule_gpu_task_; GpuVSyncCallback gpu_vsync_callback_; // ImplOnGpu::CopyOutput can create SharedImages via ImplOnGpu's // SharedImageFactory. Clients can use these images via CopyOutputResult and // when done, release the resources by invoking the provided callback. If // ImplOnGpu is already destroyed, however, there is no way of running the - // release callback from the client, so this vector holds all pending release - // callbacks so resources can still be cleaned up in the dtor. - std::vector<std::unique_ptr<ReleaseCallback>> release_on_gpu_callbacks_; + // release callback from the client, so this vector holds all pending images + // so resources can still be cleaned up in the dtor. + std::vector<std::unique_ptr<gpu::SharedImageRepresentationSkia>> + copy_output_images_; // Helper, creates a release callback for the passed in |representation|. ReleaseCallback CreateDestroyCopyOutputResourcesOnGpuThreadCallback(
diff --git a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc index 411603d..d4924b12 100644 --- a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc +++ b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc
@@ -971,7 +971,17 @@ return; } - if (absl::holds_alternative<RegionCaptureCropId>(target_->sub_target)) { + // If the target is in a different renderer than the root renderer (indicated + // by having a different frame sink ID), we currently cannot provide + // reasonable metadata about the region capture rect. For more context, see + // https://crbug.com/1327560. + // + // TODO(https://crbug.com/1335175): Provide accurate bounds for elements + // embedded in different renderers. + const bool is_same_frame_sink_as_requested = + resolved_target_->GetFrameSinkId() == target_->frame_sink_id; + if (absl::holds_alternative<RegionCaptureCropId>(target_->sub_target) && + is_same_frame_sink_as_requested) { const float scale_factor = frame_metadata.device_scale_factor; metadata.region_capture_rect = scale_factor ? ScaleToEnclosingRect(capture_region, 1.0f / scale_factor)
diff --git a/components/webrtc/BUILD.gn b/components/webrtc/BUILD.gn index b9e6f308..0f641b599 100644 --- a/components/webrtc/BUILD.gn +++ b/components/webrtc/BUILD.gn
@@ -99,16 +99,3 @@ "//third_party/webrtc_overrides:metronome_like_task_queue_test", ] } - -if (is_android) { - java_cpp_features("java_features_srcjar") { - # External code should depend on ":components_webrtc_java" instead. - visibility = [ ":*" ] - sources = [ "//components/webrtc/thread_wrapper.cc" ] - template = - "//components/webrtc/java_templates/ComponentsWebRtcFeatures.java.tmpl" - } - android_library("components_webrtc_java") { - srcjar_deps = [ ":java_features_srcjar" ] - } -}
diff --git a/components/webrtc/java_templates/ComponentsWebRtcFeatures.java.tmpl b/components/webrtc/java_templates/ComponentsWebRtcFeatures.java.tmpl deleted file mode 100644 index 0586785..0000000 --- a/components/webrtc/java_templates/ComponentsWebRtcFeatures.java.tmpl +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.components.webrtc; - -/** - * Contains features that are specific to components/webrtc/. - */ -public final class ComponentsWebRtcFeatures {{ - -{NATIVE_FEATURES} - - // Prevents instantiation. - private ComponentsWebRtcFeatures() {{}} -}}
diff --git a/components/webrtc/thread_wrapper.cc b/components/webrtc/thread_wrapper.cc index 34714c5..f35c3d41 100644 --- a/components/webrtc/thread_wrapper.cc +++ b/components/webrtc/thread_wrapper.cc
@@ -29,9 +29,6 @@ constexpr base::TimeDelta kTaskLatencySampleDuration = base::Seconds(3); } -const base::Feature kThreadWrapperUsesMetronome{ - "ThreadWrapperUsesMetronome", base::FEATURE_ENABLED_BY_DEFAULT}; - // Class intended to conditionally live for the duration of ThreadWrapper // that periodically captures task latencies (definition in docs for // SetLatencyAndTaskDurationCallbacks). @@ -139,7 +136,6 @@ : Thread(std::make_unique<rtc::PhysicalSocketServer>()), task_runner_(task_runner), send_allowed_(false), - use_metronome_(base::FeatureList::IsEnabled(kThreadWrapperUsesMetronome)), last_task_id_(0), pending_send_event_(base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED) { @@ -341,26 +337,17 @@ uint32_t milliseconds) { base::TimeTicks target_time = base::TimeTicks::Now() + base::Milliseconds(milliseconds); - if (use_metronome_) { - // Coalesce tasks onto the metronome. - base::TimeTicks snapped_target_time = - blink::MetronomeSource::TimeSnappedToNextTick(target_time); - if (coalesced_tasks_.QueueDelayedTask(target_time, std::move(task), - snapped_target_time)) { - task_runner_->PostDelayedTaskAt( - base::subtle::PostDelayedTaskPassKey(), FROM_HERE, - base::BindOnce(&ThreadWrapper::RunCoalescedTaskQueueTasks, weak_ptr_, - snapped_target_time), - snapped_target_time, base::subtle::DelayPolicy::kPrecise); - } - return; + // Coalesce low precision tasks onto the metronome. + base::TimeTicks snapped_target_time = + blink::MetronomeSource::TimeSnappedToNextTick(target_time); + if (coalesced_tasks_.QueueDelayedTask(target_time, std::move(task), + snapped_target_time)) { + task_runner_->PostDelayedTaskAt( + base::subtle::PostDelayedTaskPassKey(), FROM_HERE, + base::BindOnce(&ThreadWrapper::RunCoalescedTaskQueueTasks, weak_ptr_, + snapped_target_time), + snapped_target_time, base::subtle::DelayPolicy::kPrecise); } - // Do not coalesce tasks onto the metronome. - task_runner_->PostDelayedTaskAt( - base::subtle::PostDelayedTaskPassKey(), FROM_HERE, - base::BindOnce(&ThreadWrapper::RunTaskQueueTask, weak_ptr_, - std::move(task)), - target_time, base::subtle::DelayPolicy::kPrecise); } void ThreadWrapper::PostDelayedHighPrecisionTask(
diff --git a/components/webrtc/thread_wrapper.h b/components/webrtc/thread_wrapper.h index df5572f..86ef52aa 100644 --- a/components/webrtc/thread_wrapper.h +++ b/components/webrtc/thread_wrapper.h
@@ -26,10 +26,6 @@ namespace webrtc { -// Whether ThreadWrapper should schedule low-precision tasks on the metronome. -// Default: disabled. -extern const base::Feature kThreadWrapperUsesMetronome; - // ThreadWrapper implements rtc::Thread interface on top of // Chromium's SingleThreadTaskRunner interface. Currently only the bare minimum // that is used by P2P part of libjingle is implemented. There are two ways to @@ -174,7 +170,6 @@ bool send_allowed_; - const bool use_metronome_; // |lock_| must be locked when accessing |messages_|. base::Lock lock_; int last_task_id_; @@ -184,9 +179,8 @@ std::unique_ptr<PostTaskLatencySampler> latency_sampler_; SampledDurationCallback task_latency_callback_; SampledDurationCallback task_duration_callback_; - // If |kThreadWrapperUsesMetronome| is enabled, low precision tasks are - // coalesced onto metronome ticks and stored in |coalesced_tasks_| until they - // are ready to run. + // Low precision tasks are coalesced onto metronome ticks and stored in + // `coalesced_tasks_` until they are ready to run. blink::CoalescedTasks coalesced_tasks_; base::WeakPtr<ThreadWrapper> weak_ptr_;
diff --git a/components/webrtc/thread_wrapper_unittest.cc b/components/webrtc/thread_wrapper_unittest.cc index c7d0c15..13ea7e32 100644 --- a/components/webrtc/thread_wrapper_unittest.cc +++ b/components/webrtc/thread_wrapper_unittest.cc
@@ -13,7 +13,6 @@ #include "base/synchronization/waitable_event.h" #include "base/task/single_thread_task_runner.h" #include "base/task/thread_pool.h" -#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/threading/thread.h" #include "testing/gmock/include/gmock/gmock.h" @@ -319,7 +318,6 @@ class ThreadWrapperProvider : public blink::MetronomeLikeTaskQueueProvider { public: void Initialize() override { - scoped_feature_list_.InitAndEnableFeature(kThreadWrapperUsesMetronome); ThreadWrapper::EnsureForCurrentMessageLoop(); thread_ = rtc::Thread::Current(); } @@ -334,7 +332,6 @@ webrtc::TaskQueueBase* TaskQueue() const override { return thread_; } private: - base::test::ScopedFeatureList scoped_feature_list_; // ThreadWrapper destroys itself when |message_loop_| is destroyed. raw_ptr<rtc::Thread> thread_; };
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.cc b/content/browser/accessibility/dump_accessibility_browsertest_base.cc index 63e912c..313c258 100644 --- a/content/browser/accessibility/dump_accessibility_browsertest_base.cc +++ b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -310,6 +310,12 @@ test_helper_.GetExpectationFilePath(file_path, expectations_qualifier); if (!expected_file.empty()) { expected_lines = test_helper_.LoadExpectationFile(expected_file); + } else if (GetParam() == ui::AXApiType::kWinUIA) { + // TODO: UIA is not yet supported, see crbug.com/1327652, crbug.com/1329523, + // crbug.com/1329847. + LOG(INFO) << "No expectation file present, ignoring test on this " + "platform."; + return; } #if BUILDFLAG(IS_FUCHSIA) else { @@ -318,13 +324,6 @@ return; } #endif - // TODO: UIA is not yet supported, see crbug.com/1327652, crbug.com/1329523, - // crbug.com/1329847. - if (GetParam() == ui::AXApiType::kWinUIA) { - LOG(INFO) << "No expectation file present, ignoring test on this " - "platform."; - return; - } // Get the test URL. GURL url(embedded_test_server()->GetURL(
diff --git a/content/browser/attribution_reporting/attributions_browsertest.cc b/content/browser/attribution_reporting/attributions_browsertest.cc index 606711678..a6d38c499 100644 --- a/content/browser/attribution_reporting/attributions_browsertest.cc +++ b/content/browser/attribution_reporting/attributions_browsertest.cc
@@ -112,25 +112,28 @@ base::Value body = base::test::ParseJson(request.content); EXPECT_THAT(body, base::test::DictionaryHasValues(expected_body)); + const base::Value::Dict& body_dict = body.GetDict(); // The report ID is random, so just test that the field exists here and is a // valid GUID. - std::string* report_id = body.FindStringKey("report_id"); - EXPECT_TRUE(report_id); + const std::string* report_id = body_dict.FindString("report_id"); + ASSERT_TRUE(report_id); EXPECT_TRUE(base::GUID::ParseLowercase(*report_id).is_valid()); - EXPECT_TRUE(body.FindDoubleKey("randomized_trigger_rate")); + EXPECT_TRUE(body_dict.FindDouble("randomized_trigger_rate")); if (source_debug_key.empty()) { - EXPECT_FALSE(body.FindStringKey("source_debug_key")); + EXPECT_FALSE(body_dict.FindString("source_debug_key")); } else { - base::ExpectDictStringValue(source_debug_key, body, "source_debug_key"); + base::ExpectDictStringValue(source_debug_key, body_dict, + "source_debug_key"); } if (trigger_debug_key.empty()) { - EXPECT_FALSE(body.FindStringKey("trigger_debug_key")); + EXPECT_FALSE(body_dict.FindString("trigger_debug_key")); } else { - base::ExpectDictStringValue(trigger_debug_key, body, "trigger_debug_key"); + base::ExpectDictStringValue(trigger_debug_key, body_dict, + "trigger_debug_key"); } // Clear the port as it is assigned by the EmbeddedTestServer at runtime.
diff --git a/content/browser/cache_storage/cache_storage.cc b/content/browser/cache_storage/cache_storage.cc index 5923cfd..42e8025d 100644 --- a/content/browser/cache_storage/cache_storage.cc +++ b/content/browser/cache_storage/cache_storage.cc
@@ -351,11 +351,14 @@ // backwards compatibility with older data. The serializations are // subtly different, e.g. Origin does not include a trailing "/". // TODO(crbug.com/809329): Add a test for validating fields in the proto - // - // TODO(https://crbug.com/1199077): We need to serialize the entire - // `storage_key_` into the index file. + // TODO(https://crbug.com/1199077): Stop setting the origin field once + // `CacheStorageManager` no longer uses the origin as a fallback for + // getting the storage key associated with each cache (for more info, see + // `GetStorageKeysAndLastModifiedOnTaskRunner`). protobuf_index.set_origin(storage_key_.origin().GetURL().spec()); + protobuf_index.set_storage_key(storage_key_.Serialize()); + for (const auto& cache_metadata : index.ordered_cache_metadata()) { DCHECK(base::Contains(cache_name_to_cache_dir_, cache_metadata.name)); @@ -548,6 +551,12 @@ } } + if (!index.has_storage_key()) { + DCHECK(storage_key.origin().GetURL().spec() == index.origin()); + index.set_storage_key(storage_key.Serialize()); + index_modified = true; + } + if (index_modified) { base::FilePath tmp_path = origin_path.AppendASCII("index.txt.tmp"); if (!index.SerializeToString(&body) ||
diff --git a/content/browser/cache_storage/cache_storage.proto b/content/browser/cache_storage/cache_storage.proto index 87fedf7..3a4ea30 100644 --- a/content/browser/cache_storage/cache_storage.proto +++ b/content/browser/cache_storage/cache_storage.proto
@@ -18,7 +18,8 @@ optional int32 padding_version = 6; } repeated Cache cache = 1; - optional string origin = 2; + optional string origin = 2 [deprecated = true]; + optional string storage_key = 3; } message CacheHeaderMap {
diff --git a/content/browser/cache_storage/cache_storage_manager.cc b/content/browser/cache_storage/cache_storage_manager.cc index b90a673..b0e5466 100644 --- a/content/browser/cache_storage/cache_storage_manager.cc +++ b/content/browser/cache_storage/cache_storage_manager.cc
@@ -104,8 +104,9 @@ kEmptyOriginUrl = 3, kPathMismatch = 4, kPathFileInfoFailed = 5, + kInvalidStorageKey = 6, // Add new enums above - kMaxValue = kPathFileInfoFailed, + kMaxValue = kInvalidStorageKey, }; IndexResult ValidateIndex(proto::CacheStorageIndex index) { @@ -116,6 +117,10 @@ if (url.is_empty()) return IndexResult::kEmptyOriginUrl; + // TODO(https://crbug.com/1199077): Consider adding a + // 'index.has_storage_key()' check here once we've ensured that a + // sufficient number of CacheStorage instances have been migrated (or + // verified that `ValidateIndex` won't be passed an unmigrated `index`). return IndexResult::kOk; } @@ -157,8 +162,25 @@ continue; } - auto storage_key = - blink::StorageKey(url::Origin::Create(GURL(index.origin()))); + blink::StorageKey storage_key; + if (index.has_storage_key()) { + absl::optional<blink::StorageKey> result = + blink::StorageKey::Deserialize(index.storage_key()); + if (!result) { + RecordIndexValidationResult(IndexResult::kInvalidStorageKey); + continue; + } + storage_key = result.value(); + } else { + // TODO(https://crbug.com/1199077): Since index file migrations happen + // lazily, it's plausible that the index file we are reading doesn't have + // a storage key yet. For now, fall back to creating the storage key + // from the origin. This should be removed after either enough time has + // passed for most caches to have been migrated naturally or after we + // implement follow-on code that can force a migration. + storage_key = + blink::StorageKey(url::Origin::Create(GURL(index.origin()))); + } DCHECK(!storage_key.origin().GetURL().is_empty()); auto origin_path = CacheStorageManager::ConstructStorageKeyPath(
diff --git a/content/browser/cache_storage/cache_storage_manager_unittest.cc b/content/browser/cache_storage/cache_storage_manager_unittest.cc index 5ac043a75..394d4ac 100644 --- a/content/browser/cache_storage/cache_storage_manager_unittest.cc +++ b/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -2597,6 +2597,22 @@ })); } +TEST_F(CacheStorageIndexMigrationTest, StorageKeyMigration) { + DoTest("content/test/data/cache_storage/storage_key/", + base::BindLambdaForTesting( + [this](const proto::CacheStorageIndex& original_index, + const proto::CacheStorageIndex& upgraded_index, + int64_t total_usage) { + EXPECT_FALSE(original_index.has_storage_key()); + EXPECT_TRUE(upgraded_index.has_storage_key()); + + absl::optional<blink::StorageKey> result = + blink::StorageKey::Deserialize(upgraded_index.storage_key()); + ASSERT_TRUE(result.has_value()); + EXPECT_EQ(this->storage_key1_, result.value()); + })); +} + INSTANTIATE_TEST_SUITE_P(CacheStorageManagerTests, CacheStorageManagerTestP, ::testing::Values(TestStorage::kMemory,
diff --git a/content/browser/media/capture_handle_manager.cc b/content/browser/media/capture_handle_manager.cc index a2174789..4475eac 100644 --- a/content/browser/media/capture_handle_manager.cc +++ b/content/browser/media/capture_handle_manager.cc
@@ -43,7 +43,7 @@ // Observing CaptureHandle wheneither the capturing or the captured party // is incognito is disallowed, except for self-capture. - if (capturer->GetMainFrame() != captured->GetMainFrame()) { + if (capturer->GetMainFrame() != captured->GetPrimaryMainFrame()) { if (capturer->GetBrowserContext()->IsOffTheRecord() || captured->GetBrowserContext()->IsOffTheRecord()) { return nullptr; @@ -52,7 +52,7 @@ auto result = media::mojom::CaptureHandle::New(); if (capture_handle_config.expose_origin) { - result->origin = captured->GetMainFrame()->GetLastCommittedOrigin(); + result->origin = captured->GetPrimaryMainFrame()->GetLastCommittedOrigin(); } result->capture_handle = capture_handle_config.capture_handle;
diff --git a/content/browser/preloading_data_impl.cc b/content/browser/preloading_data_impl.cc index 0cf9bf05..56db477 100644 --- a/content/browser/preloading_data_impl.cc +++ b/content/browser/preloading_data_impl.cc
@@ -37,7 +37,7 @@ // TODO(crbug.com/1330783): Extend this for non-primary page and inner // WebContents preloading attempts. ukm::SourceId triggered_primary_page_source_id = - web_contents()->GetMainFrame()->GetPageUkmSourceId(); + web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId(); auto attempt = std::make_unique<PreloadingAttemptImpl>( predictor, preloading_type, triggered_primary_page_source_id, @@ -59,7 +59,7 @@ // TODO(crbug.com/1330783): Extend this for non-primary page and inner // WebContents preloading predictions. ukm::SourceId triggered_primary_page_source_id = - web_contents()->GetMainFrame()->GetPageUkmSourceId(); + web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId(); auto prediction = std::make_unique<PreloadingPrediction>( predictor, confidence, triggered_primary_page_source_id,
diff --git a/content/browser/renderer_host/input/fling_browsertest.cc b/content/browser/renderer_host/input/fling_browsertest.cc index 61b5f7c..6988223 100644 --- a/content/browser/renderer_host/input/fling_browsertest.cc +++ b/content/browser/renderer_host/input/fling_browsertest.cc
@@ -351,9 +351,10 @@ EXPECT_TRUE(GetWidgetHost()->GetView()->view_stopped_flinging_for_test()); } -// Flaky on Linux ASAN and TSAN. https://crbug.com/1269960 -#if BUILDFLAG(IS_LINUX) && \ - (defined(THREAD_SANITIZER) || defined(ADDRESS_SANITIZER)) +// Flaky on Linux ASAN, TSAN and MSAN. https://crbug.com/1269960 +#if BUILDFLAG(IS_LINUX) && \ + (defined(THREAD_SANITIZER) || defined(ADDRESS_SANITIZER) || \ + defined(MEMORY_SANITIZER)) #define MAYBE_FlingingStopsAfterNavigation DISABLED_FlingingStopsAfterNavigation #else #define MAYBE_FlingingStopsAfterNavigation FlingingStopsAfterNavigation
diff --git a/content/browser/renderer_host/render_widget_host_browsertest.cc b/content/browser/renderer_host/render_widget_host_browsertest.cc index 88a78e3..0bcbbc6 100644 --- a/content/browser/renderer_host/render_widget_host_browsertest.cc +++ b/content/browser/renderer_host/render_widget_host_browsertest.cc
@@ -978,4 +978,46 @@ host()->render_frame_metadata_provider()->LastRenderFrameMetadata()); } +// If the DelegatedInkTrailPresenter creates a metadata that has the same +// timestamp as the previous one, it does not set the metadata. +IN_PROC_BROWSER_TEST_F(RenderWidgetHostDelegatedInkMetadataTest, + DuplicateMetadata) { + ASSERT_TRUE(ExecJs(shell()->web_contents(), R"( + let presenter = null; + navigator.ink.requestPresenter().then(e => { presenter = e; }); + let style = { color: 'green', diameter: 21 }; + let first_move_event = null; + + window.addEventListener('pointermove' , evt => { + if (first_move_event == null) { + first_move_event = evt; + } + presenter.updateInkTrailStartPoint(first_move_event, style); + }); + )")); + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 10, 10, 0, + false); + RunUntilInputProcessed(host()); + + { + const cc::RenderFrameMetadata& last_metadata = + host()->render_frame_metadata_provider()->LastRenderFrameMetadata(); + EXPECT_TRUE(last_metadata.delegated_ink_metadata.has_value()); + EXPECT_TRUE( + last_metadata.delegated_ink_metadata.value().delegated_ink_is_hovering); + } + + // Confirm metadata has no value when updateInkTrailStartPoint is called + // with the same event. + SimulateRoutedMouseEvent(blink::WebInputEvent::Type::kMouseMove, 20, 20, + blink::WebInputEvent::kLeftButtonDown, false); + RunUntilInputProcessed(host()); + + { + const cc::RenderFrameMetadata& last_metadata = + host()->render_frame_metadata_provider()->LastRenderFrameMetadata(); + EXPECT_FALSE(last_metadata.delegated_ink_metadata.has_value()); + } +} + } // namespace content
diff --git a/content/test/data/cache_storage/storage_key/0430f1a484a0ea6d8de562488c5fbeec0111d16f/ba31f73b-95e8-44fb-a273-265e7e76f5ab/3767fbd3edc759b5_0 b/content/test/data/cache_storage/storage_key/0430f1a484a0ea6d8de562488c5fbeec0111d16f/ba31f73b-95e8-44fb-a273-265e7e76f5ab/3767fbd3edc759b5_0 new file mode 100644 index 0000000..24161f27 --- /dev/null +++ b/content/test/data/cache_storage/storage_key/0430f1a484a0ea6d8de562488c5fbeec0111d16f/ba31f73b-95e8-44fb-a273-265e7e76f5ab/3767fbd3edc759b5_0 Binary files differ
diff --git a/content/test/data/cache_storage/storage_key/0430f1a484a0ea6d8de562488c5fbeec0111d16f/ba31f73b-95e8-44fb-a273-265e7e76f5ab/index b/content/test/data/cache_storage/storage_key/0430f1a484a0ea6d8de562488c5fbeec0111d16f/ba31f73b-95e8-44fb-a273-265e7e76f5ab/index new file mode 100644 index 0000000..79bd403a --- /dev/null +++ b/content/test/data/cache_storage/storage_key/0430f1a484a0ea6d8de562488c5fbeec0111d16f/ba31f73b-95e8-44fb-a273-265e7e76f5ab/index Binary files differ
diff --git a/content/test/data/cache_storage/storage_key/0430f1a484a0ea6d8de562488c5fbeec0111d16f/ba31f73b-95e8-44fb-a273-265e7e76f5ab/index-dir/the-real-index b/content/test/data/cache_storage/storage_key/0430f1a484a0ea6d8de562488c5fbeec0111d16f/ba31f73b-95e8-44fb-a273-265e7e76f5ab/index-dir/the-real-index new file mode 100644 index 0000000..d833a4cd --- /dev/null +++ b/content/test/data/cache_storage/storage_key/0430f1a484a0ea6d8de562488c5fbeec0111d16f/ba31f73b-95e8-44fb-a273-265e7e76f5ab/index-dir/the-real-index Binary files differ
diff --git a/content/test/data/cache_storage/storage_key/0430f1a484a0ea6d8de562488c5fbeec0111d16f/index.txt b/content/test/data/cache_storage/storage_key/0430f1a484a0ea6d8de562488c5fbeec0111d16f/index.txt new file mode 100644 index 0000000..227f284 --- /dev/null +++ b/content/test/data/cache_storage/storage_key/0430f1a484a0ea6d8de562488c5fbeec0111d16f/index.txt Binary files differ
diff --git a/docs/callback.md b/docs/callback.md index c0aac4c0..c0dabf4 100644 --- a/docs/callback.md +++ b/docs/callback.md
@@ -459,7 +459,7 @@ ```cpp // Binds |foo_ptr| to a no-op OnceCallback takes a scoped_refptr<Foo>. // ANTIPATTERN WARNING: This should likely be changed to ReleaseSoon()! -base::BindOnce(base::DoNothing::Once<scoped_refptr<Foo>>(), foo_ptr); +base::BindOnce(base::DoNothingAs<void(scoped_refptr<Foo>)>(), foo_ptr); ``` ### Passing Unbound Input Parameters
diff --git a/extensions/browser/app_window/app_window_contents.cc b/extensions/browser/app_window/app_window_contents.cc index bf230ee..a6fda89 100644 --- a/extensions/browser/app_window/app_window_contents.cc +++ b/extensions/browser/app_window/app_window_contents.cc
@@ -122,7 +122,7 @@ // This message should come from a primary main frame. if (!sender->IsInPrimaryMainFrame()) { bad_message::ReceivedBadMessage( - web_contents_->GetMainFrame()->GetProcess(), + web_contents_->GetPrimaryMainFrame()->GetProcess(), bad_message::AWCI_INVALID_CALL_FROM_NOT_PRIMARY_MAIN_FRAME); return; }
diff --git a/extensions/renderer/bindings/listener_tracker.cc b/extensions/renderer/bindings/listener_tracker.cc index 197afff..dba8f600 100644 --- a/extensions/renderer/bindings/listener_tracker.cc +++ b/extensions/renderer/bindings/listener_tracker.cc
@@ -61,7 +61,8 @@ EventMatcher* matcher = event_filter_.GetEventMatcher(filter_id); DCHECK(matcher); std::unique_ptr<base::DictionaryValue> filter_copy = - matcher->value()->CreateDeepCopy(); + base::DictionaryValue::From( + base::Value::ToUniquePtrValue(matcher->value()->Clone())); FilteredEventListenerKey key(context_owner_id, event_name); FilteredListeners::const_iterator counts = filtered_listeners_.find(key);
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_angle_vulkan.cc b/gpu/command_buffer/service/shared_image_backing_factory_angle_vulkan.cc index b7bfe43d..33206e1f 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_angle_vulkan.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_angle_vulkan.cc
@@ -597,7 +597,7 @@ context_state->progress_reporter()), context_state_(context_state) { DCHECK(context_state_->GrContextIsVulkan()); - DCHECK(gl::GLSurfaceEGL::GetGLDisplayEGL()->IsANGLEVulkanImageSupported()); + DCHECK(gl::GLSurfaceEGL::GetGLDisplayEGL()->ext->b_EGL_ANGLE_vulkan_image); } SharedImageBackingFactoryAngleVulkan::~SharedImageBackingFactoryAngleVulkan() =
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc b/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc index ae564df0..8d5944e 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc
@@ -22,6 +22,7 @@ #include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/native_pixmap.h" #include "ui/gl/buildflags.h" +#include "ui/gl/gl_bindings.h" #include "ui/gl/gl_surface_egl.h" #include "ui/ozone/public/ozone_platform.h" #include "ui/ozone/public/surface_factory_ozone.h" @@ -234,7 +235,7 @@ return false; } if (used_by_gl && - !gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension("EGL_KHR_image")) { + !gl::GLSurfaceEGL::GetGLDisplayEGL()->ext->b_EGL_KHR_image) { return false; } #else
diff --git a/gpu/command_buffer/service/shared_image_factory.cc b/gpu/command_buffer/service/shared_image_factory.cc index a92b327..1f37a592b 100644 --- a/gpu/command_buffer/service/shared_image_factory.cc +++ b/gpu/command_buffer/service/shared_image_factory.cc
@@ -264,7 +264,7 @@ #endif // BUILDFLAG(ENABLE_VULKAN) bool egl_ext_supported = - gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension("EGL_KHR_image"); + gl::GLSurfaceEGL::GetGLDisplayEGL()->ext->b_EGL_KHR_image; bool glx_ext_supported = false; #if defined(USE_OZONE) #if BUILDFLAG(OZONE_PLATFORM_X11)
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc index b18dd1f..d465294 100644 --- a/gpu/command_buffer/service/webgpu_decoder_impl.cc +++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -1033,6 +1033,7 @@ case WGPUFeatureName_PipelineStatisticsQuery: case WGPUFeatureName_ChromiumExperimentalDp4a: case WGPUFeatureName_DawnMultiPlanarFormats: + case WGPUFeatureName_DepthClipControl: return allow_unsafe_apis_; case WGPUFeatureName_Depth32FloatStencil8: case WGPUFeatureName_TextureCompressionBC:
diff --git a/gpu/config/gpu_info_collector.cc b/gpu/config/gpu_info_collector.cc index 56406bb..d95ffa8 100644 --- a/gpu/config/gpu_info_collector.cc +++ b/gpu/config/gpu_info_collector.cc
@@ -386,13 +386,11 @@ base::UmaHistogramSparse("GPU.MaxMSAASampleCount", max_samples); #if BUILDFLAG(IS_ANDROID) + gl::GLDisplayEGL* display = gl::GLSurfaceEGL::GetGLDisplayEGL(); gpu_info->can_support_threaded_texture_mailbox = - gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( - "EGL_KHR_fence_sync") && - gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( - "EGL_KHR_image_base") && - gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( - "EGL_KHR_gl_texture_2D_image") && + display->ext->b_EGL_KHR_fence_sync && + display->ext->b_EGL_KHR_image_base && + display->ext->b_EGL_KHR_gl_texture_2D_image && gfx::HasExtension(extension_set, "GL_OES_EGL_image"); #else gl::GLWindowSystemBindingInfo window_system_binding_info; @@ -566,7 +564,7 @@ const GpuPreferences& prefs) { // Populate the list of ANGLE features by querying the functions exposed by // EGL_ANGLE_feature_control if it's available. - if (gl::GLSurfaceEGL::GetGLDisplayEGL()->IsANGLEFeatureControlSupported()) { + if (gl::g_driver_egl.client_ext.b_EGL_ANGLE_feature_control) { EGLDisplay display = gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); EGLAttrib feature_count = 0;
diff --git a/headless/BUILD.gn b/headless/BUILD.gn index a6e8bfd..42249c7 100644 --- a/headless/BUILD.gn +++ b/headless/BUILD.gn
@@ -373,6 +373,8 @@ "lib/browser/headless_quota_permission_context.h", "lib/browser/headless_request_context_manager.cc", "lib/browser/headless_request_context_manager.h", + "lib/browser/headless_select_file_dialog_factory.cc", + "lib/browser/headless_select_file_dialog_factory.h", "lib/browser/headless_window_tree_host.h", "lib/browser/protocol/browser_handler.cc", "lib/browser/protocol/browser_handler.h", @@ -477,6 +479,7 @@ "//ui/display", "//ui/events/devices", "//ui/gfx", + "//ui/shell_dialogs", "//url", ] @@ -846,6 +849,7 @@ "//testing/gmock", "//testing/gtest", "//ui/base/clipboard", + "//ui/shell_dialogs", ] if (is_mac) {
diff --git a/headless/lib/browser/DEPS b/headless/lib/browser/DEPS index 10d356d..aba14f0 100644 --- a/headless/lib/browser/DEPS +++ b/headless/lib/browser/DEPS
@@ -40,4 +40,7 @@ "headless_web_contents_impl.cc": [ "+components/printing/browser/print_to_pdf", ], + "headless_select_file_dialog_factory.*": [ + "+ui/shell_dialogs", + ], }
diff --git a/headless/lib/browser/headless_browser_main_parts.cc b/headless/lib/browser/headless_browser_main_parts.cc index 1dad925..2dbdd29 100644 --- a/headless/lib/browser/headless_browser_main_parts.cc +++ b/headless/lib/browser/headless_browser_main_parts.cc
@@ -15,6 +15,7 @@ #include "headless/lib/browser/headless_browser_impl.h" #include "headless/lib/browser/headless_devtools.h" #include "headless/lib/browser/headless_screen.h" +#include "headless/lib/browser/headless_select_file_dialog_factory.h" #if defined(HEADLESS_USE_PREFS) #include "components/os_crypt/os_crypt.h" // nogncheck @@ -61,6 +62,7 @@ MaybeStartLocalDevToolsHttpHandler(); browser_->PlatformInitialize(); browser_->RunOnStartCallback(); + HeadlessSelectFileDialogFactory::SetUp(); return content::RESULT_CODE_NORMAL_EXIT; }
diff --git a/headless/lib/browser/headless_select_file_dialog_factory.cc b/headless/lib/browser/headless_select_file_dialog_factory.cc new file mode 100644 index 0000000..22a6d95 --- /dev/null +++ b/headless/lib/browser/headless_select_file_dialog_factory.cc
@@ -0,0 +1,91 @@ +// Copyright 2022 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 "headless/lib/browser/headless_select_file_dialog_factory.h" + +namespace headless { + +namespace { +// SelectFileDialogFactory is a destructable singleton, see +// SelectFileDialog::SetFactory(), so we must make it disposable. +HeadlessSelectFileDialogFactory* g_factory_instance = nullptr; +} // namespace + +// HeadlessSelectFileDialog implements a stub select file dialog +// that cancels itself as soon as it gets open, optionally calling +// back the owner. + +class HeadlessSelectFileDialog : public ui::SelectFileDialog { + public: + HeadlessSelectFileDialog(Listener* listener, + std::unique_ptr<ui::SelectFilePolicy> policy, + SelectFileDialogCallback callback) + : ui::SelectFileDialog(listener, std::move(policy)), + callback_(std::move(callback)) {} + + protected: + ~HeadlessSelectFileDialog() override = default; + + // ui::BaseShellDialog + bool IsRunning(gfx::NativeWindow owning_window) const override { + return false; + } + + void ListenerDestroyed() override { listener_ = nullptr; } + + // ui::SelectFileDialog + void SelectFileImpl(Type type, + const std::u16string& title, + const base::FilePath& default_path, + const FileTypeInfo* file_types, + int file_type_index, + const base::FilePath::StringType& default_extension, + gfx::NativeWindow owning_window, + void* params) override { + if (callback_) + std::move(callback_).Run(type); + + if (listener_) + listener_->FileSelectionCanceled(/*params=*/nullptr); + } + + private: + // ui::SelectFileDialog: + bool HasMultipleFileTypeChoicesImpl() override { return false; } + + SelectFileDialogCallback callback_; +}; + +// HeadlessSelectFileDialogFactory creates cancelable SelectFileDialog's + +// static +void HeadlessSelectFileDialogFactory::SetUp() { + ui::SelectFileDialog::SetFactory(new HeadlessSelectFileDialogFactory()); +} + +// static +void HeadlessSelectFileDialogFactory::SetSelectFileDialogOnceCallbackForTests( + SelectFileDialogCallback callback) { + DCHECK(g_factory_instance); + g_factory_instance->callback_ = std::move(callback); +} + +ui::SelectFileDialog* HeadlessSelectFileDialogFactory::Create( + ui::SelectFileDialog::Listener* listener, + std::unique_ptr<ui::SelectFilePolicy> policy) { + return new HeadlessSelectFileDialog(listener, std::move(policy), + std::move(callback_)); +} + +HeadlessSelectFileDialogFactory::HeadlessSelectFileDialogFactory() { + DCHECK(!g_factory_instance); + g_factory_instance = this; +} + +HeadlessSelectFileDialogFactory::~HeadlessSelectFileDialogFactory() { + DCHECK_EQ(g_factory_instance, this); + g_factory_instance = nullptr; +} + +} // namespace headless
diff --git a/headless/lib/browser/headless_select_file_dialog_factory.h b/headless/lib/browser/headless_select_file_dialog_factory.h new file mode 100644 index 0000000..5ec6be54 --- /dev/null +++ b/headless/lib/browser/headless_select_file_dialog_factory.h
@@ -0,0 +1,54 @@ +// Copyright 2022 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 HEADLESS_LIB_BROWSER_HEADLESS_SELECT_FILE_DIALOG_FACTORY_H_ +#define HEADLESS_LIB_BROWSER_HEADLESS_SELECT_FILE_DIALOG_FACTORY_H_ + +#include <memory> + +#include "base/callback.h" +#include "base/files/file_path.h" +#include "headless/public/headless_export.h" +#include "ui/shell_dialogs/select_file_dialog.h" +#include "ui/shell_dialogs/select_file_dialog_factory.h" +#include "ui/shell_dialogs/select_file_policy.h" + +namespace headless { + +using SelectFileDialogCallback = + base::OnceCallback<void(ui::SelectFileDialog::Type type)>; + +class HEADLESS_EXPORT HeadlessSelectFileDialogFactory + : public ui::SelectFileDialogFactory { + public: + HeadlessSelectFileDialogFactory(const HeadlessSelectFileDialogFactory&) = + delete; + HeadlessSelectFileDialogFactory& operator=( + const HeadlessSelectFileDialogFactory&) = delete; + + // Creates the factory and sets it into ui::SelectFileDialog. + static void SetUp(); + + // Registers a one time callback that would be called when the next Select + // File Dialog comes up. This can only be called after SetUp(). + static void SetSelectFileDialogOnceCallbackForTests( + SelectFileDialogCallback callback); + + private: + friend class HeadlessSelectFileDialog; + + // ui::SelectFileDialogFactory + ui::SelectFileDialog* Create( + ui::SelectFileDialog::Listener* listener, + std::unique_ptr<ui::SelectFilePolicy> policy) override; + + HeadlessSelectFileDialogFactory(); + ~HeadlessSelectFileDialogFactory() override; + + SelectFileDialogCallback callback_; +}; + +} // namespace headless + +#endif // HEADLESS_LIB_BROWSER_HEADLESS_SELECT_FILE_DIALOG_FACTORY_H_
diff --git a/headless/test/DEPS b/headless/test/DEPS index 65b1bf2..568cd2db 100644 --- a/headless/test/DEPS +++ b/headless/test/DEPS
@@ -12,3 +12,9 @@ "+components/prefs", "+services/device/public/cpp/test/fake_geolocation_manager.h", ] +specific_include_rules = { + "headless_browser_browsertest.*": [ + "+storage/browser", + "+ui/shell_dialogs", + ], +}
diff --git a/headless/test/headless_browser_browsertest.cc b/headless/test/headless_browser_browsertest.cc index 5dd9fb6..d147bfc 100644 --- a/headless/test/headless_browser_browsertest.cc +++ b/headless/test/headless_browser_browsertest.cc
@@ -3,7 +3,9 @@ // found in the LICENSE file. #include <memory> +#include <string> #include <tuple> +#include <vector> #include "base/bind.h" #include "base/command_line.h" @@ -11,6 +13,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/memory/raw_ptr.h" +#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_restrictions.h" #include "base/values.h" @@ -27,6 +30,7 @@ #include "headless/app/headless_shell_switches.h" #include "headless/lib/browser/headless_browser_context_impl.h" #include "headless/lib/browser/headless_browser_impl.h" +#include "headless/lib/browser/headless_select_file_dialog_factory.h" #include "headless/lib/browser/headless_web_contents_impl.h" #include "headless/public/devtools/domains/inspector.h" #include "headless/public/devtools/domains/network.h" @@ -41,16 +45,19 @@ #include "net/cert/cert_status_flags.h" #include "net/ssl/ssl_server_config.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "storage/browser/file_system/external_mount_points.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/chrome_debug_urls.h" #include "third_party/blink/public/common/permissions/permission_utils.h" +#include "third_party/blink/public/mojom/frame/user_activation_notification_type.mojom.h" #include "third_party/blink/public/resources/grit/blink_resources.h" #include "third_party/blink/public/strings/grit/blink_strings.h" #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/geometry/size.h" +#include "ui/shell_dialogs/select_file_dialog.h" #if !BUILDFLAG(IS_FUCHSIA) #include "third_party/crashpad/crashpad/client/crash_report_database.h" // nogncheck @@ -813,4 +820,108 @@ testing::Ne("")); } +class SelectFileDialogHeadlessBrowserTest + : public HeadlessBrowserTest, + public testing::WithParamInterface< + std::tuple<const char*, ui::SelectFileDialog::Type>> { + public: + static constexpr char kTestMountPoint[] = "testfs"; + + void SetUp() override { + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + + // Register an external mount point to test support for virtual paths. + // This maps the virtual path a native local path to make these tests work + // on all platforms. + storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem( + kTestMountPoint, storage::kFileSystemTypeLocal, + storage::FileSystemMountOption(), temp_dir_.GetPath()); + + HeadlessBrowserTest::SetUp(); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + // Enable experimental web platform features to enable write access. + command_line->AppendSwitch( + ::switches::kEnableExperimentalWebPlatformFeatures); + } + + void TearDown() override { + HeadlessBrowserTest::TearDown(); + storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem( + kTestMountPoint); + ASSERT_TRUE(temp_dir_.Delete()); + } + + void WaitForSelectFileDialogCallback() { + if (select_file_dialog_type_ != ui::SelectFileDialog::SELECT_NONE) + return; + + ASSERT_FALSE(run_loop_); + run_loop_ = std::make_unique<base::RunLoop>( + base::RunLoop::Type::kNestableTasksAllowed); + run_loop_->Run(); + run_loop_ = nullptr; + } + + void OnSelectFileDialogCallback(ui::SelectFileDialog::Type type) { + select_file_dialog_type_ = type; + + if (run_loop_) + run_loop_->Quit(); + } + + const char* file_dialog_script() { return std::get<0>(GetParam()); } + ui::SelectFileDialog::Type expected_type() { return std::get<1>(GetParam()); } + + protected: + std::unique_ptr<base::RunLoop> run_loop_; + base::ScopedTempDir temp_dir_; + ui::SelectFileDialog::Type select_file_dialog_type_ = + ui::SelectFileDialog::SELECT_NONE; +}; + +INSTANTIATE_TEST_SUITE_P( + SelectFileDialogHeadlessBrowserTest, + SelectFileDialogHeadlessBrowserTest, + testing::Values(std::make_tuple("window.showOpenFilePicker()", + ui::SelectFileDialog::SELECT_OPEN_FILE), + std::make_tuple("window.showSaveFilePicker()", + ui::SelectFileDialog::SELECT_SAVEAS_FILE), + std::make_tuple("window.showDirectoryPicker()", + ui::SelectFileDialog::SELECT_FOLDER))); + +IN_PROC_BROWSER_TEST_P(SelectFileDialogHeadlessBrowserTest, SelectFileDialog) { + base::ScopedAllowBlockingForTesting allow_blocking; + ASSERT_TRUE(embedded_test_server()->Start()); + + HeadlessBrowserContext* browser_context = + browser()->CreateBrowserContextBuilder().Build(); + + HeadlessWebContents* web_contents = + browser_context->CreateWebContentsBuilder() + .SetInitialURL(embedded_test_server()->GetURL("/hello.html")) + .Build(); + ASSERT_TRUE(WaitForLoad(web_contents)); + + // Select file dialog will not be shown if the owning frame does not + // have user activation, see VerifyIsAllowedToShowFilePicker in + // third_party/blink/renderer/.../global_file_system_access.cc + content::WebContents* content = + HeadlessWebContentsImpl::From(web_contents)->web_contents(); + content::RenderFrameHost* main_frame = content->GetMainFrame(); + main_frame->NotifyUserActivation( + blink::mojom::UserActivationNotificationType::kTest); + + HeadlessSelectFileDialogFactory::SetSelectFileDialogOnceCallbackForTests( + base::BindOnce( + &SelectFileDialogHeadlessBrowserTest::OnSelectFileDialogCallback, + base::Unretained(this))); + + EvaluateScript(web_contents, file_dialog_script()); + WaitForSelectFileDialogCallback(); + + EXPECT_EQ(select_file_dialog_type_, expected_type()); +} + } // namespace headless
diff --git a/headless/test/headless_browser_test.cc b/headless/test/headless_browser_test.cc index 6c0ef2d..0683c01 100644 --- a/headless/test/headless_browser_test.cc +++ b/headless/test/headless_browser_test.cc
@@ -237,7 +237,7 @@ // is issued first is undefined. The following code is waiting on both, in any // order. content::TestNavigationObserver load_observer(content, 1); - content::FrameFocusedObserver focus_observer(content->GetMainFrame()); + content::FrameFocusedObserver focus_observer(content->GetPrimaryMainFrame()); load_observer.Wait(); focus_observer.Wait(); }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 8815a1a8..0fd1674 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -45745,7 +45745,7 @@ builders { name: "ios-simulator reclient staging" swarming_host: "chromium-swarm.appspot.com" - dimensions: "builder:ios-simulator reclient staging" + dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" dimensions: "os:Mac-11|Mac-12" @@ -45823,7 +45823,7 @@ builders { name: "ios-simulator reclient test" swarming_host: "chromium-swarm.appspot.com" - dimensions: "builder:ios-simulator reclient test" + dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" dimensions: "os:Mac-11|Mac-12"
diff --git a/infra/config/lib/args.star b/infra/config/lib/args.star index 2f3bbb42a..a5947a94 100644 --- a/infra/config/lib/args.star +++ b/infra/config/lib/args.star
@@ -96,6 +96,8 @@ return listify(value) return listify(default, value) + fail("unknown merge value: {}".format(merge)) + def get_value_from_kwargs(name, kwargs, merge = None): return get_value(name, kwargs.get(name, DEFAULT), merge = merge)
diff --git a/infra/config/lib/consoles.star b/infra/config/lib/consoles.star index 3eed963..d07a73b 100644 --- a/infra/config/lib/consoles.star +++ b/infra/config/lib/consoles.star
@@ -40,7 +40,7 @@ _CONSOLE_VIEW_ORDERING = nodes.create_unscoped_node_type("console_view_ordering") _OVERVIEW_CONSOLE_ORDERING = nodes.create_unscoped_node_type("overview_console_ordering") -def _console_view_ordering_impl(ctx, *, console_name, ordering): +def _console_view_ordering_impl(_ctx, *, console_name, ordering): key = _CONSOLE_VIEW_ORDERING.add(console_name, props = { "ordering": ordering, }) @@ -49,7 +49,7 @@ _console_view_ordering = lucicfg.rule(impl = _console_view_ordering_impl) -def _overview_console_view_ordering_impl(ctx, *, console_name, top_level_ordering): +def _overview_console_view_ordering_impl(_ctx, *, console_name, top_level_ordering): key = _OVERVIEW_CONSOLE_ORDERING.add(console_name, props = { "top_level_ordering": top_level_ordering, }) @@ -266,7 +266,7 @@ ordering = ordering or {}, ) -def overview_console_view(*, name, top_level_ordering, branch_selector = branches.MAIN, **kwargs): +def overview_console_view(*, name, top_level_ordering, **kwargs): """Create an overview console view. An overview console view is a console view that contains a subset of @@ -285,9 +285,6 @@ name does not appear in the list will be sorted lexicographically by the console name and appear after entries whose console does appear in the list. - branch_selector - A branch selector value controlling whether the - console view definition is executed. See branches.star for - more information. kwargs - Additional keyword arguments to forward on to `luci.console_view`. The header and repo arguments support module-level defaults. @@ -351,7 +348,7 @@ return None return lambda b: b.name -def _sorted_list_view_impl(ctx, *, console_name): +def _sorted_list_view_impl(_ctx, *, console_name): key = _sorted_list_view_graph_key(console_name) graph.add_node(key) graph.add_edge(keys.project(), key)
diff --git a/infra/config/outages/outages.star b/infra/config/outages/outages.star index 1673612..6ada1be 100644 --- a/infra/config/outages/outages.star +++ b/infra/config/outages/outages.star
@@ -33,7 +33,7 @@ for b in c.verifiers.tryjob.builders: if not b.experiment_percentage: continue - project, bucket, builder = b.name.split("/", 2) + project, bucket, _ = b.name.split("/", 2) if project == "chromium" and bucket == "try": b.includable_only = True b.experiment_percentage = 0
diff --git a/infra/config/subprojects/reclient/reclient.star b/infra/config/subprojects/reclient/reclient.star index 6cfae324..36e0168 100644 --- a/infra/config/subprojects/reclient/reclient.star +++ b/infra/config/subprojects/reclient/reclient.star
@@ -222,6 +222,7 @@ ), console_view_category = "ios", os = os.MAC_DEFAULT, + builderless = True, ) fyi_reclient_staging_builder( @@ -242,4 +243,5 @@ ), console_view_category = "ios", os = os.MAC_DEFAULT, + builderless = True, )
diff --git a/media/audio/audio_output_dispatcher_impl.cc b/media/audio/audio_output_dispatcher_impl.cc index 72f824b..dd9279f 100644 --- a/media/audio/audio_output_dispatcher_impl.cc +++ b/media/audio/audio_output_dispatcher_impl.cc
@@ -75,8 +75,7 @@ AudioOutputStream::AudioSourceCallback* callback, AudioOutputProxy* stream_proxy) { DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread()); - DCHECK(proxy_to_physical_map_.find(stream_proxy) == - proxy_to_physical_map_.end()); + DCHECK(!proxy_to_physical_map_.contains(stream_proxy)); if (idle_streams_.empty() && !CreateAndOpenStream()) return false;
diff --git a/media/base/android/android_cdm_factory.cc b/media/base/android/android_cdm_factory.cc index 53f4a29..15084f3 100644 --- a/media/base/android/android_cdm_factory.cc +++ b/media/base/android/android_cdm_factory.cc
@@ -99,7 +99,7 @@ const std::string& error_message) { DVLOG(1) << __func__ << ": creation_id = " << creation_id; - DCHECK(pending_creations_.count(creation_id)); + DCHECK(pending_creations_.contains(creation_id)); CdmCreatedCB cdm_created_cb = std::move(pending_creations_[creation_id].second); pending_creations_.erase(creation_id);
diff --git a/media/base/mime_util_internal.cc b/media/base/mime_util_internal.cc index 0ba71149..1f9a1af 100644 --- a/media/base/mime_util_internal.cc +++ b/media/base/mime_util_internal.cc
@@ -424,8 +424,7 @@ } bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const { - return media_format_map_.find(base::ToLowerASCII(mime_type)) != - media_format_map_.end(); + return media_format_map_.contains(base::ToLowerASCII(mime_type)); } void MimeUtil::SplitCodecs(const std::string& codecs,
diff --git a/media/base/video_frame_metadata.h b/media/base/video_frame_metadata.h index 26dbe8a..3f92d91 100644 --- a/media/base/video_frame_metadata.h +++ b/media/base/video_frame_metadata.h
@@ -57,6 +57,10 @@ // If cropping was applied due to Region Capture to produce this frame, // then this reflects where the frame's contents originate from in the // original uncropped frame. + // + // NOTE: May also be nullopt if region capture is enabled but the capture rect + // is in a different coordinate space. For more info, see + // https://crbug.com/1327560. absl::optional<gfx::Rect> region_capture_rect; // Whenever cropTo() is called, Blink increments the crop_version and records
diff --git a/media/fuchsia/cdm/fuchsia_cdm.cc b/media/fuchsia/cdm/fuchsia_cdm.cc index 4cedfff..51297937 100644 --- a/media/fuchsia/cdm/fuchsia_cdm.cc +++ b/media/fuchsia/cdm/fuchsia_cdm.cc
@@ -407,7 +407,7 @@ } session->set_session_id(session_id); - DCHECK(session_map_.find(session_id) == session_map_.end()) + DCHECK(!session_map_.contains(session_id)) << "Duplicated session id " << session_id; session_map_[session_id] = std::move(session); } @@ -467,7 +467,7 @@ } std::string session_id = session->session_id(); - DCHECK(session_map_.find(session_id) == session_map_.end()) + DCHECK(!session_map_.contains(session_id)) << "Duplicated session id " << session_id; session_map_.emplace(session_id, std::move(session));
diff --git a/media/fuchsia/common/stream_processor_helper.cc b/media/fuchsia/common/stream_processor_helper.cc index b4f71511..95449cd1 100644 --- a/media/fuchsia/common/stream_processor_helper.cc +++ b/media/fuchsia/common/stream_processor_helper.cc
@@ -104,7 +104,7 @@ fidl::Clone(input.format())); } - DCHECK(input_packets_.find(input.buffer_index()) == input_packets_.end()); + DCHECK(!input_packets_.contains(input.buffer_index())); input_packets_.insert_or_assign(input.buffer_index(), std::move(input)); processor_->QueueInputPacket(std::move(packet)); }
diff --git a/media/gpu/mac/vt_video_decode_accelerator_mac.cc b/media/gpu/mac/vt_video_decode_accelerator_mac.cc index 45395a6..9b6818c 100644 --- a/media/gpu/mac/vt_video_decode_accelerator_mac.cc +++ b/media/gpu/mac/vt_video_decode_accelerator_mac.cc
@@ -1086,8 +1086,8 @@ } // Record the configuration. - DCHECK(seen_pps_.count(slice_hdr.pic_parameter_set_id)); - DCHECK(seen_sps_.count(pps->seq_parameter_set_id)); + DCHECK(seen_pps_.contains(slice_hdr.pic_parameter_set_id)); + DCHECK(seen_sps_.contains(pps->seq_parameter_set_id)); active_sps_ = seen_sps_[pps->seq_parameter_set_id]; // Note: SPS extension lookup may create an empty entry. active_spsext_ = seen_spsext_[pps->seq_parameter_set_id]; @@ -1481,9 +1481,9 @@ } // Record the configuration. - DCHECK(seen_pps_.count(curr_slice_hdr->slice_pic_parameter_set_id)); - DCHECK(seen_sps_.count(pps->pps_seq_parameter_set_id)); - DCHECK(seen_vps_.count(sps->sps_video_parameter_set_id)); + DCHECK(seen_pps_.contains(curr_slice_hdr->slice_pic_parameter_set_id)); + DCHECK(seen_sps_.contains(pps->pps_seq_parameter_set_id)); + DCHECK(seen_vps_.contains(sps->sps_video_parameter_set_id)); active_vps_ = seen_vps_[sps->sps_video_parameter_set_id]; active_sps_ = seen_sps_[pps->pps_seq_parameter_set_id]; active_pps_ = seen_pps_[curr_slice_hdr->slice_pic_parameter_set_id]; @@ -1696,7 +1696,7 @@ // pending_frames_.erase() will delete |frame|. int32_t bitstream_id = frame->bitstream_id; - DCHECK_EQ(1u, pending_frames_.count(bitstream_id)); + DCHECK(pending_frames_.contains(bitstream_id)); if (state_ == STATE_ERROR || state_ == STATE_DESTROYING) { // Destroy() handles NotifyEndOfBitstreamBuffer(). @@ -1809,7 +1809,7 @@ for (const PictureBuffer& picture : pictures) { DVLOG(3) << "AssignPictureBuffer(" << picture.id() << ")"; - DCHECK(!picture_info_map_.count(picture.id())); + DCHECK(!picture_info_map_.contains(picture.id())); assigned_picture_ids_.insert(picture.id()); available_picture_ids_.push_back(picture.id()); if (picture.client_texture_ids().empty() &&
diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn index 6a635eff..1223202 100644 --- a/media/gpu/v4l2/BUILD.gn +++ b/media/gpu/v4l2/BUILD.gn
@@ -161,6 +161,8 @@ "test/av1_decoder.cc", "test/av1_decoder.h", "test/av1_pix_fmt.h", + "test/h264_decoder.cc", + "test/h264_decoder.h", "test/v4l2_ioctl_shim.cc", "test/v4l2_ioctl_shim.h", "test/v4l2_stateless_decoder.cc",
diff --git a/media/gpu/v4l2/test/h264_decoder.cc b/media/gpu/v4l2/test/h264_decoder.cc new file mode 100644 index 0000000..ebe3bbf --- /dev/null +++ b/media/gpu/v4l2/test/h264_decoder.cc
@@ -0,0 +1,73 @@ +// Copyright 2022 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 "media/gpu/v4l2/test/h264_decoder.h" + +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "media/video/h264_parser.h" + +namespace media { + +namespace v4l2_test { + +constexpr uint32_t kNumberOfBuffersInCaptureQueue = 10; + +static_assert(kNumberOfBuffersInCaptureQueue <= 16, + "Too many CAPTURE buffers are used. The number of CAPTURE " + "buffers is currently assumed to be no larger than 16."); + +// static +std::unique_ptr<H264Decoder> H264Decoder::Create( + const base::MemoryMappedFile& stream) { + H264Parser parser; + parser.SetStream(stream.data(), stream.length()); + + // Advance through NALUs until the first SPS. The start of the decodable + // data in an h.264 bistreams starts with an SPS. + while (true) { + H264NALU nalu; + H264Parser::Result res = parser.AdvanceToNextNALU(&nalu); + if (res != H264Parser::kOk) { + LOG(ERROR) << "Unable to find SPS in stream"; + return nullptr; + } + + if (nalu.nal_unit_type == H264NALU::kSPS) + break; + } + + int id; + H264Parser::Result res = parser.ParseSPS(&id); + CHECK(res == H264Parser::kOk); + + const H264SPS* sps = parser.GetSPS(id); + CHECK(sps); + + absl::optional<gfx::Size> coded_size = sps->GetCodedSize(); + CHECK(coded_size); + LOG(INFO) << "h.264 coded size : " << coded_size->ToString(); + + return nullptr; +} + +H264Decoder::H264Decoder(std::unique_ptr<V4L2IoctlShim> v4l2_ioctl, + std::unique_ptr<V4L2Queue> OUTPUT_queue, + std::unique_ptr<V4L2Queue> CAPTURE_queue) + : VideoDecoder::VideoDecoder(std::move(v4l2_ioctl), + std::move(OUTPUT_queue), + std::move(CAPTURE_queue)) {} + +H264Decoder::~H264Decoder() = default; + +VideoDecoder::Result H264Decoder::DecodeNextFrame(std::vector<char>& y_plane, + std::vector<char>& u_plane, + std::vector<char>& v_plane, + gfx::Size& size, + const int frame_number) { + return VideoDecoder::kError; +} + +} // namespace v4l2_test +} // namespace media
diff --git a/media/gpu/v4l2/test/h264_decoder.h b/media/gpu/v4l2/test/h264_decoder.h new file mode 100644 index 0000000..874016ad --- /dev/null +++ b/media/gpu/v4l2/test/h264_decoder.h
@@ -0,0 +1,43 @@ +// Copyright 2022 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 MEDIA_GPU_V4L2_TEST_H264_DECODER_H_ +#define MEDIA_GPU_V4L2_TEST_H264_DECODER_H_ + +#include "media/gpu/v4l2/test/video_decoder.h" + +#include "base/files/memory_mapped_file.h" +#include "media/gpu/v4l2/test/v4l2_ioctl_shim.h" + +namespace media { +namespace v4l2_test { +class H264Decoder : public VideoDecoder { + public: + H264Decoder(const H264Decoder&) = delete; + H264Decoder& operator=(const H264Decoder&) = delete; + ~H264Decoder() override; + + // Creates a H264Decoder after verifying that the bitstream is h.264 + // and the underlying implementation supports H.264 slice decoding. + static std::unique_ptr<H264Decoder> Create( + const base::MemoryMappedFile& stream); + + // Parses next frame from IVF stream and decodes the frame. This method will + // place the Y, U, and V values into the respective vectors and update the + // size with the display area size of the decoded frame. + VideoDecoder::Result DecodeNextFrame(std::vector<char>& y_plane, + std::vector<char>& u_plane, + std::vector<char>& v_plane, + gfx::Size& size, + const int frame_number) override; + + private: + H264Decoder(std::unique_ptr<V4L2IoctlShim> v4l2_ioctl, + std::unique_ptr<V4L2Queue> OUTPUT_queue, + std::unique_ptr<V4L2Queue> CAPTURE_queue); +}; + +} // namespace v4l2_test +} // namespace media + +#endif // MEDIA_GPU_V4L2_TEST_H264_DECODER_H_
diff --git a/media/gpu/v4l2/test/v4l2_stateless_decoder.cc b/media/gpu/v4l2/test/v4l2_stateless_decoder.cc index 6ed2821..2b444e5 100644 --- a/media/gpu/v4l2/test/v4l2_stateless_decoder.cc +++ b/media/gpu/v4l2/test/v4l2_stateless_decoder.cc
@@ -14,10 +14,12 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "media/gpu/v4l2/test/av1_decoder.h" +#include "media/gpu/v4l2/test/h264_decoder.h" #include "media/gpu/v4l2/test/video_decoder.h" #include "media/gpu/v4l2/test/vp9_decoder.h" using media::v4l2_test::Av1Decoder; +using media::v4l2_test::H264Decoder; using media::v4l2_test::VideoDecoder; using media::v4l2_test::Vp9Decoder; @@ -79,6 +81,9 @@ if (!decoder) decoder = Vp9Decoder::Create(stream); + if (!decoder) + decoder = H264Decoder::Create(stream); + return decoder; } @@ -102,26 +107,33 @@ cmd->GetSwitchValueASCII("output_path_prefix"); const base::FilePath video_path = cmd->GetSwitchValuePath("video"); - if (video_path.empty()) - LOG(FATAL) << "No input video path provided to decode.\n" << kUsageMsg; + if (video_path.empty()) { + LOG(ERROR) << "No input video path provided to decode.\n" << kUsageMsg; + return EXIT_FAILURE; + } const std::string frames = cmd->GetSwitchValueASCII("frames"); int n_frames; if (frames.empty()) { n_frames = 0; } else if (!base::StringToInt(frames, &n_frames) || n_frames <= 0) { - LOG(FATAL) << "Number of frames to decode must be positive integer, got " + LOG(ERROR) << "Number of frames to decode must be positive integer, got " << frames; + return EXIT_FAILURE; } // Set up video stream. base::MemoryMappedFile stream; - if (!stream.Initialize(video_path)) - LOG(FATAL) << "Couldn't open file: " << video_path; + if (!stream.Initialize(video_path)) { + LOG(ERROR) << "Couldn't open file: " << video_path; + return EXIT_FAILURE; + } const std::unique_ptr<VideoDecoder> dec = CreateVideoDecoder(stream); - if (!dec) - LOG(FATAL) << "Failed to create decoder for file: " << video_path; + if (!dec) { + LOG(ERROR) << "Failed to create decoder for file: " << video_path; + return EXIT_FAILURE; + } dec->Initialize(); @@ -137,6 +149,9 @@ if (res == VideoDecoder::kEOStream) { LOG(INFO) << "End of stream."; break; + } else if (res == VideoDecoder::kError) { + LOG(ERROR) << "Unable to decode next frame."; + break; } if (cmd->HasSwitch("visible") && !dec->LastDecodedFrameVisible())
diff --git a/media/gpu/windows/dxva_video_decode_accelerator_win.cc b/media/gpu/windows/dxva_video_decode_accelerator_win.cc index 622686b1..88c4996 100644 --- a/media/gpu/windows/dxva_video_decode_accelerator_win.cc +++ b/media/gpu/windows/dxva_video_decode_accelerator_win.cc
@@ -1554,11 +1554,11 @@ RETURN_ON_HR_FAILURE(hr, "Failed to pass D3D manager to decoder", false); } - if (!gl::GLSurfaceEGL::GetGLDisplayEGL()->IsPixelFormatFloatSupported()) + gl::GLDisplayEGL* display = gl::GLSurfaceEGL::GetGLDisplayEGL(); + if (!display->ext->b_EGL_EXT_pixel_format_float) use_fp16_ = false; - EGLDisplay egl_display = - gl::GLSurfaceEGL::GetGLDisplayEGL()->GetHardwareDisplay(); + EGLDisplay egl_display = display->GetHardwareDisplay(); while (true) { std::vector<EGLint> config_attribs = {EGL_BUFFER_SIZE, 32,
diff --git a/media/learning/impl/random_tree_trainer.cc b/media/learning/impl/random_tree_trainer.cc index 041cd88..c2749d6 100644 --- a/media/learning/impl/random_tree_trainer.cc +++ b/media/learning/impl/random_tree_trainer.cc
@@ -78,7 +78,7 @@ // Add |child| has the node for feature value |v|. void AddChild(FeatureValue v, std::unique_ptr<Model> child) { - DCHECK_EQ(children_.count(v), 0u); + DCHECK(!children_.contains(v)); children_.emplace(v, std::move(child)); }
diff --git a/media/renderers/win/media_foundation_texture_pool.cc b/media/renderers/win/media_foundation_texture_pool.cc index 0c3ad4dd..6b1838a4 100644 --- a/media/renderers/win/media_foundation_texture_pool.cc +++ b/media/renderers/win/media_foundation_texture_pool.cc
@@ -122,8 +122,9 @@ void MediaFoundationTexturePool::ReleaseTexture( const base::UnguessableToken& texture_token) { - if (texture_pool_.count(texture_token) > 0) { - texture_pool_.at(texture_token).texture_in_use_ = false; + auto it = texture_pool_.find(texture_token); + if (it != texture_pool_.end()) { + it->second.texture_in_use_ = false; } }
diff --git a/net/base/features.cc b/net/base/features.cc index a732dca..d9127ee 100644 --- a/net/base/features.cc +++ b/net/base/features.cc
@@ -212,6 +212,11 @@ const base::FeatureParam<int> kCertDualVerificationTrialCacheSize{ &kCertDualVerificationTrialFeature, "cachesize", 0}; #endif /* BUILDFLAG(IS_MAC) */ +#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED) && \ + BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) +const base::FeatureParam<bool> kCertDualVerificationTrialUseCrs{ + &kCertDualVerificationTrialFeature, "use_crs", false}; +#endif #endif #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
diff --git a/net/base/features.h b/net/base/features.h index 0bb96470..e053127c 100644 --- a/net/base/features.h +++ b/net/base/features.h
@@ -314,6 +314,14 @@ NET_EXPORT extern const base::FeatureParam<int> kCertDualVerificationTrialCacheSize; #endif /* BUILDFLAG(IS_MAC) */ +#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED) && \ + BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) +// If both builtin verifier+system roots and builtin verifier+CRS flags are +// supported in the same build, this param can be used to choose which to test +// in the trial. +NET_EXPORT extern const base::FeatureParam<bool> + kCertDualVerificationTrialUseCrs; +#endif #endif /* BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED) */ #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc index 19608b6..6b52912 100644 --- a/net/cert/cert_verify_proc_unittest.cc +++ b/net/cert/cert_verify_proc_unittest.cc
@@ -229,7 +229,8 @@ #elif BUILDFLAG(IS_IOS) CERT_VERIFY_PROC_IOS #elif BUILDFLAG(IS_MAC) - CERT_VERIFY_PROC_MAC, CERT_VERIFY_PROC_BUILTIN + CERT_VERIFY_PROC_MAC, CERT_VERIFY_PROC_BUILTIN, + CERT_VERIFY_PROC_BUILTIN_CHROME_ROOTS #elif BUILDFLAG(IS_WIN) CERT_VERIFY_PROC_WIN, CERT_VERIFY_PROC_BUILTIN_CHROME_ROOTS #elif BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) @@ -1621,7 +1622,7 @@ << "against mattm."; EXPECT_TRUE(verify_result.is_issued_by_known_root); #if BUILDFLAG(IS_MAC) - if (VerifyProcTypeIsBuiltin()) { + if (verify_proc_type() == CERT_VERIFY_PROC_BUILTIN) { auto* mac_trust_debug_info = net::TrustStoreMac::ResultDebugData::Get(&verify_result); ASSERT_TRUE(mac_trust_debug_info);
diff --git a/net/cert/internal/system_trust_store.cc b/net/cert/internal/system_trust_store.cc index c5ba97f..a665c3b 100644 --- a/net/cert/internal/system_trust_store.cc +++ b/net/cert/internal/system_trust_store.cc
@@ -4,6 +4,7 @@ #include "net/cert/internal/system_trust_store.h" +#include "base/memory/ptr_util.h" #include "build/build_config.h" #include "crypto/crypto_buildflags.h" @@ -78,15 +79,18 @@ } // namespace #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) -class SystemTrustStoreChrome : public SystemTrustStore { +class SystemTrustStoreChromeWithUnOwnedSystemStore : public SystemTrustStore { public: - explicit SystemTrustStoreChrome( + // Creates a SystemTrustStore that gets publicly trusted roots from + // |trust_store_chrome| and local trust settings from |trust_store_system|. + // Does not take ownership of |trust_store_system|, which must outlive this + // object. + explicit SystemTrustStoreChromeWithUnOwnedSystemStore( std::unique_ptr<TrustStoreChrome> trust_store_chrome, - std::unique_ptr<TrustStore> trust_store_system) - : trust_store_chrome_(std::move(trust_store_chrome)), - trust_store_system_(std::move(trust_store_system)) { + TrustStore* trust_store_system) + : trust_store_chrome_(std::move(trust_store_chrome)) { trust_store_collection_.AddTrustStore(trust_store_chrome_.get()); - trust_store_collection_.AddTrustStore(trust_store_system_.get()); + trust_store_collection_.AddTrustStore(trust_store_system); } TrustStore* GetTrustStore() override { return &trust_store_collection_; } @@ -105,17 +109,32 @@ private: std::unique_ptr<TrustStoreChrome> trust_store_chrome_; - std::unique_ptr<TrustStore> trust_store_system_; TrustStoreCollection trust_store_collection_; }; +class SystemTrustStoreChrome + : public SystemTrustStoreChromeWithUnOwnedSystemStore { + public: + // Creates a SystemTrustStore that gets publicly trusted roots from + // |trust_store_chrome| and local trust settings from |trust_store_system|. + explicit SystemTrustStoreChrome( + std::unique_ptr<TrustStoreChrome> trust_store_chrome, + std::unique_ptr<TrustStore> trust_store_system) + : SystemTrustStoreChromeWithUnOwnedSystemStore( + std::move(trust_store_chrome), + trust_store_system.get()), + trust_store_system_(std::move(trust_store_system)) {} + + private: + std::unique_ptr<TrustStore> trust_store_system_; +}; + std::unique_ptr<SystemTrustStore> CreateSystemTrustStoreChromeForTesting( std::unique_ptr<TrustStoreChrome> trust_store_chrome, std::unique_ptr<TrustStore> trust_store_system) { return std::make_unique<SystemTrustStoreChrome>( std::move(trust_store_chrome), std::move(trust_store_system)); } - #endif // CHROME_ROOT_STORE_SUPPORTED #if BUILDFLAG(USE_NSS_CERTS) @@ -193,6 +212,61 @@ #elif BUILDFLAG(IS_MAC) +namespace { + +TrustStoreMac::TrustImplType ParamToTrustImplType( + int param, + TrustStoreMac::TrustImplType default_impl) { + switch (param) { + case 1: + return TrustStoreMac::TrustImplType::kDomainCache; + case 2: + return TrustStoreMac::TrustImplType::kSimple; + case 3: + return TrustStoreMac::TrustImplType::kLruCache; + default: + return default_impl; + } +} + +TrustStoreMac::TrustImplType GetTrustStoreImplParam( + TrustStoreMac::TrustImplType default_impl) { + // TODO(https://crbug.com/1327433): A limitation of this approach is that if + // the primary verifier is being set to use the builtin verifier via a + // feature flag, it isn't possible to run dual verifier trial comparing that + // to the builtin verifier with different flags, since this method can't tell + // which flags to use for which verifier. + // If handling that becomes necessary, the flags should be checked in the + // higher level code (maybe in cert_verifier_creation.cc) so that each + // type of CertVerifyProc could be created with the appropriate flags. + if (base::FeatureList::IsEnabled(features::kCertVerifierBuiltinFeature)) { + return ParamToTrustImplType(features::kCertVerifierBuiltinImpl.Get(), + default_impl); + } + if (base::FeatureList::IsEnabled( + features::kCertDualVerificationTrialFeature)) { + return ParamToTrustImplType(features::kCertDualVerificationTrialImpl.Get(), + default_impl); + } + return default_impl; +} + +size_t GetTrustStoreCacheSize() { + if (base::FeatureList::IsEnabled(features::kCertVerifierBuiltinFeature) && + features::kCertVerifierBuiltinCacheSize.Get() > 0) { + return features::kCertVerifierBuiltinCacheSize.Get(); + } + if (base::FeatureList::IsEnabled( + features::kCertDualVerificationTrialFeature) && + features::kCertDualVerificationTrialCacheSize.Get() > 0) { + return features::kCertDualVerificationTrialCacheSize.Get(); + } + constexpr size_t kDefaultCacheSize = 512; + return kDefaultCacheSize; +} + +} // namespace + class SystemTrustStoreMac : public SystemTrustStore { public: SystemTrustStoreMac() = default; @@ -211,50 +285,18 @@ GetGlobalTrustStoreMac()->InitializeTrustCache(); } +#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) + int64_t chrome_root_store_version() override { return 0; } +#endif + private: static constexpr TrustStoreMac::TrustImplType kDefaultTrustImpl = TrustStoreMac::TrustImplType::kLruCache; - static TrustStoreMac::TrustImplType ParamToTrustImplType(int param) { - switch (param) { - case 1: - return TrustStoreMac::TrustImplType::kDomainCache; - case 2: - return TrustStoreMac::TrustImplType::kSimple; - case 3: - return TrustStoreMac::TrustImplType::kLruCache; - default: - return kDefaultTrustImpl; - } - } - - static TrustStoreMac::TrustImplType GetTrustStoreImplParam() { - if (base::FeatureList::IsEnabled(features::kCertVerifierBuiltinFeature)) - return ParamToTrustImplType(features::kCertVerifierBuiltinImpl.Get()); - if (base::FeatureList::IsEnabled( - features::kCertDualVerificationTrialFeature)) - return ParamToTrustImplType( - features::kCertDualVerificationTrialImpl.Get()); - return kDefaultTrustImpl; - } - - static size_t GetTrustStoreCacheSize() { - if (base::FeatureList::IsEnabled(features::kCertVerifierBuiltinFeature) && - features::kCertVerifierBuiltinCacheSize.Get() > 0) { - return features::kCertVerifierBuiltinCacheSize.Get(); - } - if (base::FeatureList::IsEnabled( - features::kCertDualVerificationTrialFeature) && - features::kCertDualVerificationTrialCacheSize.Get() > 0) { - return features::kCertDualVerificationTrialCacheSize.Get(); - } - constexpr size_t kDefaultCacheSize = 512; - return kDefaultCacheSize; - } - static TrustStoreMac* GetGlobalTrustStoreMac() { static base::NoDestructor<TrustStoreMac> static_trust_store_mac( - kSecPolicyAppleSSL, GetTrustStoreImplParam(), GetTrustStoreCacheSize()); + kSecPolicyAppleSSL, GetTrustStoreImplParam(kDefaultTrustImpl), + GetTrustStoreCacheSize(), TrustStoreMac::TrustDomains::kAll); return static_trust_store_mac.get(); } }; @@ -263,11 +305,45 @@ return std::make_unique<SystemTrustStoreMac>(); } +#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) +namespace { + +TrustStoreMac* GetGlobalTrustStoreMacForCRS() { + constexpr TrustStoreMac::TrustImplType kDefaultMacTrustImplForCRS = + TrustStoreMac::TrustImplType::kDomainCache; + static base::NoDestructor<TrustStoreMac> static_trust_store_mac( + kSecPolicyAppleSSL, GetTrustStoreImplParam(kDefaultMacTrustImplForCRS), + GetTrustStoreCacheSize(), TrustStoreMac::TrustDomains::kUserAndAdmin); + return static_trust_store_mac.get(); +} + +void InitializeTrustCacheForCRSOnWorkerThread() { + GetGlobalTrustStoreMacForCRS()->InitializeTrustCache(); +} + +} // namespace + +std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot( + std::unique_ptr<TrustStoreChrome> chrome_root) { + return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>( + std::move(chrome_root), GetGlobalTrustStoreMacForCRS()); +} +#endif // CHROME_ROOT_STORE_SUPPORTED + void InitializeTrustStoreMacCache() { - base::ThreadPool::PostTask( - FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::BindOnce(&SystemTrustStoreMac::InitializeTrustCacheOnWorkerThread)); + if (base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed)) { + base::ThreadPool::PostTask( + FROM_HERE, + {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::BindOnce(&InitializeTrustCacheForCRSOnWorkerThread)); + } else if (base::FeatureList::IsEnabled( + net::features::kCertVerifierBuiltinFeature)) { + base::ThreadPool::PostTask( + FROM_HERE, + {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::BindOnce( + &SystemTrustStoreMac::InitializeTrustCacheOnWorkerThread)); + } } #elif BUILDFLAG(IS_FUCHSIA)
diff --git a/net/cert/internal/system_trust_store.h b/net/cert/internal/system_trust_store.h index 9cbf4da..cc1cd6be 100644 --- a/net/cert/internal/system_trust_store.h +++ b/net/cert/internal/system_trust_store.h
@@ -99,7 +99,8 @@ NET_EXPORT std::unique_ptr<SystemTrustStore> CreateEmptySystemTrustStore(); #if BUILDFLAG(IS_MAC) -// Initializes trust cache on a worker thread. +// Initializes trust cache on a worker thread, if the builtin verifier is +// enabled. NET_EXPORT void InitializeTrustStoreMacCache(); #endif
diff --git a/net/cert/internal/trust_store_mac.cc b/net/cert/internal/trust_store_mac.cc index fed6c8e..5a179e71 100644 --- a/net/cert/internal/trust_store_mac.cc +++ b/net/cert/internal/trust_store_mac.cc
@@ -288,6 +288,7 @@ TrustStatus IsCertificateTrustedForPolicy(const ParsedCertificate* cert, const CFStringRef policy_oid, + TrustStoreMac::TrustDomains domains, int* debug_info, KnownRootStatus* out_is_known_root) { // |*out_is_known_root| is intentionally not cleared before starting, as @@ -309,6 +310,10 @@ for (const auto& trust_domain : {kSecTrustSettingsDomainUser, kSecTrustSettingsDomainAdmin, kSecTrustSettingsDomainSystem}) { + if (domains == TrustStoreMac::TrustDomains::kUserAndAdmin && + trust_domain == kSecTrustSettingsDomainSystem) { + continue; + } base::ScopedCFTypeRef<CFArrayRef> trust_settings; OSStatus err; { @@ -596,10 +601,14 @@ // modified. class TrustStoreMac::TrustImplDomainCache : public TrustStoreMac::TrustImpl { public: - explicit TrustImplDomainCache(CFStringRef policy_oid) - : system_domain_cache_(kSecTrustSettingsDomainSystem, policy_oid), + explicit TrustImplDomainCache(CFStringRef policy_oid, TrustDomains domains) + : use_system_domain_cache_(domains == TrustDomains::kAll), admin_domain_cache_(kSecTrustSettingsDomainAdmin, policy_oid), user_domain_cache_(kSecTrustSettingsDomainUser, policy_oid) { + if (use_system_domain_cache_) { + system_domain_cache_ = std::make_unique<TrustDomainCache>( + kSecTrustSettingsDomainSystem, policy_oid); + } keychain_observer_ = std::make_unique<KeychainTrustObserver>(); } @@ -613,11 +622,13 @@ // Returns true if |cert| is present in kSecTrustSettingsDomainSystem. bool IsKnownRoot(const ParsedCertificate* cert) override { + if (!use_system_domain_cache_) + return false; SHA256HashValue cert_hash = CalculateFingerprint256(cert->der_cert()); base::AutoLock lock(cache_lock_); MaybeInitializeCache(); - return system_domain_cache_.ContainsCert(cert_hash); + return system_domain_cache_->ContainsCert(cert_hash); } // Returns the trust status for |cert|. @@ -632,12 +643,15 @@ // override system ones, and user settings can override both admin and // system. for (TrustDomainCache* trust_domain_cache : - {&user_domain_cache_, &admin_domain_cache_, &system_domain_cache_}) { + {&user_domain_cache_, &admin_domain_cache_}) { TrustStatus ts = trust_domain_cache->IsCertTrusted(cert, cert_hash, debug_data); if (ts != TrustStatus::UNSPECIFIED) return ts; } + if (use_system_domain_cache_) { + return system_domain_cache_->IsCertTrusted(cert, cert_hash, debug_data); + } // Cert did not have trust settings in any domain. return TrustStatus::UNSPECIFIED; @@ -661,22 +675,26 @@ iteration_ = keychain_iteration; user_domain_cache_.Initialize(); admin_domain_cache_.Initialize(); - if (!system_domain_initialized_) { + if (use_system_domain_cache_ && !system_domain_initialized_) { // In practice, the system trust domain does not change during runtime, // and SecTrustSettingsCopyCertificates on the system domain is quite // slow, so the system domain cache is not reset on keychain changes. - system_domain_cache_.Initialize(); + system_domain_cache_->Initialize(); system_domain_initialized_ = true; } } std::unique_ptr<KeychainTrustObserver> keychain_observer_; + // Store whether to use the system domain in a const bool that is initialized + // in constructor so it is safe to read without having to lock first. + const bool use_system_domain_cache_; base::Lock cache_lock_; // |cache_lock_| must be held while accessing any following members. int64_t iteration_ GUARDED_BY(cache_lock_) = -1; bool system_domain_initialized_ GUARDED_BY(cache_lock_) = false; - TrustDomainCache system_domain_cache_ GUARDED_BY(cache_lock_); + std::unique_ptr<TrustDomainCache> system_domain_cache_ + GUARDED_BY(cache_lock_); TrustDomainCache admin_domain_cache_ GUARDED_BY(cache_lock_); TrustDomainCache user_domain_cache_ GUARDED_BY(cache_lock_); }; @@ -685,7 +703,8 @@ // SecTrustSettingsCopyTrustSettings on every cert checked, with no caching. class TrustStoreMac::TrustImplNoCache : public TrustStoreMac::TrustImpl { public: - explicit TrustImplNoCache(CFStringRef policy_oid) : policy_oid_(policy_oid) {} + explicit TrustImplNoCache(CFStringRef policy_oid, TrustDomains domains) + : policy_oid_(policy_oid), domains_(domains) {} TrustImplNoCache(const TrustImplNoCache&) = delete; TrustImplNoCache& operator=(const TrustImplNoCache&) = delete; @@ -694,6 +713,8 @@ // Returns true if |cert| is present in kSecTrustSettingsDomainSystem. bool IsKnownRoot(const ParsedCertificate* cert) override { + if (domains_ == TrustDomains::kUserAndAdmin) + return false; HashValue cert_hash(CalculateFingerprint256(cert->der_cert())); base::AutoLock lock(crypto::GetMacSecurityServicesLock()); return net::IsKnownRoot(cert_hash); @@ -703,8 +724,9 @@ TrustStatus IsCertTrusted(const ParsedCertificate* cert, base::SupportsUserData* debug_data) override { int debug_info = 0; - TrustStatus result = IsCertificateTrustedForPolicy( - cert, policy_oid_, &debug_info, /*out_is_known_root=*/nullptr); + TrustStatus result = + IsCertificateTrustedForPolicy(cert, policy_oid_, domains_, &debug_info, + /*out_is_known_root=*/nullptr); UpdateUserData(debug_info, debug_data, TrustStoreMac::TrustImplType::kSimple); return result; @@ -716,6 +738,7 @@ private: const CFStringRef policy_oid_; + const TrustDomains domains_; }; // TrustImplLRUCache is calls SecTrustSettingsCopyTrustSettings on every cert @@ -723,8 +746,12 @@ // keychain updates. class TrustStoreMac::TrustImplLRUCache : public TrustStoreMac::TrustImpl { public: - TrustImplLRUCache(CFStringRef policy_oid, size_t cache_size) - : policy_oid_(policy_oid), trust_status_cache_(cache_size) { + TrustImplLRUCache(CFStringRef policy_oid, + size_t cache_size, + TrustDomains domains) + : policy_oid_(policy_oid), + domains_(domains), + trust_status_cache_(cache_size) { keychain_observer_ = std::make_unique<KeychainTrustObserver>(); } @@ -738,6 +765,8 @@ // Returns true if |cert| has trust settings in kSecTrustSettingsDomainSystem. bool IsKnownRoot(const ParsedCertificate* cert) override { + if (domains_ == TrustDomains::kUserAndAdmin) + return false; return GetKnownRootStatus(cert) == KnownRootStatus::IS_KNOWN_ROOT; } @@ -818,7 +847,7 @@ } trust_details.trust_status = IsCertificateTrustedForPolicy( - cert, policy_oid_, &trust_details.debug_info, + cert, policy_oid_, domains_, &trust_details.debug_info, &trust_details.is_known_root); { @@ -841,6 +870,7 @@ } const CFStringRef policy_oid_; + const TrustDomains domains_; std::unique_ptr<KeychainTrustObserver> keychain_observer_; base::Lock cache_lock_; @@ -858,20 +888,23 @@ TrustStoreMac::TrustStoreMac(CFStringRef policy_oid, TrustImplType impl, - size_t cache_size) { + size_t cache_size, + TrustDomains domains) + : domains_(domains) { switch (impl) { case TrustImplType::kUnknown: DCHECK(false); break; case TrustImplType::kDomainCache: - trust_cache_ = std::make_unique<TrustImplDomainCache>(policy_oid); + trust_cache_ = + std::make_unique<TrustImplDomainCache>(policy_oid, domains); break; case TrustImplType::kSimple: - trust_cache_ = std::make_unique<TrustImplNoCache>(policy_oid); + trust_cache_ = std::make_unique<TrustImplNoCache>(policy_oid, domains); break; case TrustImplType::kLruCache: trust_cache_ = - std::make_unique<TrustImplLRUCache>(policy_oid, cache_size); + std::make_unique<TrustImplLRUCache>(policy_oid, cache_size, domains); break; } } @@ -893,7 +926,7 @@ return; std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> matching_cert_buffers = - FindMatchingCertificatesForMacNormalizedSubject(name_data); + FindMatchingCertificatesForMacNormalizedSubject(name_data, domains_); // Convert to ParsedCertificate. for (auto& buffer : matching_cert_buffers) { @@ -937,7 +970,8 @@ // static std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( - CFDataRef name_data) { + CFDataRef name_data, + TrustDomains domains) { std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> matching_cert_buffers; base::ScopedCFTypeRef<CFMutableDictionaryRef> query( CFDictionaryCreateMutable(nullptr, 0, &kCFTypeDictionaryKeyCallBacks, @@ -961,43 +995,48 @@ } } - // If a TestKeychainSearchList is present, it will have already set - // |scoped_alternate_keychain_search_list|, which will be used as the - // basis for reordering the keychain. Otherwise, get the current keychain - // search list and use that. - if (!scoped_alternate_keychain_search_list) { - OSStatus status = SecKeychainCopySearchList( - scoped_alternate_keychain_search_list.InitializeInto()); - if (status) { - OSSTATUS_LOG(ERROR, status) << "SecKeychainCopySearchList error"; + if (domains == TrustDomains::kAll) { + // If a TestKeychainSearchList is present, it will have already set + // |scoped_alternate_keychain_search_list|, which will be used as the + // basis for reordering the keychain. Otherwise, get the current keychain + // search list and use that. + if (!scoped_alternate_keychain_search_list) { + OSStatus status = SecKeychainCopySearchList( + scoped_alternate_keychain_search_list.InitializeInto()); + if (status) { + OSSTATUS_LOG(ERROR, status) << "SecKeychainCopySearchList error"; + return matching_cert_buffers; + } + } + + CFMutableArrayRef mutable_keychain_search_list = CFArrayCreateMutableCopy( + kCFAllocatorDefault, + CFArrayGetCount(scoped_alternate_keychain_search_list.get()) + 1, + scoped_alternate_keychain_search_list.get()); + if (!mutable_keychain_search_list) { + LOG(ERROR) << "CFArrayCreateMutableCopy"; return matching_cert_buffers; } + scoped_alternate_keychain_search_list.reset(mutable_keychain_search_list); + + base::ScopedCFTypeRef<SecKeychainRef> roots_keychain; + // The System Roots keychain is not normally searched by + // SecItemCopyMatching. Get a reference to it and include in the keychain + // search list. + OSStatus status = SecKeychainOpen( + "/System/Library/Keychains/SystemRootCertificates.keychain", + roots_keychain.InitializeInto()); + if (status) { + OSSTATUS_LOG(ERROR, status) << "SecKeychainOpen error"; + return matching_cert_buffers; + } + CFArrayAppendValue(mutable_keychain_search_list, roots_keychain); } - CFMutableArrayRef mutable_keychain_search_list = CFArrayCreateMutableCopy( - kCFAllocatorDefault, - CFArrayGetCount(scoped_alternate_keychain_search_list.get()) + 1, - scoped_alternate_keychain_search_list.get()); - if (!mutable_keychain_search_list) { - LOG(ERROR) << "CFArrayCreateMutableCopy"; - return matching_cert_buffers; + if (scoped_alternate_keychain_search_list) { + CFDictionarySetValue(query, kSecMatchSearchList, + scoped_alternate_keychain_search_list.get()); } - scoped_alternate_keychain_search_list.reset(mutable_keychain_search_list); - - base::ScopedCFTypeRef<SecKeychainRef> roots_keychain; - // The System Roots keychain is not normally searched by SecItemCopyMatching. - // Get a reference to it and include in the keychain search list. - OSStatus status = SecKeychainOpen( - "/System/Library/Keychains/SystemRootCertificates.keychain", - roots_keychain.InitializeInto()); - if (status) { - OSSTATUS_LOG(ERROR, status) << "SecKeychainOpen error"; - return matching_cert_buffers; - } - CFArrayAppendValue(mutable_keychain_search_list, roots_keychain); - - CFDictionarySetValue(query, kSecMatchSearchList, - scoped_alternate_keychain_search_list.get()); base::ScopedCFTypeRef<CFArrayRef> matching_items; OSStatus err = SecItemCopyMatching(
diff --git a/net/cert/internal/trust_store_mac.h b/net/cert/internal/trust_store_mac.h index 02c39fc..693cb122 100644 --- a/net/cert/internal/trust_store_mac.h +++ b/net/cert/internal/trust_store_mac.h
@@ -81,6 +81,17 @@ kLruCache = 3, }; + enum class TrustDomains { + // Load trust settings and certificates from all three trust domains + // (user, admin, system). + kAll = 0, + + // Load trust settings and certificates from only the user and admin trust + // domains. This will find trust settings that have been set locally or by + // an enterprise, but not those distributed with the OS. + kUserAndAdmin = 1, + }; + class ResultDebugData : public base::SupportsUserData::Data { public: static const ResultDebugData* Get(const base::SupportsUserData* debug_data); @@ -111,7 +122,10 @@ // |impl| selects which internal implementation is used for checking trust // settings, and the interpretation of |cache_size| varies depending on // |impl|. - TrustStoreMac(CFStringRef policy_oid, TrustImplType impl, size_t cache_size); + TrustStoreMac(CFStringRef policy_oid, + TrustImplType impl, + size_t cache_size, + TrustDomains domains); TrustStoreMac(const TrustStoreMac&) = delete; TrustStoreMac& operator=(const TrustStoreMac&) = delete; @@ -143,7 +157,8 @@ // The result is an array of CRYPTO_BUFFERs containing the DER certificate // data. static std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> - FindMatchingCertificatesForMacNormalizedSubject(CFDataRef name_data); + FindMatchingCertificatesForMacNormalizedSubject(CFDataRef name_data, + TrustDomains domains); // Returns the OS-normalized issuer of |cert|. // macOS internally uses a normalized form of subject/issuer names for @@ -152,6 +167,7 @@ static base::ScopedCFTypeRef<CFDataRef> GetMacNormalizedIssuer( const ParsedCertificate* cert); + TrustDomains domains_; std::unique_ptr<TrustImpl> trust_cache_; };
diff --git a/net/cert/internal/trust_store_mac_unittest.cc b/net/cert/internal/trust_store_mac_unittest.cc index 095b90d..1d5ab31 100644 --- a/net/cert/internal/trust_store_mac_unittest.cc +++ b/net/cert/internal/trust_store_mac_unittest.cc
@@ -4,15 +4,20 @@ #include "net/cert/internal/trust_store_mac.h" +#include <algorithm> +#include <set> + #include "base/base_paths.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/logging.h" #include "base/path_service.h" #include "base/process/launch.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/synchronization/lock.h" #include "crypto/mac_security_services_lock.h" +#include "crypto/sha2.h" #include "net/cert/internal/cert_errors.h" #include "net/cert/internal/test_helpers.h" #include "net/cert/known_roots_mac.h" @@ -83,6 +88,28 @@ return result; } +std::set<std::string> ParseFindCertificateOutputToDerCerts(std::string output) { + std::set<std::string> certs; + for (const std::string& hash_and_pem_partial : base::SplitStringUsingSubstr( + output, "-----END CERTIFICATE-----", base::TRIM_WHITESPACE, + base::SPLIT_WANT_NONEMPTY)) { + // Re-add the PEM ending mark, since SplitStringUsingSubstr eats it. + const std::string hash_and_pem = + hash_and_pem_partial + "\n-----END CERTIFICATE-----\n"; + + // Parse the PEM encoded text to DER bytes. + PEMTokenizer pem_tokenizer(hash_and_pem, {kCertificateHeader}); + if (!pem_tokenizer.GetNext()) { + ADD_FAILURE() << "!pem_tokenizer.GetNext()"; + continue; + } + std::string cert_der(pem_tokenizer.data()); + EXPECT_FALSE(pem_tokenizer.GetNext()); + certs.insert(cert_der); + } + return certs; +} + class DebugData : public base::SupportsUserData { public: ~DebugData() override = default; @@ -96,8 +123,9 @@ } // namespace class TrustStoreMacImplTest - : public testing::TestWithParam< - std::tuple<TrustStoreMac::TrustImplType, IsKnownRootTestOrder>> {}; + : public testing::TestWithParam<std::tuple<TrustStoreMac::TrustImplType, + IsKnownRootTestOrder, + TrustStoreMac::TrustDomains>> {}; // Test the trust store using known test certificates in a keychain. Tests // that issuer searching returns the expected certificates, and that none of @@ -120,7 +148,9 @@ const TrustStoreMac::TrustImplType trust_impl = std::get<0>(GetParam()); const IsKnownRootTestOrder is_known_root_test_order = std::get<1>(GetParam()); - TrustStoreMac trust_store(kSecPolicyAppleSSL, trust_impl, kDefaultCacheSize); + const TrustStoreMac::TrustDomains trust_domains = std::get<2>(GetParam()); + TrustStoreMac trust_store(kSecPolicyAppleSSL, trust_impl, kDefaultCacheSize, + trust_domains); scoped_refptr<ParsedCertificate> a_by_b, b_by_c, b_by_f, c_by_d, c_by_e, f_by_e, d_by_d, e_by_e; @@ -155,7 +185,7 @@ { std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> scoped_matching_items = TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( - normalized_name_b.get()); + normalized_name_b.get(), trust_domains); EXPECT_THAT(CryptoBufferVectorAsStringVector(scoped_matching_items), UnorderedElementsAreArray( @@ -165,7 +195,7 @@ { std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> scoped_matching_items = TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( - normalized_name_c.get()); + normalized_name_c.get(), trust_domains); EXPECT_THAT(CryptoBufferVectorAsStringVector(scoped_matching_items), UnorderedElementsAreArray( ParsedCertificateListAsDER({c_by_d, c_by_e}))); @@ -174,7 +204,7 @@ { std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> scoped_matching_items = TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( - normalized_name_f.get()); + normalized_name_f.get(), trust_domains); EXPECT_THAT( CryptoBufferVectorAsStringVector(scoped_matching_items), UnorderedElementsAreArray(ParsedCertificateListAsDER({f_by_e}))); @@ -183,7 +213,7 @@ { std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> scoped_matching_items = TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( - normalized_name_d.get()); + normalized_name_d.get(), trust_domains); EXPECT_THAT( CryptoBufferVectorAsStringVector(scoped_matching_items), UnorderedElementsAreArray(ParsedCertificateListAsDER({d_by_d}))); @@ -192,7 +222,7 @@ { std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> scoped_matching_items = TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( - normalized_name_e.get()); + normalized_name_e.get(), trust_domains); EXPECT_THAT( CryptoBufferVectorAsStringVector(scoped_matching_items), UnorderedElementsAreArray(ParsedCertificateListAsDER({e_by_e}))); @@ -242,43 +272,31 @@ "/System/Library/Keychains/SystemRootCertificates.keychain"}, &find_certificate_system_roots_output)); + std::set<std::string> find_certificate_default_search_list_certs = + ParseFindCertificateOutputToDerCerts( + find_certificate_default_search_list_output); + std::set<std::string> find_certificate_system_roots_certs = + ParseFindCertificateOutputToDerCerts( + find_certificate_system_roots_output); + const TrustStoreMac::TrustImplType trust_impl = std::get<0>(GetParam()); const IsKnownRootTestOrder is_known_root_test_order = std::get<1>(GetParam()); + const TrustStoreMac::TrustDomains trust_domains = std::get<2>(GetParam()); TrustStoreMac trust_store(kSecPolicyAppleX509Basic, trust_impl, - kDefaultCacheSize); + kDefaultCacheSize, trust_domains); base::ScopedCFTypeRef<SecPolicyRef> sec_policy(SecPolicyCreateBasicX509()); ASSERT_TRUE(sec_policy); - for (const std::string& hash_and_pem_partial : base::SplitStringUsingSubstr( - find_certificate_system_roots_output + - find_certificate_default_search_list_output, - "-----END CERTIFICATE-----", base::TRIM_WHITESPACE, - base::SPLIT_WANT_NONEMPTY)) { - // Re-add the PEM ending mark, since SplitStringUsingSubstr eats it. - const std::string hash_and_pem = - hash_and_pem_partial + "\n-----END CERTIFICATE-----\n"; - - // Use the first hash value found in the text. This might be SHA-256 or - // SHA-1, but it's only for debugging purposes so it doesn't matter as long - // as one exists. - std::string::size_type hash_pos = hash_and_pem.find("hash: "); - ASSERT_NE(std::string::npos, hash_pos); - hash_pos += 6; - std::string::size_type eol_pos = hash_and_pem.find_first_of("\r\n"); - ASSERT_NE(std::string::npos, eol_pos); - // Extract the hash of the certificate. This isn't necessary for the - // test, but is a convenient identifier to use in any error messages. - std::string hash_text = hash_and_pem.substr(hash_pos, eol_pos - hash_pos); - + std::vector<std::string> all_certs; + std::set_union(find_certificate_default_search_list_certs.begin(), + find_certificate_default_search_list_certs.end(), + find_certificate_system_roots_certs.begin(), + find_certificate_system_roots_certs.end(), + std::back_inserter(all_certs)); + for (const std::string& cert_der : all_certs) { + std::string hash = crypto::SHA256HashString(cert_der); + std::string hash_text = base::HexEncode(hash.data(), hash.size()); SCOPED_TRACE(hash_text); - // TODO(mattm): The same cert might exist in both lists, could de-dupe - // before testing? - - // Parse the PEM encoded text to DER bytes. - PEMTokenizer pem_tokenizer(hash_and_pem, {kCertificateHeader}); - ASSERT_TRUE(pem_tokenizer.GetNext()); - std::string cert_der(pem_tokenizer.data()); - ASSERT_FALSE(pem_tokenizer.GetNext()); CertErrors errors; // Note: don't actually need to make a ParsedCertificate here, just need @@ -307,9 +325,11 @@ if (is_known_root_test_order == TEST_IS_KNOWN_ROOT_BEFORE) { bool trust_store_is_known_root = trust_store.IsKnownRoot(cert.get()); - { + if (trust_domains == TrustStoreMac::TrustDomains::kAll) { base::AutoLock lock(crypto::GetMacSecurityServicesLock()); EXPECT_EQ(net::IsKnownRoot(cert_handle), trust_store_is_known_root); + } else { + EXPECT_FALSE(trust_store_is_known_root); } } @@ -334,13 +354,18 @@ kSecTrustOptionAllowExpired | kSecTrustOptionAllowExpiredRoot)); - SecTrustResultType trust_result; - ASSERT_EQ(noErr, SecTrustEvaluate(trust, &trust_result)); - bool expected_trust_anchor = - ((trust_result == kSecTrustResultProceed) || - (trust_result == kSecTrustResultUnspecified)) && - (SecTrustGetCertificateCount(trust) == 1); - EXPECT_EQ(expected_trust_anchor, is_trust_anchor); + if (trust_domains == TrustStoreMac::TrustDomains::kUserAndAdmin && + !find_certificate_default_search_list_certs.count(cert_der)) { + EXPECT_FALSE(is_trust_anchor); + } else { + SecTrustResultType trust_result; + ASSERT_EQ(noErr, SecTrustEvaluate(trust, &trust_result)); + bool expected_trust_anchor = + ((trust_result == kSecTrustResultProceed) || + (trust_result == kSecTrustResultUnspecified)) && + (SecTrustGetCertificateCount(trust) == 1); + EXPECT_EQ(expected_trust_anchor, is_trust_anchor); + } auto* trust_debug_data = TrustStoreMac::ResultDebugData::Get(&debug_data); ASSERT_TRUE(trust_debug_data); if (is_trust_anchor) { @@ -355,9 +380,11 @@ if (is_known_root_test_order == TEST_IS_KNOWN_ROOT_AFTER) { bool trust_store_is_known_root = trust_store.IsKnownRoot(cert.get()); - { + if (trust_domains == TrustStoreMac::TrustDomains::kAll) { base::AutoLock lock(crypto::GetMacSecurityServicesLock()); EXPECT_EQ(net::IsKnownRoot(cert_handle), trust_store_is_known_root); + } else { + EXPECT_FALSE(trust_store_is_known_root); } } @@ -388,6 +415,8 @@ // values independently, so test with calling IsKnownRoot both before // and after GetTrust to try to ensure there is no ordering issue with // which one initializes the cache first. - testing::Values(TEST_IS_KNOWN_ROOT_BEFORE, TEST_IS_KNOWN_ROOT_AFTER))); + testing::Values(TEST_IS_KNOWN_ROOT_BEFORE, TEST_IS_KNOWN_ROOT_AFTER), + testing::Values(TrustStoreMac::TrustDomains::kAll, + TrustStoreMac::TrustDomains::kUserAndAdmin))); } // namespace net
diff --git a/net/data/ssl/chrome_root_store/README.md b/net/data/ssl/chrome_root_store/README.md index 040f80e..b8f9423 100644 --- a/net/data/ssl/chrome_root_store/README.md +++ b/net/data/ssl/chrome_root_store/README.md
@@ -4,11 +4,32 @@ [Chrome Root Store](https://www.chromium.org/Home/chromium-security/root-ca-policy). It is currently not used for trust decisions in Chrome. -The root store is defined by `store/root_store.textproto` file, which is a -`RootStore` [protobuf](https://developers.google.com/protocol-buffers) message, -defined in -[`//net/tools/root_store_tool/root_store.proto`](/net/tools/root_store_tool/root_store.proto). -It references certificates in the `store/certs` directory. The -[`root_store_tool`](/net/tools/root_store_tool/root_store_tool.cc) will -files in this directory to eventually use this data for trust decisions in -Chrome. +The root store is defined by two files: + +* `root_store.textproto` file, which is a `RootStore` + [protobuf](https://developers.google.com/protocol-buffers) message, defined in + [`//net/cert/root_store.proto`](/net/cert/root_store.proto). + +* `root_store.certs` which stores the certificates referenced by + `root_store.textproto` + +The [`root_store_tool`](/net/tools/root_store_tool/root_store_tool.cc) uses the +two files above to generate code that is included in Chrome. This generated code +will eventually be used for trust decisions in Chrome. + +## Testing + +To test the Chrome Root store, do the following: + +* On M102 or higher on Windows, run Chrome with the following flag: + + `--enable-features=ChromeRootStoreUsed` + +As of 2022-06, an example of a web site that is trusted by Windows Root Store +but not by Chrome Root Store is https://rootcertificateprograms.edicom.es/. This +can be used to test if Chrome Root Store is turned on or not (for best results +use a fresh incognito window to avoid any caching issues). + +If you're running 104.0.5110.0 or higher, the currently used Chrome Root Store +version can be seen in a [NetLog +dump](https://www.chromium.org/for-testers/providing-network-details/).
diff --git a/net/features.gni b/net/features.gni index a812f6f7..3cf1e4a 100644 --- a/net/features.gni +++ b/net/features.gni
@@ -47,5 +47,5 @@ # Platforms for which the builtin cert verifier can use the Chrome Root Store. # See https://crbug.com/1216547 for status. - chrome_root_store_supported = is_win + chrome_root_store_supported = is_win || is_mac }
diff --git a/net/network_error_logging/network_error_logging_service_unittest.cc b/net/network_error_logging/network_error_logging_service_unittest.cc index 675f8513..2cd8921 100644 --- a/net/network_error_logging/network_error_logging_service_unittest.cc +++ b/net/network_error_logging/network_error_logging_service_unittest.cc
@@ -429,27 +429,28 @@ EXPECT_EQ(0, reports()[0].depth); const base::Value* body = reports()[0].body.get(); - const base::Value::Dict* body_dict = body->GetIfDict(); - ASSERT_TRUE(body_dict); + ASSERT_TRUE(body); + ASSERT_TRUE(body->is_dict()); + const base::Value::Dict& body_dict = body->GetDict(); - base::ExpectDictStringValue(kReferrer_.spec(), *body, + base::ExpectDictStringValue(kReferrer_.spec(), body_dict, NetworkErrorLoggingService::kReferrerKey); // TODO(juliatuttle): Extract these constants. - ExpectDictDoubleValue(1.0, *body_dict, + ExpectDictDoubleValue(1.0, body_dict, NetworkErrorLoggingService::kSamplingFractionKey); - base::ExpectDictStringValue(kServerIP_.ToString(), *body, + base::ExpectDictStringValue(kServerIP_.ToString(), body_dict, NetworkErrorLoggingService::kServerIpKey); - base::ExpectDictStringValue("", *body, + base::ExpectDictStringValue("", body_dict, NetworkErrorLoggingService::kProtocolKey); - base::ExpectDictStringValue("GET", *body, + base::ExpectDictStringValue("GET", body_dict, NetworkErrorLoggingService::kMethodKey); - base::ExpectDictIntegerValue(0, *body, + base::ExpectDictIntegerValue(0, body_dict, NetworkErrorLoggingService::kStatusCodeKey); - base::ExpectDictIntegerValue(1000, *body, + base::ExpectDictIntegerValue(1000, body_dict, NetworkErrorLoggingService::kElapsedTimeKey); - base::ExpectDictStringValue("application", *body, + base::ExpectDictStringValue("application", body_dict, NetworkErrorLoggingService::kPhaseKey); - base::ExpectDictStringValue("ok", *body, + base::ExpectDictStringValue("ok", body_dict, NetworkErrorLoggingService::kTypeKey); } @@ -473,27 +474,28 @@ EXPECT_EQ(0, reports()[0].depth); const base::Value* body = reports()[0].body.get(); - const base::Value::Dict* body_dict = body->GetIfDict(); - ASSERT_TRUE(body_dict); + ASSERT_TRUE(body); + ASSERT_TRUE(body->is_dict()); + const base::Value::Dict& body_dict = body->GetDict(); - base::ExpectDictStringValue(kReferrer_.spec(), *body, + base::ExpectDictStringValue(kReferrer_.spec(), body_dict, NetworkErrorLoggingService::kReferrerKey); // TODO(juliatuttle): Extract these constants. - ExpectDictDoubleValue(1.0, *body_dict, + ExpectDictDoubleValue(1.0, body_dict, NetworkErrorLoggingService::kSamplingFractionKey); - base::ExpectDictStringValue(kServerIP_.ToString(), *body, + base::ExpectDictStringValue(kServerIP_.ToString(), body_dict, NetworkErrorLoggingService::kServerIpKey); - base::ExpectDictStringValue("", *body, + base::ExpectDictStringValue("", body_dict, NetworkErrorLoggingService::kProtocolKey); - base::ExpectDictStringValue("GET", *body, + base::ExpectDictStringValue("GET", body_dict, NetworkErrorLoggingService::kMethodKey); - base::ExpectDictIntegerValue(0, *body, + base::ExpectDictIntegerValue(0, body_dict, NetworkErrorLoggingService::kStatusCodeKey); - base::ExpectDictIntegerValue(1000, *body, + base::ExpectDictIntegerValue(1000, body_dict, NetworkErrorLoggingService::kElapsedTimeKey); - base::ExpectDictStringValue("connection", *body, + base::ExpectDictStringValue("connection", body_dict, NetworkErrorLoggingService::kPhaseKey); - base::ExpectDictStringValue("tcp.refused", *body, + base::ExpectDictStringValue("tcp.refused", body_dict, NetworkErrorLoggingService::kTypeKey); } @@ -511,10 +513,12 @@ ASSERT_EQ(1u, reports().size()); const base::Value* body = reports()[0].body.get(); + ASSERT_TRUE(body); ASSERT_TRUE(body->is_dict()); - base::ExpectDictStringValue("application", *body, + const base::Value::Dict& body_dict = body->GetDict(); + base::ExpectDictStringValue("application", body_dict, NetworkErrorLoggingService::kPhaseKey); - base::ExpectDictStringValue("unknown", *body, + base::ExpectDictStringValue("unknown", body_dict, NetworkErrorLoggingService::kTypeKey); } @@ -534,10 +538,12 @@ ASSERT_EQ(1u, reports().size()); const base::Value* body = reports()[0].body.get(); + ASSERT_TRUE(body); ASSERT_TRUE(body->is_dict()); - base::ExpectDictStringValue("connection", *body, + const base::Value::Dict& body_dict = body->GetDict(); + base::ExpectDictStringValue("connection", body_dict, NetworkErrorLoggingService::kPhaseKey); - base::ExpectDictStringValue("unknown", *body, + base::ExpectDictStringValue("unknown", body_dict, NetworkErrorLoggingService::kTypeKey); } @@ -560,27 +566,28 @@ EXPECT_EQ(0, reports()[0].depth); const base::Value* body = reports()[0].body.get(); - const base::Value::Dict* body_dict = body->GetIfDict(); - ASSERT_TRUE(body_dict); + ASSERT_TRUE(body); + ASSERT_TRUE(body->is_dict()); + const base::Value::Dict& body_dict = body->GetDict(); - base::ExpectDictStringValue(kReferrer_.spec(), *body, + base::ExpectDictStringValue(kReferrer_.spec(), body_dict, NetworkErrorLoggingService::kReferrerKey); // TODO(juliatuttle): Extract these constants. - ExpectDictDoubleValue(1.0, *body_dict, + ExpectDictDoubleValue(1.0, body_dict, NetworkErrorLoggingService::kSamplingFractionKey); - base::ExpectDictStringValue(kServerIP_.ToString(), *body, + base::ExpectDictStringValue(kServerIP_.ToString(), body_dict, NetworkErrorLoggingService::kServerIpKey); - base::ExpectDictStringValue("", *body, + base::ExpectDictStringValue("", body_dict, NetworkErrorLoggingService::kProtocolKey); - base::ExpectDictStringValue("GET", *body, + base::ExpectDictStringValue("GET", body_dict, NetworkErrorLoggingService::kMethodKey); - base::ExpectDictIntegerValue(504, *body, + base::ExpectDictIntegerValue(504, body_dict, NetworkErrorLoggingService::kStatusCodeKey); - base::ExpectDictIntegerValue(1000, *body, + base::ExpectDictIntegerValue(1000, body_dict, NetworkErrorLoggingService::kElapsedTimeKey); - base::ExpectDictStringValue("application", *body, + base::ExpectDictStringValue("application", body_dict, NetworkErrorLoggingService::kPhaseKey); - base::ExpectDictStringValue("http.error", *body, + base::ExpectDictStringValue("http.error", body_dict, NetworkErrorLoggingService::kTypeKey); } @@ -601,26 +608,27 @@ EXPECT_EQ(0, reports()[0].depth); const base::Value* body = reports()[0].body.get(); - const base::Value::Dict* body_dict = body->GetIfDict(); - ASSERT_TRUE(body_dict); + ASSERT_TRUE(body); + ASSERT_TRUE(body->is_dict()); + const base::Value::Dict& body_dict = body->GetDict(); - base::ExpectDictStringValue(kReferrer_.spec(), *body, + base::ExpectDictStringValue(kReferrer_.spec(), body_dict, NetworkErrorLoggingService::kReferrerKey); - ExpectDictDoubleValue(1.0, *body_dict, + ExpectDictDoubleValue(1.0, body_dict, NetworkErrorLoggingService::kSamplingFractionKey); - base::ExpectDictStringValue(kOtherServerIP_.ToString(), *body, + base::ExpectDictStringValue(kOtherServerIP_.ToString(), body_dict, NetworkErrorLoggingService::kServerIpKey); - base::ExpectDictStringValue("", *body, + base::ExpectDictStringValue("", body_dict, NetworkErrorLoggingService::kProtocolKey); - base::ExpectDictStringValue("GET", *body, + base::ExpectDictStringValue("GET", body_dict, NetworkErrorLoggingService::kMethodKey); - base::ExpectDictIntegerValue(0, *body, + base::ExpectDictIntegerValue(0, body_dict, NetworkErrorLoggingService::kStatusCodeKey); - base::ExpectDictIntegerValue(0, *body, + base::ExpectDictIntegerValue(0, body_dict, NetworkErrorLoggingService::kElapsedTimeKey); - base::ExpectDictStringValue("dns", *body, + base::ExpectDictStringValue("dns", body_dict, NetworkErrorLoggingService::kPhaseKey); - base::ExpectDictStringValue("dns.address_changed", *body, + base::ExpectDictStringValue("dns.address_changed", body_dict, NetworkErrorLoggingService::kTypeKey); } @@ -641,26 +649,27 @@ EXPECT_EQ(0, reports()[0].depth); const base::Value* body = reports()[0].body.get(); - const base::Value::Dict* body_dict = body->GetIfDict(); - ASSERT_TRUE(body_dict); + ASSERT_TRUE(body); + ASSERT_TRUE(body->is_dict()); + const base::Value::Dict& body_dict = body->GetDict(); - base::ExpectDictStringValue(kReferrer_.spec(), *body, + base::ExpectDictStringValue(kReferrer_.spec(), body_dict, NetworkErrorLoggingService::kReferrerKey); - ExpectDictDoubleValue(1.0, *body_dict, + ExpectDictDoubleValue(1.0, body_dict, NetworkErrorLoggingService::kSamplingFractionKey); - base::ExpectDictStringValue(kOtherServerIP_.ToString(), *body, + base::ExpectDictStringValue(kOtherServerIP_.ToString(), body_dict, NetworkErrorLoggingService::kServerIpKey); - base::ExpectDictStringValue("", *body, + base::ExpectDictStringValue("", body_dict, NetworkErrorLoggingService::kProtocolKey); - base::ExpectDictStringValue("GET", *body, + base::ExpectDictStringValue("GET", body_dict, NetworkErrorLoggingService::kMethodKey); - base::ExpectDictIntegerValue(0, *body, + base::ExpectDictIntegerValue(0, body_dict, NetworkErrorLoggingService::kStatusCodeKey); - base::ExpectDictIntegerValue(0, *body, + base::ExpectDictIntegerValue(0, body_dict, NetworkErrorLoggingService::kElapsedTimeKey); - base::ExpectDictStringValue("dns", *body, + base::ExpectDictStringValue("dns", body_dict, NetworkErrorLoggingService::kPhaseKey); - base::ExpectDictStringValue("dns.address_changed", *body, + base::ExpectDictStringValue("dns.address_changed", body_dict, NetworkErrorLoggingService::kTypeKey); } @@ -681,26 +690,27 @@ EXPECT_EQ(0, reports()[0].depth); const base::Value* body = reports()[0].body.get(); - const base::Value::Dict* body_dict = body->GetIfDict(); - ASSERT_TRUE(body_dict); + ASSERT_TRUE(body); + ASSERT_TRUE(body->is_dict()); + const base::Value::Dict& body_dict = body->GetDict(); - base::ExpectDictStringValue(kReferrer_.spec(), *body, + base::ExpectDictStringValue(kReferrer_.spec(), body_dict, NetworkErrorLoggingService::kReferrerKey); - ExpectDictDoubleValue(1.0, *body_dict, + ExpectDictDoubleValue(1.0, body_dict, NetworkErrorLoggingService::kSamplingFractionKey); - base::ExpectDictStringValue(kOtherServerIP_.ToString(), *body, + base::ExpectDictStringValue(kOtherServerIP_.ToString(), body_dict, NetworkErrorLoggingService::kServerIpKey); - base::ExpectDictStringValue("", *body, + base::ExpectDictStringValue("", body_dict, NetworkErrorLoggingService::kProtocolKey); - base::ExpectDictStringValue("GET", *body, + base::ExpectDictStringValue("GET", body_dict, NetworkErrorLoggingService::kMethodKey); - base::ExpectDictIntegerValue(0, *body, + base::ExpectDictIntegerValue(0, body_dict, NetworkErrorLoggingService::kStatusCodeKey); - base::ExpectDictIntegerValue(0, *body, + base::ExpectDictIntegerValue(0, body_dict, NetworkErrorLoggingService::kElapsedTimeKey); - base::ExpectDictStringValue("dns", *body, + base::ExpectDictStringValue("dns", body_dict, NetworkErrorLoggingService::kPhaseKey); - base::ExpectDictStringValue("dns.address_changed", *body, + base::ExpectDictStringValue("dns.address_changed", body_dict, NetworkErrorLoggingService::kTypeKey); } @@ -721,26 +731,27 @@ EXPECT_EQ(0, reports()[0].depth); const base::Value* body = reports()[0].body.get(); - const base::Value::Dict* body_dict = body->GetIfDict(); - ASSERT_TRUE(body_dict); + ASSERT_TRUE(body); + ASSERT_TRUE(body->is_dict()); + const base::Value::Dict& body_dict = body->GetDict(); - base::ExpectDictStringValue(kReferrer_.spec(), *body, + base::ExpectDictStringValue(kReferrer_.spec(), body_dict, NetworkErrorLoggingService::kReferrerKey); - ExpectDictDoubleValue(1.0, *body_dict, + ExpectDictDoubleValue(1.0, body_dict, NetworkErrorLoggingService::kSamplingFractionKey); - base::ExpectDictStringValue(kOtherServerIP_.ToString(), *body, + base::ExpectDictStringValue(kOtherServerIP_.ToString(), body_dict, NetworkErrorLoggingService::kServerIpKey); - base::ExpectDictStringValue("", *body, + base::ExpectDictStringValue("", body_dict, NetworkErrorLoggingService::kProtocolKey); - base::ExpectDictStringValue("GET", *body, + base::ExpectDictStringValue("GET", body_dict, NetworkErrorLoggingService::kMethodKey); - base::ExpectDictIntegerValue(0, *body, + base::ExpectDictIntegerValue(0, body_dict, NetworkErrorLoggingService::kStatusCodeKey); - base::ExpectDictIntegerValue(1000, *body, + base::ExpectDictIntegerValue(1000, body_dict, NetworkErrorLoggingService::kElapsedTimeKey); - base::ExpectDictStringValue("dns", *body, + base::ExpectDictStringValue("dns", body_dict, NetworkErrorLoggingService::kPhaseKey); - base::ExpectDictStringValue("dns.name_not_resolved", *body, + base::ExpectDictStringValue("dns.name_not_resolved", body_dict, NetworkErrorLoggingService::kTypeKey); } @@ -760,22 +771,23 @@ EXPECT_EQ(0, reports()[0].depth); const base::Value* body = reports()[0].body.get(); - const base::Value::Dict* body_dict = body->GetIfDict(); - ASSERT_TRUE(body_dict); + ASSERT_TRUE(body); + ASSERT_TRUE(body->is_dict()); + const base::Value::Dict& body_dict = body->GetDict(); - base::ExpectDictStringValue(kReferrer_.spec(), *body, + base::ExpectDictStringValue(kReferrer_.spec(), body_dict, NetworkErrorLoggingService::kReferrerKey); - ExpectDictDoubleValue(1.0, *body_dict, + ExpectDictDoubleValue(1.0, body_dict, NetworkErrorLoggingService::kSamplingFractionKey); - base::ExpectDictStringValue(kServerIP_.ToString(), *body, + base::ExpectDictStringValue(kServerIP_.ToString(), body_dict, NetworkErrorLoggingService::kServerIpKey); - base::ExpectDictStringValue("", *body, + base::ExpectDictStringValue("", body_dict, NetworkErrorLoggingService::kProtocolKey); - base::ExpectDictStringValue("POST", *body, + base::ExpectDictStringValue("POST", body_dict, NetworkErrorLoggingService::kMethodKey); - base::ExpectDictStringValue("application", *body, + base::ExpectDictStringValue("application", body_dict, NetworkErrorLoggingService::kPhaseKey); - base::ExpectDictStringValue("ok", *body, + base::ExpectDictStringValue("ok", body_dict, NetworkErrorLoggingService::kTypeKey); } @@ -1237,41 +1249,41 @@ EXPECT_EQ(0, reports()[0].depth); const base::Value* body = reports()[0].body.get(); - const base::Value::Dict* body_dict = body->GetIfDict(); - ASSERT_TRUE(body_dict); + ASSERT_TRUE(body); + ASSERT_TRUE(body->is_dict()); + const base::Value::Dict& body_dict = body->GetDict(); - base::ExpectDictStringValue(kReferrer_.spec(), *body, + base::ExpectDictStringValue(kReferrer_.spec(), body_dict, NetworkErrorLoggingService::kReferrerKey); - ExpectDictDoubleValue(1.0, *body_dict, + ExpectDictDoubleValue(1.0, body_dict, NetworkErrorLoggingService::kSamplingFractionKey); - base::ExpectDictStringValue(kServerIP_.ToString(), *body, + base::ExpectDictStringValue(kServerIP_.ToString(), body_dict, NetworkErrorLoggingService::kServerIpKey); - base::ExpectDictStringValue("http/1.1", *body, + base::ExpectDictStringValue("http/1.1", body_dict, NetworkErrorLoggingService::kProtocolKey); - base::ExpectDictStringValue("GET", *body, + base::ExpectDictStringValue("GET", body_dict, NetworkErrorLoggingService::kMethodKey); - base::ExpectDictIntegerValue(200, *body, + base::ExpectDictIntegerValue(200, body_dict, NetworkErrorLoggingService::kStatusCodeKey); - base::ExpectDictIntegerValue(1234, *body, + base::ExpectDictIntegerValue(1234, body_dict, NetworkErrorLoggingService::kElapsedTimeKey); base::ExpectDictStringValue( - NetworkErrorLoggingService::kSignedExchangePhaseValue, *body, + NetworkErrorLoggingService::kSignedExchangePhaseValue, body_dict, NetworkErrorLoggingService::kPhaseKey); - base::ExpectDictStringValue("ok", *body, + base::ExpectDictStringValue("ok", body_dict, NetworkErrorLoggingService::kTypeKey); - const base::Value* sxg_body = - body_dict->Find(NetworkErrorLoggingService::kSignedExchangeBodyKey); - ASSERT_TRUE(sxg_body && sxg_body->is_dict()); + const base::Value::Dict* sxg_body = + body_dict.FindDict(NetworkErrorLoggingService::kSignedExchangeBodyKey); + ASSERT_TRUE(sxg_body); base::ExpectDictStringValue(kUrl_.spec(), *sxg_body, NetworkErrorLoggingService::kOuterUrlKey); base::ExpectDictStringValue(kInnerUrl_.spec(), *sxg_body, NetworkErrorLoggingService::kInnerUrlKey); - base::ExpectStringValue(kCertUrl_.spec(), - sxg_body->GetDict() - .Find(NetworkErrorLoggingService::kCertUrlKey) - ->GetList()[0]); + base::ExpectStringValue( + kCertUrl_.spec(), + sxg_body->Find(NetworkErrorLoggingService::kCertUrlKey)->GetList()[0]); } TEST_P(NetworkErrorLoggingServiceTest, FailureReportQueued_SignedExchange) { @@ -1291,41 +1303,41 @@ EXPECT_EQ(0, reports()[0].depth); const base::Value* body = reports()[0].body.get(); - const base::Value::Dict* body_dict = body->GetIfDict(); - ASSERT_TRUE(body_dict); + ASSERT_TRUE(body); + ASSERT_TRUE(body->is_dict()); + const base::Value::Dict& body_dict = body->GetDict(); - base::ExpectDictStringValue(kReferrer_.spec(), *body, + base::ExpectDictStringValue(kReferrer_.spec(), body_dict, NetworkErrorLoggingService::kReferrerKey); - ExpectDictDoubleValue(1.0, *body_dict, + ExpectDictDoubleValue(1.0, body_dict, NetworkErrorLoggingService::kSamplingFractionKey); - base::ExpectDictStringValue(kServerIP_.ToString(), *body, + base::ExpectDictStringValue(kServerIP_.ToString(), body_dict, NetworkErrorLoggingService::kServerIpKey); - base::ExpectDictStringValue("http/1.1", *body, + base::ExpectDictStringValue("http/1.1", body_dict, NetworkErrorLoggingService::kProtocolKey); - base::ExpectDictStringValue("GET", *body, + base::ExpectDictStringValue("GET", body_dict, NetworkErrorLoggingService::kMethodKey); - base::ExpectDictIntegerValue(200, *body, + base::ExpectDictIntegerValue(200, body_dict, NetworkErrorLoggingService::kStatusCodeKey); - base::ExpectDictIntegerValue(1234, *body, + base::ExpectDictIntegerValue(1234, body_dict, NetworkErrorLoggingService::kElapsedTimeKey); base::ExpectDictStringValue( - NetworkErrorLoggingService::kSignedExchangePhaseValue, *body, + NetworkErrorLoggingService::kSignedExchangePhaseValue, body_dict, NetworkErrorLoggingService::kPhaseKey); - base::ExpectDictStringValue("sxg.failed", *body, + base::ExpectDictStringValue("sxg.failed", body_dict, NetworkErrorLoggingService::kTypeKey); - const base::Value* sxg_body = - body_dict->Find(NetworkErrorLoggingService::kSignedExchangeBodyKey); - ASSERT_TRUE(sxg_body && sxg_body->is_dict()); + const base::Value::Dict* sxg_body = + body_dict.FindDict(NetworkErrorLoggingService::kSignedExchangeBodyKey); + ASSERT_TRUE(sxg_body); base::ExpectDictStringValue(kUrl_.spec(), *sxg_body, NetworkErrorLoggingService::kOuterUrlKey); base::ExpectDictStringValue(kInnerUrl_.spec(), *sxg_body, NetworkErrorLoggingService::kInnerUrlKey); - base::ExpectStringValue(kCertUrl_.spec(), - sxg_body->GetDict() - .Find(NetworkErrorLoggingService::kCertUrlKey) - ->GetList()[0]); + base::ExpectStringValue( + kCertUrl_.spec(), + sxg_body->Find(NetworkErrorLoggingService::kCertUrlKey)->GetList()[0]); } TEST_P(NetworkErrorLoggingServiceTest, MismatchingSubdomain_SignedExchange) {
diff --git a/net/reporting/reporting_delivery_agent_unittest.cc b/net/reporting/reporting_delivery_agent_unittest.cc index 5d38ffe..8096155a 100644 --- a/net/reporting/reporting_delivery_agent_unittest.cc +++ b/net/reporting/reporting_delivery_agent_unittest.cc
@@ -160,15 +160,16 @@ ASSERT_TRUE(value->is_list()); ASSERT_EQ(1u, value->GetList().size()); - base::Value& report = value->GetList()[0]; + const base::Value& report = value->GetList()[0]; ASSERT_TRUE(report.is_dict()); - EXPECT_EQ(5u, report.GetDict().size()); + const base::Value::Dict& report_dict = report.GetDict(); + EXPECT_EQ(5u, report_dict.size()); - ExpectDictIntegerValue(0, report, "age"); - ExpectDictStringValue(kType_, report, "type"); - ExpectDictStringValue(kUrl_.spec(), report, "url"); - ExpectDictStringValue(kUserAgent_, report, "user_agent"); - const base::Value::Dict* body = report.GetDict().FindDict("body"); + ExpectDictIntegerValue(0, report_dict, "age"); + ExpectDictStringValue(kType_, report_dict, "type"); + ExpectDictStringValue(kUrl_.spec(), report_dict, "url"); + ExpectDictStringValue(kUserAgent_, report_dict, "user_agent"); + const base::Value::Dict* body = report_dict.FindDict("body"); EXPECT_EQ("value", *body->FindString("key")); } pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); @@ -238,12 +239,13 @@ const base::Value& report = value->GetList()[0]; ASSERT_TRUE(report.is_dict()); + const base::Value::Dict& report_dict = report.GetDict(); - ExpectDictIntegerValue(0, report, "age"); - ExpectDictStringValue(kType_, report, "type"); - ExpectDictStringValue(kUrl_.spec(), report, "url"); - ExpectDictStringValue(kUserAgent_, report, "user_agent"); - const base::Value::Dict* body = report.GetDict().FindDict("body"); + ExpectDictIntegerValue(0, report_dict, "age"); + ExpectDictStringValue(kType_, report_dict, "type"); + ExpectDictStringValue(kUrl_.spec(), report_dict, "url"); + ExpectDictStringValue(kUserAgent_, report_dict, "user_agent"); + const base::Value::Dict* body = report_dict.FindDict("body"); EXPECT_EQ("value", *body->FindString("key")); } pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); @@ -314,15 +316,16 @@ ASSERT_TRUE(value->is_list()); ASSERT_EQ(1u, value->GetList().size()); - base::Value& report = value->GetList()[0]; + const base::Value& report = value->GetList()[0]; ASSERT_TRUE(report.is_dict()); - EXPECT_EQ(5u, report.GetDict().size()); + const base::Value::Dict& report_dict = report.GetDict(); + EXPECT_EQ(5u, report_dict.size()); - ExpectDictIntegerValue(0, report, "age"); - ExpectDictStringValue(kType_, report, "type"); - ExpectDictStringValue(kSubdomainUrl_.spec(), report, "url"); - ExpectDictStringValue(kUserAgent_, report, "user_agent"); - const base::Value::Dict* body = report.GetDict().FindDict("body"); + ExpectDictIntegerValue(0, report_dict, "age"); + ExpectDictStringValue(kType_, report_dict, "type"); + ExpectDictStringValue(kSubdomainUrl_.spec(), report_dict, "url"); + ExpectDictStringValue(kUserAgent_, report_dict, "user_agent"); + const base::Value::Dict* body = report_dict.FindDict("body"); EXPECT_EQ("value", *body->FindString("key")); } pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); @@ -393,15 +396,16 @@ ASSERT_TRUE(value->is_list()); ASSERT_EQ(1u, value->GetList().size()); - base::Value& report = value->GetList()[0]; + const base::Value& report = value->GetList()[0]; ASSERT_TRUE(report.is_dict()); - EXPECT_EQ(5u, report.GetDict().size()); + const base::Value::Dict& report_dict = report.GetDict(); + EXPECT_EQ(5u, report_dict.size()); - ExpectDictIntegerValue(0, report, "age"); - ExpectDictStringValue(kType_, report, "type"); - ExpectDictStringValue(kUrl_.spec(), report, "url"); - ExpectDictStringValue(kUserAgent_, report, "user_agent"); - const base::Value::Dict* body = report.GetDict().FindDict("body"); + ExpectDictIntegerValue(0, report_dict, "age"); + ExpectDictStringValue(kType_, report_dict, "type"); + ExpectDictStringValue(kUrl_.spec(), report_dict, "url"); + ExpectDictStringValue(kUserAgent_, report_dict, "user_agent"); + const base::Value::Dict* body = report_dict.FindDict("body"); EXPECT_EQ("value", *body->FindString("key")); } pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
diff --git a/printing/backend/print_backend.h b/printing/backend/print_backend.h index 2320c63c..c64365f 100644 --- a/printing/backend/print_backend.h +++ b/printing/backend/print_backend.h
@@ -210,12 +210,12 @@ public: // Enumerates the list of installed local and network printers. It will // return success when the available installed printers have been enumerated - // into `printer_list`. Note that `printer_list` must not be null and also - // should be empty prior to this call. If there are no printers installed - // then it will still return success, and `printer_list` remains empty. The - // result code will return one of the error result codes when there is a - // failure in generating the list. - virtual mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) = 0; + // into `printer_list`. Note that `printer_list` should be empty prior to + // this call. If there are no printers installed then it will still return + // success, and `printer_list` remains empty. The result code will return + // one of the error result codes when there is a failure in generating the + // list. + virtual mojom::ResultCode EnumeratePrinters(PrinterList& printer_list) = 0; // Gets the default printer name. If there is no default printer then it // will still return success and `default_printer` will be empty. The result
diff --git a/printing/backend/print_backend_chromeos.cc b/printing/backend/print_backend_chromeos.cc index 332ab95..da17144 100644 --- a/printing/backend/print_backend_chromeos.cc +++ b/printing/backend/print_backend_chromeos.cc
@@ -23,7 +23,7 @@ PrintBackendChromeOS() = default; // PrintBackend implementation. - mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) override; + mojom::ResultCode EnumeratePrinters(PrinterList& printer_list) override; mojom::ResultCode GetDefaultPrinterName( std::string& default_printer) override; mojom::ResultCode GetPrinterBasicInfo( @@ -43,7 +43,7 @@ }; mojom::ResultCode PrintBackendChromeOS::EnumeratePrinters( - PrinterList* printer_list) { + PrinterList& printer_list) { return mojom::ResultCode::kSuccess; }
diff --git a/printing/backend/print_backend_cups.cc b/printing/backend/print_backend_cups.cc index 0025d77..ac1029b0 100644 --- a/printing/backend/print_backend_cups.cc +++ b/printing/backend/print_backend_cups.cc
@@ -136,9 +136,8 @@ } mojom::ResultCode PrintBackendCUPS::EnumeratePrinters( - PrinterList* printer_list) { - DCHECK(printer_list); - printer_list->clear(); + PrinterList& printer_list) { + DCHECK(printer_list.empty()); // If possible prefer to use cupsEnumDests() over GetDests(), because the // latter has been found to filter out some destination values if a device @@ -191,14 +190,14 @@ PrinterBasicInfo printer_info; if (PrinterBasicInfoFromCUPS(printer, &printer_info) == mojom::ResultCode::kSuccess) { - printer_list->push_back(printer_info); + printer_list.push_back(printer_info); } } cupsFreeDests(dests_data.num_dests, dests_data.dests); VLOG(1) << "CUPS: Enumerated printers, server: " << print_server_url_ - << ", # of printers: " << printer_list->size(); + << ", # of printers: " << printer_list.size(); return mojom::ResultCode::kSuccess; }
diff --git a/printing/backend/print_backend_cups.h b/printing/backend/print_backend_cups.h index 707a556..d57acda07 100644 --- a/printing/backend/print_backend_cups.h +++ b/printing/backend/print_backend_cups.h
@@ -42,7 +42,7 @@ ~PrintBackendCUPS() override; // PrintBackend implementation. - mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) override; + mojom::ResultCode EnumeratePrinters(PrinterList& printer_list) override; mojom::ResultCode GetDefaultPrinterName( std::string& default_printer) override; mojom::ResultCode GetPrinterBasicInfo(
diff --git a/printing/backend/print_backend_cups_ipp.cc b/printing/backend/print_backend_cups_ipp.cc index 571f0ee..46b1a928 100644 --- a/printing/backend/print_backend_cups_ipp.cc +++ b/printing/backend/print_backend_cups_ipp.cc
@@ -29,9 +29,8 @@ PrintBackendCupsIpp::~PrintBackendCupsIpp() = default; mojom::ResultCode PrintBackendCupsIpp::EnumeratePrinters( - PrinterList* printer_list) { - DCHECK(printer_list); - printer_list->clear(); + PrinterList& printer_list) { + DCHECK(printer_list.empty()); std::vector<std::unique_ptr<CupsPrinter>> printers; if (!cups_connection_->GetDests(printers)) { @@ -47,7 +46,7 @@ for (const auto& printer : printers) { PrinterBasicInfo basic_info; if (printer->ToPrinterInfo(&basic_info)) { - printer_list->push_back(basic_info); + printer_list.push_back(basic_info); } }
diff --git a/printing/backend/print_backend_cups_ipp.h b/printing/backend/print_backend_cups_ipp.h index 554601e1..e133cc08 100644 --- a/printing/backend/print_backend_cups_ipp.h +++ b/printing/backend/print_backend_cups_ipp.h
@@ -22,7 +22,7 @@ ~PrintBackendCupsIpp() override; // PrintBackend implementation. - mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) override; + mojom::ResultCode EnumeratePrinters(PrinterList& printer_list) override; mojom::ResultCode GetDefaultPrinterName( std::string& default_printer) override; mojom::ResultCode GetPrinterBasicInfo(
diff --git a/printing/backend/print_backend_dummy.cc b/printing/backend/print_backend_dummy.cc index 4ef0ddc..d8bb625 100644 --- a/printing/backend/print_backend_dummy.cc +++ b/printing/backend/print_backend_dummy.cc
@@ -19,7 +19,7 @@ DummyPrintBackend(const DummyPrintBackend&) = delete; DummyPrintBackend& operator=(const DummyPrintBackend&) = delete; - mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) override { + mojom::ResultCode EnumeratePrinters(PrinterList& printer_list) override { return mojom::ResultCode::kFailed; }
diff --git a/printing/backend/print_backend_unittest.cc b/printing/backend/print_backend_unittest.cc index 83dfc0e..595b0ea 100644 --- a/printing/backend/print_backend_unittest.cc +++ b/printing/backend/print_backend_unittest.cc
@@ -39,7 +39,7 @@ TEST_F(PrintBackendTest, MANUAL_EnumeratePrintersSomeInstalled) { PrinterList printer_list; - EXPECT_EQ(GetPrintBackend()->EnumeratePrinters(&printer_list), + EXPECT_EQ(GetPrintBackend()->EnumeratePrinters(printer_list), mojom::ResultCode::kSuccess); EXPECT_FALSE(printer_list.empty()); @@ -52,7 +52,7 @@ TEST_F(PrintBackendTest, MANUAL_EnumeratePrintersNoneInstalled) { PrinterList printer_list; - EXPECT_EQ(GetPrintBackend()->EnumeratePrinters(&printer_list), + EXPECT_EQ(GetPrintBackend()->EnumeratePrinters(printer_list), mojom::ResultCode::kSuccess); EXPECT_TRUE(printer_list.empty()); } @@ -63,7 +63,7 @@ // specific printer. TEST_F(PrintBackendTest, MANUAL_GetXmlPrinterCapabilitiesForXpsDriver) { PrinterList printer_list; - EXPECT_EQ(GetPrintBackend()->EnumeratePrinters(&printer_list), + EXPECT_EQ(GetPrintBackend()->EnumeratePrinters(printer_list), mojom::ResultCode::kSuccess); for (const auto& printer : printer_list) { std::string capabilities;
diff --git a/printing/backend/print_backend_win.cc b/printing/backend/print_backend_win.cc index 81af33e..a4eb611b 100644 --- a/printing/backend/print_backend_win.cc +++ b/printing/backend/print_backend_win.cc
@@ -266,7 +266,7 @@ PrintBackendWin() = default; // PrintBackend implementation. - mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) override; + mojom::ResultCode EnumeratePrinters(PrinterList& printer_list) override; mojom::ResultCode GetDefaultPrinterName( std::string& default_printer) override; mojom::ResultCode GetPrinterBasicInfo( @@ -286,8 +286,8 @@ }; mojom::ResultCode PrintBackendWin::EnumeratePrinters( - PrinterList* printer_list) { - DCHECK(printer_list); + PrinterList& printer_list) { + DCHECK(printer_list.empty()); DWORD bytes_needed = 0; DWORD count_returned = 0; constexpr DWORD kFlags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS; @@ -329,7 +329,7 @@ if (printer.OpenPrinterWithName(printer_info[index].pPrinterName) && InitBasicPrinterInfo(printer.Get(), &info)) { info.is_default = (info.printer_name == default_printer); - printer_list->push_back(info); + printer_list.push_back(info); } }
diff --git a/printing/backend/test_print_backend.cc b/printing/backend/test_print_backend.cc index 0c17a26..8d3e8336 100644 --- a/printing/backend/test_print_backend.cc +++ b/printing/backend/test_print_backend.cc
@@ -46,8 +46,8 @@ TestPrintBackend::~TestPrintBackend() = default; mojom::ResultCode TestPrintBackend::EnumeratePrinters( - PrinterList* printer_list) { - DCHECK(printer_list->empty()); + PrinterList& printer_list) { + DCHECK(printer_list.empty()); if (printer_map_.empty()) return mojom::ResultCode::kSuccess; @@ -56,7 +56,7 @@ // Can only return basic info for printers which have registered info. if (data->info) - printer_list->emplace_back(*data->info); + printer_list.emplace_back(*data->info); } return mojom::ResultCode::kSuccess; }
diff --git a/printing/backend/test_print_backend.h b/printing/backend/test_print_backend.h index f9dae87..2d493970d 100644 --- a/printing/backend/test_print_backend.h +++ b/printing/backend/test_print_backend.h
@@ -21,7 +21,7 @@ TestPrintBackend(); // PrintBackend overrides - mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) override; + mojom::ResultCode EnumeratePrinters(PrinterList& printer_list) override; mojom::ResultCode GetDefaultPrinterName( std::string& default_printer) override; mojom::ResultCode GetPrinterBasicInfo(
diff --git a/printing/backend/test_print_backend_unittest.cc b/printing/backend/test_print_backend_unittest.cc index df18b87..439c081 100644 --- a/printing/backend/test_print_backend_unittest.cc +++ b/printing/backend/test_print_backend_unittest.cc
@@ -101,7 +101,7 @@ AddPrinters(); - EXPECT_EQ(GetPrintBackend()->EnumeratePrinters(&printer_list), + EXPECT_EQ(GetPrintBackend()->EnumeratePrinters(printer_list), mojom::ResultCode::kSuccess); EXPECT_THAT(printer_list, testing::ContainerEq(kPrinterList)); } @@ -111,7 +111,7 @@ PrinterList printer_list; // Should return true even when there are no printers in the environment. - EXPECT_EQ(GetPrintBackend()->EnumeratePrinters(&printer_list), + EXPECT_EQ(GetPrintBackend()->EnumeratePrinters(printer_list), mojom::ResultCode::kSuccess); EXPECT_TRUE(printer_list.empty()); }
diff --git a/services/cert_verifier/cert_verifier_creation.cc b/services/cert_verifier/cert_verifier_creation.cc index 89af309..77047c6a 100644 --- a/services/cert_verifier/cert_verifier_creation.cc +++ b/services/cert_verifier/cert_verifier_creation.cc
@@ -191,7 +191,17 @@ primary_proc_factory->CreateCertVerifyProc(cert_net_fetcher, root_store_data); -#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) +#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED) && \ + BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) + scoped_refptr<net::CertVerifyProcFactory> trial_proc_factory; + if (net::features::kCertDualVerificationTrialUseCrs.Get()) { + trial_proc_factory = + base::MakeRefCounted<NewCertVerifyProcChromeRootStoreFactory>(); + } else { + trial_proc_factory = + base::MakeRefCounted<NewCertVerifyProcBuiltinFactory>(); + } +#elif BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) auto trial_proc_factory = base::MakeRefCounted<NewCertVerifyProcChromeRootStoreFactory>(); #else
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc index 8ddf6ba9b..d4f63ca 100644 --- a/services/network/cors/cors_url_loader_factory.cc +++ b/services/network/cors/cors_url_loader_factory.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/bind.h" +#include "base/debug/crash_logging.h" #include "base/logging.h" #include "mojo/public/cpp/bindings/message.h" #include "mojo/public/cpp/bindings/remote.h" @@ -250,6 +251,9 @@ mojo::PendingRemote<mojom::URLLoaderClient> client, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { debug::ScopedResourceRequestCrashKeys request_crash_keys(resource_request); + SCOPED_CRASH_KEY_NUMBER("net", "traffic_annotation_hash", + traffic_annotation.unique_id_hash_code); + SCOPED_CRASH_KEY_STRING64("network", "factory_debug_tag", debug_tag_); if (!IsValidRequest(resource_request, options)) { mojo::Remote<mojom::URLLoaderClient>(std::move(client))
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 1c8b786..6b5b62d9 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -327,6 +327,22 @@ ] } ], + "AndroidSearchEnginePromoV2": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SearchEnginePromo.ExistingDeviceVer2", + "SearchEnginePromo.NewDeviceVer2" + ] + } + ] + } + ], "AndroidSystemTracing": [ { "platforms": [ @@ -2691,33 +2707,6 @@ ] } ], - "ContentLanguagesInLanguagePicker": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "EnabledWithoutObservers", - "params": { - "disable_observers": "true" - }, - "enable_features": [ - "ContentLanguagesInLanguagePicker" - ] - }, - { - "name": "EnabledWithObservers", - "params": { - "disable_observers": "false" - }, - "enable_features": [ - "ContentLanguagesInLanguagePicker" - ] - } - ] - } - ], "ContextMenuGoogleLensChip": [ { "platforms": [ @@ -8175,6 +8164,22 @@ ] } ], + "TranslateMessageUI": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ContentLanguagesInLanguagePicker", + "TranslateMessageUI" + ] + } + ] + } + ], "TrustSafetySentimentSurvey": [ { "platforms": [ @@ -8359,6 +8364,25 @@ ] } ], + "UnifiedPasswordManagerDesktop": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UnifiedPasswordManagerDesktop" + ] + } + ] + } + ], "UpdateHistoryEntryPointsInIncognito": [ { "platforms": [
diff --git a/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy b/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy index f0738d7..0a3f4495 100644 --- a/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy +++ b/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
@@ -659,7 +659,7 @@ sb.append(' ignore_aidl = true\n') break case 'androidx_test_uiautomator_uiautomator': - sb.append(' deps = [":androidx_test_runner_java"]\n') + sb.append(' deps += [":androidx_test_runner_java"]\n') break case 'androidx_mediarouter_mediarouter': sb.append(' # https://crbug.com/1000382\n')
diff --git a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc index 1d8035b..cbc5a25 100644 --- a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc +++ b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc
@@ -143,6 +143,10 @@ TRACE_EVENT_FLAG_FLOW_OUT, "metadata", metadata->ToString()); + if (last_delegated_ink_metadata_timestamp_ == metadata->timestamp()) + return; + + last_delegated_ink_metadata_timestamp_ = metadata->timestamp(); Page* page = local_frame_->GetPage(); page->GetChromeClient().SetDelegatedInkMetadata(local_frame_, std::move(metadata));
diff --git a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h index f4ab09c..6c812f6 100644 --- a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h +++ b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_DELEGATED_INK_DELEGATED_INK_TRAIL_PRESENTER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_DELEGATED_INK_DELEGATED_INK_TRAIL_PRESENTER_H_ +#include "base/time/time.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/member.h" @@ -45,6 +46,7 @@ Member<Element> presentation_area_; Member<LocalFrame> local_frame_; uint32_t expected_improvement_; + base::TimeTicks last_delegated_ink_metadata_timestamp_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc index 4f0edb2..5fb6a90c 100644 --- a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc +++ b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc
@@ -183,34 +183,54 @@ return promise; } + MediaStreamComponent* const component = Component(); + DCHECK(component); + + MediaStreamSource* const source = component->Source(); + DCHECK(component->Source()); // We don't currently instantiate BrowserCaptureMediaStreamTrack for audio // tracks. If we do in the future, we'll have to raise an exception if // cropTo() is called on a non-video track. - DCHECK(Component()); - DCHECK(Component()->Source()); - MediaStreamSource* const source = Component()->Source(); DCHECK_EQ(source->GetType(), MediaStreamSource::kTypeVideo); + MediaStreamVideoSource* const native_source = MediaStreamVideoSource::GetVideoSource(source); - DCHECK(native_source); + MediaStreamTrackPlatform* const native_track = + MediaStreamTrackPlatform::GetTrack(WebMediaStreamTrack(component)); + if (!native_source || !native_track) { + // TODO(crbug.com/1266378): Use dedicate UMA values. + RecordUma(CropToResult::kRejectedWithErrorGeneric); + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kUnknownError, "Native/platform track missing.")); + return promise; + } // TODO(crbug.com/1332628): Instead of using GetNextCropVersion(), move the // ownership of the Promises from this->pending_promises_ into native_source. - const absl::optional<uint32_t> crop_version = + const absl::optional<uint32_t> optional_crop_version = native_source->GetNextCropVersion(); - if (!crop_version.has_value()) { + if (!optional_crop_version.has_value()) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kOperationError, "Can't change crop-target while clones exist.")); return promise; } + const uint32_t crop_version = optional_crop_version.value(); - pending_promises_.Set(crop_version.value(), resolver); + pending_promises_.Set(crop_version, + MakeGarbageCollected<CropPromiseInfo>(resolver)); + + // Register for a one-off notification when the first frame cropped + // to the new crop-target is observed. + native_track->AddCropVersionCallback( + crop_version, + WTF::Bind(&BrowserCaptureMediaStreamTrack::OnCropVersionObserved, + WrapWeakPersistent(this), crop_version)); native_source->Crop( - crop_id_token.value(), crop_version.value(), - WTF::Bind(&BrowserCaptureMediaStreamTrack::ResolveCropPromise, - WrapPersistent(this), crop_version.value())); + crop_id_token.value(), crop_version, + WTF::Bind(&BrowserCaptureMediaStreamTrack::OnResultFromBrowserProcess, + WrapWeakPersistent(this), crop_version)); return promise; #endif @@ -232,15 +252,74 @@ } #if !BUILDFLAG(IS_ANDROID) -void BrowserCaptureMediaStreamTrack::ResolveCropPromise( +void BrowserCaptureMediaStreamTrack::OnResultFromBrowserProcess( uint32_t crop_version, media::mojom::CropRequestResult result) { - const auto promise_it = pending_promises_.find(crop_version); - if (promise_it == pending_promises_.end()) { + DCHECK(IsMainThread()); + DCHECK_GT(crop_version, 0u); + + const auto iter = pending_promises_.find(crop_version); + if (iter == pending_promises_.end()) { return; } - ScriptPromiseResolver* const resolver = promise_it->value; - pending_promises_.erase(promise_it); + CropPromiseInfo* const info = iter->value; + + DCHECK(!info->crop_result.has_value()) << "Invoked twice."; + info->crop_result = result; + + MaybeFinalizeCropPromise(iter); +} + +void BrowserCaptureMediaStreamTrack::OnCropVersionObserved( + uint32_t crop_version) { + DCHECK(IsMainThread()); + DCHECK_GT(crop_version, 0u); + + const auto iter = pending_promises_.find(crop_version); + if (iter == pending_promises_.end()) { + return; + } + CropPromiseInfo* const info = iter->value; + + DCHECK(!info->crop_version_observed) << "Invoked twice."; + info->crop_version_observed = true; + + MaybeFinalizeCropPromise(iter); +} + +void BrowserCaptureMediaStreamTrack::MaybeFinalizeCropPromise( + BrowserCaptureMediaStreamTrack::PromiseMapIterator iter) { + DCHECK(IsMainThread()); + DCHECK_NE(iter, pending_promises_.end()); + + CropPromiseInfo* const info = iter->value; + + if (!info->crop_result.has_value()) { + return; + } + + const media::mojom::CropRequestResult result = info->crop_result.value(); + + // Failure can be reported immediately, but success is only reported once + // the new crop-version is observed. + if (result == media::mojom::CropRequestResult::kSuccess && + !info->crop_version_observed) { + return; + } + + // When `result == kSuccess`, the callback will be removed by the track + // itself as it invokes it. For failure, we remove the callback immediately, + // since there's no need to wait. + if (result != media::mojom::CropRequestResult::kSuccess) { + MediaStreamTrackPlatform* const native_track = + MediaStreamTrackPlatform::GetTrack(WebMediaStreamTrack(Component())); + if (native_track) { + native_track->RemoveCropVersionCallback(iter->key); + } + } + + ScriptPromiseResolver* const resolver = info->promise_resolver; + pending_promises_.erase(iter); ResolveCropPromiseHelper(resolver, result); } #endif // !BUILDFLAG(IS_ANDROID)
diff --git a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.h b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.h index 05021fa..452d86a 100644 --- a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.h +++ b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_BROWSER_CAPTURE_MEDIA_STREAM_TRACK_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_BROWSER_CAPTURE_MEDIA_STREAM_TRACK_H_ +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/modules/mediastream/crop_target.h" #include "third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.h" @@ -31,8 +32,16 @@ const String& descriptor_id, bool is_clone = false); + ~BrowserCaptureMediaStreamTrack() override = default; + #if !BUILDFLAG(IS_ANDROID) void Trace(Visitor*) const override; + + // Allows tests to invoke OnCropVersionObserved() directly, since triggering + // it via mocks would be prohibitively difficult. + void OnCropVersionObservedForTesting(uint32_t crop_version) { + OnCropVersionObserved(crop_version); + } #endif ScriptPromise cropTo(ScriptState*, CropTarget*, ExceptionState&); @@ -41,9 +50,48 @@ private: #if !BUILDFLAG(IS_ANDROID) - // Resolves the Promise associated with |crop_version|. - void ResolveCropPromise(uint32_t crop_version, - media::mojom::CropRequestResult result); + struct CropPromiseInfo : GarbageCollected<CropPromiseInfo> { + explicit CropPromiseInfo(ScriptPromiseResolver* promise_resolver) + : promise_resolver(promise_resolver) {} + + void Trace(Visitor* visitor) const { visitor->Trace(promise_resolver); } + + const Member<ScriptPromiseResolver> promise_resolver; + absl::optional<media::mojom::CropRequestResult> crop_result; + bool crop_version_observed = false; + }; + + using CropVersionToPromiseInfoMap = + HeapHashMap<uint32_t, + Member<BrowserCaptureMediaStreamTrack::CropPromiseInfo>>; + using PromiseMapIterator = CropVersionToPromiseInfoMap::iterator; + + // Each cropTo() call is associated with a unique |crop_version| which + // identifies this specific cropTo() invocation. When the browser process + // responds with the result of the cropTo() invocation, it triggers + // a call to OnResultFromBrowserProcess() with that |crop_version|. + void OnResultFromBrowserProcess(uint32_t crop_version, + media::mojom::CropRequestResult result); + + // OnCropVersionObserved() is posted as a callback, bound to a unique + // |crop_version|. This callback be invoked when the first frame is observed + // which is associated with that |crop_version|. + // TODO(crbug.com/1266378): The Promise should also be resolved if a + // a barrier event is observed. (That is, although no frame is delivered, + // there is a guarantee that all future frames will be of this version + // or later. This would happen if cropping a muted track, for instance.) + void OnCropVersionObserved(uint32_t crop_version); + + // The Promise that cropTo() issued is resolved when both conditions + // are fulfulled: + // 1. OnResultFromBrowserProcess(kSuccess) called. + // 2. OnCropVersionObserved() called for the associated |crop_version|. + // + // The order of fulfillment does not matter. + // + // The Promise is rejected if OnResultFromBrowserProcess() is called with + // an error value. + void MaybeFinalizeCropPromise(PromiseMapIterator iter); // Each time cropTo() is called on a given track, its crop version increments. // Associate each Promise with its crop version, so that Viz can easily stamp @@ -54,7 +102,7 @@ // // Note that frames before the first call to cropTo() will be associated // with a version of 0, both here and in Viz. - HeapHashMap<uint32_t, Member<ScriptPromiseResolver>> pending_promises_; + HeapHashMap<uint32_t, Member<CropPromiseInfo>> pending_promises_; #endif // !BUILDFLAG(IS_ANDROID) };
diff --git a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track_test.cc b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track_test.cc index 1d49522..abb11de 100644 --- a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track_test.cc +++ b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track_test.cc
@@ -8,16 +8,22 @@ #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/web/web_heap.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/modules/mediastream/crop_target.h" +#include "third_party/blink/renderer/modules/mediastream/media_stream_video_track.h" #include "third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h" #include "third_party/blink/renderer/platform/region_capture_crop_id.h" +#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" namespace blink { namespace { using ::testing::_; +using ::testing::Args; +using ::testing::Invoke; +using ::testing::Mock; using ::testing::Return; std::unique_ptr<MockMediaStreamVideoSource> MakeMockMediaStreamVideoSource() { @@ -30,12 +36,18 @@ BrowserCaptureMediaStreamTrack* MakeTrack( V8TestingScope& v8_scope, std::unique_ptr<MockMediaStreamVideoSource> media_stream_video_source) { + auto media_stream_video_track = std::make_unique<MediaStreamVideoTrack>( + media_stream_video_source.get(), + WebPlatformMediaStreamSource::ConstraintsOnceCallback(), + /*enabled=*/true); + MediaStreamSource* const source = MakeGarbageCollected<MediaStreamSource>( "id", MediaStreamSource::StreamType::kTypeVideo, "name", /*remote=*/false, std::move(media_stream_video_source)); MediaStreamComponent* const component = - MakeGarbageCollected<MediaStreamComponent>(source); + MakeGarbageCollected<MediaStreamComponent>( + "component_id", source, std::move(media_stream_video_track)); return MakeGarbageCollected<BrowserCaptureMediaStreamTrack>( v8_scope.GetExecutionContext(), component, /*callback=*/base::DoNothing(), @@ -46,13 +58,16 @@ class BrowserCaptureMediaStreamTrackTest : public testing::Test { public: - ~BrowserCaptureMediaStreamTrackTest() override { - WebHeap::CollectAllGarbageForTesting(); - } + ~BrowserCaptureMediaStreamTrackTest() override = default; + + void TearDown() override { WebHeap::CollectAllGarbageForTesting(); } + + protected: + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; }; #if !BUILDFLAG(IS_ANDROID) -TEST_F(BrowserCaptureMediaStreamTrackTest, CropToOnValidId) { +TEST_F(BrowserCaptureMediaStreamTrackTest, CropToOnValidIdResultFirst) { V8TestingScope v8_scope; const base::GUID valid_id = base::GUID::GenerateRandomV4(); @@ -65,7 +80,11 @@ .WillOnce(Return(absl::optional<uint32_t>(1))); EXPECT_CALL(*media_stream_video_source, Crop(GUIDToToken(valid_id), _, _)) - .Times(1); + .Times(1) + .WillOnce(::testing::WithArg<2>(::testing::Invoke( + [](base::OnceCallback<void(media::mojom::CropRequestResult)> cb) { + std::move(cb).Run(media::mojom::CropRequestResult::kSuccess); + }))); BrowserCaptureMediaStreamTrack* const track = MakeTrack(v8_scope, std::move(media_stream_video_source)); @@ -75,6 +94,78 @@ MakeGarbageCollected<CropTarget>( WTF::String(valid_id.AsLowercaseString())), v8_scope.GetExceptionState()); + + track->OnCropVersionObservedForTesting(/*crop_version=*/1); + + ScriptPromiseTester script_promise_tester(v8_scope.GetScriptState(), promise); + script_promise_tester.WaitUntilSettled(); + EXPECT_TRUE(script_promise_tester.IsFulfilled()); +} + +TEST_F(BrowserCaptureMediaStreamTrackTest, + CropToRejectsIfResultFromBrowserProcessIsNotSuccess) { + V8TestingScope v8_scope; + + const base::GUID valid_id = base::GUID::GenerateRandomV4(); + + std::unique_ptr<MockMediaStreamVideoSource> media_stream_video_source = + MakeMockMediaStreamVideoSource(); + + EXPECT_CALL(*media_stream_video_source, GetNextCropVersion) + .Times(1) + .WillOnce(Return(absl::optional<uint32_t>(1))); + + EXPECT_CALL(*media_stream_video_source, Crop(GUIDToToken(valid_id), _, _)) + .Times(1) + .WillOnce(::testing::WithArg<2>(::testing::Invoke( + [](base::OnceCallback<void(media::mojom::CropRequestResult)> cb) { + std::move(cb).Run(media::mojom::CropRequestResult::kErrorGeneric); + }))); + + BrowserCaptureMediaStreamTrack* const track = + MakeTrack(v8_scope, std::move(media_stream_video_source)); + + const ScriptPromise promise = + track->cropTo(v8_scope.GetScriptState(), + MakeGarbageCollected<CropTarget>( + WTF::String(valid_id.AsLowercaseString())), + v8_scope.GetExceptionState()); + + track->OnCropVersionObservedForTesting(/*crop_version=*/1); + + ScriptPromiseTester script_promise_tester(v8_scope.GetScriptState(), promise); + script_promise_tester.WaitUntilSettled(); + EXPECT_TRUE(script_promise_tester.IsRejected()); +} + +TEST_F(BrowserCaptureMediaStreamTrackTest, + CropToRejectsIfSourceReturnsNulloptForNextCropVersion) { + V8TestingScope v8_scope; + + const base::GUID valid_id = base::GUID::GenerateRandomV4(); + + std::unique_ptr<MockMediaStreamVideoSource> media_stream_video_source = + MakeMockMediaStreamVideoSource(); + + EXPECT_CALL(*media_stream_video_source, GetNextCropVersion) + .Times(1) + .WillOnce(Return(absl::nullopt)); + + EXPECT_CALL(*media_stream_video_source, Crop(GUIDToToken(valid_id), _, _)) + .Times(0); + + BrowserCaptureMediaStreamTrack* const track = + MakeTrack(v8_scope, std::move(media_stream_video_source)); + + const ScriptPromise promise = + track->cropTo(v8_scope.GetScriptState(), + MakeGarbageCollected<CropTarget>( + WTF::String(valid_id.AsLowercaseString())), + v8_scope.GetExceptionState()); + + ScriptPromiseTester script_promise_tester(v8_scope.GetScriptState(), promise); + script_promise_tester.WaitUntilSettled(); + EXPECT_TRUE(script_promise_tester.IsRejected()); } #else @@ -97,7 +188,10 @@ MakeGarbageCollected<CropTarget>( WTF::String(valid_id.AsLowercaseString())), v8_scope.GetExceptionState()); - EXPECT_EQ(promise.V8Promise()->State(), v8::Promise::kRejected); + + ScriptPromiseTester script_promise_tester(v8_scope.GetScriptState(), promise); + script_promise_tester.WaitUntilSettled(); + EXPECT_TRUE(script_promise_tester.IsRejected()); } #endif
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc index a48c2c6..61e5294e 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc
@@ -124,6 +124,10 @@ void SetIsRefreshingForMinFrameRate(bool is_refreshing_for_min_frame_rate); + void AddCropVersionCallback(uint32_t crop_version, + base::OnceClosure callback); + void RemoveCropVersionCallback(uint32_t crop_version); + private: friend class WTF::ThreadSafeRefCounted<FrameDeliverer>; virtual ~FrameDeliverer(); @@ -144,6 +148,12 @@ void SetIsRefreshingForMinFrameRateOnIO( bool is_refreshing_for_min_frame_rate); + void AddCropVersionCallbackOnIO(uint32_t crop_version, + WTF::CrossThreadOnceClosure callback); + void RemoveCropVersionCallbackOnIO(uint32_t crop_version); + + void MaybeInvokeNewCropVersionCallbacksOnIO(uint32_t crop_version); + // Returns a black frame where the size and time stamp is set to the same as // as in |reference_frame|. scoped_refptr<media::VideoFrame> GetBlackFrame( @@ -165,6 +175,13 @@ std::pair<VideoSinkId, VideoCaptureDeliverFrameInternalCallback>; Vector<VideoIdCallbackPair> callbacks_; HashMap<VideoSinkId, EncodedVideoFrameInternalCallback> encoded_callbacks_; + + // Callbacks that will be invoked a single time when a crop-version + // is observed that is at least equal to the key. + // The map itself (crop_version_callbacks_) is bound to the IO thread. + // The callbacks are bound to their respective threads (BindPostTask). + HashMap<uint32_t, WTF::CrossThreadOnceClosure> crop_version_callbacks_; + bool await_next_key_frame_; // This should only be accessed on the IO thread. @@ -312,18 +329,76 @@ is_refreshing_for_min_frame_rate)); } +void MediaStreamVideoTrack::FrameDeliverer::AddCropVersionCallback( + uint32_t crop_version, + base::OnceClosure callback) { + DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_); + + PostCrossThreadTask( + *io_task_runner_, FROM_HERE, + CrossThreadBindOnce(&FrameDeliverer::AddCropVersionCallbackOnIO, + WrapRefCounted(this), crop_version, + CrossThreadBindOnce(std::move(callback)))); +} + +void MediaStreamVideoTrack::FrameDeliverer::RemoveCropVersionCallback( + uint32_t crop_version) { + DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_); + + PostCrossThreadTask( + *io_task_runner_, FROM_HERE, + CrossThreadBindOnce(&FrameDeliverer::RemoveCropVersionCallbackOnIO, + WrapRefCounted(this), crop_version)); +} + void MediaStreamVideoTrack::FrameDeliverer::SetIsRefreshingForMinFrameRateOnIO( bool is_refreshing_for_min_frame_rate) { DCHECK(io_task_runner_->BelongsToCurrentThread()); is_refreshing_for_min_frame_rate_ = is_refreshing_for_min_frame_rate; } +void MediaStreamVideoTrack::FrameDeliverer::AddCropVersionCallbackOnIO( + uint32_t crop_version, + WTF::CrossThreadOnceClosure callback) { + DCHECK(io_task_runner_->BelongsToCurrentThread()); + DCHECK(!base::Contains(crop_version_callbacks_, crop_version)); + + crop_version_callbacks_.Set(crop_version, std::move(callback)); +} + +void MediaStreamVideoTrack::FrameDeliverer::RemoveCropVersionCallbackOnIO( + uint32_t crop_version) { + DCHECK(io_task_runner_->BelongsToCurrentThread()); + + // Note: Might or might not be here, depending on whether a later crop + // version has already been observed or not. + crop_version_callbacks_.erase(crop_version); +} + +void MediaStreamVideoTrack::FrameDeliverer:: + MaybeInvokeNewCropVersionCallbacksOnIO(uint32_t crop_version) { + DCHECK(io_task_runner_->BelongsToCurrentThread()); + + Vector<uint32_t> to_be_removed_keys; + for (auto& iter : crop_version_callbacks_) { + if (iter.key > crop_version) { + continue; + } + std::move(iter.value).Run(); + to_be_removed_keys.push_back(iter.key); + } + crop_version_callbacks_.RemoveAll(to_be_removed_keys); +} + void MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO( scoped_refptr<media::VideoFrame> frame, std::vector<scoped_refptr<media::VideoFrame>> scaled_video_frames, base::TimeTicks estimated_capture_time) { DCHECK(io_task_runner_->BelongsToCurrentThread()); - if (!enabled_ && emit_frame_drop_events_) { + + const uint32_t crop_version = frame->metadata().crop_version; + + if (!enabled_ && main_render_task_runner_ && emit_frame_drop_events_) { emit_frame_drop_events_ = false; // TODO(crbug.com/964947): A weak ptr instance of MediaStreamVideoTrack is @@ -359,6 +434,8 @@ CrossThreadBindOnce(&MediaStreamVideoTrack::ResetRefreshTimer, media_stream_video_track_)); } + + MaybeInvokeNewCropVersionCallbacksOnIO(crop_version); } void MediaStreamVideoTrack::FrameDeliverer::DeliverEncodedVideoFrameOnIO( @@ -743,6 +820,21 @@ return capture_handle; } +void MediaStreamVideoTrack::AddCropVersionCallback(uint32_t crop_version, + base::OnceClosure callback) { + DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_); + + frame_deliverer_->AddCropVersionCallback( + crop_version, base::BindPostTask(base::ThreadTaskRunnerHandle::Get(), + std::move(callback))); +} + +void MediaStreamVideoTrack::RemoveCropVersionCallback(uint32_t crop_version) { + DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_); + + frame_deliverer_->RemoveCropVersionCallback(crop_version); +} + void MediaStreamVideoTrack::OnReadyStateChanged( WebMediaStreamSource::ReadyState state) { DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_track.h b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.h index 44b96b4..414b90f 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_video_track.h +++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.h
@@ -88,6 +88,9 @@ void StopAndNotify(base::OnceClosure callback) override; void GetSettings(MediaStreamTrackPlatform::Settings& settings) override; MediaStreamTrackPlatform::CaptureHandle GetCaptureHandle() override; + void AddCropVersionCallback(uint32_t crop_version, + base::OnceClosure callback) override; + void RemoveCropVersionCallback(uint32_t crop_version) override; // Add |sink| to receive state changes on the main render thread and video // frames in the |callback| method on the IO-thread.
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc index b8987384..f799baa 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc +++ b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc
@@ -445,8 +445,8 @@ return WGPUFeatureName_TimestampQuery; case V8GPUFeatureName::Enum::kShaderFloat16: return WGPUFeatureName_DawnShaderFloat16; - case V8GPUFeatureName::Enum::kDepthClamping: - return WGPUFeatureName_DepthClamping; + case V8GPUFeatureName::Enum::kDepthClipControl: + return WGPUFeatureName_DepthClipControl; case V8GPUFeatureName::Enum::kDepth32FloatStencil8: return WGPUFeatureName_Depth32FloatStencil8; case V8GPUFeatureName::Enum::kIndirectFirstInstance:
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc index d0eda40..f2f6de1 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
@@ -59,8 +59,8 @@ case WGPUFeatureName_IndirectFirstInstance: features->AddFeatureName("indirect-first-instance"); break; - case WGPUFeatureName_DepthClamping: - features->AddFeatureName("depth-clamping"); + case WGPUFeatureName_DepthClipControl: + features->AddFeatureName("depth-clip-control"); break; case WGPUFeatureName_DawnShaderFloat16: features->AddFeatureName("shader-float16");
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_primitive_state.idl b/third_party/blink/renderer/modules/webgpu/gpu_primitive_state.idl index 94f3ed2..0ea11b4 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_primitive_state.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_primitive_state.idl
@@ -9,7 +9,7 @@ GPUIndexFormat stripIndexFormat; GPUFrontFace frontFace = "ccw"; GPUCullMode cullMode = "none"; - boolean? clampDepth; + boolean? unclippedDepth; }; enum GPUIndexFormat {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc b/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc index b192b3bd..0adc01b3 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc
@@ -120,13 +120,14 @@ dawn_state->dawn_desc.frontFace = AsDawnEnum(webgpu_desc->frontFace()); dawn_state->dawn_desc.cullMode = AsDawnEnum(webgpu_desc->cullMode()); - if (webgpu_desc->hasClampDepth()) { - auto* clamp_state = &dawn_state->depth_clamping_state; - clamp_state->chain.sType = WGPUSType_PrimitiveDepthClampingState; - clamp_state->clampDepth = webgpu_desc->clampDepth().has_value() && - webgpu_desc->clampDepth().value(); + if (webgpu_desc->hasUnclippedDepth()) { + auto* depth_clip_control = &dawn_state->depth_clip_control; + depth_clip_control->chain.sType = WGPUSType_PrimitiveDepthClipControl; + depth_clip_control->unclippedDepth = + webgpu_desc->unclippedDepth().has_value() && + webgpu_desc->unclippedDepth().value(); dawn_state->dawn_desc.nextInChain = - reinterpret_cast<WGPUChainedStruct*>(clamp_state); + reinterpret_cast<WGPUChainedStruct*>(depth_clip_control); } }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.h b/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.h index 77810221..c644cf2 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.h
@@ -44,7 +44,7 @@ OwnedPrimitiveState& operator=(OwnedPrimitiveState&& desc) = delete; WGPUPrimitiveState dawn_desc = {}; - WGPUPrimitiveDepthClampingState depth_clamping_state = {}; + WGPUPrimitiveDepthClipControl depth_clip_control = {}; }; struct OwnedRenderPipelineDescriptor {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl b/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl index 90ec6fe8e..2679c73 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl
@@ -11,7 +11,7 @@ "texture-compression-astc", "timestamp-query", "shader-float16", - "depth-clamping", + "depth-clip-control", "depth32float-stencil8", "indirect-first-instance", "chromium-experimental-dp4a",
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.cc b/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.cc index fe6f902e..8b6d4c8 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.cc
@@ -30,6 +30,7 @@ X(maxVertexAttributes) \ X(maxVertexBufferArrayStride) \ X(maxInterStageShaderComponents) \ + X(maxColorAttachments) \ X(maxComputeWorkgroupStorageSize) \ X(maxComputeInvocationsPerWorkgroup) \ X(maxComputeWorkgroupSizeX) \
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.h b/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.h index c38550d..b85e795 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.h
@@ -49,6 +49,7 @@ unsigned maxVertexAttributes() const; unsigned maxVertexBufferArrayStride() const; unsigned maxInterStageShaderComponents() const; + unsigned maxColorAttachments() const; unsigned maxComputeWorkgroupStorageSize() const; unsigned maxComputeInvocationsPerWorkgroup() const; unsigned maxComputeWorkgroupSizeX() const;
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.idl b/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.idl index ff64b9a..39d6d6c 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.idl
@@ -28,6 +28,7 @@ readonly attribute unsigned long maxVertexAttributes; readonly attribute unsigned long maxVertexBufferArrayStride; readonly attribute unsigned long maxInterStageShaderComponents; + readonly attribute unsigned long maxColorAttachments; readonly attribute unsigned long maxComputeWorkgroupStorageSize; readonly attribute unsigned long maxComputeInvocationsPerWorkgroup; readonly attribute unsigned long maxComputeWorkgroupSizeX;
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_track_platform.h b/third_party/blink/renderer/platform/mediastream/media_stream_track_platform.h index cc9a4ec..36d8156 100644 --- a/third_party/blink/renderer/platform/mediastream/media_stream_track_platform.h +++ b/third_party/blink/renderer/platform/mediastream/media_stream_track_platform.h
@@ -84,6 +84,14 @@ virtual void GetSettings(Settings& settings) {} virtual CaptureHandle GetCaptureHandle(); + // Adds a one off callback that will be invoked when observing the first frame + // where |metadata.crop_version >= crop_version|. + virtual void AddCropVersionCallback(uint32_t crop_version, + base::OnceClosure callback) {} + + // Removes the callback that was associated with this |crop_version|, if any. + virtual void RemoveCropVersionCallback(uint32_t crop_version) {} + bool is_local_track() const { return is_local_track_; } enum class StreamType { kAudio, kVideo };
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 6ad47e4..93fab66c 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1687,6 +1687,7 @@ crbug.com/1121942 virtual/layout_ng_printing/printing/named-page-breaks.html [ Failure ] crbug.com/1121942 [ Linux ] virtual/layout_ng_printing/printing/overflow-auto.html [ Crash ] crbug.com/1121942 [ Mac11 ] virtual/layout_ng_printing/printing/overflow-auto.html [ Crash ] +crbug.com/1121942 [ Mac12 ] virtual/layout_ng_printing/printing/overflow-auto.html [ Crash ] crbug.com/1121942 [ Win ] virtual/layout_ng_printing/printing/overflow-auto.html [ Crash ] crbug.com/1121942 virtual/layout_ng_printing/printing/page-break-avoid.html [ Failure ] crbug.com/1121942 virtual/layout_ng_printing/printing/page-orientation-propagated.html [ Failure ] @@ -4237,9 +4238,6 @@ crbug.com/709227 external/wpt/html/canvas/offscreen/path-objects/2d.path.stroke.prune.curve.worker.html [ Failure ] crbug.com/709227 external/wpt/html/canvas/offscreen/path-objects/2d.path.stroke.prune.line.worker.html [ Failure ] crbug.com/709227 external/wpt/html/canvas/offscreen/path-objects/2d.path.stroke.prune.rect.worker.html [ Failure ] -crbug.com/709227 external/wpt/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.nonfinite.worker.html [ Failure ] -crbug.com/709227 external/wpt/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonfinite.worker.html [ Failure ] -crbug.com/709227 external/wpt/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.nonfinite.worker.html [ Failure ] # ====== Tests from enabling .any.js/.worker.js tests end here ========
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version index 3d60afd3..04ddc420 100644 --- a/third_party/blink/web_tests/external/Version +++ b/third_party/blink/web_tests/external/Version
@@ -1 +1 @@ -Version: 2a9034c89e115e5bdb8b6d77bf2ca5551acf9873 +Version: a8393d01f484ff9446568c9d25d986221107c9ec
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index d3de8a4..61cb587f 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -318807,7 +318807,7 @@ [] ], "META.yml": [ - "b7e2497681e98960fd00d70ced82aa9e3a48d144", + "e11810cc10fa16774924fe8a8080ab5aae161ac7", [] ], "OWNERS": [
diff --git a/third_party/blink/web_tests/external/wpt/attribution-reporting/resources/reports.py b/third_party/blink/web_tests/external/wpt/attribution-reporting/resources/reports.py index 49305354..4af2b6a 100644 --- a/third_party/blink/web_tests/external/wpt/attribution-reporting/resources/reports.py +++ b/third_party/blink/web_tests/external/wpt/attribution-reporting/resources/reports.py
@@ -16,6 +16,22 @@ CLEAR_STASH = isomorphic_encode("clear_stash") +def decode_headers(headers: dict) -> dict: + """Decodes the headers from wptserve. + + wptserve headers are encoded like + { + encoded(key): [encoded(value1), encoded(value2),...] + } + This method decodes the above using the wptserve.utils.isomorphic_decode + method + """ + return { + isomorphic_decode(key): [isomorphic_decode(el) for el in value + ] for key, value in headers.items() + } + + def handle_post_report(request: Request, headers: List[Header]) -> Response: """Handles POST request for reports. @@ -28,7 +44,11 @@ "code": 200, "message": "Stash successfully cleared.", }) - store_report(request.server.stash, request.body.decode("utf-8")) + store_report( + request.server.stash, { + "body": request.body.decode("utf-8"), + "headers": decode_headers(request.headers) + }) return (201, "OK"), headers, json.dumps({ "code": 201, "message": "Report successfully stored."
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/META.yml b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/META.yml index b7e2497..e11810c 100644 --- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/META.yml +++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/META.yml
@@ -1,4 +1,4 @@ -spec: https://wicg.github.io/largest-contentful-paint/ +spec: https://w3c.github.io/largest-contentful-paint/ suggested_reviewers: - npm1 - yoavweiss
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/resources/helpers.js b/third_party/blink/web_tests/wpt_internal/attribution-reporting/resources/helpers.js index ce96c6a..87cd58b 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/resources/helpers.js +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/resources/helpers.js
@@ -63,3 +63,11 @@ pollAttributionReports(eventLevelReportsUrl, interval); const pollAggregatableReports = interval => pollAttributionReports(aggregatableReportsUrl, interval); + +const validateReportHeaders = headers => { + assert_array_equals(headers['content-type'], ['application/json']); + assert_array_equals(headers['cache-control'], ['no-cache']); + assert_own_property(headers, 'user-agent'); + assert_not_own_property(headers, 'cookie'); + assert_not_own_property(headers, 'referer'); +}
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-aggregatable-report-test.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-aggregatable-report-test.sub.https.html index af4cd12..358d321 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-aggregatable-report-test.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-aggregatable-report-test.sub.https.html
@@ -38,7 +38,8 @@ registerAttributionSrc('Attribution-Reporting-Register-Trigger', trigger); const payload = await pollAggregatableReports(interval); assert_equals(payload.reports.length, 1); - const report = JSON.parse(payload.reports[0]); + const report = JSON.parse(payload.reports[0].body); + const headers = payload.reports[0].headers; assert_own_property(report, 'shared_info'); const shared_info = JSON.parse(report.shared_info); assert_own_property(shared_info, 'api'); @@ -57,5 +58,6 @@ assert_own_property(aggregation_service_payload, 'payload'); assert_own_property(aggregation_service_payload, 'key_id'); assert_not_own_property(aggregation_service_payload, 'debug_cleartext_payload'); + validateReportHeaders(headers); }, 'Ensure aggregatable attribution report is received.'); </script>
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-event-level-report-test.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-event-level-report-test.sub.https.html index cb9f5485..60052daa 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-event-level-report-test.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/simple-event-level-report-test.sub.https.html
@@ -20,7 +20,8 @@ 'Attribution-Reporting-Register-Trigger', trigger); const payload = await pollEventLevelReports(interval); assert_equals(payload.reports.length, 1); - const report = JSON.parse(payload.reports[0]); + const report = JSON.parse(payload.reports[0].body); + const headers = payload.reports[0].headers; // The trigger data is sanitized to "0" because event sources are limited to 1 // bit. assert_equals(report.trigger_data, '0'); @@ -33,5 +34,6 @@ assert_equals(typeof report.report_id, 'string'); assert_not_own_property(report, 'source_debug_key'); assert_not_own_property(report, 'trigger_debug_key'); + validateReportHeaders(headers); }, 'Ensure attribution report is received.'); </script>
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader_test.cc b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader_test.cc index 74a21be..8b7e3ff1 100644 --- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader_test.cc +++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader_test.cc
@@ -460,19 +460,16 @@ test_mach_o_image_annotations_reader.Run(); } -#if defined(ADDRESS_SANITIZER) -// https://crbug.com/844396 -#define MAYBE_CrashModuleInitialization DISABLED_CrashModuleInitialization -#else -#define MAYBE_CrashModuleInitialization CrashModuleInitialization -#endif -TEST(MachOImageAnnotationsReader, MAYBE_CrashModuleInitialization) { +// Flaky on ASAN https://crbug.com/844396 +// Flaky in general https://crbug.com/1334418 +TEST(MachOImageAnnotationsReader, DISABLED_CrashModuleInitialization) { TestMachOImageAnnotationsReader test_mach_o_image_annotations_reader( TestMachOImageAnnotationsReader::kCrashModuleInitialization); test_mach_o_image_annotations_reader.Run(); } -TEST(MachOImageAnnotationsReader, CrashDyld) { +// Flaky in general https://crbug.com/1334418 +TEST(MachOImageAnnotationsReader, DISABLED_CrashDyld) { TestMachOImageAnnotationsReader test_mach_o_image_annotations_reader( TestMachOImageAnnotationsReader::kCrashDyld); test_mach_o_image_annotations_reader.Run();
diff --git a/third_party/wayland-protocols/README.chromium b/third_party/wayland-protocols/README.chromium index 95b22036..67670f6b 100644 --- a/third_party/wayland-protocols/README.chromium +++ b/third_party/wayland-protocols/README.chromium
@@ -9,6 +9,8 @@ wayland-protocols/src contains the official library of Wayland protocol extensions maintained by the developers of the Wayland project. +unstable/ contains unofficial ChromeOS extensions to wayland. + Repository: https://anongit.freedesktop.org/git/wayland/wayland-protocols.git.
diff --git a/tools/fuchsia/size_tests/fyi_sizes_warning.json b/tools/fuchsia/size_tests/fyi_sizes_warning.json index a51f6a3f..ede2e1d 100644 --- a/tools/fuchsia/size_tests/fyi_sizes_warning.json +++ b/tools/fuchsia/size_tests/fyi_sizes_warning.json
@@ -5,6 +5,6 @@ ], "far_total_name" : "chrome_fuchsia", "size_limits" : { - "chrome_fuchsia_compressed": 41718752 + "chrome_fuchsia_compressed": 41906064 } }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index c660588..f10b0dc 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -24230,6 +24230,12 @@ <int value="1" label="New key accelerator is used"/> </enum> +<enum name="DeprecateStylusFeaturesToastEvent"> + <int value="0" label="Features not deprecated, toast not shown"/> + <int value="1" label="Features deprecated, toast shown (first time)"/> + <int value="2" label="Features deprecated, toast not shown (already shown)"/> +</enum> + <enum name="DeskCloseType"> <int value="0" label="Combine desks."/> <int value="1" label="Close all windows"/> @@ -56460,6 +56466,7 @@ <int value="-1092211161" label="BluetoothWbsDogfood:disabled"/> <int value="-1089665395" label="HTMLParamElementUrlSupport:enabled"/> <int value="-1088804127" label="DuetTabStripIntegrationAndroid:disabled"/> + <int value="-1087409065" label="RoundedDisplay:enabled"/> <int value="-1086987072" label="NearbySharingSelfShareAutoAccept:enabled"/> <int value="-1086728979" label="kids-management-url-classification:enabled"/> <int value="-1086656172" @@ -56703,6 +56710,7 @@ <int value="-943304570" label="PaintHolding:enabled"/> <int value="-943223021" label="FeatureNotificationGuideSkipCheckForLowEngagedUsers:disabled"/> + <int value="-940390151" label="RoundedDisplay:disabled"/> <int value="-939676447" label="CrostiniResetLxdDb:enabled"/> <int value="-938178614" label="enable-suggestions-with-substring-match"/> <int value="-937430451" label="IntensiveWakeUpThrottling:disabled"/> @@ -84665,6 +84673,12 @@ <int value="2" label="Gesture Tap"/> </enum> +<enum name="SearchBoxTextMatch"> + <int value="0" label="No Match"/> + <int value="1" label="Prefix Match"/> + <int value="2" label="Substring Match"/> +</enum> + <enum name="SearchEngine"> <obsolete> Deprecated 8/2013. No longer generated. @@ -84808,6 +84822,26 @@ <int value="2" label="Network error"/> </enum> +<enum name="SecureChannelConnectionAttemptFailureReason"> + <int value="0" label="Authentication error"/> + <int value="1" label="Could not generate advertisement"/> + <int value="2" label="GATT connection error"/> + <int value="3" label="Nearby Connections error"/> + <int value="4" label="Local device has invalid public key"/> + <int value="5" label="Local device has invalid psk"/> + <int value="6" label="Local device has invalid bluetooth address"/> + <int value="7" label="Remote device has invalid public key"/> + <int value="8" label="Remote device has invalid psk"/> + <int value="9" label="Remote device has invalid bluetooth address"/> + <int value="10" label="Timeout discovering remote device"/> + <int value="11" label="Bluetoth adapter disabled"/> + <int value="12" label="Bluetooth adapter not available"/> + <int value="13" label="Unsupported connection medium"/> + <int value="14" label="Missing nearby connector"/> + <int value="15" + label="Connection was intentionally cancelled due to a status change"/> +</enum> + <enum name="SecureChannelNearbyConnectionMedium"> <int value="0" label="Connected via Bluetooth"/> <int value="1" label="Upgraded bandwidth to WebRTC"/>
diff --git a/tools/metrics/histograms/metadata/apps/histograms.xml b/tools/metrics/histograms/metadata/apps/histograms.xml index b5aa8a5..41d0675 100644 --- a/tools/metrics/histograms/metadata/apps/histograms.xml +++ b/tools/metrics/histograms/metadata/apps/histograms.xml
@@ -1607,6 +1607,18 @@ </summary> </histogram> +<histogram name="Apps.AppListSearchAutocomplete" enum="SearchBoxTextMatch" + expires_after="2022-12-01"> + <owner>yulunwu@chromium.org</owner> + <owner>tbarzic@chromium.org</owner> + <summary> + The outcome of app list search attempting to autocomplete queries by + matching user entered text with search result text. This metric is split by + prefix match, substring match, and no match. This is gathered each time app + list attempts to perform an autocomplete. + </summary> +</histogram> + <histogram name="Apps.AppListSearchBoxActivated" enum="SearchBoxActivationSource" expires_after="2022-05-01"> <!-- Name completed by histogram_suffixes name="TabletOrClamshellMode" -->
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index f05442a3b..347efd0 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -3665,6 +3665,18 @@ </summary> </histogram> +<histogram name="Ash.Shelf.Palette.Assistant.DeprecateStylusFeaturesToastEvent" + units="dp" expires_after="2022-12-15"> + <owner>angelaxiao@chromium.org</owner> + <owner>assistive-eng@google.com</owner> + <summary> + Whether or not the user is shown the limitation toast notifying that the + Assistant stylus features (i.e. what's on my screen) have been deprecated. + Also considers whether or not the deprecation flag has been set. Recorded + upon every stylus long press action. + </summary> +</histogram> + <histogram name="Ash.Shelf.Palette.Assistant.GestureDuration" units="ms" expires_after="2021-12-12"> <owner>amehfooz@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index 8db3d42..fd651cb 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -5204,7 +5204,7 @@ <histogram name="Eche.Connection.Duration" units="ms" expires_after="2022-10-04"> <owner>samchiu@chromium.org</owner> - <owner>better-together-dev@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> <summary> The duration of time the phone is in the state connected to eche signaling service, and becomes disconnected. @@ -5212,19 +5212,33 @@ </histogram> <histogram name="Eche.Connection.Result" enum="BooleanSuccess" - expires_after="2022-12-04"> + expires_after="2023-06-06"> <owner>samchiu@chromium.org</owner> - <owner>better-together-dev@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> <summary> - Measures Eche connection success rate, considering attempts where the phone - is not nearby as failures. + Measures Eche connection success rate. This is recorded at the end of each + connection attempt whether it fails or succeeds and the failure bucket is + broken down to more specific segments in + Eche.Connection.Result.FailureReason + </summary> +</histogram> + +<histogram name="Eche.Connection.Result.FailureReason" + enum="SecureChannelConnectionAttemptFailureReason" + expires_after="2023-06-06"> + <owner>jonmann@chromium.org</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + The reason for which the connection attempt to the phone has failed. This is + a breakdown of the failure bucket of Eche.Connection.Result and is recorded + at the time a connection attempt fails. </summary> </histogram> <histogram name="Eche.Connectivity.Latency" units="ms" expires_after="2022-12-04"> <owner>samchiu@chromium.org</owner> - <owner>better-together-dev@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> <summary> The duration of time the phone is in the state connecting to eche signaling service, and becomes connected.
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml index 3d15cf4..dbe9b0cd 100644 --- a/tools/metrics/histograms/metadata/password/histograms.xml +++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -161,7 +161,7 @@ </histogram> <histogram name="KeyboardAccessory.DisabledSavingAccessoryImpressions" - enum="BooleanShown" expires_after="M105"> + enum="BooleanShown" expires_after="M108"> <owner>ioanap@chromium.org</owner> <owner>fhorschig@chromium.org</owner> <summary> @@ -174,7 +174,7 @@ </histogram> <histogram name="KeyboardAccessory.GenerationDialogChoice.{GenerationType}" - enum="GenerationDialogChoice" expires_after="M105"> + enum="GenerationDialogChoice" expires_after="M108"> <owner>ioanap@chromium.org</owner> <owner>vasilii@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/phonehub/histograms.xml b/tools/metrics/histograms/metadata/phonehub/histograms.xml index 315b1c3..c4be584 100644 --- a/tools/metrics/histograms/metadata/phonehub/histograms.xml +++ b/tools/metrics/histograms/metadata/phonehub/histograms.xml
@@ -189,7 +189,22 @@ <owner>chromeos-cross-device-eng@google.com</owner> <summary> Measures PhoneHub connection success rate, considering attempts where the - phone is not nearby as failures. + phone is not nearby as failures. This is recorded at the end of each + connection attempt, whether it fails or succeeds and the failures are broken + down into more specific categories in + PhoneHub.Connection.Result.FailureReason + </summary> +</histogram> + +<histogram name="PhoneHub.Connection.Result.FailureReason" + enum="SecureChannelConnectionAttemptFailureReason" + expires_after="2023-02-01"> + <owner>jonmann@chromium.org</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + The reason for which a connection attempt to the phone has failed. This is a + breakdown of the failure bucket of PhoneHub.Connection.Result and is + recorded on each connection failure. </summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/sharing/histograms.xml b/tools/metrics/histograms/metadata/sharing/histograms.xml index 9455f39..24ad5477 100644 --- a/tools/metrics/histograms/metadata/sharing/histograms.xml +++ b/tools/metrics/histograms/metadata/sharing/histograms.xml
@@ -168,7 +168,7 @@ </histogram> <histogram name="Sharing.LongScreenshots.BitmapGenerationStatus" - enum="SharingLongScreenshotsEvent" expires_after="M105"> + enum="SharingLongScreenshotsEvent" expires_after="M107"> <owner>skare@chromium.org</owner> <owner>src/chrome/browser/share/OWNERS</owner> <summary> @@ -179,7 +179,7 @@ </histogram> <histogram name="Sharing.LongScreenshots.BitmapSelectedHeight" units="pixels" - expires_after="M105"> + expires_after="M107"> <owner>skare@chromium.org</owner> <owner>src/chrome/browser/share/OWNERS</owner> <summary> @@ -189,7 +189,7 @@ </histogram> <histogram name="Sharing.LongScreenshots.Event" - enum="SharingLongScreenshotsEvent" expires_after="M105"> + enum="SharingLongScreenshotsEvent" expires_after="M107"> <owner>skare@chromium.org</owner> <owner>src/chrome/browser/share/OWNERS</owner> <summary> @@ -532,7 +532,7 @@ <histogram name="Sharing.SharingHubAndroid.TimeToSaveScreenshotImageBeforeShare" - units="ms" expires_after="M105"> + units="ms" expires_after="M107"> <owner>skare@chromium.org</owner> <owner>src/chrome/browser/share/OWNERS</owner> <summary>
diff --git a/tools/perf/OWNERS b/tools/perf/OWNERS index 1bba60e1..f8c8f72 100644 --- a/tools/perf/OWNERS +++ b/tools/perf/OWNERS
@@ -23,7 +23,6 @@ # Perf bot sheriffs can disable stories. per-file expectations.config=skyostil@chromium.org per-file expectations.config=nuskos@chromium.org -per-file expectations.config=sadrul@chromium.org per-file expectations.config=eseckler@chromium.org # emeritus:
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index d1f9e00..a0d6c2a 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,7 +6,7 @@ }, "win": { "hash": "3df88cdecaaaad7bc0b58d8f90a813352b11f024", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/5fb67c4d2c82a17bf682d715662b4ab3e37116c9/trace_processor_shell.exe" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/f533ef185cb9157bf0046a50b7b23bea3382e5e0/trace_processor_shell.exe" }, "linux_arm": { "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893", @@ -21,8 +21,8 @@ "full_remote_path": "perfetto-luci-artifacts/v25.0/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "d9d4b43a64ed378a237b72ad67c86913f0bce7c7", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/f533ef185cb9157bf0046a50b7b23bea3382e5e0/trace_processor_shell" + "hash": "9a7e89dd21b196a0486e1f1a0e4fb5a028f0e75e", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/aee702e883cb0fd9a087a71b467746f54d68ca53/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/perf/experimental/story_clustering/OWNERS b/tools/perf/experimental/story_clustering/OWNERS index 2b84d944..29a8320 100644 --- a/tools/perf/experimental/story_clustering/OWNERS +++ b/tools/perf/experimental/story_clustering/OWNERS
@@ -1,2 +1 @@ behdadb@chromium.org -sadrul@chromium.org
diff --git a/tools/perf/page_sets/rendering/OWNERS b/tools/perf/page_sets/rendering/OWNERS index e4fed44..a8ec03e 100644 --- a/tools/perf/page_sets/rendering/OWNERS +++ b/tools/perf/page_sets/rendering/OWNERS
@@ -1,2 +1 @@ -sadrul@chromium.org vmiura@chromium.org
diff --git a/ui/aura/test/aura_test_utils.cc b/ui/aura/test/aura_test_utils.cc index cec696d5..4661cb26 100644 --- a/ui/aura/test/aura_test_utils.cc +++ b/ui/aura/test/aura_test_utils.cc
@@ -31,6 +31,10 @@ void disable_ime() { host_->dispatcher_->set_skip_ime(true); } + void OnHostResizedInPixels(const gfx::Size& size_in_pixels) { + host_->OnHostResizedInPixels(size_in_pixels); + } + static const base::flat_set<WindowTreeHost*>& GetThrottledHosts() { return WindowTreeHost::GetThrottledHostsForTesting(); } @@ -62,5 +66,11 @@ return WindowTreeHostTestApi::GetThrottledHosts(); } +void CallOnHostResizedInPixels(WindowTreeHost* host, + const gfx::Size& size_in_pixels) { + WindowTreeHostTestApi host_test_api(host); + host_test_api.OnHostResizedInPixels(size_in_pixels); +} + } // namespace test } // namespace aura
diff --git a/ui/aura/test/aura_test_utils.h b/ui/aura/test/aura_test_utils.h index 0ee880c..1ba81f06 100644 --- a/ui/aura/test/aura_test_utils.h +++ b/ui/aura/test/aura_test_utils.h
@@ -11,6 +11,7 @@ namespace gfx { class Point; +class Size; } namespace aura { @@ -25,6 +26,8 @@ void DisableIME(WindowTreeHost* host); void DisableNativeWindowOcclusionTracking(WindowTreeHost* host); const base::flat_set<WindowTreeHost*>& GetThrottledHosts(); +void CallOnHostResizedInPixels(WindowTreeHost* host, + const gfx::Size& size_in_pixels); } // namespace test } // namespace aura
diff --git a/ui/aura/window_tree_host.cc b/ui/aura/window_tree_host.cc index 19f0865..aa600c7 100644 --- a/ui/aura/window_tree_host.cc +++ b/ui/aura/window_tree_host.cc
@@ -256,7 +256,7 @@ return invert; } -void WindowTreeHost::UpdateCompositorScaleAndSize( +bool WindowTreeHost::UpdateCompositorScaleAndSize( const gfx::Size& new_size_in_pixels) { gfx::Rect new_bounds(new_size_in_pixels); if (compositor_->display_transform_hint() == @@ -265,12 +265,16 @@ gfx::OVERLAY_TRANSFORM_ROTATE_270) { new_bounds.Transpose(); } + bool changed = compositor_->device_scale_factor() != device_scale_factor_ || + compositor_->size() != new_bounds.size(); + // TODO(crbug.com/1329481): Skip updating the compositor if not changed. // Allocate a new LocalSurfaceId for the new size or scale factor. window_->AllocateLocalSurfaceId(); ScopedLocalSurfaceIdValidator lsi_validator(window()); compositor_->SetScaleAndSize(device_scale_factor_, new_bounds.size(), window_->GetLocalSurfaceId()); + return changed; } void WindowTreeHost::ConvertDIPToScreenInPixels(gfx::Point* point) const { @@ -690,10 +694,10 @@ // from GetBoundsInPixels() on Windows to contain extra space for window // transition animations and should be used to set compositor size instead of // GetBoundsInPixels() in such case. - UpdateCompositorScaleAndSize(new_size_in_pixels); - - for (WindowTreeHostObserver& observer : observers_) - observer.OnHostResized(this); + if (UpdateCompositorScaleAndSize(new_size_in_pixels)) { + for (WindowTreeHostObserver& observer : observers_) + observer.OnHostResized(this); + } } void WindowTreeHost::OnHostWorkspaceChanged() {
diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h index e89deeb3..d926669 100644 --- a/ui/aura/window_tree_host.h +++ b/ui/aura/window_tree_host.h
@@ -133,7 +133,8 @@ // Updates the compositor's size and scale from |new_size_in_pixels|, // |device_scale_factor_| and the compositor's transform hint. - void UpdateCompositorScaleAndSize(const gfx::Size& new_size_in_pixels); + // Return false if the compositor already has the same scale factor and size. + bool UpdateCompositorScaleAndSize(const gfx::Size& new_size_in_pixels); // Converts |point| from the root window's coordinate system to native // screen's.
diff --git a/ui/aura/window_tree_host_unittest.cc b/ui/aura/window_tree_host_unittest.cc index 82fddad..ed17825 100644 --- a/ui/aura/window_tree_host_unittest.cc +++ b/ui/aura/window_tree_host_unittest.cc
@@ -15,6 +15,7 @@ #include "ui/aura/test/test_screen.h" #include "ui/aura/test/window_event_dispatcher_test_api.h" #include "ui/aura/window.h" +#include "ui/aura/window_tree_host_observer.h" #include "ui/aura/window_tree_host_platform.h" #include "ui/base/ime/input_method.h" #include "ui/base/ui_base_features.h" @@ -295,6 +296,45 @@ gfx::PointF(5.3f, 0)); } +namespace { + +class TestWindowTreeHostObserver : public WindowTreeHostObserver { + public: + TestWindowTreeHostObserver() = default; + TestWindowTreeHostObserver(const TestWindowTreeHostObserver&) = delete; + TestWindowTreeHostObserver& operator=(const TestWindowTreeHostObserver&) = + delete; + // WndowTreeHostObserver: + ~TestWindowTreeHostObserver() override = default; + void OnHostResized(WindowTreeHost* host) override { resize_notified_ = true; } + + bool resize_notified_and_reset() { + bool r = resize_notified_; + resize_notified_ = false; + return r; + } + + private: + bool resize_notified_ = false; +}; + +} // namespace + +TEST_F(WindowTreeHostTest, DontNotifyWhenNoChange) { + // make sure we're on the same size. + gfx::Size size_px = host()->compositor()->size(); + TestWindowTreeHostObserver observer; + host()->AddObserver(&observer); + test::CallOnHostResizedInPixels(host(), size_px); + EXPECT_FALSE(observer.resize_notified_and_reset()); + test_screen()->SetDeviceScaleFactor(2.0f, /*notify resize=*/true); + EXPECT_TRUE(observer.resize_notified_and_reset()); + // Updating with same scale factor shouldn't notify observers. + test_screen()->SetDeviceScaleFactor(2.0f, /*notify resize=*/true); + EXPECT_FALSE(observer.resize_notified_and_reset()); + host()->RemoveObserver(&observer); +} + class TestWindow : public ui::StubWindow { public: explicit TestWindow(ui::PlatformWindowDelegate* delegate)
diff --git a/ui/chromeos/strings/network_element_localized_strings_provider.cc b/ui/chromeos/strings/network_element_localized_strings_provider.cc index 593e218..8d0f68f 100644 --- a/ui/chromeos/strings/network_element_localized_strings_provider.cc +++ b/ui/chromeos/strings/network_element_localized_strings_provider.cc
@@ -428,6 +428,8 @@ chromeos::features::ShouldUseAttachApn()); html_source->AddBoolean("esimPolicyEnabled", chromeos::features::IsESimPolicyEnabled()); + html_source->AddBoolean("isSimLockPolicyEnabled", + chromeos::features::IsSimLockPolicyEnabled()); } void AddConfigLocalizedStrings(content::WebUIDataSource* html_source) {
diff --git a/ui/gl/direct_composition_surface_win.cc b/ui/gl/direct_composition_surface_win.cc index 480c380..cab0de03 100644 --- a/ui/gl/direct_composition_surface_win.cc +++ b/ui/gl/direct_composition_surface_win.cc
@@ -431,7 +431,7 @@ // EGL_KHR_no_config_context surface compatibility is required to be able to // MakeCurrent with the default pbuffer surface. - if (!display->IsEGLNoConfigContextSupported()) { + if (!display->ext->b_EGL_KHR_no_config_context) { DLOG(ERROR) << "EGL_KHR_no_config_context not supported"; return; }
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py index dfd2196..9970647 100755 --- a/ui/gl/generate_bindings.py +++ b/ui/gl/generate_bindings.py
@@ -2814,18 +2814,23 @@ 'EGL_ANGLE_display_semaphore_share_group', 'EGL_ANGLE_display_texture_share_group', 'EGL_ANGLE_context_virtualization', + 'EGL_ANGLE_create_context_backwards_compatible', 'EGL_ANGLE_create_context_client_arrays', 'EGL_ANGLE_create_context_webgl_compatibility', 'EGL_ANGLE_external_context_and_surface', 'EGL_ANGLE_keyed_mutex', + 'EGL_ANGLE_robust_resource_initialization', 'EGL_ANGLE_surface_orientation', 'EGL_ANGLE_window_fixed_size', + 'EGL_ARM_implicit_external_sync', 'EGL_CHROMIUM_create_context_bind_generates_resource', 'EGL_EXT_create_context_robustness', 'EGL_EXT_gl_colorspace_display_p3', 'EGL_EXT_gl_colorspace_display_p3_passthrough', + 'EGL_EXT_image_dma_buf_import', 'EGL_EXT_pixel_format_float', 'EGL_IMG_context_priority', + 'EGL_KHR_create_context', 'EGL_KHR_gl_colorspace', 'EGL_KHR_no_config_context', 'EGL_KHR_surfaceless_context',
diff --git a/ui/gl/gl_angle_util_vulkan.cc b/ui/gl/gl_angle_util_vulkan.cc index c0099aa..847e477 100644 --- a/ui/gl/gl_angle_util_vulkan.cc +++ b/ui/gl/gl_angle_util_vulkan.cc
@@ -19,7 +19,7 @@ return nullptr; } - if (!gl::GLSurfaceEGL::GetGLDisplayEGL()->IsEGLQueryDeviceSupported()) { + if (!gl::g_driver_egl.client_ext.b_EGL_EXT_device_query) { LOG(ERROR) << "EGL_EXT_device_query not supported"; return nullptr; }
diff --git a/ui/gl/gl_angle_util_win.cc b/ui/gl/gl_angle_util_win.cc index 3427df23..69f460e 100644 --- a/ui/gl/gl_angle_util_win.cc +++ b/ui/gl/gl_angle_util_win.cc
@@ -24,7 +24,7 @@ return nullptr; } - if (!gl::GLSurfaceEGL::GetGLDisplayEGL()->IsEGLQueryDeviceSupported()) { + if (!gl::g_driver_egl.client_ext.b_EGL_EXT_device_query) { DVLOG(1) << "EGL_EXT_device_query not supported"; return nullptr; }
diff --git a/ui/gl/gl_bindings_autogen_egl.cc b/ui/gl/gl_bindings_autogen_egl.cc index 8cbbadd..33bb5b2 100644 --- a/ui/gl/gl_bindings_autogen_egl.cc +++ b/ui/gl/gl_bindings_autogen_egl.cc
@@ -285,6 +285,8 @@ gfx::HasExtension(extensions, "EGL_ANDROID_native_fence_sync"); b_EGL_ANGLE_context_virtualization = gfx::HasExtension(extensions, "EGL_ANGLE_context_virtualization"); + b_EGL_ANGLE_create_context_backwards_compatible = gfx::HasExtension( + extensions, "EGL_ANGLE_create_context_backwards_compatible"); b_EGL_ANGLE_create_context_client_arrays = gfx::HasExtension(extensions, "EGL_ANGLE_create_context_client_arrays"); b_EGL_ANGLE_create_context_webgl_compatibility = gfx::HasExtension( @@ -303,6 +305,8 @@ gfx::HasExtension(extensions, "EGL_ANGLE_power_preference"); b_EGL_ANGLE_query_surface_pointer = gfx::HasExtension(extensions, "EGL_ANGLE_query_surface_pointer"); + b_EGL_ANGLE_robust_resource_initialization = + gfx::HasExtension(extensions, "EGL_ANGLE_robust_resource_initialization"); b_EGL_ANGLE_stream_producer_d3d_texture = gfx::HasExtension(extensions, "EGL_ANGLE_stream_producer_d3d_texture"); b_EGL_ANGLE_surface_d3d_texture_2d_share_handle = gfx::HasExtension( @@ -315,6 +319,8 @@ gfx::HasExtension(extensions, "EGL_ANGLE_vulkan_image"); b_EGL_ANGLE_window_fixed_size = gfx::HasExtension(extensions, "EGL_ANGLE_window_fixed_size"); + b_EGL_ARM_implicit_external_sync = + gfx::HasExtension(extensions, "EGL_ARM_implicit_external_sync"); b_EGL_CHROMIUM_create_context_bind_generates_resource = gfx::HasExtension( extensions, "EGL_CHROMIUM_create_context_bind_generates_resource"); b_EGL_CHROMIUM_sync_control = @@ -325,6 +331,8 @@ gfx::HasExtension(extensions, "EGL_EXT_gl_colorspace_display_p3"); b_EGL_EXT_gl_colorspace_display_p3_passthrough = gfx::HasExtension( extensions, "EGL_EXT_gl_colorspace_display_p3_passthrough"); + b_EGL_EXT_image_dma_buf_import = + gfx::HasExtension(extensions, "EGL_EXT_image_dma_buf_import"); b_EGL_EXT_image_dma_buf_import_modifiers = gfx::HasExtension(extensions, "EGL_EXT_image_dma_buf_import_modifiers"); b_EGL_EXT_image_flush_external = @@ -333,6 +341,8 @@ gfx::HasExtension(extensions, "EGL_EXT_pixel_format_float"); b_EGL_IMG_context_priority = gfx::HasExtension(extensions, "EGL_IMG_context_priority"); + b_EGL_KHR_create_context = + gfx::HasExtension(extensions, "EGL_KHR_create_context"); b_EGL_KHR_fence_sync = gfx::HasExtension(extensions, "EGL_KHR_fence_sync"); b_EGL_KHR_gl_colorspace = gfx::HasExtension(extensions, "EGL_KHR_gl_colorspace");
diff --git a/ui/gl/gl_bindings_autogen_egl.h b/ui/gl/gl_bindings_autogen_egl.h index 5819b20..985e75a 100644 --- a/ui/gl/gl_bindings_autogen_egl.h +++ b/ui/gl/gl_bindings_autogen_egl.h
@@ -347,6 +347,7 @@ bool b_EGL_ANDROID_get_native_client_buffer; bool b_EGL_ANDROID_native_fence_sync; bool b_EGL_ANGLE_context_virtualization; + bool b_EGL_ANGLE_create_context_backwards_compatible; bool b_EGL_ANGLE_create_context_client_arrays; bool b_EGL_ANGLE_create_context_webgl_compatibility; bool b_EGL_ANGLE_d3d_share_handle_client_buffer; @@ -356,21 +357,25 @@ bool b_EGL_ANGLE_keyed_mutex; bool b_EGL_ANGLE_power_preference; bool b_EGL_ANGLE_query_surface_pointer; + bool b_EGL_ANGLE_robust_resource_initialization; bool b_EGL_ANGLE_stream_producer_d3d_texture; bool b_EGL_ANGLE_surface_d3d_texture_2d_share_handle; bool b_EGL_ANGLE_surface_orientation; bool b_EGL_ANGLE_sync_control_rate; bool b_EGL_ANGLE_vulkan_image; bool b_EGL_ANGLE_window_fixed_size; + bool b_EGL_ARM_implicit_external_sync; bool b_EGL_CHROMIUM_create_context_bind_generates_resource; bool b_EGL_CHROMIUM_sync_control; bool b_EGL_EXT_create_context_robustness; bool b_EGL_EXT_gl_colorspace_display_p3; bool b_EGL_EXT_gl_colorspace_display_p3_passthrough; + bool b_EGL_EXT_image_dma_buf_import; bool b_EGL_EXT_image_dma_buf_import_modifiers; bool b_EGL_EXT_image_flush_external; bool b_EGL_EXT_pixel_format_float; bool b_EGL_IMG_context_priority; + bool b_EGL_KHR_create_context; bool b_EGL_KHR_fence_sync; bool b_EGL_KHR_gl_colorspace; bool b_EGL_KHR_gl_texture_2D_image;
diff --git a/ui/gl/gl_context_egl.cc b/ui/gl/gl_context_egl.cc index ef7207b..d210618 100644 --- a/ui/gl/gl_context_egl.cc +++ b/ui/gl/gl_context_egl.cc
@@ -130,7 +130,7 @@ // Always prefer to use EGL_KHR_no_config_context so that all surfaces and // contexts are compatible - if (!gl_display_->IsEGLNoConfigContextSupported()) { + if (!gl_display_->ext->b_EGL_KHR_no_config_context) { config_ = compatible_surface->GetConfig(); EGLint config_renderable_type = 0; if (!eglGetConfigAttrib(gl_display_->GetDisplay(), config_, @@ -158,7 +158,7 @@ // EGL_KHR_create_context allows requesting both a major and minor context // version - if (gl_display_->HasEGLExtension("EGL_KHR_create_context")) { + if (gl_display_->ext->b_EGL_KHR_create_context) { context_attributes.push_back(EGL_CONTEXT_MAJOR_VERSION); context_attributes.push_back(context_client_major_version); @@ -176,7 +176,7 @@ bool is_swangle = IsSoftwareGLImplementation(GetGLImplementationParts()); - if (gl_display_->IsCreateContextRobustnessSupported() || is_swangle) { + if (gl_display_->ext->b_EGL_EXT_create_context_robustness || is_swangle) { DVLOG(1) << "EGL_EXT_create_context_robustness supported."; context_attributes.push_back(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT); context_attributes.push_back( @@ -186,7 +186,7 @@ EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT); context_attributes.push_back(EGL_LOSE_CONTEXT_ON_RESET_EXT); - if (gl_display_->IsRobustnessVideoMemoryPurgeSupported()) { + if (gl_display_->ext->b_EGL_NV_robustness_video_memory_purge) { context_attributes.push_back( EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV); context_attributes.push_back(EGL_TRUE); @@ -204,7 +204,7 @@ return false; } - if (gl_display_->IsCreateContextBindGeneratesResourceSupported()) { + if (gl_display_->ext->b_EGL_CHROMIUM_create_context_bind_generates_resource) { context_attributes.push_back(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM); context_attributes.push_back(attribs.bind_generates_resource ? EGL_TRUE : EGL_FALSE); @@ -212,7 +212,7 @@ DCHECK(attribs.bind_generates_resource); } - if (gl_display_->IsCreateContextWebGLCompatabilitySupported()) { + if (gl_display_->ext->b_EGL_ANGLE_create_context_webgl_compatibility) { context_attributes.push_back(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE); context_attributes.push_back( attribs.webgl_compatibility_context ? EGL_TRUE : EGL_FALSE); @@ -234,7 +234,7 @@ } } - if (gl_display_->IsDisplayTextureShareGroupSupported()) { + if (gl_display_->ext->b_EGL_ANGLE_display_texture_share_group) { context_attributes.push_back(EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE); context_attributes.push_back( attribs.global_texture_share_group ? EGL_TRUE : EGL_FALSE); @@ -242,7 +242,7 @@ DCHECK(!attribs.global_texture_share_group); } - if (gl_display_->IsDisplaySemaphoreShareGroupSupported()) { + if (gl_display_->ext->b_EGL_ANGLE_display_semaphore_share_group) { context_attributes.push_back(EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE); context_attributes.push_back( attribs.global_semaphore_share_group ? EGL_TRUE : EGL_FALSE); @@ -250,13 +250,14 @@ DCHECK(!attribs.global_semaphore_share_group); } - if (gl_display_->IsCreateContextClientArraysSupported()) { + if (gl_display_->ext->b_EGL_ANGLE_create_context_client_arrays) { // Disable client arrays if the context supports it context_attributes.push_back(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE); context_attributes.push_back(EGL_FALSE); } - if (gl_display_->IsRobustResourceInitSupported() || is_swangle) { + if (gl_display_->ext->b_EGL_ANGLE_robust_resource_initialization || + is_swangle) { context_attributes.push_back(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE); context_attributes.push_back( (attribs.robust_resource_initialization || is_swangle) ? EGL_TRUE @@ -265,15 +266,14 @@ DCHECK(!attribs.robust_resource_initialization); } - if (gl_display_->HasEGLExtension( - "EGL_ANGLE_create_context_backwards_compatible")) { + if (gl_display_->ext->b_EGL_ANGLE_create_context_backwards_compatible) { // Request a specific context version. The Passthrough command decoder // relies on the returned context being the exact version it requested. context_attributes.push_back(EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE); context_attributes.push_back(EGL_FALSE); } - if (gl_display_->IsANGLEPowerPreferenceSupported()) { + if (gl_display_->ext->b_EGL_ANGLE_power_preference) { GpuPreference pref = attribs.gpu_preference; pref = GLSurface::AdjustGpuPreference(pref); switch (pref) { @@ -293,7 +293,7 @@ } } - if (gl_display_->IsANGLEExternalContextAndSurfaceSupported()) { + if (gl_display_->ext->b_EGL_ANGLE_external_context_and_surface) { if (attribs.angle_create_from_external_context) { context_attributes.push_back(EGL_EXTERNAL_CONTEXT_ANGLE); context_attributes.push_back(EGL_TRUE); @@ -304,7 +304,7 @@ } } - if (gl_display_->IsANGLEContextVirtualizationSupported()) { + if (gl_display_->ext->b_EGL_ANGLE_context_virtualization) { context_attributes.push_back(EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE); context_attributes.push_back( static_cast<EGLint>(attribs.angle_context_virtualization_group_number)); @@ -322,7 +322,7 @@ // If EGL_KHR_no_config_context is in use and context creation failed, // it might indicate that an unsupported ES version was requested. Try // falling back to a lower version. - if (!context_ && gl_display_->IsEGLNoConfigContextSupported() && + if (!context_ && gl_display_->ext->b_EGL_KHR_no_config_context && eglGetError() == EGL_BAD_MATCH) { // Set up the list of versions to try: 3.1 -> 3.0 -> 2.0 std::vector<std::pair<EGLint, EGLint>> candidate_versions; @@ -395,7 +395,7 @@ } void GLContextEGL::SetVisibility(bool visibility) { - if (gl_display_->IsANGLEPowerPreferenceSupported()) { + if (gl_display_->ext->b_EGL_ANGLE_power_preference) { // It doesn't matter whether this context was explicitly allocated // with a power preference - ANGLE will take care of any default behavior. if (visibility) { @@ -555,7 +555,7 @@ DCHECK(g_current_gl_driver); const ExtensionsGL& ext = g_current_gl_driver->ext; if ((graphics_reset_status_ == GL_NO_ERROR) && - gl_display_->IsCreateContextRobustnessSupported() && + gl_display_->ext->b_EGL_EXT_create_context_robustness && (ext.b_GL_KHR_robustness || ext.b_GL_EXT_robustness || ext.b_GL_ARB_robustness)) { graphics_reset_status_ = glGetGraphicsResetStatusARB();
diff --git a/ui/gl/gl_display.cc b/ui/gl/gl_display.cc index 7ee36c2..92dfb47 100644 --- a/ui/gl/gl_display.cc +++ b/ui/gl/gl_display.cc
@@ -55,32 +55,6 @@ return context ? context->GetGLDisplayEGL() : nullptr; } -bool GLDisplayEGL::HasEGLClientExtension(const char* name) { - if (!egl_client_extensions) - return false; - return GLSurface::ExtensionsContain(egl_client_extensions, name); -} - -bool GLDisplayEGL::HasEGLExtension(const char* name) { - return GLSurface::ExtensionsContain(egl_extensions, name); -} - -bool GLDisplayEGL::IsCreateContextRobustnessSupported() { - return egl_create_context_robustness_supported; -} - -bool GLDisplayEGL::IsRobustnessVideoMemoryPurgeSupported() { - return egl_robustness_video_memory_purge_supported; -} - -bool GLDisplayEGL::IsCreateContextBindGeneratesResourceSupported() { - return egl_create_context_bind_generates_resource_supported; -} - -bool GLDisplayEGL::IsCreateContextWebGLCompatabilitySupported() { - return egl_create_context_webgl_compatability_supported; -} - bool GLDisplayEGL::IsEGLSurfacelessContextSupported() { return egl_surfaceless_context_supported; } @@ -89,66 +63,13 @@ return egl_context_priority_supported; } -bool GLDisplayEGL::IsEGLNoConfigContextSupported() { - return egl_no_config_context_supported; -} - -bool GLDisplayEGL::IsRobustResourceInitSupported() { - return egl_robust_resource_init_supported; -} - -bool GLDisplayEGL::IsDisplayTextureShareGroupSupported() { - return egl_display_texture_share_group_supported; -} - -bool GLDisplayEGL::IsDisplaySemaphoreShareGroupSupported() { - return egl_display_semaphore_share_group_supported; -} - -bool GLDisplayEGL::IsCreateContextClientArraysSupported() { - return egl_create_context_client_arrays_supported; -} - bool GLDisplayEGL::IsAndroidNativeFenceSyncSupported() { return egl_android_native_fence_sync_supported; } -bool GLDisplayEGL::IsPixelFormatFloatSupported() { - return egl_ext_pixel_format_float_supported; -} - -bool GLDisplayEGL::IsANGLEFeatureControlSupported() { - return egl_angle_feature_control_supported; -} - -bool GLDisplayEGL::IsANGLEPowerPreferenceSupported() { - return egl_angle_power_preference_supported; -} - -bool GLDisplayEGL::IsANGLEDisplayPowerPreferenceSupported() { - return egl_angle_display_power_preference_supported; -} - -bool GLDisplayEGL::IsANGLEPlatformANGLEDeviceIdSupported() { - return egl_angle_platform_angle_device_id_supported; -} - bool GLDisplayEGL::IsANGLEExternalContextAndSurfaceSupported() { - return egl_angle_external_context_and_surface_supported; + return this->ext->b_EGL_ANGLE_external_context_and_surface; } - -bool GLDisplayEGL::IsANGLEContextVirtualizationSupported() { - return egl_angle_context_virtualization_supported; -} - -bool GLDisplayEGL::IsANGLEVulkanImageSupported() { - return egl_angle_vulkan_image_supported; -} - -bool GLDisplayEGL::IsEGLQueryDeviceSupported() { - return egl_ext_query_device_supported; -} - #endif // defined(USE_EGL) #if defined(USE_GLX)
diff --git a/ui/gl/gl_display.h b/ui/gl/gl_display.h index 7ce5bec..ef4f069 100644 --- a/ui/gl/gl_display.h +++ b/ui/gl/gl_display.h
@@ -99,64 +99,18 @@ EGLNativeDisplayType GetNativeDisplay(); DisplayType GetDisplayType(); - bool HasEGLClientExtension(const char* name); - bool HasEGLExtension(const char* name); - bool IsCreateContextRobustnessSupported(); - bool IsRobustnessVideoMemoryPurgeSupported(); - bool IsCreateContextBindGeneratesResourceSupported(); - bool IsCreateContextWebGLCompatabilitySupported(); bool IsEGLSurfacelessContextSupported(); bool IsEGLContextPrioritySupported(); - bool IsEGLNoConfigContextSupported(); - bool IsRobustResourceInitSupported(); - bool IsDisplayTextureShareGroupSupported(); - bool IsDisplaySemaphoreShareGroupSupported(); - bool IsCreateContextClientArraysSupported(); bool IsAndroidNativeFenceSyncSupported(); - bool IsPixelFormatFloatSupported(); - bool IsANGLEFeatureControlSupported(); - bool IsANGLEPowerPreferenceSupported(); - bool IsANGLEDisplayPowerPreferenceSupported(); - bool IsANGLEPlatformANGLEDeviceIdSupported(); bool IsANGLEExternalContextAndSurfaceSupported(); - bool IsANGLEContextVirtualizationSupported(); - bool IsANGLEVulkanImageSupported(); - bool IsEGLQueryDeviceSupported(); EGLDisplayPlatform native_display = EGLDisplayPlatform(EGL_DEFAULT_DISPLAY); DisplayType display_type = DisplayType::DEFAULT; - const char* egl_client_extensions = nullptr; - const char* egl_extensions = nullptr; - bool egl_create_context_robustness_supported = false; - bool egl_robustness_video_memory_purge_supported = false; - bool egl_create_context_bind_generates_resource_supported = false; - bool egl_create_context_webgl_compatability_supported = false; - bool egl_sync_control_supported = false; - bool egl_sync_control_rate_supported = false; - bool egl_window_fixed_size_supported = false; bool egl_surfaceless_context_supported = false; - bool egl_surface_orientation_supported = false; bool egl_context_priority_supported = false; - bool egl_khr_colorspace = false; - bool egl_ext_colorspace_display_p3 = false; - bool egl_ext_colorspace_display_p3_passthrough = false; - bool egl_no_config_context_supported = false; - bool egl_robust_resource_init_supported = false; - bool egl_display_texture_share_group_supported = false; - bool egl_display_semaphore_share_group_supported = false; - bool egl_create_context_client_arrays_supported = false; bool egl_android_native_fence_sync_supported = false; - bool egl_ext_pixel_format_float_supported = false; - bool egl_angle_feature_control_supported = false; - bool egl_angle_power_preference_supported = false; - bool egl_angle_display_power_preference_supported = false; - bool egl_angle_platform_angle_device_id_supported = false; - bool egl_angle_external_context_and_surface_supported = false; - bool egl_ext_query_device_supported = false; - bool egl_angle_context_virtualization_supported = false; - bool egl_angle_vulkan_image_supported = false; std::unique_ptr<DisplayExtensionsEGL> ext;
diff --git a/ui/gl/gl_image_native_pixmap.cc b/ui/gl/gl_image_native_pixmap.cc index effe6136..299eb9e3 100644 --- a/ui/gl/gl_image_native_pixmap.cc +++ b/ui/gl/gl_image_native_pixmap.cc
@@ -131,12 +131,10 @@ : GLImageEGL(size), format_(format), plane_(plane), - has_image_flush_external_( - gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( - "EGL_EXT_image_flush_external")), - has_image_dma_buf_export_( - gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( - "EGL_MESA_image_dma_buf_export")) {} + has_image_flush_external_(gl::GLSurfaceEGL::GetGLDisplayEGL() + ->ext->b_EGL_EXT_image_flush_external), + has_image_dma_buf_export_(gl::GLSurfaceEGL::GetGLDisplayEGL() + ->ext->b_EGL_MESA_image_dma_buf_export) {} GLImageNativePixmap::~GLImageNativePixmap() {} @@ -174,8 +172,8 @@ EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT}; bool has_dma_buf_import_modifier = - gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( - "EGL_EXT_image_dma_buf_import_modifiers"); + gl::GLSurfaceEGL::GetGLDisplayEGL() + ->ext->b_EGL_EXT_image_dma_buf_import_modifiers; for (size_t attrs_plane = 0; attrs_plane < pixmap->GetNumberOfPlanes(); ++attrs_plane) {
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc index 9906e709..7a8f3ee 100644 --- a/ui/gl/gl_surface_egl.cc +++ b/ui/gl/gl_surface_egl.cc
@@ -228,7 +228,7 @@ static bool IsSupported(GLDisplayEGL* display) { DCHECK(display); return SyncControlVSyncProvider::IsSupported() && - display->egl_sync_control_supported; + display->ext->b_EGL_CHROMIUM_sync_control; } protected: @@ -249,7 +249,7 @@ } bool GetMscRate(int32_t* numerator, int32_t* denominator) override { - if (!display_->egl_sync_control_rate_supported) { + if (!display_->ext->b_EGL_ANGLE_sync_control_rate) { return false; } @@ -272,7 +272,7 @@ } void OnGpuSwitched(gl::GpuPreference active_gpu_heuristic) override { - DCHECK(display_->IsANGLEPowerPreferenceSupported()); + DCHECK(display_->ext->b_EGL_ANGLE_power_preference); eglHandleGPUSwitchANGLE(display_->GetDisplay()); } @@ -340,7 +340,7 @@ GetAttribArrayFromStringVector(enabled_features); std::vector<const char*> disabled_features_attribs = GetAttribArrayFromStringVector(disabled_features); - if (gl_display->egl_angle_feature_control_supported) { + if (g_driver_egl.client_ext.b_EGL_ANGLE_feature_control) { if (!enabled_features_attribs.empty()) { display_attribs.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE); display_attribs.push_back( @@ -354,7 +354,7 @@ } // TODO(dbehr) Add an attrib to Angle to pass EGL platform. - if (gl_display->IsANGLEDisplayPowerPreferenceSupported()) { + if (g_driver_egl.client_ext.b_EGL_ANGLE_display_power_preference) { GpuPreference pref = GLSurface::AdjustGpuPreference(GpuPreference::kDefault); switch (pref) { @@ -398,7 +398,7 @@ extra_display_attribs.push_back(EGL_TRUE); } if (system_device_id != 0 && - gl_display->IsANGLEPlatformANGLEDeviceIdSupported()) { + g_driver_egl.client_ext.b_EGL_ANGLE_platform_angle_device_id) { uint32_t low_part = system_device_id & 0xffffffff; extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE); extra_display_attribs.push_back(low_part); @@ -1030,34 +1030,6 @@ // static void GLSurfaceEGL::InitializeOneOffCommon(GLDisplayEGL* display) { - display->egl_client_extensions = - eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - display->egl_extensions = - eglQueryString(display->GetDisplay(), EGL_EXTENSIONS); - - display->egl_create_context_robustness_supported = - display->HasEGLExtension("EGL_EXT_create_context_robustness"); - display->egl_robustness_video_memory_purge_supported = - display->HasEGLExtension("EGL_NV_robustness_video_memory_purge"); - display->egl_create_context_bind_generates_resource_supported = - display->HasEGLExtension( - "EGL_CHROMIUM_create_context_bind_generates_resource"); - display->egl_create_context_webgl_compatability_supported = - display->HasEGLExtension("EGL_ANGLE_create_context_webgl_compatibility"); - display->egl_sync_control_supported = - display->HasEGLExtension("EGL_CHROMIUM_sync_control"); - display->egl_sync_control_rate_supported = - display->HasEGLExtension("EGL_ANGLE_sync_control_rate"); - display->egl_window_fixed_size_supported = - display->HasEGLExtension("EGL_ANGLE_window_fixed_size"); - display->egl_surface_orientation_supported = - display->HasEGLExtension("EGL_ANGLE_surface_orientation"); - display->egl_khr_colorspace = - display->HasEGLExtension("EGL_KHR_gl_colorspace"); - display->egl_ext_colorspace_display_p3 = - display->HasEGLExtension("EGL_EXT_gl_colorspace_display_p3"); - display->egl_ext_colorspace_display_p3_passthrough = - display->HasEGLExtension("EGL_EXT_gl_colorspace_display_p3_passthrough"); // According to https://source.android.com/compatibility/android-cdd.html the // EGL_IMG_context_priority extension is mandatory for Virtual Reality High // Performance support, but due to a bug in Android Nougat the extension @@ -1066,27 +1038,13 @@ // that this implies context priority is also supported. See also: // https://github.com/googlevr/gvr-android-sdk/issues/330 display->egl_context_priority_supported = - display->HasEGLExtension("EGL_IMG_context_priority") || - (display->HasEGLExtension("EGL_ANDROID_front_buffer_auto_refresh") && - display->HasEGLExtension("EGL_ANDROID_create_native_client_buffer")); - - // Need EGL_KHR_no_config_context to allow surfaces with and without alpha to - // be bound to the same context. - display->egl_no_config_context_supported = - display->HasEGLExtension("EGL_KHR_no_config_context"); - - display->egl_display_texture_share_group_supported = - display->HasEGLExtension("EGL_ANGLE_display_texture_share_group"); - display->egl_display_semaphore_share_group_supported = - display->HasEGLExtension("EGL_ANGLE_display_semaphore_share_group"); - display->egl_create_context_client_arrays_supported = - display->HasEGLExtension("EGL_ANGLE_create_context_client_arrays"); - display->egl_robust_resource_init_supported = - display->HasEGLExtension("EGL_ANGLE_robust_resource_initialization"); + display->ext->b_EGL_IMG_context_priority || + (display->ext->b_EGL_ANDROID_front_buffer_auto_refresh && + display->ext->b_EGL_ANDROID_create_native_client_buffer); // Check if SurfacelessEGL is supported. display->egl_surfaceless_context_supported = - display->HasEGLExtension("EGL_KHR_surfaceless_context"); + display->ext->b_EGL_KHR_surfaceless_context; // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary // workaround, since code written for Android WebView takes different paths @@ -1098,7 +1056,7 @@ #if BUILDFLAG(IS_ANDROID) // Use the WebGL compatibility extension for detecting ANGLE. ANGLE always // exposes it. - bool is_angle = display->egl_create_context_webgl_compatability_supported; + bool is_angle = display->ext->b_EGL_ANGLE_create_context_webgl_compatibility; if (!is_angle) { display->egl_surfaceless_context_supported = false; } @@ -1133,7 +1091,7 @@ // Android level, update the heuristic to trust the reported extension from // that version onward. display->egl_android_native_fence_sync_supported = - display->HasEGLExtension("EGL_ANDROID_native_fence_sync"); + display->ext->b_EGL_ANDROID_native_fence_sync; #if BUILDFLAG(IS_ANDROID) if (!display->egl_android_native_fence_sync_supported && base::android::BuildInfo::GetInstance()->sdk_int() >= @@ -1145,25 +1103,7 @@ } #endif - display->egl_ext_pixel_format_float_supported = - display->HasEGLExtension("EGL_EXT_pixel_format_float"); - - display->egl_angle_power_preference_supported = - display->HasEGLExtension("EGL_ANGLE_power_preference"); - - display->egl_angle_external_context_and_surface_supported = - display->HasEGLExtension("EGL_ANGLE_external_context_and_surface"); - - display->egl_ext_query_device_supported = - display->HasEGLClientExtension("EGL_EXT_device_query"); - - display->egl_angle_context_virtualization_supported = - display->HasEGLExtension("EGL_ANGLE_context_virtualization"); - - display->egl_angle_vulkan_image_supported = - display->HasEGLExtension("EGL_ANGLE_vulkan_image"); - - if (display->egl_angle_power_preference_supported) { + if (display->ext->b_EGL_ANGLE_power_preference) { g_egl_gpu_switching_observer = new EGLGpuSwitchingObserver(display); ui::GpuSwitchingManager::GetInstance()->AddObserver( g_egl_gpu_switching_observer); @@ -1176,11 +1116,6 @@ if (display->GetDisplay() == EGL_NO_DISPLAY) return false; display->ext->UpdateConditionalExtensionSettings(display); - display->egl_client_extensions = - eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - display->egl_extensions = - eglQueryString(display->GetDisplay(), EGL_EXTENSIONS); - return true; } @@ -1201,21 +1136,9 @@ eglTerminate(display->GetDisplay()); display->SetDisplay(EGL_NO_DISPLAY); - display->egl_client_extensions = nullptr; - display->egl_extensions = nullptr; - display->egl_create_context_robustness_supported = false; - display->egl_robustness_video_memory_purge_supported = false; - display->egl_create_context_bind_generates_resource_supported = false; - display->egl_create_context_webgl_compatability_supported = false; - display->egl_sync_control_supported = false; - display->egl_sync_control_rate_supported = false; - display->egl_window_fixed_size_supported = false; - display->egl_surface_orientation_supported = false; display->egl_surfaceless_context_supported = false; - display->egl_robust_resource_init_supported = false; - display->egl_display_texture_share_group_supported = false; - display->egl_create_context_client_arrays_supported = false; - display->egl_angle_feature_control_supported = false; + display->egl_context_priority_supported = false; + display->egl_android_native_fence_sync_supported = false; } GLSurfaceEGL::~GLSurfaceEGL() = default; @@ -1233,12 +1156,7 @@ gl_display->native_display = native_display; - // If EGL_EXT_client_extensions not supported this call to eglQueryString - // will return nullptr. - gl_display->egl_client_extensions = - eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - - bool supports_egl_debug = gl_display->HasEGLClientExtension("EGL_KHR_debug"); + bool supports_egl_debug = g_driver_egl.client_ext.b_EGL_KHR_debug; if (supports_egl_debug) { EGLAttrib controls[] = { EGL_DEBUG_MSG_CRITICAL_KHR, @@ -1264,36 +1182,27 @@ bool supports_angle_egl = false; bool supports_angle_metal = false; // Check for availability of ANGLE extensions. - if (gl_display->HasEGLClientExtension("EGL_ANGLE_platform_angle")) { - supports_angle_d3d = - gl_display->HasEGLClientExtension("EGL_ANGLE_platform_angle_d3d"); + if (g_driver_egl.client_ext.b_EGL_ANGLE_platform_angle) { + supports_angle_d3d = g_driver_egl.client_ext.b_EGL_ANGLE_platform_angle_d3d; supports_angle_opengl = - gl_display->HasEGLClientExtension("EGL_ANGLE_platform_angle_opengl"); + g_driver_egl.client_ext.b_EGL_ANGLE_platform_angle_opengl; supports_angle_null = - gl_display->HasEGLClientExtension("EGL_ANGLE_platform_angle_null"); + g_driver_egl.client_ext.b_EGL_ANGLE_platform_angle_null; supports_angle_vulkan = - gl_display->HasEGLClientExtension("EGL_ANGLE_platform_angle_vulkan"); - supports_angle_swiftshader = gl_display->HasEGLClientExtension( - "EGL_ANGLE_platform_angle_device_type_swiftshader"); - supports_angle_egl = gl_display->HasEGLClientExtension( - "EGL_ANGLE_platform_angle_device_type_egl_angle"); + g_driver_egl.client_ext.b_EGL_ANGLE_platform_angle_vulkan; + supports_angle_swiftshader = + g_driver_egl.client_ext + .b_EGL_ANGLE_platform_angle_device_type_swiftshader; + supports_angle_egl = g_driver_egl.client_ext + .b_EGL_ANGLE_platform_angle_device_type_egl_angle; supports_angle_metal = - gl_display->HasEGLClientExtension("EGL_ANGLE_platform_angle_metal"); + g_driver_egl.client_ext.b_EGL_ANGLE_platform_angle_metal; } bool supports_angle = supports_angle_d3d || supports_angle_opengl || supports_angle_null || supports_angle_vulkan || supports_angle_swiftshader || supports_angle_metal; - gl_display->egl_angle_feature_control_supported = - gl_display->HasEGLClientExtension("EGL_ANGLE_feature_control"); - - gl_display->egl_angle_display_power_preference_supported = - gl_display->HasEGLClientExtension("EGL_ANGLE_display_power_preference"); - - gl_display->egl_angle_platform_angle_device_id_supported = - gl_display->HasEGLClientExtension("EGL_ANGLE_platform_angle_device_id"); - std::vector<DisplayType> init_displays; base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); GetEGLInitDisplays(supports_angle_d3d, supports_angle_opengl, @@ -1408,7 +1317,8 @@ std::vector<EGLint> egl_window_attributes; - if (display_->egl_window_fixed_size_supported && enable_fixed_size_angle_) { + if (display_->ext->b_EGL_ANGLE_window_fixed_size && + enable_fixed_size_angle_) { egl_window_attributes.push_back(EGL_FIXED_SIZE_ANGLE); egl_window_attributes.push_back(EGL_TRUE); egl_window_attributes.push_back(EGL_WIDTH); @@ -1422,7 +1332,7 @@ egl_window_attributes.push_back(EGL_TRUE); } - if (display_->egl_surface_orientation_supported) { + if (display_->ext->b_EGL_ANGLE_surface_orientation) { EGLint attrib; eglGetConfigAttrib(display_->GetDisplay(), GetConfig(), EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE, &attrib); @@ -1443,7 +1353,7 @@ // Note that COLORSPACE_LINEAR refers to the sRGB color space, but // without opting into sRGB blending. It is equivalent to // COLORSPACE_SRGB with Disable(FRAMEBUFFER_SRGB). - if (display_->egl_khr_colorspace) { + if (display_->ext->b_EGL_KHR_gl_colorspace) { egl_window_attributes.push_back(EGL_GL_COLORSPACE_KHR); egl_window_attributes.push_back(EGL_GL_COLORSPACE_LINEAR_KHR); } @@ -1457,15 +1367,16 @@ // with the P3 gamut instead of the the sRGB gamut. // COLORSPACE_DISPLAY_P3_LINEAR has a linear transfer function, and is // intended for use with 16-bit formats. - bool p3_supported = display_->egl_ext_colorspace_display_p3 || - display_->egl_ext_colorspace_display_p3_passthrough; - if (display_->egl_khr_colorspace && p3_supported) { + bool p3_supported = + display_->ext->b_EGL_EXT_gl_colorspace_display_p3 || + display_->ext->b_EGL_EXT_gl_colorspace_display_p3_passthrough; + if (display_->ext->b_EGL_KHR_gl_colorspace && p3_supported) { egl_window_attributes.push_back(EGL_GL_COLORSPACE_KHR); // Chrome relied on incorrect Android behavior when dealing with P3 / // framebuffer_srgb interactions. This behavior was fixed in Q, which // causes invalid Chrome rendering. To achieve Android-P behavior in Q+, // use EGL_GL_COLORSPACE_P3_PASSTHROUGH_EXT where possible. - if (display_->egl_ext_colorspace_display_p3_passthrough) { + if (display_->ext->b_EGL_EXT_gl_colorspace_display_p3_passthrough) { egl_window_attributes.push_back( EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT); } else { @@ -2091,7 +2002,7 @@ // Enable robust resource init when using SwANGLE if (IsSoftwareGLImplementation(GetGLImplementationParts()) && - display_->IsRobustResourceInitSupported()) { + display_->ext->b_EGL_ANGLE_robust_resource_initialization) { pbuffer_attribs.push_back(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE); pbuffer_attribs.push_back(EGL_TRUE); }
diff --git a/ui/gl/gl_utils.cc b/ui/gl/gl_utils.cc index c98a7cd..dffa2e5 100644 --- a/ui/gl/gl_utils.cc +++ b/ui/gl/gl_utils.cc
@@ -104,11 +104,11 @@ GLDisplayEGL* display = gl::GLSurfaceEGL::GetGLDisplayEGL(); // Using the passthrough command buffer requires that specific ANGLE // extensions are exposed - return display->IsCreateContextBindGeneratesResourceSupported() && - display->IsCreateContextWebGLCompatabilitySupported() && - display->IsRobustResourceInitSupported() && - display->IsDisplayTextureShareGroupSupported() && - display->IsCreateContextClientArraysSupported(); + return display->ext->b_EGL_CHROMIUM_create_context_bind_generates_resource && + display->ext->b_EGL_ANGLE_create_context_webgl_compatibility && + display->ext->b_EGL_ANGLE_robust_resource_initialization && + display->ext->b_EGL_ANGLE_display_texture_share_group && + display->ext->b_EGL_ANGLE_create_context_client_arrays; #else // The passthrough command buffer is only supported on top of ANGLE/EGL return false;
diff --git a/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc b/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc index 43cb0c2..60b3bfa 100644 --- a/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc +++ b/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc
@@ -45,9 +45,9 @@ window_(std::move(window)), widget_(widget), has_implicit_external_sync_( - GetGLDisplayEGL()->HasEGLExtension("EGL_ARM_implicit_external_sync")), + GetGLDisplayEGL()->ext->b_EGL_ARM_implicit_external_sync), has_image_flush_external_( - GetGLDisplayEGL()->HasEGLExtension("EGL_EXT_image_flush_external")) { + GetGLDisplayEGL()->ext->b_EGL_EXT_image_flush_external) { surface_factory_->RegisterSurface(window_->widget(), this); supports_plane_gpu_fences_ = window_->SupportsGpuFences(); unsubmitted_frames_.push_back(std::make_unique<PendingFrame>());
diff --git a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc index ebaf402..ae16deb 100644 --- a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc +++ b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
@@ -16,6 +16,7 @@ #include "ui/gfx/geometry/rrect_f.h" #include "ui/gfx/linux/drm_util_linux.h" #include "ui/gfx/overlay_priority_hint.h" +#include "ui/gl/gl_bindings.h" #include "ui/gl/gl_surface_egl.h" #include "ui/ozone/platform/wayland/common/wayland_overlay_config.h" #include "ui/ozone/platform/wayland/gpu/wayland_surface_gpu.h" @@ -297,10 +298,9 @@ #if defined(WAYLAND_GBM) GbmDevice* WaylandBufferManagerGpu::GetGbmDevice() { // Wayland won't support wl_drm or zwp_linux_dmabuf without this extension. - if (!supports_dmabuf_ || - (!gl::GLSurfaceEGL::GetGLDisplayEGL()->HasEGLExtension( - "EGL_EXT_image_dma_buf_import") && - !use_fake_gbm_device_for_test_)) { + if (!supports_dmabuf_ || (!gl::GLSurfaceEGL::GetGLDisplayEGL() + ->ext->b_EGL_EXT_image_dma_buf_import && + !use_fake_gbm_device_for_test_)) { supports_dmabuf_ = false; return nullptr; }
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html index eb6bfd8..34c7abb 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html +++ b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html
@@ -67,7 +67,8 @@ </div> </div> <cr-button id="changePinButton" on-click="onChangePinTap_" - hidden$="[[!showChangePinButton_(deviceState, isActiveSim_)]]" + hidden$="[[!showChangePinButton_(deviceState, isActiveSim_, + isSimPinLockRestricted_)]]" disabled="[[disabled]]"> [[i18n('networkSimChangePin')]] </cr-button> @@ -82,7 +83,8 @@ <div class="separator"></div> </template> <cr-toggle id="simLockButton" - disabled="[[isSimLockButtonDisabled_(disabled, isActiveSim_)]]" + disabled="[[isSimLockButtonDisabled_(disabled, isActiveSim_, + isSimPinLockRestricted_, lockEnabled_)]]" on-change="onSimLockEnabledChange_" checked="{{lockEnabled_}}" aria-labelledby="pinRequiredLabel pinRequiredSublabel"> </cr-toggle>
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js index 88c34eb..76bcb6e 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js +++ b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js
@@ -42,6 +42,9 @@ value: null, }, + /** @type {!chromeos.networkConfig.mojom.GlobalPolicy|undefined} */ + globalPolicy: Object, + disabled: { type: Boolean, value: false, @@ -96,6 +99,23 @@ computed: 'computeState_(networkState, deviceState, deviceState.*,' + 'isActiveSim_)', }, + + /** @private {boolean} */ + isSimLockPolicyEnabled_: { + type: Boolean, + value() { + return loadTimeData.valueExists('isSimLockPolicyEnabled') && + loadTimeData.getBoolean('isSimLockPolicyEnabled'); + } + }, + + /** @private {boolean} */ + isSimPinLockRestricted_: { + type: Boolean, + value: false, + computed: 'computeIsSimPinLockRestricted_(isSimLockPolicyEnabled_,' + + 'globalPolicy, globalPolicy.*, lockEnabled_)', + }, }, /** @private {boolean|undefined} */ @@ -250,6 +270,10 @@ * @private */ showChangePinButton_() { + if (this.isSimPinLockRestricted_) { + return false; + } + if (!this.deviceState || !this.deviceState.simLockStatus) { return false; } @@ -262,6 +286,12 @@ * @private */ isSimLockButtonDisabled_() { + // If SIM PIN locking is restricted by admin, and the SIM does not have SIM + // PIN lock enabled, users should not be able to enable PIN locking. + if (this.isSimPinLockRestricted_ && !this.lockEnabled_) { + return true; + } + return this.disabled || !this.isActiveSim_; }, @@ -286,6 +316,15 @@ }, /** + * @return {boolean} + * @private + */ + computeIsSimPinLockRestricted_() { + return this.isSimLockPolicyEnabled_ && !!this.globalPolicy && + !this.globalPolicy.allowCellularSimLock; + }, + + /** * @param {!State} state1 * @param {!State} state2 * @return {boolean} Whether state1 is the same as state2.