diff --git a/DEPS b/DEPS index 68dfcd1..73abc78 100644 --- a/DEPS +++ b/DEPS
@@ -199,11 +199,11 @@ # 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': 'd12c91ba318b6d6bc62411a754fdc33baca2e92e', + 'skia_revision': 'caca7bfff996b38ee6bb6413eb5ca62b0c9a380f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '711cf5ad4a12abe0f6b50058cb2248d7fb80374e', + 'v8_revision': 'c1afed6d5ce09f38a9eb7f39b34b4c087cd80503', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -211,7 +211,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': 'cde0e3ab3d710ca9838d226873462c5f093f60bd', + 'angle_revision': '5e606e5bfce2b23c139c5289cbf1299844fa4b43', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -274,7 +274,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': 'b4a82aa3575f22267816d59a3af93f22ddb80bea', + 'devtools_frontend_revision': '8793dbe78e44bc6eeceaed0cc8cf0e542d6efd4a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -314,7 +314,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '700809a7f75bab9df6d1195153ea1cbfb078046c', + 'dawn_revision': 'c8d5277e86ee8c51b1dd7892b41e83eb26ac2ede', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -553,7 +553,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '4b7c446e7e14b43202421311894e388b18df6650', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '8bd8b295e227310a8c835ec9d3f58ca3b651319a', 'condition': 'checkout_ios', }, @@ -873,7 +873,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'a281380c8e264cad58769385a9fc5fcff99be110', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '7a1af10b707bf9939fbe63abf0f2b305ae55dc4c', 'condition': 'checkout_chromeos', }, @@ -893,7 +893,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '67e12286df04ef0eeec3aeaf6f224d2fe11751b7', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '46ef281c525f704bb9445142e9e4d70dacae7d4d', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1514,7 +1514,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '3c2fe3888658d82b47ca831d59a2e07579619c2d', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'fec83cc8602580ce1c078f7cd4e7f4d2be4ac850', + Var('webrtc_git') + '/src.git' + '@' + 'a45df0b3491ea72cfcf40e21106eb046c8594223', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1586,7 +1586,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@a437db8d0e0716d8b3c34bb11c9e50eea530a7b6', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3a0cc86fe501ebb245b7d6191903579a2a7c40fe', 'condition': 'checkout_src_internal', }, @@ -1594,7 +1594,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'MIvUdF0qcP07nO7qcpskiwhrIY76sEXm3cja55KTAs4C', + 'version': 'qJhtBw7ouc--Fdht1yXy9-ZDPYguiqAZbixcf8MasiwC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1605,7 +1605,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'lSR2dtMxiibk0G8cpsbKHgxUhPJId7kspY1yn5iOeZEC', + 'version': 'RYs0dVeLJjwsPik_WXMr4pMuzN55DAmi4gfQCMX-evUC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/browser/tracing/aw_tracing_delegate.cc b/android_webview/browser/tracing/aw_tracing_delegate.cc index 652c4960..3084412 100644 --- a/android_webview/browser/tracing/aw_tracing_delegate.cc +++ b/android_webview/browser/tracing/aw_tracing_delegate.cc
@@ -33,7 +33,8 @@ bool AwTracingDelegate::IsAllowedToEndBackgroundScenario( const content::BackgroundTracingConfig& config, - bool requires_anonymized_data) { + bool requires_anonymized_data, + bool is_crash_scenario) { // Background tracing is allowed in general and can be restricted when // configuring BackgroundTracingManager. return true;
diff --git a/android_webview/browser/tracing/aw_tracing_delegate.h b/android_webview/browser/tracing/aw_tracing_delegate.h index 74d118b..fd76f6b4 100644 --- a/android_webview/browser/tracing/aw_tracing_delegate.h +++ b/android_webview/browser/tracing/aw_tracing_delegate.h
@@ -28,7 +28,8 @@ bool requires_anonymized_data) override; bool IsAllowedToEndBackgroundScenario( const content::BackgroundTracingConfig& config, - bool requires_anonymized_data) override; + bool requires_anonymized_data, + bool is_crash_scenario) override; std::unique_ptr<base::DictionaryValue> GenerateMetadataDict() override; };
diff --git a/ash/system/holding_space/holding_space_item_views_section.cc b/ash/system/holding_space/holding_space_item_views_section.cc index e5fc23d3..6e7cbcf 100644 --- a/ash/system/holding_space/holding_space_item_views_section.cc +++ b/ash/system/holding_space/holding_space_item_views_section.cc
@@ -26,10 +26,6 @@ base::TimeDelta::FromMilliseconds(167); constexpr SkScalar kAnimationTranslationY = 20; -// Value returned during notification of animation completion events in order to -// delete the observer which provided notification. -constexpr bool kDeleteObserver = true; - // Helpers --------------------------------------------------------------------- // Initializes the layer for the specified `view` for animations. @@ -105,6 +101,24 @@ observer); } +// Returns a callback which deletes the associated animation observer after +// running another `callback`. +using AnimationCompletedCallback = + base::OnceCallback<void(const ui::CallbackLayerAnimationObserver&)>; +base::RepeatingCallback<bool(const ui::CallbackLayerAnimationObserver&)> +DeleteObserverAfterRunning(AnimationCompletedCallback callback) { + return base::BindRepeating( + [](AnimationCompletedCallback callback, + const ui::CallbackLayerAnimationObserver& observer) { + // NOTE: It's safe to move `callback` since this code will only run + // once due to deletion of the associated `observer`. The `observer` is + // deleted by returning `true`. + std::move(callback).Run(observer); + return true; + }, + base::Passed(std::move(callback))); +} + // HoldingSpaceScrollView ------------------------------------------------------ class HoldingSpaceScrollView : public views::ScrollView, @@ -340,9 +354,9 @@ // NOTE: `animate_in_observer` is deleted after `OnAnimateInCompleted()`. ui::CallbackLayerAnimationObserver* animate_in_observer = - new ui::CallbackLayerAnimationObserver(base::BindRepeating( - &HoldingSpaceItemViewsSection::OnAnimateInCompleted, - base::Unretained(this))); + new ui::CallbackLayerAnimationObserver(DeleteObserverAfterRunning( + base::BindOnce(&HoldingSpaceItemViewsSection::OnAnimateInCompleted, + weak_factory_.GetWeakPtr()))); AnimateIn(animate_in_observer); animate_in_observer->SetActive(); @@ -361,9 +375,9 @@ // NOTE: `animate_out_observer` is deleted after `OnAnimateOutCompleted()`. ui::CallbackLayerAnimationObserver* animate_out_observer = - new ui::CallbackLayerAnimationObserver(base::BindRepeating( - &HoldingSpaceItemViewsSection::OnAnimateOutCompleted, - base::Unretained(this))); + new ui::CallbackLayerAnimationObserver(DeleteObserverAfterRunning( + base::BindOnce(&HoldingSpaceItemViewsSection::OnAnimateOutCompleted, + weak_factory_.GetWeakPtr()))); AnimateOut(animate_out_observer); animate_out_observer->SetActive(); @@ -394,13 +408,13 @@ DoAnimateOut(container_, animation_duration, observer); } -bool HoldingSpaceItemViewsSection::OnAnimateInCompleted( +void HoldingSpaceItemViewsSection::OnAnimateInCompleted( const ui::CallbackLayerAnimationObserver& observer) { DCHECK(animation_state_ & AnimationState::kAnimatingIn); animation_state_ &= ~AnimationState::kAnimatingIn; if (observer.aborted_count()) - return kDeleteObserver; + return; DCHECK_EQ(animation_state_, AnimationState::kNotAnimating); @@ -408,17 +422,15 @@ // that have been animated in should all be associated with holding space // items that exist in the model. SetCanProcessEventsWithinSubtree(true); - - return kDeleteObserver; } -bool HoldingSpaceItemViewsSection::OnAnimateOutCompleted( +void HoldingSpaceItemViewsSection::OnAnimateOutCompleted( const ui::CallbackLayerAnimationObserver& observer) { DCHECK(animation_state_ & AnimationState::kAnimatingOut); animation_state_ &= ~AnimationState::kAnimatingOut; if (observer.aborted_count()) - return kDeleteObserver; + return; DCHECK_EQ(animation_state_, AnimationState::kNotAnimating); @@ -437,7 +449,7 @@ HoldingSpaceModel* model = HoldingSpaceController::Get()->model(); if (!model) - return kDeleteObserver; + return; for (const auto& item : model->items()) { if (item->IsFinalized() && base::Contains(supported_types_, item->type())) { @@ -457,8 +469,6 @@ } MaybeAnimateIn(); - - return kDeleteObserver; } } // namespace ash
diff --git a/ash/system/holding_space/holding_space_item_views_section.h b/ash/system/holding_space/holding_space_item_views_section.h index 9b7d430..bfe6c20 100644 --- a/ash/system/holding_space/holding_space_item_views_section.h +++ b/ash/system/holding_space/holding_space_item_views_section.h
@@ -115,10 +115,9 @@ void AnimateOut(ui::LayerAnimationObserver* observer); // Invoked when an animate in/out of the contents of this section has been - // completed. These methods always return true to delete the observer which - // notified the event. - bool OnAnimateInCompleted(const ui::CallbackLayerAnimationObserver&); - bool OnAnimateOutCompleted(const ui::CallbackLayerAnimationObserver&); + // completed. Note that the provided observer will be deleted after returning. + void OnAnimateInCompleted(const ui::CallbackLayerAnimationObserver&); + void OnAnimateOutCompleted(const ui::CallbackLayerAnimationObserver&); HoldingSpaceItemViewDelegate* const delegate_; const std::vector<HoldingSpaceItem::Type> supported_types_; @@ -142,8 +141,11 @@ base::ScopedObservation<HoldingSpaceController, HoldingSpaceControllerObserver> controller_observer_{this}; + base::ScopedObservation<HoldingSpaceModel, HoldingSpaceModelObserver> model_observer_{this}; + + base::WeakPtrFactory<HoldingSpaceItemViewsSection> weak_factory_{this}; }; } // namespace ash
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 0d41908..6966cd4 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20201223.3.1 +0.20201225.3.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 0d41908..6966cd4 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20201223.3.1 +0.20201225.3.1
diff --git a/chrome/VERSION b/chrome/VERSION index f40dde32..15fb5e2b 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=89 MINOR=0 -BUILD=4367 +BUILD=4369 PATCH=0
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java index b056cff..83a3c141 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java
@@ -12,6 +12,7 @@ import static org.chromium.base.test.util.CriteriaHelper.DEFAULT_POLLING_INTERVAL; import static org.chromium.components.embedder_support.util.UrlConstants.NTP_URL; +import android.os.Build.VERSION_CODES; import android.support.test.InstrumentationRegistry; import androidx.annotation.Nullable; @@ -30,6 +31,7 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; +import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.EnormousTest; import org.chromium.base.test.util.FlakyTest; @@ -133,7 +135,10 @@ @Test @EnormousTest @CommandLineFlags.Add({BASE_PARAMS + "/soft-cleanup-delay/10000/cleanup-delay/10000"}) - public void testTabToGridFromLiveTabWith10TabsWarm() throws InterruptedException { + @DisableIf.Build(message = "Flaky on Android P, see https://crbug.com/1161731", + sdk_is_greater_than = VERSION_CODES.O_MR1, sdk_is_less_than = VERSION_CODES.Q) + public void + testTabToGridFromLiveTabWith10TabsWarm() throws InterruptedException { prepareTabs(10, NTP_URL); reportTabToGridPerf(mUrl, "Tab-to-Grid from live tab with 10 tabs (warm)"); } @@ -339,7 +344,10 @@ @Test @EnormousTest @CommandLineFlags.Add({BASE_PARAMS}) - public void testGridToTabToOtherFrozen() throws InterruptedException { + @DisableIf.Build(message = "Flaky on Android P, see https://crbug.com/1161731", + sdk_is_greater_than = VERSION_CODES.O_MR1, sdk_is_less_than = VERSION_CODES.Q) + public void + testGridToTabToOtherFrozen() throws InterruptedException { prepareTabs(2, mUrl); reportGridToTabPerf(true, true, "Grid-to-Tab to other frozen tab"); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java index 4a25aca..7d9d6df 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java
@@ -797,12 +797,13 @@ // SignOutDialogListener implementation: @Override public void onSignOutClicked(boolean forceWipeUserData) { + final Profile profile = Profile.getLastUsedRegularProfile(); // In case sign-out happened while the dialog was displayed, we guard the sign out so // we do not hit a native crash. - if (!IdentityServicesProvider.get().getIdentityManager().hasPrimaryAccount()) return; + if (!IdentityServicesProvider.get().getIdentityManager(profile).hasPrimaryAccount()) return; final DialogFragment clearDataProgressDialog = new ClearDataProgressDialog(); - IdentityServicesProvider.get().getSigninManager().signOut( + IdentityServicesProvider.get().getSigninManager(profile).signOut( SignoutReason.USER_CLICKED_SIGNOUT_SETTINGS, new SigninManager.SignOutCallback() { @Override public void preWipeData() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/read_later/ReadLaterIphTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/read_later/ReadLaterIphTest.java index 55c0da4..5c3e77e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/read_later/ReadLaterIphTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/read_later/ReadLaterIphTest.java
@@ -41,7 +41,7 @@ import org.chromium.base.Callback; import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.FlakyTest; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.R; import org.chromium.chrome.browser.app.ChromeActivity; @@ -123,7 +123,7 @@ @Test @MediumTest @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) - @FlakyTest(message = "https://crbug.com/1155085") + @DisabledTest(message = "Flaky test, see https://crbug.com/1161737, https://crbug.com/1155085") public void testShowBookmarksReadLaterIPH() throws Throwable { mActivityTestRule.loadUrl(mTestServer.getServer().getURL(CONTEXT_MENU_TEST_URL)); ChromeActivity activity = mActivityTestRule.getActivity();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/UkmTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/UkmTest.java index 53e575b..071060c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/UkmTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/UkmTest.java
@@ -104,7 +104,7 @@ () -> UmaSessionStats.updateMetricsAndCrashReportingForTesting(true)); // Enable a Syncing account. - CoreAccountInfo account = mSyncTestRule.setUpAccountAndSignInForTesting(); + CoreAccountInfo account = mSyncTestRule.setUpAccountAndEnableSyncForTesting(); Tab normalTab = mSyncTestRule.getActivity().getActivityTab(); Assert.assertTrue("UKM Enabled:", isUkmEnabled(normalTab));
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index b4321da..a0deade 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -658,6 +658,8 @@ "login_detection/login_detection_util.h", "login_detection/oauth_login_detector.cc", "login_detection/oauth_login_detector.h", + "login_detection/password_store_sites.cc", + "login_detection/password_store_sites.h", "lookalikes/lookalike_url_blocking_page.cc", "lookalikes/lookalike_url_blocking_page.h", "lookalikes/lookalike_url_controller_client.cc",
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index aa521b5..67665ca1 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -3349,6 +3349,7 @@ "apps/metrics/intent_handling_metrics_unittest.cc", "arc/accessibility/accessibility_node_info_data_wrapper_unittest.cc", "arc/accessibility/arc_accessibility_helper_bridge_unittest.cc", + "arc/accessibility/arc_accessibility_test_util.h", "arc/accessibility/arc_accessibility_util_unittest.cc", "arc/accessibility/auto_complete_handler_unittest.cc", "arc/accessibility/ax_tree_source_arc_unittest.cc",
diff --git a/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper_unittest.cc b/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper_unittest.cc index 6f314921..1009547 100644 --- a/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper_unittest.cc +++ b/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper_unittest.cc
@@ -9,6 +9,7 @@ #include <utility> #include "chrome/browser/chromeos/arc/accessibility/accessibility_window_info_data_wrapper.h" +#include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_test_util.h" #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h" #include "chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h" #include "chrome/grit/generated_resources.h" @@ -33,30 +34,6 @@ using AXStringListProperty = mojom::AccessibilityStringListProperty; using AXStringProperty = mojom::AccessibilityStringProperty; -namespace { - -void SetProperty(AXNodeInfoData* node, AXBooleanProperty prop, bool value) { - arc::SetProperty(node->boolean_properties, prop, value); -} - -void SetProperty(AXNodeInfoData* node, AXIntProperty prop, int value) { - arc::SetProperty(node->int_properties, prop, value); -} - -void SetProperty(AXNodeInfoData* node, - AXIntListProperty prop, - const std::vector<int>& value) { - arc::SetProperty(node->int_list_properties, prop, value); -} - -void SetProperty(AXNodeInfoData* node, - AXStringProperty prop, - const std::string& value) { - arc::SetProperty(node->string_properties, prop, value); -} - -} // namespace - class AccessibilityNodeInfoDataWrapperTest : public testing::Test, public AXTreeSourceArc::Delegate { public: @@ -133,7 +110,7 @@ TEST_F(AccessibilityNodeInfoDataWrapperTest, Name) { AXNodeInfoData node; - SetProperty(&node, AXStringProperty::CLASS_NAME, ""); + SetProperty(node, AXStringProperty::CLASS_NAME, ""); AccessibilityNodeInfoDataWrapper wrapper(tree_source(), &node); @@ -144,14 +121,14 @@ data.GetStringAttribute(ax::mojom::StringAttribute::kName, &name)); // Text (empty). - SetProperty(&node, AXStringProperty::TEXT, ""); + SetProperty(node, AXStringProperty::TEXT, ""); data = CallSerialize(wrapper); ASSERT_FALSE( data.GetStringAttribute(ax::mojom::StringAttribute::kName, &name)); // Text (non-empty). - SetProperty(&node, AXStringProperty::TEXT, "label text"); + SetProperty(node, AXStringProperty::TEXT, "label text"); data = CallSerialize(wrapper); ASSERT_TRUE( @@ -159,7 +136,7 @@ EXPECT_EQ("label text", name); // Content description (empty), text (non-empty). - SetProperty(&node, AXStringProperty::CONTENT_DESCRIPTION, ""); + SetProperty(node, AXStringProperty::CONTENT_DESCRIPTION, ""); data = CallSerialize(wrapper); ASSERT_TRUE( @@ -167,8 +144,8 @@ EXPECT_EQ("label text", name); // Content description (non-empty), text (empty). - SetProperty(&node, AXStringProperty::TEXT, ""); - SetProperty(&node, AXStringProperty::CONTENT_DESCRIPTION, + SetProperty(node, AXStringProperty::TEXT, ""); + SetProperty(node, AXStringProperty::CONTENT_DESCRIPTION, "label content description"); data = CallSerialize(wrapper); @@ -177,7 +154,7 @@ EXPECT_EQ("label content description", name); // Content description (non-empty), text (non-empty). - SetProperty(&node, AXStringProperty::TEXT, "label text"); + SetProperty(node, AXStringProperty::TEXT, "label text"); data = CallSerialize(wrapper); ASSERT_TRUE( @@ -190,31 +167,31 @@ root.id = 10; AccessibilityNodeInfoDataWrapper root_wrapper(tree_source(), &root); SetIdToWrapper(&root_wrapper); - SetProperty(&root, AXStringProperty::CLASS_NAME, ""); - SetProperty(&root, AXBooleanProperty::IMPORTANCE, true); - SetProperty(&root, AXIntListProperty::CHILD_NODE_IDS, + SetProperty(root, AXStringProperty::CLASS_NAME, ""); + SetProperty(root, AXBooleanProperty::IMPORTANCE, true); + SetProperty(root, AXIntListProperty::CHILD_NODE_IDS, std::vector<int>({1, 2})); AXNodeInfoData child1; child1.id = 1; AccessibilityNodeInfoDataWrapper child1_wrapper(tree_source(), &child1); SetIdToWrapper(&child1_wrapper); - SetProperty(&child1, AXBooleanProperty::IMPORTANCE, true); + SetProperty(child1, AXBooleanProperty::IMPORTANCE, true); AXNodeInfoData child2; child2.id = 2; AccessibilityNodeInfoDataWrapper child2_wrapper(tree_source(), &child2); SetIdToWrapper(&child2_wrapper); - SetProperty(&child2, AXBooleanProperty::IMPORTANCE, true); + SetProperty(child2, AXBooleanProperty::IMPORTANCE, true); SetParentId(child1.id, root.id); SetParentId(child2.id, root.id); // Root node has no name, but has descendants with name. // Name from contents can happen if a node is focusable. - SetProperty(&root, AXBooleanProperty::FOCUSABLE, true); - SetProperty(&child1, AXStringProperty::TEXT, "child1 label text"); - SetProperty(&child2, AXStringProperty::TEXT, "child2 label text"); + SetProperty(root, AXBooleanProperty::FOCUSABLE, true); + SetProperty(child1, AXStringProperty::TEXT, "child1 label text"); + SetProperty(child2, AXStringProperty::TEXT, "child2 label text"); // If the screen reader mode is off, do not compute from descendants. set_full_focus_mode(false); @@ -251,13 +228,13 @@ ASSERT_TRUE(data.IsIgnored()); // Don't compute name from descendants for scrollable, e.g. ScrollView. - SetProperty(&root, AXBooleanProperty::SCROLLABLE, true); + SetProperty(root, AXBooleanProperty::SCROLLABLE, true); data = CallSerialize(root_wrapper); ASSERT_FALSE( data.GetStringAttribute(ax::mojom::StringAttribute::kName, &name)); - SetProperty(&root, AXBooleanProperty::SCROLLABLE, false); + SetProperty(root, AXBooleanProperty::SCROLLABLE, false); // Don't compute name from descendants for virtual views, e.g. WebView. root.is_virtual_node = true; @@ -273,7 +250,7 @@ child2.is_virtual_node = false; // If one child is clickable, do not use clickable child. - SetProperty(&child1, AXBooleanProperty::CLICKABLE, true); + SetProperty(child1, AXBooleanProperty::CLICKABLE, true); data = CallSerialize(root_wrapper); ASSERT_TRUE( @@ -290,7 +267,7 @@ ASSERT_TRUE(data.IsIgnored()); // If both children are also clickable, do not use child properties. - SetProperty(&child2, AXBooleanProperty::CLICKABLE, true); + SetProperty(child2, AXBooleanProperty::CLICKABLE, true); data = CallSerialize(root_wrapper); ASSERT_FALSE( @@ -299,7 +276,7 @@ // If the node has a name, it should override the contents. child1.boolean_properties->clear(); child2.boolean_properties->clear(); - SetProperty(&root, AXStringProperty::TEXT, "root label text"); + SetProperty(root, AXStringProperty::TEXT, "root label text"); data = CallSerialize(root_wrapper); ASSERT_TRUE( @@ -320,11 +297,11 @@ root.id = 10; AccessibilityNodeInfoDataWrapper root_wrapper(tree_source(), &root); SetIdToWrapper(&root_wrapper); - SetProperty(&root, AXStringProperty::CLASS_NAME, ""); - SetProperty(&root, AXBooleanProperty::IMPORTANCE, true); - SetProperty(&root, AXBooleanProperty::CLICKABLE, true); - SetProperty(&root, AXBooleanProperty::FOCUSABLE, true); - SetProperty(&root, AXIntListProperty::CHILD_NODE_IDS, std::vector<int>({1})); + SetProperty(root, AXStringProperty::CLASS_NAME, ""); + SetProperty(root, AXBooleanProperty::IMPORTANCE, true); + SetProperty(root, AXBooleanProperty::CLICKABLE, true); + SetProperty(root, AXBooleanProperty::FOCUSABLE, true); + SetProperty(root, AXIntListProperty::CHILD_NODE_IDS, std::vector<int>({1})); AXNodeInfoData child1; child1.id = 1; @@ -332,11 +309,10 @@ SetIdToWrapper(&child1_wrapper); // Set all properties that will be used in name computation. - SetProperty(&child1, AXStringProperty::TEXT, "text"); - SetProperty(&child1, AXStringProperty::CONTENT_DESCRIPTION, + SetProperty(child1, AXStringProperty::TEXT, "text"); + SetProperty(child1, AXStringProperty::CONTENT_DESCRIPTION, "content_description"); - SetProperty(&child1, AXStringProperty::STATE_DESCRIPTION, - "state_description"); + SetProperty(child1, AXStringProperty::STATE_DESCRIPTION, "state_description"); AccessibilityNodeInfoDataWrapper wrapper(tree_source(), &root); @@ -349,7 +325,7 @@ ASSERT_EQ("text", name); // Unset TEXT property, and confirm that CONTENT_DESCRIPTION is used as name. - SetProperty(&child1, AXStringProperty::TEXT, ""); + SetProperty(child1, AXStringProperty::TEXT, ""); data = CallSerialize(wrapper); ASSERT_TRUE( data.GetStringAttribute(ax::mojom::StringAttribute::kName, &name)); @@ -357,7 +333,7 @@ // Unset CONTENT_DESCRIPTION property, and confirm that STATE_DESCRIPTION is // used as name. - SetProperty(&child1, AXStringProperty::CONTENT_DESCRIPTION, ""); + SetProperty(child1, AXStringProperty::CONTENT_DESCRIPTION, ""); data = CallSerialize(wrapper); ASSERT_TRUE( data.GetStringAttribute(ax::mojom::StringAttribute::kName, &name)); @@ -366,8 +342,8 @@ TEST_F(AccessibilityNodeInfoDataWrapperTest, TextFieldNameAndValue) { AXNodeInfoData node; - SetProperty(&node, AXStringProperty::CLASS_NAME, ""); - SetProperty(&node, AXBooleanProperty::EDITABLE, true); + SetProperty(node, AXStringProperty::CLASS_NAME, ""); + SetProperty(node, AXBooleanProperty::EDITABLE, true); struct AndroidState { std::string content_description, text, hint_text; @@ -421,11 +397,11 @@ }; for (const auto& test_case : test_cases) { - SetProperty(&node, AXStringProperty::CONTENT_DESCRIPTION, + SetProperty(node, AXStringProperty::CONTENT_DESCRIPTION, test_case.first.content_description); - SetProperty(&node, AXStringProperty::TEXT, test_case.first.text); - SetProperty(&node, AXStringProperty::HINT_TEXT, test_case.first.hint_text); - SetProperty(&node, AXBooleanProperty::SHOWING_HINT_TEXT, + SetProperty(node, AXStringProperty::TEXT, test_case.first.text); + SetProperty(node, AXStringProperty::HINT_TEXT, test_case.first.hint_text); + SetProperty(node, AXBooleanProperty::SHOWING_HINT_TEXT, test_case.first.showingHint); AccessibilityNodeInfoDataWrapper wrapper(tree_source(), &node); @@ -449,9 +425,9 @@ TEST_F(AccessibilityNodeInfoDataWrapperTest, StringProperties) { AXNodeInfoData node; node.id = 10; - SetProperty(&node, AXStringProperty::CLASS_NAME, ""); - SetProperty(&node, AXStringProperty::PACKAGE_NAME, "com.android.vending"); - SetProperty(&node, AXStringProperty::TOOLTIP, "tooltip text"); + SetProperty(node, AXStringProperty::CLASS_NAME, ""); + SetProperty(node, AXStringProperty::PACKAGE_NAME, "com.android.vending"); + SetProperty(node, AXStringProperty::TOOLTIP, "tooltip text"); SetNodeRootId(node.id); @@ -474,20 +450,20 @@ AccessibilityNodeInfoDataWrapper wrapper(tree_source(), &node); // Node is checkable, but not checked. - SetProperty(&node, AXBooleanProperty::CHECKABLE, true); - SetProperty(&node, AXBooleanProperty::CHECKED, false); + SetProperty(node, AXBooleanProperty::CHECKABLE, true); + SetProperty(node, AXBooleanProperty::CHECKED, false); ui::AXNodeData data = CallSerialize(wrapper); EXPECT_EQ(ax::mojom::CheckedState::kFalse, data.GetCheckedState()); // Make the node checked. - SetProperty(&node, AXBooleanProperty::CHECKED, true); + SetProperty(node, AXBooleanProperty::CHECKED, true); data = CallSerialize(wrapper); EXPECT_EQ(ax::mojom::CheckedState::kTrue, data.GetCheckedState()); // Make the node expandable (i.e. collapsed). - SetProperty(&node, AXIntListProperty::STANDARD_ACTION_IDS, + SetProperty(node, AXIntListProperty::STANDARD_ACTION_IDS, std::vector<int>({static_cast<int>(AXActionType::EXPAND)})); data = CallSerialize(wrapper); @@ -495,7 +471,7 @@ EXPECT_FALSE(data.HasState(ax::mojom::State::kExpanded)); // Make the node collapsible (i.e. expanded). - SetProperty(&node, AXIntListProperty::STANDARD_ACTION_IDS, + SetProperty(node, AXIntListProperty::STANDARD_ACTION_IDS, std::vector<int>({static_cast<int>(AXActionType::COLLAPSE)})); data = CallSerialize(wrapper); @@ -506,7 +482,7 @@ TEST_F(AccessibilityNodeInfoDataWrapperTest, SelectedState) { AXNodeInfoData grid; grid.id = 1; - SetProperty(&grid, AXIntListProperty::CHILD_NODE_IDS, + SetProperty(grid, AXIntListProperty::CHILD_NODE_IDS, std::vector<int>({10, 11, 12, 13})); grid.collection_info = AXCollectionInfoData::New(); grid.collection_info->row_count = 2; @@ -523,7 +499,7 @@ node.collection_item_info = AXCollectionItemInfoData::New(); node.collection_item_info->row_index = i % 2; node.collection_item_info->column_index = i / 2; - SetProperty(&node, AXBooleanProperty::SELECTED, true); + SetProperty(node, AXBooleanProperty::SELECTED, true); SetParentId(node.id, grid.id); } @@ -539,8 +515,8 @@ // text_node is simple static text, which doesn't supports selected state in // the web. AXNodeInfoData text_node; - SetProperty(&text_node, AXStringProperty::TEXT, "text."); - SetProperty(&text_node, AXBooleanProperty::SELECTED, true); + SetProperty(text_node, AXStringProperty::TEXT, "text."); + SetProperty(text_node, AXBooleanProperty::SELECTED, true); AccessibilityNodeInfoDataWrapper text_wrapper(tree_source(), &text_node); @@ -559,8 +535,8 @@ AccessibilityNodeInfoDataWrapper wrapper(tree_source(), &node); // Editable node is textField. - SetProperty(&node, AXStringProperty::CLASS_NAME, ui::kAXEditTextClassname); - SetProperty(&node, AXBooleanProperty::EDITABLE, true); + SetProperty(node, AXStringProperty::CLASS_NAME, ui::kAXEditTextClassname); + SetProperty(node, AXBooleanProperty::EDITABLE, true); ui::AXNodeData data = CallSerialize(wrapper); EXPECT_EQ(ax::mojom::Role::kTextField, data.role); @@ -568,14 +544,14 @@ // Non-editable node is not textField even if it has EditTextClassname. // When it has text and no children, it is staticText. Otherwise, it's // genericContainer. - SetProperty(&node, AXBooleanProperty::EDITABLE, false); - SetProperty(&node, AXStringProperty::TEXT, "text"); + SetProperty(node, AXBooleanProperty::EDITABLE, false); + SetProperty(node, AXStringProperty::TEXT, "text"); data = CallSerialize(wrapper); EXPECT_EQ(ax::mojom::Role::kStaticText, data.role); // Add a child. - SetProperty(&node, AXIntListProperty::CHILD_NODE_IDS, std::vector<int>({2})); + SetProperty(node, AXIntListProperty::CHILD_NODE_IDS, std::vector<int>({2})); AXNodeInfoData child; child.id = 2; AccessibilityNodeInfoDataWrapper child_wrapper(tree_source(), &node); @@ -605,7 +581,7 @@ &checked_state_description)); // State Description without Range Value should be stored as kDescription - SetProperty(&node, AXStringProperty::STATE_DESCRIPTION, "state description"); + SetProperty(node, AXStringProperty::STATE_DESCRIPTION, "state description"); data = CallSerialize(wrapper); ASSERT_TRUE(data.GetStringAttribute(ax::mojom::StringAttribute::kDescription, @@ -633,7 +609,7 @@ // State Description for compound button should be stores as // checkedDescription. node.range_info.reset(); - SetProperty(&node, AXBooleanProperty::CHECKABLE, true); + SetProperty(node, AXBooleanProperty::CHECKABLE, true); data = CallSerialize(wrapper); ASSERT_FALSE(data.GetStringAttribute(ax::mojom::StringAttribute::kDescription, @@ -649,7 +625,7 @@ TEST_F(AccessibilityNodeInfoDataWrapperTest, LabeledByLoop) { AXNodeInfoData root; root.id = 1; - SetProperty(&root, AXIntProperty::LABELED_BY, 2); + SetProperty(root, AXIntProperty::LABELED_BY, 2); AccessibilityNodeInfoDataWrapper wrapper(tree_source(), &root); SetIdToWrapper(&wrapper); @@ -657,8 +633,8 @@ node2.id = 2; AccessibilityNodeInfoDataWrapper child1_wrapper(tree_source(), &node2); SetIdToWrapper(&child1_wrapper); - SetProperty(&node2, AXStringProperty::CONTENT_DESCRIPTION, "node2"); - SetProperty(&node2, AXIntProperty::LABELED_BY, 1); + SetProperty(node2, AXStringProperty::CONTENT_DESCRIPTION, "node2"); + SetProperty(node2, AXIntProperty::LABELED_BY, 1); ui::AXNodeData data = CallSerialize(wrapper); std::string name; @@ -683,9 +659,9 @@ ASSERT_FALSE(data.GetStringAttribute(ax::mojom::StringAttribute::kDescription, &description)); - SetProperty(&node, AXStringProperty::STATE_DESCRIPTION, "state description"); - SetProperty(&node, AXBooleanProperty::SELECTED, true); - SetProperty(&node, AXStringProperty::TEXT, "text"); + SetProperty(node, AXStringProperty::STATE_DESCRIPTION, "state description"); + SetProperty(node, AXBooleanProperty::SELECTED, true); + SetProperty(node, AXStringProperty::TEXT, "text"); data = CallSerialize(wrapper); ASSERT_TRUE(data.GetStringAttribute(ax::mojom::StringAttribute::kDescription, @@ -698,10 +674,10 @@ TEST_F(AccessibilityNodeInfoDataWrapperTest, ControlIsFocusable) { AXNodeInfoData root; root.id = 1; - SetProperty(&root, AXStringProperty::CLASS_NAME, ui::kAXSeekBarClassname); - SetProperty(&root, AXStringProperty::TEXT, ""); - SetProperty(&root, AXBooleanProperty::FOCUSABLE, true); - SetProperty(&root, AXBooleanProperty::IMPORTANCE, true); + SetProperty(root, AXStringProperty::CLASS_NAME, ui::kAXSeekBarClassname); + SetProperty(root, AXStringProperty::TEXT, ""); + SetProperty(root, AXBooleanProperty::FOCUSABLE, true); + SetProperty(root, AXBooleanProperty::IMPORTANCE, true); AccessibilityNodeInfoDataWrapper wrapper(tree_source(), &root); // Check the pre conditions required, before checking whether this @@ -720,29 +696,28 @@ root.id = 10; AccessibilityNodeInfoDataWrapper root_wrapper(tree_source(), &root); SetIdToWrapper(&root_wrapper); - SetProperty(&root, AXStringProperty::CLASS_NAME, ""); - SetProperty(&root, AXBooleanProperty::IMPORTANCE, true); - SetProperty(&root, AXBooleanProperty::FOCUSABLE, true); - SetProperty(&root, AXBooleanProperty::CLICKABLE, true); - SetProperty(&root, AXIntListProperty::CHILD_NODE_IDS, std::vector<int>({1})); + SetProperty(root, AXStringProperty::CLASS_NAME, ""); + SetProperty(root, AXBooleanProperty::IMPORTANCE, true); + SetProperty(root, AXBooleanProperty::FOCUSABLE, true); + SetProperty(root, AXBooleanProperty::CLICKABLE, true); + SetProperty(root, AXIntListProperty::CHILD_NODE_IDS, std::vector<int>({1})); AXNodeInfoData child1; child1.id = 1; AccessibilityNodeInfoDataWrapper child1_wrapper(tree_source(), &child1); SetIdToWrapper(&child1_wrapper); - SetProperty(&child1, AXBooleanProperty::IMPORTANCE, true); - SetProperty(&child1, AXIntListProperty::CHILD_NODE_IDS, - std::vector<int>({2})); + SetProperty(child1, AXBooleanProperty::IMPORTANCE, true); + SetProperty(child1, AXIntListProperty::CHILD_NODE_IDS, std::vector<int>({2})); SetParentId(child1.id, root.id); AXNodeInfoData child2; child2.id = 2; AccessibilityNodeInfoDataWrapper child2_wrapper(tree_source(), &child2); SetIdToWrapper(&child2_wrapper); - SetProperty(&child2, AXBooleanProperty::IMPORTANCE, true); + SetProperty(child2, AXBooleanProperty::IMPORTANCE, true); SetParentId(child2.id, child1.id); - SetProperty(&child2, AXStringProperty::CONTENT_DESCRIPTION, "test text"); + SetProperty(child2, AXStringProperty::CONTENT_DESCRIPTION, "test text"); set_full_focus_mode(true); @@ -762,7 +737,7 @@ // Set click and focus action to child1. child1 will be clickable and // focusable, and gets ax name from descendants. - SetProperty(&child1, AXIntListProperty::STANDARD_ACTION_IDS, + SetProperty(child1, AXIntListProperty::STANDARD_ACTION_IDS, std::vector<int>({static_cast<int>(AXActionType::CLICK), static_cast<int>(AXActionType::FOCUS)})); @@ -780,7 +755,7 @@ EXPECT_TRUE(data.HasState(ax::mojom::State::kFocusable)); // Same for clear_focus action instead of focus action. - SetProperty(&child1, AXIntListProperty::STANDARD_ACTION_IDS, + SetProperty(child1, AXIntListProperty::STANDARD_ACTION_IDS, std::vector<int>({static_cast<int>(AXActionType::CLICK), static_cast<int>(AXActionType::CLEAR_FOCUS)}));
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc index 697c84f..a5df2b6 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc
@@ -23,6 +23,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" +#include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_test_util.h" #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h" #include "chrome/common/extensions/api/accessibility_private.h" #include "chrome/common/pref_names.h" @@ -338,7 +339,7 @@ event->node_data.push_back(arc::mojom::AccessibilityNodeInfoData::New()); event->node_data[0]->id = 10; event->node_data[0]->window_id = 100; - SetProperty(event->node_data[0]->int_list_properties, + SetProperty(event->node_data[0].get(), mojom::AccessibilityIntListProperty::CHILD_NODE_IDS, {1, 2, 3}); for (int i = 1; i <= 3; i++) { // This creates focusable nodes. @@ -346,11 +347,11 @@ event->node_data.push_back(arc::mojom::AccessibilityNodeInfoData::New()); event->node_data[i]->id = i; event->node_data[i]->window_id = 100; - SetProperty(event->node_data[i]->boolean_properties, + SetProperty(event->node_data[i].get(), mojom::AccessibilityBooleanProperty::IMPORTANCE, true); - SetProperty(event->node_data[i]->boolean_properties, + SetProperty(event->node_data[i].get(), mojom::AccessibilityBooleanProperty::VISIBLE_TO_USER, true); - SetProperty(event->node_data[i]->string_properties, + SetProperty(event->node_data[i].get(), mojom::AccessibilityStringProperty::CONTENT_DESCRIPTION, "node" + base::NumberToString(i) + " description"); } @@ -361,8 +362,8 @@ event->window_data->back().get(); root_window->window_id = 100; root_window->root_node_id = 10; - SetProperty(root_window->boolean_properties, - mojom::AccessibilityWindowBooleanProperty::FOCUSED, true); + SetProperty(root_window, mojom::AccessibilityWindowBooleanProperty::FOCUSED, + true); // There's no active window. helper_bridge->OnAccessibilityEvent(event.Clone());
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_test_util.h b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_test_util.h new file mode 100644 index 0000000..7d4afc1 --- /dev/null +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_test_util.h
@@ -0,0 +1,83 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ARC_ACCESSIBILITY_ARC_ACCESSIBILITY_TEST_UTIL_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_ACCESSIBILITY_ARC_ACCESSIBILITY_TEST_UTIL_H_ + +#include "base/containers/flat_map.h" +#include "base/optional.h" +#include "base/stl_util.h" +#include "components/arc/mojom/accessibility_helper.mojom.h" + +namespace arc { + +template <class PropType, class ValueType> +void SetProperty( + base::Optional<base::flat_map<PropType, ValueType>>& properties, + PropType prop, + const ValueType& value) { + if (!properties.has_value()) + properties = base::flat_map<PropType, ValueType>(); + + properties->insert_or_assign(prop, value); +} + +#define DEF_SET_PROP(data_type, prop_type, data_member_name, value_type) \ + inline void SetProperty(data_type* data, prop_type prop, \ + const value_type& value) { \ + SetProperty(data->data_member_name, prop, value); \ + } \ + inline void SetProperty(data_type& data, prop_type prop, \ + const value_type& value) { \ + SetProperty(data.data_member_name, prop, value); \ + } + +DEF_SET_PROP(mojom::AccessibilityEventData, + mojom::AccessibilityEventIntProperty, + int_properties, + int32_t) +DEF_SET_PROP(mojom::AccessibilityEventData, + mojom::AccessibilityEventIntListProperty, + int_list_properties, + std::vector<int32_t>) + +DEF_SET_PROP(mojom::AccessibilityNodeInfoData, + mojom::AccessibilityBooleanProperty, + boolean_properties, + bool) +DEF_SET_PROP(mojom::AccessibilityNodeInfoData, + mojom::AccessibilityIntProperty, + int_properties, + int32_t) +DEF_SET_PROP(mojom::AccessibilityNodeInfoData, + mojom::AccessibilityIntListProperty, + int_list_properties, + std::vector<int32_t>) +DEF_SET_PROP(mojom::AccessibilityNodeInfoData, + mojom::AccessibilityStringProperty, + string_properties, + std::string) + +DEF_SET_PROP(mojom::AccessibilityWindowInfoData, + mojom::AccessibilityWindowBooleanProperty, + boolean_properties, + bool) +DEF_SET_PROP(mojom::AccessibilityWindowInfoData, + mojom::AccessibilityWindowIntProperty, + int_properties, + int32_t) +DEF_SET_PROP(mojom::AccessibilityWindowInfoData, + mojom::AccessibilityWindowIntListProperty, + int_list_properties, + std::vector<int32_t>) +DEF_SET_PROP(mojom::AccessibilityWindowInfoData, + mojom::AccessibilityWindowStringProperty, + string_properties, + std::string) + +#undef DEF_SET_PROP + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_ACCESSIBILITY_ARC_ACCESSIBILITY_TEST_UTIL_H_
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h index f5d64c1..8a09868c 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h
@@ -97,20 +97,6 @@ return !it->second.empty(); } -// Sets property to mojom struct. Used in test. -template <class PropType, class ValueType> -void SetProperty( - base::Optional<base::flat_map<PropType, ValueType>>& properties, - PropType prop, - const ValueType& value) { - if (!properties.has_value()) - properties = base::flat_map<PropType, ValueType>(); - - auto& prop_map = properties.value(); - base::EraseIf(prop_map, [prop](auto it) { return it.first == prop; }); - prop_map.insert(std::make_pair(prop, value)); -} - } // namespace arc #endif // CHROME_BROWSER_CHROMEOS_ARC_ACCESSIBILITY_ARC_ACCESSIBILITY_UTIL_H_
diff --git a/chrome/browser/chromeos/arc/accessibility/auto_complete_handler_unittest.cc b/chrome/browser/chromeos/arc/accessibility/auto_complete_handler_unittest.cc index 0082d713..550576a0 100644 --- a/chrome/browser/chromeos/arc/accessibility/auto_complete_handler_unittest.cc +++ b/chrome/browser/chromeos/arc/accessibility/auto_complete_handler_unittest.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/chromeos/arc/accessibility/accessibility_info_data_wrapper.h" #include "chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.h" #include "chrome/browser/chromeos/arc/accessibility/accessibility_window_info_data_wrapper.h" +#include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_test_util.h" #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h" #include "chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h" #include "components/arc/mojom/accessibility_helper.mojom.h" @@ -32,38 +33,6 @@ using AXWindowIntProperty = mojom::AccessibilityWindowIntProperty; using AXWindowIntListProperty = mojom::AccessibilityWindowIntListProperty; -namespace { - -void SetProperty(AXNodeInfoData* node, AXBooleanProperty prop, bool value) { - arc::SetProperty(node->boolean_properties, prop, value); -} - -void SetProperty(AXNodeInfoData* node, - AXIntListProperty prop, - const std::vector<int>& value) { - arc::SetProperty(node->int_list_properties, prop, value); -} - -void SetProperty(AXNodeInfoData* node, - AXStringProperty prop, - const std::string& value) { - arc::SetProperty(node->string_properties, prop, value); -} - -void SetProperty(AXWindowInfoData* window, - AXWindowIntProperty prop, - int value) { - arc::SetProperty(window->int_properties, prop, value); -} - -void SetProperty(AXWindowInfoData* window, - AXWindowIntListProperty prop, - const std::vector<int>& value) { - arc::SetProperty(window->int_list_properties, prop, value); -} - -} // namespace - class AutoCompleteHandlerTest : public testing::Test, public AXTreeSourceArc::Delegate { public:
diff --git a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc index a33b513..777a25fa 100644 --- a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc +++ b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc
@@ -10,6 +10,7 @@ #include "base/stl_util.h" #include "chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.h" #include "chrome/browser/chromeos/arc/accessibility/accessibility_window_info_data_wrapper.h" +#include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_test_util.h" #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h" #include "components/arc/mojom/accessibility_helper.mojom.h" #include "extensions/browser/api/automation_internal/automation_event_router.h" @@ -42,64 +43,6 @@ using AXWindowIntListProperty = mojom::AccessibilityWindowIntListProperty; using AXWindowStringProperty = mojom::AccessibilityWindowStringProperty; -namespace { - -void SetProperty(AXNodeInfoData* node, AXBooleanProperty prop, bool value) { - arc::SetProperty(node->boolean_properties, prop, value); -} - -void SetProperty(AXNodeInfoData* node, - AXStringProperty prop, - const std::string& value) { - arc::SetProperty(node->string_properties, prop, value); -} - -void SetProperty(AXNodeInfoData* node, AXIntProperty prop, int32_t value) { - arc::SetProperty(node->int_properties, prop, value); -} - -void SetProperty(AXWindowInfoData* window, - AXWindowStringProperty prop, - const std::string& value) { - arc::SetProperty(window->string_properties, prop, value); -} - -void SetProperty(AXNodeInfoData* node, - AXIntListProperty prop, - const std::vector<int>& value) { - arc::SetProperty(node->int_list_properties, prop, value); -} - -void SetProperty(AXWindowInfoData* window, - AXWindowBooleanProperty prop, - bool value) { - arc::SetProperty(window->boolean_properties, prop, value); -} - -void SetProperty(AXWindowInfoData* window, - AXWindowIntProperty prop, - int value) { - arc::SetProperty(window->int_properties, prop, value); -} - -void SetProperty(AXWindowInfoData* window, - AXWindowIntListProperty prop, - const std::vector<int>& value) { - arc::SetProperty(window->int_list_properties, prop, value); -} - -void SetProperty(AXEventData* event, AXEventIntProperty prop, int32_t value) { - arc::SetProperty(event->int_properties, prop, value); -} - -void SetProperty(AXEventData* event, - AXEventIntListProperty prop, - const std::vector<int>& value) { - arc::SetProperty(event->int_list_properties, prop, value); -} - -} // namespace - class MockAutomationEventRouter : public extensions::AutomationEventRouterInterface { public: @@ -601,8 +544,7 @@ AXWindowInfoData* root = event->window_data->back().get(); root->window_id = 5; SetProperty(root, AXWindowIntListProperty::CHILD_WINDOW_IDS, {1}); - SetProperty(root->boolean_properties, - mojom::AccessibilityWindowBooleanProperty::FOCUSED, true); + SetProperty(root, mojom::AccessibilityWindowBooleanProperty::FOCUSED, true); // Add a child window. event->window_data->push_back(AXWindowInfoData::New()); @@ -635,8 +577,8 @@ AXWindowInfoData* root_window = event->window_data->back().get(); root_window->window_id = 100; root_window->root_node_id = 10; - SetProperty(root_window->boolean_properties, - mojom::AccessibilityWindowBooleanProperty::FOCUSED, true); + SetProperty(root_window, mojom::AccessibilityWindowBooleanProperty::FOCUSED, + true); event->node_data.push_back(AXNodeInfoData::New()); AXNodeInfoData* root = event->node_data.back().get(); @@ -748,8 +690,8 @@ AXWindowInfoData* root_window = event->window_data->back().get(); root_window->window_id = 100; root_window->root_node_id = 10; - SetProperty(root_window->boolean_properties, - mojom::AccessibilityWindowBooleanProperty::FOCUSED, true); + SetProperty(root_window, mojom::AccessibilityWindowBooleanProperty::FOCUSED, + true); event->node_data.push_back(AXNodeInfoData::New()); AXNodeInfoData* root = event->node_data.back().get(); @@ -848,8 +790,8 @@ AXWindowInfoData* root_window = event->window_data->back().get(); root_window->window_id = 100; root_window->root_node_id = 10; - SetProperty(root_window->boolean_properties, - mojom::AccessibilityWindowBooleanProperty::FOCUSED, true); + SetProperty(root_window, mojom::AccessibilityWindowBooleanProperty::FOCUSED, + true); event->node_data.push_back(AXNodeInfoData::New()); AXNodeInfoData* root = event->node_data.back().get(); @@ -1134,8 +1076,8 @@ AXWindowInfoData* root_window = event->window_data->back().get(); root_window->window_id = 100; root_window->root_node_id = 10; - SetProperty(root_window->boolean_properties, - mojom::AccessibilityWindowBooleanProperty::FOCUSED, true); + SetProperty(root_window, mojom::AccessibilityWindowBooleanProperty::FOCUSED, + true); event->node_data.push_back(AXNodeInfoData::New()); AXNodeInfoData* root = event->node_data.back().get(); @@ -1344,8 +1286,8 @@ AXWindowInfoData* root_window = event->window_data->back().get(); root_window->window_id = 2; root_window->root_node_id = 1; - SetProperty(root_window->boolean_properties, - mojom::AccessibilityWindowBooleanProperty::FOCUSED, true); + SetProperty(root_window, mojom::AccessibilityWindowBooleanProperty::FOCUSED, + true); event->node_data.push_back(AXNodeInfoData::New()); AXNodeInfoData* node = event->node_data.back().get();
diff --git a/chrome/browser/chromeos/arc/accessibility/drawer_layout_handler_unittest.cc b/chrome/browser/chromeos/arc/accessibility/drawer_layout_handler_unittest.cc index aa76a3f..10907b1 100644 --- a/chrome/browser/chromeos/arc/accessibility/drawer_layout_handler_unittest.cc +++ b/chrome/browser/chromeos/arc/accessibility/drawer_layout_handler_unittest.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/chromeos/arc/accessibility/accessibility_info_data_wrapper.h" #include "chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.h" #include "chrome/browser/chromeos/arc/accessibility/accessibility_window_info_data_wrapper.h" +#include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_test_util.h" #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h" #include "chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h" #include "components/arc/mojom/accessibility_helper.mojom.h" @@ -28,26 +29,6 @@ using AXStringProperty = mojom::AccessibilityStringProperty; using AXWindowInfoData = mojom::AccessibilityWindowInfoData; -namespace { - -void SetProperty(AXNodeInfoData* node, AXBooleanProperty prop, bool value) { - arc::SetProperty(node->boolean_properties, prop, value); -} - -void SetProperty(AXNodeInfoData* node, - AXIntListProperty prop, - const std::vector<int>& value) { - arc::SetProperty(node->int_list_properties, prop, value); -} - -void SetProperty(AXNodeInfoData* node, - AXStringProperty prop, - const std::string& value) { - arc::SetProperty(node->string_properties, prop, value); -} - -} // namespace - class DrawerLayoutHandlerTest : public testing::Test, public AXTreeSourceArc::Delegate { public:
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 5f38cc4..f55eef1 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -157,7 +157,7 @@ { "name": "arc-file-picker-experiment", "owners": [ "niwa" ], - "expiry_milestone": 88 + "expiry_milestone": 95 }, { "name": "arc-native-bridge-64bit-support-experiment",
diff --git a/chrome/browser/login_detection/login_detection_keyed_service.cc b/chrome/browser/login_detection/login_detection_keyed_service.cc index 97a917d..90c2c0b 100644 --- a/chrome/browser/login_detection/login_detection_keyed_service.cc +++ b/chrome/browser/login_detection/login_detection_keyed_service.cc
@@ -6,6 +6,7 @@ #include "chrome/browser/login_detection/login_detection_prefs.h" #include "chrome/browser/login_detection/login_detection_util.h" +#include "chrome/browser/password_manager/account_password_store_factory.h" #include "chrome/browser/profiles/profile.h" #include "content/public/browser/child_process_security_policy.h" #include "url/gurl.h" @@ -29,7 +30,14 @@ } LoginDetectionKeyedService::LoginDetectionKeyedService(Profile* profile) - : profile_(profile), field_trial_logged_in_sites_(GetLoggedInSites()) {} + : profile_(profile), + field_trial_logged_in_sites_(GetLoggedInSites()), + profile_password_sites_(PasswordStoreFactory::GetForProfile( + profile, + ServiceAccessType::EXPLICIT_ACCESS)), + account_password_sites_(AccountPasswordStoreFactory::GetForProfile( + profile, + ServiceAccessType::EXPLICIT_ACCESS)) {} LoginDetectionKeyedService::~LoginDetectionKeyedService() = default; @@ -66,6 +74,12 @@ return LoginDetectionType::kPreloadedPasswordSiteLogin; } + // Check for sites saved in the password manager. + if (profile_password_sites_.IsSiteInPasswordStore(url) || + account_password_sites_.IsSiteInPasswordStore(url)) { + return LoginDetectionType::kPasswordManagerSavedSite; + } + return LoginDetectionType::kNoLogin; }
diff --git a/chrome/browser/login_detection/login_detection_keyed_service.h b/chrome/browser/login_detection/login_detection_keyed_service.h index 93e849c..8b9d79f 100644 --- a/chrome/browser/login_detection/login_detection_keyed_service.h +++ b/chrome/browser/login_detection/login_detection_keyed_service.h
@@ -9,6 +9,7 @@ #include <string> #include "chrome/browser/login_detection/login_detection_type.h" +#include "chrome/browser/login_detection/password_store_sites.h" #include "components/keyed_service/core/keyed_service.h" class Profile; @@ -43,6 +44,9 @@ // Set of sites that should be treated as logged-in, retrieved from field // trial. const std::set<std::string, OriginComparator> field_trial_logged_in_sites_; + + const PasswordStoreSites profile_password_sites_; + const PasswordStoreSites account_password_sites_; }; } // namespace login_detection
diff --git a/chrome/browser/login_detection/login_detection_keyed_service_factory.cc b/chrome/browser/login_detection/login_detection_keyed_service_factory.cc index 29645d4..3884595 100644 --- a/chrome/browser/login_detection/login_detection_keyed_service_factory.cc +++ b/chrome/browser/login_detection/login_detection_keyed_service_factory.cc
@@ -6,6 +6,8 @@ #include "chrome/browser/login_detection/login_detection_keyed_service.h" #include "chrome/browser/login_detection/login_detection_util.h" +#include "chrome/browser/password_manager/account_password_store_factory.h" +#include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/profiles/profile.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "content/public/browser/browser_context.h" @@ -35,7 +37,10 @@ LoginDetectionKeyedServiceFactory::LoginDetectionKeyedServiceFactory() : BrowserContextKeyedServiceFactory( "LoginDetectionKeyedService", - BrowserContextDependencyManager::GetInstance()) {} + BrowserContextDependencyManager::GetInstance()) { + DependsOn(AccountPasswordStoreFactory::GetInstance()); + DependsOn(PasswordStoreFactory::GetInstance()); +} LoginDetectionKeyedServiceFactory::~LoginDetectionKeyedServiceFactory() = default;
diff --git a/chrome/browser/login_detection/login_detection_type.h b/chrome/browser/login_detection/login_detection_type.h index 0c451d73..b47b3b2e 100644 --- a/chrome/browser/login_detection/login_detection_type.h +++ b/chrome/browser/login_detection/login_detection_type.h
@@ -33,7 +33,10 @@ // commonly logged-in. kFieldTrialLoggedInSite, - kMaxValue = kFieldTrialLoggedInSite + // The site has credentials saved in the password manager. + kPasswordManagerSavedSite, + + kMaxValue = kPasswordManagerSavedSite }; } // namespace login_detection
diff --git a/chrome/browser/login_detection/password_store_sites.cc b/chrome/browser/login_detection/password_store_sites.cc new file mode 100644 index 0000000..a86cd66 --- /dev/null +++ b/chrome/browser/login_detection/password_store_sites.cc
@@ -0,0 +1,54 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/login_detection/password_store_sites.h" + +#include "base/metrics/histogram_functions.h" +#include "base/sequence_checker.h" +#include "chrome/browser/login_detection/login_detection_util.h" +#include "components/password_manager/core/browser/password_form.h" + +namespace login_detection { + +PasswordStoreSites::PasswordStoreSites( + scoped_refptr<password_manager::PasswordStore> password_store) + : password_store_(std::move(password_store)) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (password_store_) { + password_store_->AddObserver(this); + password_store_->GetAllLogins(this); + } +} + +PasswordStoreSites::~PasswordStoreSites() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (password_store_) + password_store_->RemoveObserver(this); +} + +void PasswordStoreSites::OnLoginsChanged( + const password_manager::PasswordStoreChangeList& changes) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Fetch the login list again. + password_store_->GetAllLogins(this); +} + +void PasswordStoreSites::OnGetPasswordStoreResults( + std::vector<std::unique_ptr<password_manager::PasswordForm>> form_entries) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + password_sites_ = std::set<std::string>(); + for (const auto& entry : form_entries) { + password_sites_->insert(GetSiteNameForURL(entry->url)); + } +} + +bool PasswordStoreSites::IsSiteInPasswordStore(const GURL& url) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::UmaHistogramBoolean("Login.PasswordStoreSites.InitializedBeforeQuery", + password_sites_.has_value()); + return password_sites_ && password_sites_->find(GetSiteNameForURL(url)) != + password_sites_->end(); +} + +} // namespace login_detection
diff --git a/chrome/browser/login_detection/password_store_sites.h b/chrome/browser/login_detection/password_store_sites.h new file mode 100644 index 0000000..96caf37f --- /dev/null +++ b/chrome/browser/login_detection/password_store_sites.h
@@ -0,0 +1,54 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_LOGIN_DETECTION_PASSWORD_STORE_SITES_H_ +#define CHROME_BROWSER_LOGIN_DETECTION_PASSWORD_STORE_SITES_H_ + +#include <set> + +#include "base/memory/scoped_refptr.h" +#include "base/optional.h" +#include "chrome/browser/password_manager/password_store_factory.h" +#include "components/password_manager/core/browser/password_store.h" +#include "components/password_manager/core/browser/password_store_consumer.h" + +namespace login_detection { + +// Maintains the sites that are saved in password store. These sites will be +// treated as logged-in. +class PasswordStoreSites : public password_manager::PasswordStore::Observer, + public password_manager::PasswordStoreConsumer { + public: + explicit PasswordStoreSites( + scoped_refptr<password_manager::PasswordStore> store); + + ~PasswordStoreSites() override; + + // Returns whether the site for |url| has credentials saved in this password + // store. + bool IsSiteInPasswordStore(const GURL& url) const; + + private: + // PasswordStore::Observer: + void OnLoginsChanged( + const password_manager::PasswordStoreChangeList& changes) override; + + // PasswordStoreConsumer: + void OnGetPasswordStoreResults( + std::vector<std::unique_ptr<password_manager::PasswordForm>> form_entries) + override; + + // The password store |this| is observing site entries from. + scoped_refptr<password_manager::PasswordStore> password_store_; + + // Set of sites saved in the password store. Will be base::nullopt until the + // sites are retrieved the fist time. + base::Optional<std::set<std::string>> password_sites_; + + SEQUENCE_CHECKER(sequence_checker_); +}; + +} // namespace login_detection + +#endif // CHROME_BROWSER_LOGIN_DETECTION_PASSWORD_STORE_SITES_H_
diff --git a/chrome/browser/login_detection/password_store_sites_browsertest.cc b/chrome/browser/login_detection/password_store_sites_browsertest.cc new file mode 100644 index 0000000..9256d63 --- /dev/null +++ b/chrome/browser/login_detection/password_store_sites_browsertest.cc
@@ -0,0 +1,191 @@ +// 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 "base/strings/utf_string_conversions.h" +#include "base/test/metrics/histogram_tester.h" +#include "chrome/browser/login_detection/password_store_sites.h" +#include "chrome/browser/password_manager/account_password_store_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/password_manager/core/browser/password_store.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace login_detection { + +class LoginDetectionPasswordStoreSitesBrowserTest + : public InProcessBrowserTest { + public: + LoginDetectionPasswordStoreSitesBrowserTest() = default; + + scoped_refptr<password_manager::PasswordStore> GetProfilePasswordStore() { + return PasswordStoreFactory::GetForProfile( + ProfileManager::GetActiveUserProfile(), + ServiceAccessType::EXPLICIT_ACCESS); + } + + scoped_refptr<password_manager::PasswordStore> GetAccountPasswordStore() { + return AccountPasswordStoreFactory::GetForProfile( + ProfileManager::GetActiveUserProfile(), + ServiceAccessType::EXPLICIT_ACCESS); + } + + void AddLoginForSite(password_manager::PasswordStore* password_store, + const GURL& url) { + password_manager::PasswordForm form; + form.scheme = password_manager::PasswordForm::Scheme::kHtml; + form.url = url; + form.signon_realm = "https://www.chrome.com"; + form.username_value = base::ASCIIToUTF16("my_username"); + form.password_value = base::ASCIIToUTF16("my_password"); + form.blocked_by_user = false; + password_store->AddLogin(form); + WaitForPasswordStoreUpdate(password_store); + } + + // Wait for the password store taskrunner to complete its event processing. + void WaitForPasswordStoreUpdate( + password_manager::PasswordStore* password_store) { + base::WaitableEvent waitable_event( + base::WaitableEvent::ResetPolicy::AUTOMATIC, + base::WaitableEvent::InitialState::NOT_SIGNALED); + password_store->ScheduleTask(base::BindOnce( + &base::WaitableEvent::Signal, base::Unretained(&waitable_event))); + waitable_event.Wait(); + + // At this point, the password store has completed its processing and posted + // events to the main thread. + base::RunLoop().RunUntilIdle(); + } + + protected: + base::HistogramTester histogram_tester; +}; + +#if BUILDFLAG(IS_CHROMEOS_ASH) +#define DISABLE_ON_CHROMEOS(x) DISABLED_##x +#else +#define DISABLE_ON_CHROMEOS(x) x +#endif + +IN_PROC_BROWSER_TEST_F(LoginDetectionPasswordStoreSitesBrowserTest, + DISABLE_ON_CHROMEOS(ProfilePasswordStore)) { + auto password_store = GetProfilePasswordStore(); + PasswordStoreSites password_store_sites(password_store); + WaitForPasswordStoreUpdate(password_store.get()); + base::RunLoop().RunUntilIdle(); + + AddLoginForSite(password_store.get(), GURL("https://www.foo.com/login.html")); + WaitForPasswordStoreUpdate(password_store.get()); + base::RunLoop().RunUntilIdle(); + + // The site and its subdomains should exist in the password store. + EXPECT_TRUE( + password_store_sites.IsSiteInPasswordStore(GURL("https://www.foo.com"))); + EXPECT_TRUE( + password_store_sites.IsSiteInPasswordStore(GURL("https://foo.com"))); + EXPECT_TRUE(password_store_sites.IsSiteInPasswordStore( + GURL("https://mobile.foo.com"))); + + EXPECT_FALSE( + password_store_sites.IsSiteInPasswordStore(GURL("https://www.bar.com"))); + + histogram_tester.ExpectUniqueSample( + "Login.PasswordStoreSites.InitializedBeforeQuery", true, 4); +} + +IN_PROC_BROWSER_TEST_F(LoginDetectionPasswordStoreSitesBrowserTest, + DISABLE_ON_CHROMEOS(AccountPasswordStore)) { + auto password_store = GetAccountPasswordStore(); + PasswordStoreSites password_store_sites(password_store); + WaitForPasswordStoreUpdate(password_store.get()); + base::RunLoop().RunUntilIdle(); + + AddLoginForSite(password_store.get(), GURL("https://www.foo.com/login.html")); + WaitForPasswordStoreUpdate(password_store.get()); + base::RunLoop().RunUntilIdle(); + + // The site and its subdomains should exist in the password store. + EXPECT_TRUE( + password_store_sites.IsSiteInPasswordStore(GURL("https://www.foo.com"))); + EXPECT_TRUE( + password_store_sites.IsSiteInPasswordStore(GURL("https://foo.com"))); + EXPECT_TRUE(password_store_sites.IsSiteInPasswordStore( + GURL("https://mobile.foo.com"))); + + EXPECT_FALSE( + password_store_sites.IsSiteInPasswordStore(GURL("https://www.bar.com"))); + + histogram_tester.ExpectUniqueSample( + "Login.PasswordStoreSites.InitializedBeforeQuery", true, 4); +} + +IN_PROC_BROWSER_TEST_F(LoginDetectionPasswordStoreSitesBrowserTest, + DISABLE_ON_CHROMEOS(AccountPasswordStoreExistingLogin)) { + auto password_store = GetAccountPasswordStore(); + AddLoginForSite(password_store.get(), GURL("https://www.foo.com/login.html")); + base::RunLoop().RunUntilIdle(); + + PasswordStoreSites password_store_sites(password_store); + WaitForPasswordStoreUpdate(password_store.get()); + + // The site and its subdomains should exist in the password store. + EXPECT_TRUE( + password_store_sites.IsSiteInPasswordStore(GURL("https://www.foo.com"))); + EXPECT_TRUE( + password_store_sites.IsSiteInPasswordStore(GURL("https://foo.com"))); + EXPECT_TRUE(password_store_sites.IsSiteInPasswordStore( + GURL("https://mobile.foo.com"))); + + histogram_tester.ExpectUniqueSample( + "Login.PasswordStoreSites.InitializedBeforeQuery", true, 3); +} + +IN_PROC_BROWSER_TEST_F(LoginDetectionPasswordStoreSitesBrowserTest, + DISABLE_ON_CHROMEOS(ProfilePasswordStoreExistingLogin)) { + auto password_store = GetProfilePasswordStore(); + AddLoginForSite(password_store.get(), GURL("https://www.foo.com/login.html")); + base::RunLoop().RunUntilIdle(); + + PasswordStoreSites password_store_sites(password_store); + WaitForPasswordStoreUpdate(password_store.get()); + + // The site and its subdomains should exist in the password store. + EXPECT_TRUE( + password_store_sites.IsSiteInPasswordStore(GURL("https://www.foo.com"))); + EXPECT_TRUE( + password_store_sites.IsSiteInPasswordStore(GURL("https://foo.com"))); + EXPECT_TRUE(password_store_sites.IsSiteInPasswordStore( + GURL("https://mobile.foo.com"))); + + histogram_tester.ExpectUniqueSample( + "Login.PasswordStoreSites.InitializedBeforeQuery", true, 3); +} + +// Tests querying the password store sites before the password store is +// initialized. +IN_PROC_BROWSER_TEST_F( + LoginDetectionPasswordStoreSitesBrowserTest, + DISABLE_ON_CHROMEOS(QueryBeforePasswordStoreInitialize)) { + auto password_store = GetProfilePasswordStore(); + PasswordStoreSites password_store_sites(password_store); + + EXPECT_FALSE( + password_store_sites.IsSiteInPasswordStore(GURL("https://www.foo.com"))); + histogram_tester.ExpectUniqueSample( + "Login.PasswordStoreSites.InitializedBeforeQuery", false, 1); + + WaitForPasswordStoreUpdate(password_store.get()); + EXPECT_FALSE( + password_store_sites.IsSiteInPasswordStore(GURL("https://www.foo.com"))); + + histogram_tester.ExpectBucketCount( + "Login.PasswordStoreSites.InitializedBeforeQuery", true, 1); +} + +} // namespace login_detection
diff --git a/chrome/browser/resources/chromeos/login/debug/debug.js b/chrome/browser/resources/chromeos/login/debug/debug.js index 8b97074..33c04221 100644 --- a/chrome/browser/resources/chromeos/login/debug/debug.js +++ b/chrome/browser/resources/chromeos/login/debug/debug.js
@@ -499,6 +499,7 @@ { id: 'gaia-signin', kind: ScreenKind.NORMAL, + handledSteps: 'allowlist-error', states: [ { id: 'allowlist-customer',
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.css b/chrome/browser/resources/chromeos/login/screen_gaia_signin.css index 157ab180..b413deb 100644 --- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.css +++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.css
@@ -28,22 +28,12 @@ * border-top-right-radius: 4px; */ display: block; overflow: hidden; - position: static; -} - -:host .step-contents { - -webkit-box-pack: center; - display: -webkit-box; - height: 100%; } #saml-notice-container { - align-items: center; background: rgb(241, 243, 244); /* #F1F3F4 */ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.17); - display: flex; height: 44px; - min-height: 0; } #saml-notice-recording-indicator { @@ -56,32 +46,11 @@ font-size: 13px; } -.step-loading { - align-items: center; - bottom: 0; - display: flex; - justify-content: center; - left: 0; - min-height: 0; - position: absolute; - right: 0; - top: 0; -} - .icon20 { height: 20px; width: 20px; } -#gaia-allowlist-error { - bottom: 0; - display: block; - left: 0; - position: absolute; - right: 0; - top: 0; -} - #signin-frame-container { z-index: 10; }
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.html b/chrome/browser/resources/chromeos/login/screen_gaia_signin.html index a5d2d89..086512f 100644 --- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.html +++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.html
@@ -22,14 +22,14 @@ <oobe-dialog id="signin-frame-dialog" class="gaia-dialog" role="dialog" has-buttons="[[!isSamlSsoVisible_]]" no-header no-footer-padding no-lazy - hidden="[[!isStep_(step_, 'online-gaia', 'gaia-loading')]]"> + for-step="online-gaia, gaia-loading"> <div slot="footer" class="flex layout vertical"> <div id="signin-frame-container" transparent$="[[isLoadingUiShown_]]" animated-transparency$="[[!usedSaml_]]" hideshadows$="[[isPopUpOverlayVisible_]]" class="flex layout vertical"> <div id="saml-notice-container" - class="layout horizontal" + class="layout horizontal center" hidden="[[!isSamlSsoVisible_]]"> <div class="flex layout horizontal center-justified"> <span id="saml-notice-recording-indicator" @@ -71,12 +71,11 @@ </div> </oobe-dialog> <security-token-pin id="pinDialog" parameters="[[pinDialogParameters_]]" - hidden="[[!isStep_(step_, 'pin')]]" - on-cancel="onPinDialogCanceled_" on-completed="onPinDialogCompleted_"> + for-step="pin" on-cancel="onPinDialogCanceled_" + on-completed="onPinDialogCompleted_"> </security-token-pin> <oobe-dialog id="saml-interstitial" role="dialog" has-buttons - title-key="loginWelcomeMessage" - hidden="[[!isStep_(step_, 'saml-interstitial')]]"> + title-key="loginWelcomeMessage" for-step="saml-interstitial"> <hd-iron-icon slot="oobe-icon" icon1x="oobe-32:googleg" icon2x="oobe-64:googleg"> </hd-iron-icon> @@ -100,12 +99,12 @@ id="interstitial-next" class="focus-on-show"></oobe-next-button> </div> </oobe-dialog> - <div id="gaia-loading" class="step-loading gaia-dialog" - hidden="[[!isStep_(step_, 'loading', 'gaia-loading')]]"> + <div id="gaia-loading" class="layout center center-justified vertical fit" + for-step="loading, gaia-loading"> <throbber-notice text-key="gaiaLoading"></throbber-notice> </div> - <notification-card id="gaia-allowlist-error" type="fail" class="gaia-dialog" - hidden="[[!isStep_(step_, 'allowlist-error')]]" + <notification-card id="gaia-allowlist-error" type="fail" class="fit" + for-step="allowlist-error" button-label="[[i18nDynamic(locale, 'tryAgainButton')]]" link-label="[[i18nDynamic(locale, 'learnMoreButton')]]"> </notification-card>
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js index cb61d5cf..3be26b1 100644 --- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js +++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
@@ -57,7 +57,11 @@ Polymer({ is: 'gaia-signin-element', - behaviors: [OobeI18nBehavior, OobeDialogHostBehavior, LoginScreenBehavior], + behaviors: [ + OobeI18nBehavior, + LoginScreenBehavior, + MultiStepBehavior, + ], EXTERNAL_API: [ 'loadAuthExtension', @@ -80,16 +84,6 @@ }, /** - * Current step displayed. - * @type {DialogMode} - * @private - */ - step_: { - type: String, - value: DialogMode.GAIA, - }, - - /** * Whether the screen contents are currently being loaded. * @private */ @@ -314,6 +308,12 @@ */ clickPrimaryActionButtonForTesting_: false, + defaultUIStep() { + return DialogMode.GAIA; + }, + + UI_STEPS: DialogMode, + /** @override */ ready() { this.authenticator_ = new cr.login.Authenticator(this.getSigninFrame_()); @@ -1357,18 +1357,6 @@ }, /** - * Checks if current step is one of specified steps. - * @param {DialogMode} currentStep Name of current step. - * @param {...string} stepsVarArgs List of steps to compare with. - * @return {boolean} - */ - isStep_(currentStep, ...stepsVarArgs) { - if (stepsVarArgs.length < 1) - throw Error('At least one step to compare is required.'); - return stepsVarArgs.some(step => currentStep === step); - }, - - /** * Updates current UI step based on internal state. * @param {number} mode * @param {OobeTypes.SecurityTokenPinDialogParameter} pinParams @@ -1378,27 +1366,27 @@ */ refreshDialogStep_(mode, pinParams, isLoading, isAllowlistError) { if (pinParams !== null) { - this.step_ = DialogMode.PIN_DIALOG; + this.setUIStep(DialogMode.PIN_DIALOG); return; } if (isLoading) { if (mode == AuthMode.DEFAULT) { - this.step_ = DialogMode.GAIA_LOADING; + this.setUIStep(DialogMode.GAIA_LOADING); } else { - this.step_ = DialogMode.LOADING; + this.setUIStep(DialogMode.LOADING); } return; } if (isAllowlistError) { - this.step_ = DialogMode.GAIA_ALLOWLIST_ERROR; + this.setUIStep(DialogMode.GAIA_ALLOWLIST_ERROR); return; } switch (mode) { case AuthMode.DEFAULT: - this.step_ = DialogMode.GAIA; + this.setUIStep(DialogMode.GAIA); break; case AuthMode.SAML_INTERSTITIAL: - this.step_ = DialogMode.SAML_INTERSTITIAL; + this.setUIStep(DialogMode.SAML_INTERSTITIAL); break; } },
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn index a9b0594c..96362a9 100644 --- a/chrome/browser/safe_browsing/BUILD.gn +++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -81,10 +81,10 @@ "certificate_reporting_service_factory.h", "chrome_password_protection_service.cc", "chrome_password_protection_service.h", - "client_side_detection_host.cc", - "client_side_detection_host.h", - "client_side_detection_service.cc", - "client_side_detection_service.h", + "client_side_detection_host_delegate.cc", + "client_side_detection_host_delegate.h", + "client_side_detection_service_delegate.cc", + "client_side_detection_service_delegate.h", "client_side_detection_service_factory.cc", "client_side_detection_service_factory.h", "delayed_warning_navigation_throttle.cc", @@ -122,6 +122,7 @@ "//chrome/common/safe_browsing:proto", "//components/safe_browsing/content", "//components/safe_browsing/content/browser", + "//components/safe_browsing/content/browser:client_side_detection", "//components/safe_browsing/content/browser:client_side_model_loader", "//components/safe_browsing/content/password_protection", "//components/safe_browsing/content/triggers:ad_popup_trigger",
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_browsertest.cc b/chrome/browser/safe_browsing/client_side_detection_host_browsertest.cc index 675719c..e4f1d97e 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host_browsertest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host_browsertest.cc
@@ -2,17 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/safe_browsing/client_side_detection_host.h" +#include "chrome/browser/safe_browsing/client_side_detection_host_delegate.h" #include "base/run_loop.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/safe_browsing/client_side_detection_service.h" +#include "chrome/browser/safe_browsing/ui_manager.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/prefs/pref_service.h" #include "components/safe_browsing/buildflags.h" +#include "components/safe_browsing/content/browser/client_side_detection_service.h" #include "components/safe_browsing/core/proto/client_model.pb.h" #include "content/public/test/browser_test.h" #include "testing/gmock/include/gmock/gmock.h" @@ -112,7 +113,7 @@ ASSERT_TRUE(embedded_test_server()->Start()); std::unique_ptr<ClientSideDetectionHost> csd_host = - ClientSideDetectionHost::Create( + ClientSideDetectionHostDelegate::CreateHost( browser()->tab_strip_model()->GetActiveWebContents()); csd_host->set_client_side_detection_service(&fake_csd_service); csd_host->SendModelToRenderFrame();
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_delegate.cc b/chrome/browser/safe_browsing/client_side_detection_host_delegate.cc new file mode 100644 index 0000000..372e8b4 --- /dev/null +++ b/chrome/browser/safe_browsing/client_side_detection_host_delegate.cc
@@ -0,0 +1,58 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/safe_browsing/client_side_detection_host_delegate.h" + +#include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/safe_browsing/client_side_detection_service_factory.h" +#include "chrome/browser/safe_browsing/safe_browsing_service.h" +#include "chrome/browser/safe_browsing/user_interaction_observer.h" +#include "components/prefs/pref_service.h" +#include "components/safe_browsing/content/browser/client_side_detection_host.h" +#include "components/safe_browsing/core/db/database_manager.h" + +namespace safe_browsing { + +// static +std::unique_ptr<ClientSideDetectionHost> +ClientSideDetectionHostDelegate::CreateHost(content::WebContents* tab) { + return ClientSideDetectionHost::Create( + tab, std::make_unique<ClientSideDetectionHostDelegate>(tab)); +} + +ClientSideDetectionHostDelegate::ClientSideDetectionHostDelegate( + content::WebContents* web_contents) + : web_contents_(web_contents) {} +ClientSideDetectionHostDelegate::~ClientSideDetectionHostDelegate() = default; + +bool ClientSideDetectionHostDelegate::HasSafeBrowsingUserInteractionObserver() { + return SafeBrowsingUserInteractionObserver::FromWebContents(web_contents_); +} + +PrefService* ClientSideDetectionHostDelegate::GetPrefs() { + Profile* profile = + Profile::FromBrowserContext(web_contents_->GetBrowserContext()); + return profile ? profile->GetPrefs() : nullptr; +} + +scoped_refptr<SafeBrowsingDatabaseManager> +ClientSideDetectionHostDelegate::GetSafeBrowsingDBManager() { + SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service(); + return sb_service ? sb_service->database_manager().get() : nullptr; +} + +scoped_refptr<BaseUIManager> +ClientSideDetectionHostDelegate::GetSafeBrowsingUIManager() { + SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service(); + return sb_service ? sb_service->ui_manager() : nullptr; +} + +ClientSideDetectionService* +ClientSideDetectionHostDelegate::GetClientSideDetectionService() { + return ClientSideDetectionServiceFactory::GetForProfile( + Profile::FromBrowserContext(web_contents_->GetBrowserContext())); +} + +} // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_delegate.h b/chrome/browser/safe_browsing/client_side_detection_host_delegate.h new file mode 100644 index 0000000..97241ca4 --- /dev/null +++ b/chrome/browser/safe_browsing/client_side_detection_host_delegate.h
@@ -0,0 +1,39 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_DELEGATE_H_ +#define CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_DELEGATE_H_ + +#include "components/safe_browsing/content/browser/client_side_detection_host.h" + +namespace safe_browsing { + +// Delegate class which implements chrome specific bits for configuring +// the ClientSideDetectionHost class. +class ClientSideDetectionHostDelegate + : public ClientSideDetectionHost::Delegate { + public: + static std::unique_ptr<ClientSideDetectionHost> CreateHost( + content::WebContents* tab); + + explicit ClientSideDetectionHostDelegate(content::WebContents* web_contents); + ~ClientSideDetectionHostDelegate() override; + + // ClientSideDetectionHost::Delegate implementation. + bool HasSafeBrowsingUserInteractionObserver() override; + PrefService* GetPrefs() override; + scoped_refptr<SafeBrowsingDatabaseManager> GetSafeBrowsingDBManager() + override; + scoped_refptr<BaseUIManager> GetSafeBrowsingUIManager() override; + ClientSideDetectionService* GetClientSideDetectionService() override; + + private: + content::WebContents* web_contents_; + + DISALLOW_COPY_AND_ASSIGN(ClientSideDetectionHostDelegate); +}; + +} // namespace safe_browsing + +#endif // CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_DELEGATE_H_
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc index a2df3a6..25f93b6 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/safe_browsing/client_side_detection_host.h" +#include "chrome/browser/safe_browsing/client_side_detection_host_delegate.h" #include <memory> #include <tuple> @@ -19,13 +19,13 @@ #include "base/test/gmock_move_support.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/simple_test_tick_clock.h" -#include "chrome/browser/safe_browsing/client_side_detection_service.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/safe_browsing/ui_manager.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" #include "components/prefs/scoped_user_pref_update.h" +#include "components/safe_browsing/content/browser/client_side_detection_service.h" #include "components/safe_browsing/content/browser/client_side_model_loader.h" #include "components/safe_browsing/content/common/safe_browsing.mojom-shared.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" @@ -278,7 +278,7 @@ static_cast<safe_browsing::SafeBrowsingService*>( SafeBrowsingService::CreateSafeBrowsingService())); - csd_host_ = ClientSideDetectionHost::Create(web_contents()); + csd_host_ = ClientSideDetectionHostDelegate::CreateHost(web_contents()); csd_host_->set_client_side_detection_service(csd_service_.get()); csd_host_->set_ui_manager(ui_manager_.get()); csd_host_->set_database_manager(database_manager_.get());
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 fb68b3f..57f82bc5 100644 --- a/chrome/browser/safe_browsing/client_side_detection_service_browsertest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_service_browsertest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/safe_browsing/client_side_detection_service.h" +#include "chrome/browser/safe_browsing/client_side_detection_service_delegate.h" #include "base/test/bind.h" #include "chrome/browser/profiles/profile.h" @@ -11,6 +11,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/prefs/pref_service.h" +#include "components/safe_browsing/content/browser/client_side_detection_service.h" #include "components/safe_browsing/content/common/safe_browsing.mojom.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/safe_browsing/core/proto/client_model.pb.h"
diff --git a/chrome/browser/safe_browsing/client_side_detection_service_delegate.cc b/chrome/browser/safe_browsing/client_side_detection_service_delegate.cc new file mode 100644 index 0000000..37c957ae --- /dev/null +++ b/chrome/browser/safe_browsing/client_side_detection_service_delegate.cc
@@ -0,0 +1,52 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/safe_browsing/client_side_detection_service_delegate.h" + +#include "chrome/browser/browser_process.h" +#include "chrome/browser/policy/chrome_browser_policy_connector.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/safe_browsing/safe_browsing_service.h" +#include "components/prefs/pref_service.h" +#include "components/safe_browsing/core/common/utils.h" + +namespace safe_browsing { + +ClientSideDetectionServiceDelegate::ClientSideDetectionServiceDelegate( + Profile* profile) + : profile_(profile) {} + +ClientSideDetectionServiceDelegate::~ClientSideDetectionServiceDelegate() = + default; + +PrefService* ClientSideDetectionServiceDelegate::GetPrefs() { + if (profile_) { + return profile_->GetPrefs(); + } + return nullptr; +} +scoped_refptr<network::SharedURLLoaderFactory> +ClientSideDetectionServiceDelegate::GetURLLoaderFactory() { + if (profile_) { + return profile_->GetURLLoaderFactory(); + } + return nullptr; +} + +scoped_refptr<network::SharedURLLoaderFactory> +ClientSideDetectionServiceDelegate::GetSafeBrowsingURLLoaderFactory() { + if (g_browser_process->safe_browsing_service()) { + return g_browser_process->safe_browsing_service()->GetURLLoaderFactory( + profile_); + } + return nullptr; +} + +ChromeUserPopulation::ProfileManagementStatus +ClientSideDetectionServiceDelegate::GetManagementStatus() { + return GetProfileManagementStatus( + g_browser_process->browser_policy_connector()); +} + +} // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/client_side_detection_service_delegate.h b/chrome/browser/safe_browsing/client_side_detection_service_delegate.h new file mode 100644 index 0000000..7720216 --- /dev/null +++ b/chrome/browser/safe_browsing/client_side_detection_service_delegate.h
@@ -0,0 +1,37 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_DELEGATE_H_ +#define CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_DELEGATE_H_ + +#include "components/safe_browsing/content/browser/client_side_detection_service.h" + +class Profile; + +namespace safe_browsing { + +// Delegate class which implements chrome specific bits for configuring +// the ClientSideDetectionService class. +class ClientSideDetectionServiceDelegate + : public ClientSideDetectionService::Delegate { + public: + explicit ClientSideDetectionServiceDelegate(Profile* profile); + ~ClientSideDetectionServiceDelegate() override; + + // ClientSideDetectionService::Delegate implementation. + PrefService* GetPrefs() override; + scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; + scoped_refptr<network::SharedURLLoaderFactory> + GetSafeBrowsingURLLoaderFactory() override; + ChromeUserPopulation::ProfileManagementStatus GetManagementStatus() override; + + private: + Profile* profile_; + + DISALLOW_COPY_AND_ASSIGN(ClientSideDetectionServiceDelegate); +}; + +} // namespace safe_browsing + +#endif // CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_DELEGATE_H_
diff --git a/chrome/browser/safe_browsing/client_side_detection_service_factory.cc b/chrome/browser/safe_browsing/client_side_detection_service_factory.cc index ed2b9b13..e1dbb67 100644 --- a/chrome/browser/safe_browsing/client_side_detection_service_factory.cc +++ b/chrome/browser/safe_browsing/client_side_detection_service_factory.cc
@@ -7,10 +7,11 @@ #include "base/command_line.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/safe_browsing/client_side_detection_service.h" +#include "chrome/browser/safe_browsing/client_side_detection_service_delegate.h" #include "chrome/common/chrome_switches.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/safe_browsing/buildflags.h" +#include "components/safe_browsing/content/browser/client_side_detection_service.h" #include "components/safe_browsing/core/features.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -53,7 +54,8 @@ return nullptr; Profile* profile = Profile::FromBrowserContext(context); - return new ClientSideDetectionService(profile); + return new ClientSideDetectionService( + std::make_unique<ClientSideDetectionServiceDelegate>(profile)); } content::BrowserContext*
diff --git a/chrome/browser/safe_browsing/client_side_detection_service_factory_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_service_factory_unittest.cc index 99b9436..b5816b1 100644 --- a/chrome/browser/safe_browsing/client_side_detection_service_factory_unittest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_service_factory_unittest.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/safe_browsing/client_side_detection_service_factory.h" #include "base/command_line.h" -#include "chrome/browser/safe_browsing/client_side_detection_service.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/testing_profile.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/safe_browsing/client_side_detection_service_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_service_unittest.cc index 4dcf33a..dcd2e92 100644 --- a/chrome/browser/safe_browsing/client_side_detection_service_unittest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_service_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/safe_browsing/client_side_detection_service.h" +#include "chrome/browser/safe_browsing/client_side_detection_service_delegate.h" #include <stdint.h> @@ -23,6 +23,7 @@ #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" +#include "components/safe_browsing/content/browser/client_side_detection_service.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/safe_browsing/core/proto/client_model.pb.h" #include "components/safe_browsing/core/proto/csd.pb.h" @@ -227,7 +228,8 @@ TEST_F(ClientSideDetectionServiceTest, ServiceObjectDeletedBeforeCallbackDone) { SetModelFetchResponses(); - csd_service_ = std::make_unique<ClientSideDetectionService>(profile_); + csd_service_ = std::make_unique<ClientSideDetectionService>( + std::make_unique<ClientSideDetectionServiceDelegate>(profile_)); profile_->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled, true); EXPECT_NE(csd_service_.get(), nullptr); // We delete the client-side detection service class even though the callbacks @@ -240,7 +242,8 @@ TEST_F(ClientSideDetectionServiceTest, SendClientReportPhishingRequest) { SetModelFetchResponses(); - csd_service_ = std::make_unique<ClientSideDetectionService>(profile_); + csd_service_ = std::make_unique<ClientSideDetectionService>( + std::make_unique<ClientSideDetectionServiceDelegate>(profile_)); csd_service_->SetURLLoaderFactoryForTesting(test_shared_loader_factory_); GURL url("http://a.com/"); @@ -296,7 +299,8 @@ TEST_F(ClientSideDetectionServiceTest, GetNumReportTest) { SetModelFetchResponses(); - csd_service_ = std::make_unique<ClientSideDetectionService>(profile_); + csd_service_ = std::make_unique<ClientSideDetectionService>( + std::make_unique<ClientSideDetectionServiceDelegate>(profile_)); base::queue<base::Time>& report_times = GetPhishingReportTimes(); base::Time now = base::Time::Now(); @@ -312,14 +316,16 @@ TEST_F(ClientSideDetectionServiceTest, CacheTest) { SetModelFetchResponses(); - csd_service_ = std::make_unique<ClientSideDetectionService>(profile_); + csd_service_ = std::make_unique<ClientSideDetectionService>( + std::make_unique<ClientSideDetectionServiceDelegate>(profile_)); TestCache(); } TEST_F(ClientSideDetectionServiceTest, IsPrivateIPAddress) { SetModelFetchResponses(); - csd_service_ = std::make_unique<ClientSideDetectionService>(profile_); + csd_service_ = std::make_unique<ClientSideDetectionService>( + std::make_unique<ClientSideDetectionServiceDelegate>(profile_)); EXPECT_TRUE(csd_service_->IsPrivateIPAddress("10.1.2.3")); EXPECT_TRUE(csd_service_->IsPrivateIPAddress("127.0.0.1")); @@ -343,7 +349,8 @@ TEST_F(ClientSideDetectionServiceTest, SetEnabledAndRefreshState) { // Check that the model isn't downloaded until the service is enabled. profile_->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled, false); - csd_service_ = std::make_unique<ClientSideDetectionService>(profile_); + csd_service_ = std::make_unique<ClientSideDetectionService>( + std::make_unique<ClientSideDetectionServiceDelegate>(profile_)); EXPECT_FALSE(csd_service_->enabled()); EXPECT_TRUE(csd_service_->model_loader_ == nullptr); @@ -391,7 +398,8 @@ profile_->GetPrefs()->SetBoolean(prefs::kSafeBrowsingScoutReportingEnabled, false); profile_->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnhanced, false); - csd_service_ = std::make_unique<ClientSideDetectionService>(profile_); + csd_service_ = std::make_unique<ClientSideDetectionService>( + std::make_unique<ClientSideDetectionServiceDelegate>(profile_)); // Safe Browsing is not enabled. EXPECT_EQ(csd_service_->model_loader_, nullptr);
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc index 8f9c14a..2a17226 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -59,7 +59,6 @@ #endif #if BUILDFLAG(SAFE_BROWSING_AVAILABLE) -#include "chrome/browser/safe_browsing/client_side_detection_service.h" #include "components/safe_browsing/content/password_protection/password_protection_service.h" #endif
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc index 285cb1f..f314ca5 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -47,7 +47,6 @@ #include "chrome/browser/extensions/browsertest_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/safe_browsing/client_side_detection_service.h" #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h" #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" #include "chrome/browser/safe_browsing/ui_manager.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_tab_observer.cc b/chrome/browser/safe_browsing/safe_browsing_tab_observer.cc index be8c216..44e5b59 100644 --- a/chrome/browser/safe_browsing/safe_browsing_tab_observer.cc +++ b/chrome/browser/safe_browsing/safe_browsing_tab_observer.cc
@@ -18,10 +18,11 @@ #include "mojo/public/cpp/bindings/associated_remote.h" #if BUILDFLAG(SAFE_BROWSING_AVAILABLE) -#include "chrome/browser/safe_browsing/client_side_detection_host.h" -#include "chrome/browser/safe_browsing/client_side_detection_service.h" +#include "chrome/browser/safe_browsing/client_side_detection_host_delegate.h" #include "chrome/browser/safe_browsing/client_side_detection_service_factory.h" #include "chrome/common/chrome_render_frame.mojom.h" +#include "components/safe_browsing/content/browser/client_side_detection_host.h" +#include "components/safe_browsing/content/browser/client_side_detection_service.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #endif @@ -55,7 +56,7 @@ if (IsSafeBrowsingEnabled(*prefs) && g_browser_process->safe_browsing_service() && csd_service) { safebrowsing_detection_host_ = - ClientSideDetectionHost::Create(web_contents); + ClientSideDetectionHostDelegate::CreateHost(web_contents); csd_service->AddClientSideDetectionHost( safebrowsing_detection_host_.get()); } @@ -80,7 +81,7 @@ if (safe_browsing && csd_service) { if (!safebrowsing_detection_host_.get()) { safebrowsing_detection_host_ = - ClientSideDetectionHost::Create(web_contents_); + ClientSideDetectionHostDelegate::CreateHost(web_contents_); csd_service->AddClientSideDetectionHost( safebrowsing_detection_host_.get()); }
diff --git a/chrome/browser/safe_browsing/services_delegate_desktop.h b/chrome/browser/safe_browsing/services_delegate_desktop.h index 00f0d802..d293a6b7 100644 --- a/chrome/browser/safe_browsing/services_delegate_desktop.h +++ b/chrome/browser/safe_browsing/services_delegate_desktop.h
@@ -8,7 +8,6 @@ #include <memory> #include "base/macros.h" -#include "chrome/browser/safe_browsing/client_side_detection_service.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_service.h" #include "chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h" #include "chrome/browser/safe_browsing/services_delegate.h"
diff --git a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/IdentityServicesProvider.java b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/IdentityServicesProvider.java index 28641b3..e5e7b2e 100644 --- a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/IdentityServicesProvider.java +++ b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/IdentityServicesProvider.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.signin.services; +import androidx.annotation.MainThread; import androidx.annotation.VisibleForTesting; import org.chromium.base.ThreadUtils; @@ -19,9 +20,7 @@ public class IdentityServicesProvider { private static IdentityServicesProvider sIdentityServicesProvider; - // TODO(https://crbug.com/1152718): Change the ctor to private once the derived - // signin.IdentityServicesProvider is removed - protected IdentityServicesProvider() {} + private IdentityServicesProvider() {} public static IdentityServicesProvider get() { if (sIdentityServicesProvider == null) { @@ -40,6 +39,7 @@ * @param profile The profile to get regarding identity manager. * @return a {@link IdentityManager} instance. */ + @MainThread public IdentityManager getIdentityManager(Profile profile) { ThreadUtils.assertOnUiThread(); IdentityManager result = IdentityServicesProviderJni.get().getIdentityManager(profile); @@ -48,19 +48,11 @@ } /** - * Getter for {@link IdentityManager} instance. - * Deprecated, use {@link IdentityServicesProvider#getIdentityManager(Profile)} instead. - */ - @Deprecated - public IdentityManager getIdentityManager() { - return getIdentityManager(Profile.getLastUsedRegularProfile()); - } - - /** * Getter for {@link AccountTrackerService} instance for given profile. * @param profile The profile to get regarding account tracker service. * @return a {@link AccountTrackerService} instance. */ + @MainThread public AccountTrackerService getAccountTrackerService(Profile profile) { ThreadUtils.assertOnUiThread(); AccountTrackerService result = @@ -70,19 +62,11 @@ } /** - * Getter for {@link AccountTrackerService} instance. - * Deprecated, use {@link IdentityServicesProvider#getAccountTrackerService(Profile)} instead. - */ - @Deprecated - public AccountTrackerService getAccountTrackerService() { - return getAccountTrackerService(Profile.getLastUsedRegularProfile()); - } - - /** * Getter for {@link SigninManager} instance for given profile. * @param profile The profile to get regarding sign-in manager. * @return a {@link SigninManager} instance. */ + @MainThread public SigninManager getSigninManager(Profile profile) { ThreadUtils.assertOnUiThread(); SigninManager result = IdentityServicesProviderJni.get().getSigninManager(profile); @@ -90,15 +74,6 @@ return result; } - /** - * Getter for {@link SigninManager} instance. - * Deprecated, use {@link IdentityServicesProvider#getSigninManager(Profile)} instead. - */ - @Deprecated - public SigninManager getSigninManager() { - return getSigninManager(Profile.getLastUsedRegularProfile()); - } - @NativeMethods public interface Natives { IdentityManager getIdentityManager(Profile profile);
diff --git a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SignOutDialogRenderTest.java b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SignOutDialogRenderTest.java index 1a8c405..046a4288 100644 --- a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SignOutDialogRenderTest.java +++ b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SignOutDialogRenderTest.java
@@ -4,10 +4,6 @@ package org.chromium.chrome.browser.signin.ui; -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.pressBack; -import static androidx.test.espresso.matcher.ViewMatchers.isRoot; - import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -38,6 +34,7 @@ import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.ChromeRenderTestRule; import org.chromium.components.signin.GAIAServiceType; +import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.DisableAnimationsTestRule; import org.chromium.ui.test.util.DummyUiActivityTestCase; @@ -69,6 +66,8 @@ @Mock private Profile mProfile; + private SignOutDialogFragment mSignOutDialog; + @Before public void setUp() { initMocks(this); @@ -82,7 +81,9 @@ public void tearDown() { // Since the Dialog dismiss calls native method, we need to close the dialog before the // Native mock SigninMetricsUtils.Natives gets removed. - onView(isRoot()).perform(pressBack()); + if (mSignOutDialog != null) { + TestThreadUtils.runOnUiThreadBlocking(() -> mSignOutDialog.dismiss()); + } } @Test @@ -101,10 +102,9 @@ } private View showSignOutDialog() { - SignOutDialogFragment signOutDialog = - SignOutDialogFragment.create(GAIAServiceType.GAIA_SERVICE_TYPE_NONE); - signOutDialog.show(getActivity().getSupportFragmentManager(), null); + mSignOutDialog = SignOutDialogFragment.create(GAIAServiceType.GAIA_SERVICE_TYPE_NONE); + mSignOutDialog.show(getActivity().getSupportFragmentManager(), null); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - return signOutDialog.getDialog().getWindow().getDecorView(); + return mSignOutDialog.getDialog().getWindow().getDecorView(); } }
diff --git a/chrome/browser/tracing/chrome_tracing_delegate.cc b/chrome/browser/tracing/chrome_tracing_delegate.cc index a218fbb..b2350696 100644 --- a/chrome/browser/tracing/chrome_tracing_delegate.cc +++ b/chrome/browser/tracing/chrome_tracing_delegate.cc
@@ -131,7 +131,8 @@ } bool ProfileAllowsScenario(const content::BackgroundTracingConfig& config, - PermitMissingProfile profile_permission) { + PermitMissingProfile profile_permission, + bool is_crash_scenario) { // If the background tracing is specified on the command-line, we allow // any scenario to be traced. auto* command_line = base::CommandLine::ForCurrentProcess(); @@ -151,6 +152,27 @@ return profile_permission != PROFILE_REQUIRED; } + PrefService* local_state = g_browser_process->local_state(); + DCHECK(local_state); + +#if !BUILDFLAG(IS_CHROMEOS_ASH) && defined(OFFICIAL_BUILD) + if (!local_state->GetBoolean(metrics::prefs::kMetricsReportingEnabled)) { + RecordDisallowedMetric( + TracingFinalizationDisallowedReason::kMetricsReportingDisabled); + return false; + } +#endif // !OS_CHROMEOS && OFFICIAL_BUILD + + // Skip the rest of the checks, we know that the scenario does not have + // incognito profile and metrics reporting is enabled. Skip the upload limit + // checks. + if (is_crash_scenario) { + // Maybe we shouldn't skip the browser crash test when session begins (when + // PROFILE_NOT_REQUIRED). + DCHECK_EQ(PROFILE_REQUIRED, profile_permission); + return true; + } + // Safeguard, in case background tracing is responsible for a crash on // startup. #if !defined(OS_ANDROID) @@ -177,17 +199,6 @@ } #endif - PrefService* local_state = g_browser_process->local_state(); - DCHECK(local_state); - -#if !BUILDFLAG(IS_CHROMEOS_ASH) && defined(OFFICIAL_BUILD) - if (!local_state->GetBoolean(metrics::prefs::kMetricsReportingEnabled)) { - RecordDisallowedMetric( - TracingFinalizationDisallowedReason::kMetricsReportingDisabled); - return false; - } -#endif // !OS_CHROMEOS && OFFICIAL_BUILD - if (config.tracing_mode() == content::BackgroundTracingConfig::PREEMPTIVE) { const base::Time last_upload_time = base::Time::FromInternalValue( local_state->GetInt64(prefs::kBackgroundTracingLastUpload)); @@ -210,8 +221,14 @@ bool ChromeTracingDelegate::IsAllowedToBeginBackgroundScenario( const content::BackgroundTracingConfig& config, bool requires_anonymized_data) { - if (!ProfileAllowsScenario(config, PROFILE_NOT_REQUIRED)) + // For crash-triggered traces, we can only support preemptive tracing. For + // such preemptive traces, the profile will not be loaded yet, and calling + // ProfileAllowsScenario() will return true to allow the trace to start, + // regardless of the value of is_crash_scenario. + if (!ProfileAllowsScenario(config, PROFILE_NOT_REQUIRED, + /*is_crash_scenario=*/false)) { return false; + } if (requires_anonymized_data && chrome::IsOffTheRecordSessionActive()) return false; @@ -221,7 +238,8 @@ bool ChromeTracingDelegate::IsAllowedToEndBackgroundScenario( const content::BackgroundTracingConfig& config, - bool requires_anonymized_data) { + bool requires_anonymized_data, + bool is_crash_scenario) { if (requires_anonymized_data && (incognito_launched_ || chrome::IsOffTheRecordSessionActive())) { RecordDisallowedMetric( @@ -229,7 +247,7 @@ return false; } - if (!ProfileAllowsScenario(config, PROFILE_REQUIRED)) + if (!ProfileAllowsScenario(config, PROFILE_REQUIRED, is_crash_scenario)) return false; if (config.tracing_mode() == content::BackgroundTracingConfig::PREEMPTIVE) {
diff --git a/chrome/browser/tracing/chrome_tracing_delegate.h b/chrome/browser/tracing/chrome_tracing_delegate.h index 49e922f..df31394 100644 --- a/chrome/browser/tracing/chrome_tracing_delegate.h +++ b/chrome/browser/tracing/chrome_tracing_delegate.h
@@ -44,7 +44,8 @@ bool IsAllowedToEndBackgroundScenario( const content::BackgroundTracingConfig& config, - bool requires_anonymized_data) override; + bool requires_anonymized_data, + bool is_crash_scenario) override; bool IsProfileLoaded() override;
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index e85de09..24f9c851 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-master-1608767282-7469f12bc7883325d24b820537c86a4836b7599a.profdata +chrome-linux-master-1608938443-5e2a6a5509ef0c35b284bb575c523599912f115a.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 406ef383..82ffbf63 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1608767282-017d7dadc4601ccad45290574822bb174972e9d0.profdata +chrome-mac-master-1608938443-813619ab6447ba11a985c78bfacde75dce409fd5.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 74d9b0a..95774ae 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1608692346-a5866de54d0b0b083300633703188b0bd8d56834.profdata +chrome-win64-master-1608913095-f136f8f83569a182f681a83edbe456e8f7d0cecd.profdata
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 6f25ca93..ab655a5a 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1078,6 +1078,7 @@ "../browser/loadtimes_extension_bindings_browsertest.cc", "../browser/locale_tests_browsertest.cc", "../browser/login_detection/login_detection_browsertest.cc", + "../browser/login_detection/password_store_sites_browsertest.cc", "../browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc", "../browser/media/autoplay_metrics_browsertest.cc", "../browser/media/cast_mirroring_performance_browsertest.cc",
diff --git a/chrome/test/data/webui/new_tab_page/utils_test.js b/chrome/test/data/webui/new_tab_page/utils_test.js index 19ad9f9..6795d37 100644 --- a/chrome/test/data/webui/new_tab_page/utils_test.js +++ b/chrome/test/data/webui/new_tab_page/utils_test.js
@@ -6,7 +6,7 @@ import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; import {createScrollBorders, decodeString16, mojoString16} from 'chrome://new-tab-page/new_tab_page.js'; -import {waitAfterNextRender} from 'chrome://test/test_util.m.js'; +import {flushTasks, waitAfterNextRender} from 'chrome://test/test_util.m.js'; suite('scroll borders', () => { /** @type {!HTMLElement} */ @@ -44,6 +44,7 @@ bottom = document.body.lastElementChild; observer = createScrollBorders(container, top, bottom, 'show'); await waitAfterNextRender(); + await flushTasks(); }); teardown(() => { @@ -58,6 +59,7 @@ test('borders shown when content available above and below', async () => { container.scrollTop = 10; await waitAfterNextRender(); + await flushTasks(); assertShown(top); assertShown(bottom); }); @@ -65,6 +67,7 @@ test('bottom border hidden when no content available below', async () => { container.scrollTop = 200; await waitAfterNextRender(); + await flushTasks(); assertShown(top); assertHidden(bottom); }); @@ -72,6 +75,7 @@ test('borders hidden when all content is shown', async () => { content.style.height = '100px'; await waitAfterNextRender(); + await flushTasks(); assertHidden(top); assertHidden(bottom); });
diff --git a/chrome/test/data/webui/test_util.js b/chrome/test/data/webui/test_util.js index e07d5f5..f0d8b88 100644 --- a/chrome/test/data/webui/test_util.js +++ b/chrome/test/data/webui/test_util.js
@@ -132,7 +132,7 @@ // Promises have microtask timing, so we use setTimeout to explicitly force // a new task. return new Promise(function(resolve, reject) { - window.setTimeout(resolve, 0); + window.setTimeout(resolve, 1); }); }
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index d1246b1..470481e 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -13681.0.0 \ No newline at end of file +13685.0.0 \ No newline at end of file
diff --git a/chromeos/components/camera_app_ui/camera_app_ui.cc b/chromeos/components/camera_app_ui/camera_app_ui.cc index b795142..3de983eb 100644 --- a/chromeos/components/camera_app_ui/camera_app_ui.cc +++ b/chromeos/components/camera_app_ui/camera_app_ui.cc
@@ -6,6 +6,7 @@ #include "ash/public/cpp/window_properties.h" #include "base/bind.h" +#include "base/strings/string_util.h" #include "chromeos/components/camera_app_ui/camera_app_helper_impl.h" #include "chromeos/components/camera_app_ui/resources.h" #include "chromeos/components/camera_app_ui/url_constants.h" @@ -63,6 +64,9 @@ source->OverrideContentSecurityPolicy( network::mojom::CSPDirectiveName::ChildSrc, std::string("frame-src ") + kChromeUIUntrustedCameraAppURL + ";"); + source->OverrideContentSecurityPolicy( + network::mojom::CSPDirectiveName::ObjectSrc, + std::string("object-src 'self';")); return source; } @@ -263,12 +267,15 @@ } const GURL& CameraAppUI::url() { - return web_ui()->GetWebContents()->GetURL(); + return web_ui()->GetWebContents()->GetLastCommittedURL(); } void CameraAppUI::DevToolsAgentHostAttached( content::DevToolsAgentHost* agent_host) { - if (agent_host->GetWebContents() != web_ui()->GetWebContents()) { + if (agent_host->GetWebContents() == nullptr || + !base::StartsWith( + agent_host->GetWebContents()->GetLastCommittedURL().spec(), + kChromeUICameraAppMainURL)) { return; } app_window_manager()->SetDevToolsEnabled(true); @@ -276,7 +283,10 @@ void CameraAppUI::DevToolsAgentHostDetached( content::DevToolsAgentHost* agent_host) { - if (agent_host->GetWebContents() != web_ui()->GetWebContents()) { + if (agent_host->GetWebContents() == nullptr || + !base::StartsWith( + agent_host->GetWebContents()->GetLastCommittedURL().spec(), + kChromeUICameraAppMainURL)) { return; } app_window_manager()->SetDevToolsEnabled(false);
diff --git a/chromeos/components/camera_app_ui/camera_app_window_manager.cc b/chromeos/components/camera_app_ui/camera_app_window_manager.cc index 655faf3..6a17f68 100644 --- a/chromeos/components/camera_app_ui/camera_app_window_manager.cc +++ b/chromeos/components/camera_app_ui/camera_app_window_manager.cc
@@ -35,7 +35,9 @@ base::Unretained(this), widget)); camera_usage_monitors_.emplace(widget, std::move(remote)); - widget->AddObserver(this); + if (!widget->HasObserver(this)) { + widget->AddObserver(this); + } std::move(callback).Run(); if (widget->IsVisible()) { @@ -130,11 +132,15 @@ } } +void CameraAppWindowManager::OnWidgetDestroying(views::Widget* widget) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + widget->RemoveObserver(this); +} + CameraAppWindowManager::CameraAppWindowManager() = default; void CameraAppWindowManager::OnMonitorMojoConnectionError( views::Widget* widget) { - widget->RemoveObserver(this); camera_usage_monitors_.erase(widget); if (pending_transfer_.has_value() && widget == *pending_transfer_) {
diff --git a/chromeos/components/camera_app_ui/camera_app_window_manager.h b/chromeos/components/camera_app_ui/camera_app_window_manager.h index 82945f8..25512e3 100644 --- a/chromeos/components/camera_app_ui/camera_app_window_manager.h +++ b/chromeos/components/camera_app_ui/camera_app_window_manager.h
@@ -45,6 +45,7 @@ // views::WidgetObserver: void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override; void OnWidgetActivationChanged(views::Widget* widget, bool active) override; + void OnWidgetDestroying(views::Widget* widget) override; private: CameraAppWindowManager();
diff --git a/chromeos/components/camera_app_ui/resources.h b/chromeos/components/camera_app_ui/resources.h index b157d7d..cf0ecf0 100644 --- a/chromeos/components/camera_app_ui/resources.h +++ b/chromeos/components/camera_app_ui/resources.h
@@ -58,6 +58,7 @@ {"barcode_copy_link_button", IDS_BARCODE_COPY_LINK_BUTTON}, {"barcode_copy_text_button", IDS_BARCODE_COPY_TEXT_BUTTON}, {"barcode_link_detected", IDS_BARCODE_LINK_DETECTED}, + {"barcode_text_detected", IDS_BARCODE_TEXT_DETECTED}, {"expert_mode_button", IDS_EXPERT_MODE_BUTTON}, {"expert_preview_metadata", IDS_EXPERT_PREVIEW_METADATA}, {"expert_save_metadata", IDS_EXPERT_SAVE_METADATA},
diff --git a/chromeos/components/camera_app_ui/resources/BUILD.gn b/chromeos/components/camera_app_ui/resources/BUILD.gn index 59078aa..58ad039f4 100644 --- a/chromeos/components/camera_app_ui/resources/BUILD.gn +++ b/chromeos/components/camera_app_ui/resources/BUILD.gn
@@ -91,6 +91,7 @@ "js/sound.js", "js/state.js", "js/test_bridge.js", + "js/timer.js", "js/toast.js", "js/tooltip.js", "js/type.js",
diff --git a/chromeos/components/camera_app_ui/resources/camera_app_resources.grd b/chromeos/components/camera_app_ui/resources/camera_app_resources.grd index f212340..6bc25a6 100644 --- a/chromeos/components/camera_app_ui/resources/camera_app_resources.grd +++ b/chromeos/components/camera_app_ui/resources/camera_app_resources.grd
@@ -77,6 +77,7 @@ <structure name="IDR_CAMERA_TEST_BRIDGE_JS" file="js/test_bridge.js" type="chrome_html" /> <structure name="IDR_CAMERA_TEST_HTML" file="test/test.html" type="chrome_html" /> <structure name="IDR_CAMERA_TEST_LEGACY_HTML" file="views/test.html" type="chrome_html" /> + <structure name="IDR_CAMERA_TIMER_JS" file="js/timer.js" type="chrome_html" /> <structure name="IDR_CAMERA_TIMERTICK_JS" file="js/views/camera/timertick.js" type="chrome_html" /> <structure name="IDR_CAMERA_TOAST_JS" file="js/toast.js" type="chrome_html" /> <structure name="IDR_CAMERA_TOOLTIP_JS" file="js/tooltip.js" type="chrome_html" />
diff --git a/chromeos/components/camera_app_ui/resources/css/main.css b/chromeos/components/camera_app_ui/resources/css/main.css index a32f445..0b88716a 100644 --- a/chromeos/components/camera_app_ui/resources/css/main.css +++ b/chromeos/components/camera_app_ui/resources/css/main.css
@@ -3,6 +3,7 @@ * found in the LICENSE file. */ :root { + /* Standard CrOS styles */ --blue-300-rgb: 138, 180, 248; --blue-300: rgb(var(--blue-300-rgb)); --blue-600-dark-rgb: 37, 129, 223; @@ -11,6 +12,18 @@ --grey-200: rgb(232, 234, 237); --grey-900: rgb(32, 33, 36); + --fast1-duration: 100ms; + --fast2-duration: 200ms; + --moderate1-duration: 250ms; + --moderate2-duration: 500ms; + --slow1-duration: 600ms; + --slow2-duration: 1000ms; + + --standard-easing: cubic-bezier(0.4, 0, 0.2, 1); + --enter-easing: cubic-bezier(0, 0, 0.2, 1); + --exit-easing: cubic-bezier(0.4, 0, 1, 1); + + /* App specific settings */ --focus-color: rgba(var(--blue-600-dark-rgb), 0.7); } @@ -60,12 +73,12 @@ border: 2px solid var(--focus-color); border-radius: 4px; - bottom: calc(0px - var(--focus-ring-size)); + bottom: calc(-1 * var(--focus-ring-size)); content: ''; - left: calc(0px - var(--focus-ring-size)); + left: calc(-1 * var(--focus-ring-size)); position: absolute; - right: calc(0px - var(--focus-ring-size)); - top: calc(0px - var(--focus-ring-size)); + right: calc(-1 * var(--focus-ring-size)); + top: calc(-1 * var(--focus-ring-size)); } .cancel-animate { @@ -134,13 +147,13 @@ opacity: 1; position: absolute; transform: translateX(-50%); - transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1); + transition: opacity var(--fast2-duration) var(--standard-easing); visibility: visible; } body.taking.video .left-stripe { opacity: 0; - transition: visibility 0ms 225ms, opacity 225ms cubic-bezier(0.4, 0, 0.2, 1); + transition: visibility 0ms 225ms, opacity 225ms var(--standard-easing); visibility: hidden; } @@ -203,19 +216,41 @@ flex-direction: column-reverse; } -#modes-group { +#mode-selector { --fade-padding: 16px; + --scrollbar-height: 5px; - -webkit-mask-image: linear-gradient(to left, - rgba(0, 0, 0, 0) 0, - rgba(0, 0, 0, 1) var(--fade-padding) calc(100% - var(--fade-padding)), - rgba(0, 0, 0, 0) 100%); - display: block; left: calc(var(--left-line) * 2); + right: calc(var(--right-line) * 2); +} + +#mode-selector::before, +#mode-selector::after { + background: linear-gradient(to right, black, transparent); + content: ''; + display: block; + height: calc(100% - var(--scrollbar-height)); + pointer-events: none; + position: absolute; + top: 0; + width: var(--fade-padding); + z-index: 2; +} + +#mode-selector::before { + left: 0; +} + +#mode-selector::after { + right: 0; + transform: scaleX(-1); +} + +#modes-group { + display: block; overflow: auto; padding: 5px 0; pointer-events: auto; - right: calc(var(--right-line) * 2); text-align: center; white-space: nowrap; } @@ -234,7 +269,7 @@ } #modes-group::-webkit-scrollbar { - height: 5px; + height: var(--scrollbar-height); width: auto; } @@ -297,6 +332,14 @@ display: none; } +#modes-group .mode-item.first { + margin-inline-start: var(--fade-padding); +} + +#modes-group .mode-item.last { + margin-inline-end: var(--fade-padding); +} + div.mode-item>span { border-radius: 16px/50%; color: white; @@ -309,10 +352,6 @@ z-index: 0; } -#modes-group.hide { - visibility: hidden; -} - .mode-item>input { height: 100%; position: absolute; @@ -332,7 +371,7 @@ } body.tab-navigation .mode-item>input:focus + span::after { - --negative-size: calc(0px - var(--focus-ring-gap)); + --negative-size: calc(-1 * var(--focus-ring-gap)); border: var(--focus-ring-border) solid var(--focus-color); border-radius: 23px/50%; @@ -418,7 +457,6 @@ #recordvideo, #pause-recordvideo { - --curve: cubic-bezier(0.4, 0, 0.2, 1); --dot-size: 25%; --durtaion: 180ms; --red: #f44336; @@ -430,7 +468,7 @@ border-radius: 50%; height: var(--size); position: relative; - transition: var(--durtaion) var(--curve); + transition: var(--durtaion) var(--standard-easing); width: var(--size); } @@ -454,7 +492,7 @@ position: absolute; top: 50%; transform: translate(-50%, -50%); - transition: var(--durtaion) var(--curve); + transition: var(--durtaion) var(--standard-easing); width: var(--dot-size); } @@ -475,7 +513,7 @@ opacity: 0; position: absolute; top: 50%; - transition: var(--durtaion) var(--square-delay) var(--curve); + transition: var(--durtaion) var(--square-delay) var(--standard-easing); width: 0; } @@ -553,7 +591,8 @@ #timer-tick-msg.animate { opacity: 0.2; transform: scale(1.8, 1.8); - transition: transform 500ms ease-out, opacity 500ms ease-out; + transition: transform var(--moderate1-duration) ease-out, + opacity var(--moderate1-duration) ease-out; visibility: visible; } @@ -718,7 +757,7 @@ body.view-warning #view-warning, body.view-splash #view-splash { opacity: 1; - transition: opacity 100ms; + transition: opacity var(--fast1-duration); visibility: visible; } @@ -826,7 +865,7 @@ } #preview-video { - transition: opacity 200ms ease-in-out; + transition: opacity var(--fast2-duration) ease-in-out; } #preview-video.animate { @@ -1144,7 +1183,7 @@ } #banner.animate { - animation: emerge 6000ms cubic-bezier(0.0, 0.0, 0.2, 1); + animation: emerge 6000ms var(--enter-easing); display: block; } @@ -1155,7 +1194,7 @@ } 8%, 92% { - animation-timing-function: cubic-bezier(0.4, 0.0, 1.0, 1.0); + animation-timing-function: var(--exit-easing); bottom: 31px; } } @@ -1258,7 +1297,7 @@ button.menu-item.animate::before, label.menu-item.animate::before { - animation: inkdrop 500ms ease-out; + animation: inkdrop var(--moderate1-duration) ease-out; } @keyframes inkdrop { @@ -1344,7 +1383,7 @@ left: 12px; right: 12px; top: 12px; - transition: border-width 100ms ease-in; + transition: border-width var(--fast1-duration) ease-in; } body.tab-navigation button.menu-item:focus::after { @@ -1436,7 +1475,7 @@ flex-direction: column; padding: 20px; transform: translateY(20px); - transition: transform 200ms; + transition: transform var(--fast2-duration); } .dialog .dialog-popup { @@ -1564,30 +1603,18 @@ .barcode-chip-container { --chip-height: 32px; left: 50%; - opacity: 0; + opacity: 1; position: absolute; top: 10%; transform: translateX(-50%); + transition: opacity var(--moderate1-duration) var(--standard-easing); z-index: 50; } -/* TODO(b/172879638): Tune the animation according to the final motion spec. */ -.barcode-chip-container.animate { - /* TODO(b/172879638): This might be too short for long text. */ - animation: 8s show-barcode-chip ease-out; -} - -@keyframes show-barcode-chip { - 0% { - opacity: 0; - } - 3%, - 97% { - opacity: 1; - } - 100% { - opacity: 0; - } +.barcode-chip-container.invisible { + opacity: 0; + transition: opacity var(--moderate1-duration) var(--standard-easing), + visibility 0s var(--moderate1-duration); } .barcode-chip-url { @@ -1672,10 +1699,6 @@ width: 416px; } -#barcode-chip-text-expand.hide { - display: none; -} - #barcode-chip-text-expand { background: url(/images/barcode_chevron_down.svg) center no-repeat; height: 40px; @@ -1730,3 +1753,7 @@ .hidden { display: none; } + +.invisible { + visibility: hidden; +}
diff --git a/chromeos/components/camera_app_ui/resources/js/BUILD.gn b/chromeos/components/camera_app_ui/resources/js/BUILD.gn index 368415ae..e503061 100644 --- a/chromeos/components/camera_app_ui/resources/js/BUILD.gn +++ b/chromeos/components/camera_app_ui/resources/js/BUILD.gn
@@ -98,6 +98,7 @@ "sound.js", "state.js", "test_bridge.js", + "timer.js", "toast.js", "tooltip.js", "type.js",
diff --git a/chromeos/components/camera_app_ui/resources/js/barcode_chip.js b/chromeos/components/camera_app_ui/resources/js/barcode_chip.js index 9505344..abdc00e 100644 --- a/chromeos/components/camera_app_ui/resources/js/barcode_chip.js +++ b/chromeos/components/camera_app_ui/resources/js/barcode_chip.js
@@ -3,9 +3,14 @@ // found in the LICENSE file. import {browserProxy} from './browser_proxy/browser_proxy.js'; +import {assert} from './chrome_util.js'; import * as dom from './dom.js'; import * as snackbar from './snackbar.js'; -import * as util from './util.js'; +import * as state from './state.js'; +import {OneShotTimer} from './timer.js'; + +// TODO(b/172879638): Tune the duration according to the final motion spec. +const CHIP_DURATION = 8000; /** * The detected string that is being shown currently. @@ -20,14 +25,37 @@ let currentChip = null; /** - * Resets the variables of the current state. + * The countdown timer for dismissing the chip. + * @type {?OneShotTimer} */ -function resetCurrentState() { +let currentTimer = null; + +/** + * Resets the variables of the current state and dismisses the chip. + */ +function deactivate() { if (currentChip !== null) { - currentChip.classList.add('hidden'); + currentChip.classList.add('invisible'); } currentCode = null; currentChip = null; + currentTimer = null; +} + +/** + * Activates the chip on container and starts the timer. + * @param {!HTMLElement} container The container of the chip. + */ +function activate(container) { + container.classList.remove('invisible'); + currentChip = container; + + currentTimer = new OneShotTimer(deactivate, CHIP_DURATION); + if (state.get(state.State.TAB_NAVIGATION)) { + // Do not auto dismiss the chip when using keyboard for a11y. Screen reader + // might need long time to read the detected content. + currentTimer.stop(); + } } /** @@ -54,6 +82,7 @@ * @param {string} content The content to be copied. * @param {string} snackbarLabel The label to be displayed on snackbar when the * content is copied. + * @return {!HTMLElement} The copy button element. */ function setupCopyButton(container, content, snackbarLabel) { const copyButton = @@ -62,6 +91,7 @@ await navigator.clipboard.writeText(content); snackbar.show(snackbarLabel); }; + return copyButton; } /** @@ -70,7 +100,7 @@ */ function showUrl(url) { const container = dom.get('#barcode-chip-url-container', HTMLDivElement); - container.classList.remove('hidden'); + activate(container); const anchor = dom.getFrom(container, 'a', HTMLAnchorElement); Object.assign(anchor, { @@ -84,9 +114,6 @@ anchor.focus(); setupCopyButton(container, url, 'snackbar_link_copied'); - - currentChip = container; - util.animateOnce(container, resetCurrentState); } /** @@ -95,23 +122,30 @@ */ function showText(text) { const container = dom.get('#barcode-chip-text-container', HTMLDivElement); - container.classList.remove('hidden', 'expanded'); + activate(container); + container.classList.remove('expanded'); const textEl = dom.get('#barcode-chip-text-content', HTMLDivElement); textEl.textContent = text; const expandable = textEl.scrollWidth > textEl.clientWidth; const expandEl = dom.get('#barcode-chip-text-expand', HTMLButtonElement); - expandEl.classList.toggle('hide', !expandable); + expandEl.classList.toggle('hidden', !expandable); expandEl.onclick = () => { container.classList.toggle('expanded'); + const expanded = container.classList.contains('expanded'); + expandEl.setAttribute('aria-expanded', expanded.toString()); }; - setupCopyButton(container, text, 'snackbar_text_copied'); + const copyButton = setupCopyButton(container, text, 'snackbar_text_copied'); - // TODO(b/172879638): Handle a11y. - currentChip = container; - util.animateOnce(container, resetCurrentState); + // TODO(b/172879638): There is a race in ChromeVox which will speak the + // focused element twice. + if (expandable) { + expandEl.focus(); + } else { + copyButton.focus(); + } } /** @@ -120,11 +154,17 @@ */ export async function show(code) { if (code === currentCode) { + if (currentTimer !== null) { + // Extend the duration by resetting the timeout. + currentTimer.resetTimeout(); + } return; } - if (currentChip !== null) { - await util.animateCancel(currentChip); + if (currentTimer !== null) { + // Dismiss the previous chip. + currentTimer.fireNow(); + assert(currentTimer === null, 'The timer should be cleared.'); } currentCode = code;
diff --git a/chromeos/components/camera_app_ui/resources/js/timer.js b/chromeos/components/camera_app_ui/resources/js/timer.js new file mode 100644 index 0000000..eb43d4c1 --- /dev/null +++ b/chromeos/components/camera_app_ui/resources/js/timer.js
@@ -0,0 +1,77 @@ +// 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. + +import {assert} from './chrome_util.js'; + +/** + * A one-shot timer that is more powerful than setTimeout(). + */ +export class OneShotTimer { + /** + * The parameters are same as the parameters of setTimeout(). + * @param {function()} handler + * @param {number} timeout + */ + constructor(handler, timeout) { + /** + * @type {function()} + * @const + * @private + */ + this.handler_ = handler; + + /** + * @type {number} + * @const + * @private + */ + this.timeout_ = timeout; + + /** + * @type {number} + * @private + */ + this.timeoutId_ = 0; + + this.start(); + } + + /** + * Starts the timer. + */ + start() { + assert(this.timeoutId_ === 0); + this.timeoutId_ = setTimeout(this.handler_, this.timeout_); + } + + /** + * Stops the pending timeout. + */ + stop() { + assert(this.timeoutId_ !== 0); + clearTimeout(this.timeoutId_); + this.timeoutId_ = 0; + } + + /** + * Resets the timer delay. It's a no-op if the timer is already stopped. + */ + resetTimeout() { + if (this.timeoutId_ === 0) { + return; + } + this.stop(); + this.start(); + } + + /** + * Stops the timer and runs the scheduled handler immediately. + */ + fireNow() { + if (this.timeoutId_ !== 0) { + this.stop(); + } + this.handler_(); + } +}
diff --git a/chromeos/components/camera_app_ui/resources/js/views/camera/mode/index.js b/chromeos/components/camera_app_ui/resources/js/views/camera/mode/index.js index 28200ed..1a181e8 100644 --- a/chromeos/components/camera_app_ui/resources/js/views/camera/mode/index.js +++ b/chromeos/components/camera_app_ui/resources/js/views/camera/mode/index.js
@@ -344,14 +344,25 @@ */ async updateModeSelectionUI(deviceId) { const supportedModes = await this.getSupportedModes(deviceId); - dom.getAll('div.mode-item', HTMLDivElement).forEach((element) => { - const radio = dom.getFrom(element, 'input[type=radio]', HTMLInputElement); - element.classList.toggle( - 'hide', - !supportedModes.includes( - /** @type {!Mode} */ (radio.dataset['mode']))); + const items = dom.getAll('div.mode-item', HTMLDivElement); + let first = null; + let last = null; + items.forEach((el) => { + const radio = dom.getFrom(el, 'input[type=radio]', HTMLInputElement); + const supported = + supportedModes.includes(/** @type {!Mode} */ (radio.dataset['mode'])); + el.classList.toggle('hide', !supported); + if (supported) { + if (first === null) { + first = el; + } + last = el; + } }); - this.modesGroup_.classList.remove('hide'); + items.forEach((el) => { + el.classList.toggle('first', el === first); + el.classList.toggle('last', el === last); + }); } /**
diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings.grd b/chromeos/components/camera_app_ui/resources/strings/camera_strings.grd index 28c6f9f..da1d6e7d 100644 --- a/chromeos/components/camera_app_ui/resources/strings/camera_strings.grd +++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings.grd
@@ -333,9 +333,12 @@ <message desc="Label for the copy button of the barcode text chip." name="IDS_BARCODE_COPY_TEXT_BUTTON"> Copy text </message> - <message desc="Label for the copy button of the barcode text chip." name="IDS_BARCODE_LINK_DETECTED"> + <message desc="Label for detected link on the barcode chip." name="IDS_BARCODE_LINK_DETECTED"> Link detected. <ph name="hostname">$1<ex>www.google.com</ex></ph> </message> + <message desc="Label for detected text on the barcode chip." name="IDS_BARCODE_TEXT_DETECTED"> + Text detected. + </message> <message desc="Label for the button of expert mode options." name="IDS_EXPERT_MODE_BUTTON"> Expert mode </message>
diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings_grd/IDS_BARCODE_TEXT_DETECTED.png.sha1 b/chromeos/components/camera_app_ui/resources/strings/camera_strings_grd/IDS_BARCODE_TEXT_DETECTED.png.sha1 new file mode 100644 index 0000000..330de04c --- /dev/null +++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings_grd/IDS_BARCODE_TEXT_DETECTED.png.sha1
@@ -0,0 +1 @@ +a30cac172fff5a3100eacf1eb31e092fd2afe618 \ No newline at end of file
diff --git a/chromeos/components/camera_app_ui/resources/views/main.html b/chromeos/components/camera_app_ui/resources/views/main.html index 67511d4b..84a2678f 100644 --- a/chromeos/components/camera_app_ui/resources/views/main.html +++ b/chromeos/components/camera_app_ui/resources/views/main.html
@@ -102,34 +102,36 @@ <div class="two-bars"></div> </button> </div> - <div id="modes-group" class="buttons bottom-stripe hide"> - <div class="mode-item"> - <input type="radio" name="mode" - data-mode="video" tabindex="0" - i18n-aria="switch_record_video_button"> - <span i18n-content="label_switch_record_video_button" - aria-hidden="true"></span> - </div> - <div class="mode-item"> - <input type="radio" name="mode" - data-mode="photo" tabindex="0" - i18n-aria="switch_take_photo_button"> - <span i18n-content="label_switch_take_photo_button" - aria-hidden="true"></span> - </div> - <div class="mode-item"> - <input type="radio" name="mode" - data-mode="square" tabindex="0" - i18n-aria="switch_take_square_photo_button"> - <span i18n-content="label_switch_take_square_photo_button" - aria-hidden="true"></span> - </div> - <div class="mode-item hide"> - <input type="radio" name="mode" - data-mode="portrait" tabindex="0" - i18n-aria="switch_take_portrait_photo_button"> - <span i18n-content="label_switch_take_portrait_photo_button" - aria-hidden="true"></span> + <div id="mode-selector" class="bottom-stripe"> + <div id="modes-group" class="buttons"> + <div class="mode-item"> + <input type="radio" name="mode" + data-mode="video" tabindex="0" + i18n-aria="switch_record_video_button"> + <span i18n-content="label_switch_record_video_button" + aria-hidden="true"></span> + </div> + <div class="mode-item"> + <input type="radio" name="mode" + data-mode="photo" tabindex="0" + i18n-aria="switch_take_photo_button"> + <span i18n-content="label_switch_take_photo_button" + aria-hidden="true"></span> + </div> + <div class="mode-item"> + <input type="radio" name="mode" + data-mode="square" tabindex="0" + i18n-aria="switch_take_square_photo_button"> + <span i18n-content="label_switch_take_square_photo_button" + aria-hidden="true"></span> + </div> + <div class="mode-item"> + <input type="radio" name="mode" + data-mode="portrait" tabindex="0" + i18n-aria="switch_take_portrait_photo_button"> + <span i18n-content="label_switch_take_portrait_photo_button" + aria-hidden="true"></span> + </div> </div> </div> <div class="bottom-stripe right-stripe buttons circle"> @@ -404,7 +406,8 @@ </div> </div> <div id="toast" class="centered-overlay" aria-live="polite"></div> - <div id="barcode-chip-url-container" class="hidden barcode-chip-container"> + <div id="barcode-chip-url-container" + class="invisible barcode-chip-container"> <div class="barcode-chip-url"> <a target="_blank"></a> </div> @@ -413,10 +416,13 @@ i18n-label="barcode_copy_link_button"></button> </div> </div> - <div id="barcode-chip-text-container" class="hidden barcode-chip-container"> + <div id="barcode-chip-text-container" + class="invisible barcode-chip-container" + role="dialog" i18n-label="barcode_text_detected" + aria-live="polite" aria-describedby="barcode-chip-text-content"> <div class="barcode-chip-text"> <div id="barcode-chip-text-content"></div> - <button id="barcode-chip-text-expand"></button> + <button id="barcode-chip-text-expand" aria-expanded="false"></button> </div> <div class="circle"> <button class="barcode-copy-button" tabindex="0"
diff --git a/codelabs/OWNERS b/codelabs/OWNERS index e2fe7c6..647e878 100644 --- a/codelabs/OWNERS +++ b/codelabs/OWNERS
@@ -1,4 +1,5 @@ * # Primary +asully@chromium.org pwnall@chromium.org \ No newline at end of file
diff --git a/components/safe_browsing/content/browser/BUILD.gn b/components/safe_browsing/content/browser/BUILD.gn index 20befe8..2480b6fd 100644 --- a/components/safe_browsing/content/browser/BUILD.gn +++ b/components/safe_browsing/content/browser/BUILD.gn
@@ -81,3 +81,36 @@ "//testing/gtest", ] } + +source_set("client_side_detection") { + sources = [ + "client_side_detection_host.cc", + "client_side_detection_host.h", + "client_side_detection_service.cc", + "client_side_detection_service.h", + ] + deps = [ + ":client_side_model_loader", + "//base:base", + "//components/prefs", + "//components/safe_browsing:buildflags", + "//components/safe_browsing/content", + "//components/safe_browsing/content/common:interfaces", + "//components/safe_browsing/core:client_model_proto", + "//components/safe_browsing/core:csd_proto", + "//components/safe_browsing/core:features", + "//components/safe_browsing/core/common", + "//components/safe_browsing/core/common:safe_browsing_prefs", + "//components/safe_browsing/core/db:allowlist_checker_client", + "//components/safe_browsing/core/db:database_manager", + "//components/safe_browsing/core/db:v4_protocol_manager_util", + "//components/security_interstitials/content:security_interstitial_page", + "//components/variations", + "//content/public/browser", + "//google_apis:google_apis", + "//net:net", + "//net/traffic_annotation:traffic_annotation", + "//services/network/public/cpp", + "//url:url", + ] +}
diff --git a/components/safe_browsing/content/browser/DEPS b/components/safe_browsing/content/browser/DEPS index 3e20f42..869cfc2a 100644 --- a/components/safe_browsing/content/browser/DEPS +++ b/components/safe_browsing/content/browser/DEPS
@@ -3,6 +3,7 @@ "+components/safe_browsing/core/proto/csd.pb.h", "+components/sessions/core/session_id.h", "+content/public/browser", + "+crypto/sha2.h", "+ipc/ipc_message.h", "+net/cookies", "+net/extras", @@ -12,6 +13,7 @@ "+services/network/network_context.h", "+services/network/public", "+services/service_manager/public/cpp", + "+third_party/blink/public/mojom/loader", ] specific_include_rules = {
diff --git a/chrome/browser/safe_browsing/client_side_detection_host.cc b/components/safe_browsing/content/browser/client_side_detection_host.cc similarity index 89% rename from chrome/browser/safe_browsing/client_side_detection_host.cc rename to components/safe_browsing/content/browser/client_side_detection_host.cc index 747e6f95..9529716d 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host.cc +++ b/components/safe_browsing/content/browser/client_side_detection_host.cc
@@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/safe_browsing/client_side_detection_host.h" +#include "components/safe_browsing/content/browser/client_side_detection_host.h" #include <memory> #include <utility> @@ -18,18 +18,14 @@ #include "base/sequenced_task_runner_helpers.h" #include "base/time/default_tick_clock.h" #include "base/time/tick_clock.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/safe_browsing/client_side_detection_service.h" -#include "chrome/browser/safe_browsing/client_side_detection_service_factory.h" -#include "chrome/browser/safe_browsing/safe_browsing_service.h" -#include "chrome/browser/safe_browsing/user_interaction_observer.h" #include "components/prefs/pref_service.h" +#include "components/safe_browsing/content/browser/client_side_detection_service.h" #include "components/safe_browsing/content/common/safe_browsing.mojom-shared.h" #include "components/safe_browsing/content/common/safe_browsing.mojom.h" #include "components/safe_browsing/core/db/allowlist_checker_client.h" #include "components/safe_browsing/core/db/database_manager.h" #include "components/security_interstitials/content/unsafe_resource_util.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" @@ -111,15 +107,14 @@ } // Don't start classification if |url_| is whitelisted by enterprise policy. - Profile* profile = - Profile::FromBrowserContext(web_contents_->GetBrowserContext()); - if (profile && IsURLWhitelistedByPolicy(url_, *profile->GetPrefs())) { - DontClassifyForPhishing(NO_CLASSIFY_ALLOWLISTED_BY_POLICY); + if (host_->delegate_->GetPrefs() && + IsURLWhitelistedByPolicy(url_, *host_->delegate_->GetPrefs())) { + DontClassifyForPhishing(NO_CLASSIFY_WHITELISTED_BY_POLICY); } // If the tab has a delayed warning, ignore this second verdict. We don't // want to immediately undelay a page that's already blocked as phishy. - if (SafeBrowsingUserInteractionObserver::FromWebContents(web_contents_)) { + if (host_->delegate_->HasSafeBrowsingUserInteractionObserver()) { DontClassifyForPhishing(NO_CLASSIFY_HAS_DELAYED_WARNING); } @@ -164,7 +159,7 @@ NO_CLASSIFY_RESULT_FROM_CACHE = 9, DEPRECATED_NO_CLASSIFY_NOT_HTTP_URL = 10, NO_CLASSIFY_SCHEME_NOT_SUPPORTED = 11, - NO_CLASSIFY_ALLOWLISTED_BY_POLICY = 12, + NO_CLASSIFY_WHITELISTED_BY_POLICY = 12, CLASSIFY = 13, NO_CLASSIFY_HAS_DELAYED_WARNING = 14, @@ -172,7 +167,7 @@ }; // The destructor can be called either from the UI or the IO thread. - virtual ~ShouldClassifyUrlRequest() { } + virtual ~ShouldClassifyUrlRequest() = default; bool ShouldClassifyForPhishing() const { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -288,27 +283,29 @@ // static std::unique_ptr<ClientSideDetectionHost> ClientSideDetectionHost::Create( - WebContents* tab) { - return base::WrapUnique(new ClientSideDetectionHost(tab)); + content::WebContents* tab, + std::unique_ptr<Delegate> delegate) { + return base::WrapUnique( + new ClientSideDetectionHost(tab, std::move(delegate))); } -ClientSideDetectionHost::ClientSideDetectionHost(WebContents* tab) +ClientSideDetectionHost::ClientSideDetectionHost( + WebContents* tab, + std::unique_ptr<Delegate> delegate) : content::WebContentsObserver(tab), csd_service_(nullptr), tab_(tab), classification_request_(nullptr), - tick_clock_(base::DefaultTickClock::GetInstance()) { + tick_clock_(base::DefaultTickClock::GetInstance()), + delegate_(std::move(delegate)) { DCHECK(tab); // Note: csd_service_ and sb_service will be nullptr here in testing. - csd_service_ = ClientSideDetectionServiceFactory::GetForProfile( - Profile::FromBrowserContext(tab->GetBrowserContext())); + csd_service_ = delegate_->GetClientSideDetectionService(); - scoped_refptr<SafeBrowsingService> sb_service = - g_browser_process->safe_browsing_service(); - if (sb_service.get()) { - ui_manager_ = sb_service->ui_manager(); - database_manager_ = sb_service->database_manager(); - } + // ui_manager_ and database_manager_ can be null if safe browsing + // service is not available in the embedder. + ui_manager_ = delegate_->GetSafeBrowsingUIManager(); + database_manager_ = delegate_->GetSafeBrowsingDBManager(); } ClientSideDetectionHost::~ClientSideDetectionHost() { @@ -428,8 +425,7 @@ // We parse the protocol buffer here. If we're unable to parse it we won't // send the verdict further. std::unique_ptr<ClientPhishingRequest> verdict(new ClientPhishingRequest); - if (csd_service_ && - verdict->ParseFromString(verdict_str) && + if (csd_service_ && verdict->ParseFromString(verdict_str) && verdict->IsInitialized()) { VLOG(2) << "Phishing classification score: " << verdict->client_score(); for (auto& match : verdict->vision_match()) { @@ -437,10 +433,8 @@ VLOG(2) << "Phash Score: " << match.vision_matched_phash_score(); VLOG(2) << "EMD Score: " << match.vision_matched_emd_score(); } - Profile* profile = - Profile::FromBrowserContext(web_contents()->GetBrowserContext()); - if (!IsExtendedReportingEnabled(*profile->GetPrefs()) && - !IsEnhancedProtectionEnabled(*profile->GetPrefs())) { + if (!IsExtendedReportingEnabled(*delegate_->GetPrefs()) && + !IsEnhancedProtectionEnabled(*delegate_->GetPrefs())) { // These fields should only be set for SBER users. verdict->clear_screenshot_digest(); verdict->clear_screenshot_phash(); @@ -456,11 +450,10 @@ base::BindOnce(&ClientSideDetectionHost::MaybeShowPhishingWarning, weak_factory_.GetWeakPtr(), /*is_from_cache=*/false); - Profile* profile = - Profile::FromBrowserContext(web_contents()->GetBrowserContext()); csd_service_->SendClientReportPhishingRequest( - std::move(verdict), IsExtendedReportingEnabled(*profile->GetPrefs()), - IsEnhancedProtectionEnabled(*profile->GetPrefs()), + std::move(verdict), + IsExtendedReportingEnabled(*delegate_->GetPrefs()), + IsEnhancedProtectionEnabled(*delegate_->GetPrefs()), std::move(callback)); } } @@ -510,8 +503,7 @@ csd_service_ = service; } -void ClientSideDetectionHost::set_ui_manager( - SafeBrowsingUIManager* ui_manager) { +void ClientSideDetectionHost::set_ui_manager(BaseUIManager* ui_manager) { ui_manager_ = ui_manager; }
diff --git a/chrome/browser/safe_browsing/client_side_detection_host.h b/components/safe_browsing/content/browser/client_side_detection_host.h similarity index 72% rename from chrome/browser/safe_browsing/client_side_detection_host.h rename to components/safe_browsing/content/browser/client_side_detection_host.h index ce343b8..0617888 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host.h +++ b/components/safe_browsing/content/browser/client_side_detection_host.h
@@ -1,9 +1,9 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_H_ -#define CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_H_ +#ifndef COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_CLIENT_SIDE_DETECTION_HOST_H_ +#define COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_CLIENT_SIDE_DETECTION_HOST_H_ #include <stddef.h> @@ -12,8 +12,10 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "chrome/browser/safe_browsing/ui_manager.h" +#include "components/safe_browsing/content/base_ui_manager.h" #include "components/safe_browsing/content/browser/client_side_model_loader.h" +#include "components/safe_browsing/content/common/safe_browsing.mojom-shared.h" +#include "components/safe_browsing/content/common/safe_browsing.mojom.h" #include "components/safe_browsing/core/db/database_manager.h" #include "content/public/browser/web_contents_observer.h" #include "mojo/public/cpp/bindings/remote.h" @@ -35,10 +37,29 @@ // TODO(noelutz): move all client-side detection IPCs to this class. class ClientSideDetectionHost : public content::WebContentsObserver { public: + // Delegate which allows to provide embedder specific implementations. + class Delegate { + public: + virtual ~Delegate() = default; + + // Returns whether there is a SafeBrowsingUserInteractionObserver available. + virtual bool HasSafeBrowsingUserInteractionObserver() = 0; + // Returns the prefs service associated with the current embedders profile. + virtual PrefService* GetPrefs() = 0; + virtual scoped_refptr<SafeBrowsingDatabaseManager> + GetSafeBrowsingDBManager() = 0; + virtual scoped_refptr<BaseUIManager> GetSafeBrowsingUIManager() = 0; + virtual ClientSideDetectionService* GetClientSideDetectionService() = 0; + }; + // The caller keeps ownership of the tab object and is responsible for // ensuring that it stays valid until WebContentsDestroyed is called. static std::unique_ptr<ClientSideDetectionHost> Create( - content::WebContents* tab); + content::WebContents* tab, + std::unique_ptr<Delegate> delegate); + + // The caller keeps ownership of the tab object and is responsible for + // ensuring that it stays valid until WebContentsDestroyed is called. ~ClientSideDetectionHost() override; // From content::WebContentsObserver. If we navigate away we cancel all @@ -51,14 +72,15 @@ void SendModelToRenderFrame(); protected: - explicit ClientSideDetectionHost(content::WebContents* tab); + explicit ClientSideDetectionHost(content::WebContents* tab, + std::unique_ptr<Delegate> delegate); // From content::WebContentsObserver. void WebContentsDestroyed() override; void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; // Used for testing. - void set_ui_manager(SafeBrowsingUIManager* ui_manager); + void set_ui_manager(BaseUIManager* ui_manager); void set_database_manager(SafeBrowsingDatabaseManager* database_manager); private: @@ -101,7 +123,7 @@ content::WebContents* tab_; // These pointers may be nullptr if SafeBrowsing is disabled. scoped_refptr<SafeBrowsingDatabaseManager> database_manager_; - scoped_refptr<SafeBrowsingUIManager> ui_manager_; + scoped_refptr<BaseUIManager> ui_manager_; // Keep a handle to the latest classification request so that we can cancel // it if necessary. scoped_refptr<ShouldClassifyUrlRequest> classification_request_; @@ -113,6 +135,9 @@ // Records the start time of when phishing detection started. base::TimeTicks phishing_detection_start_time_; const base::TickClock* tick_clock_; + + std::unique_ptr<Delegate> delegate_; + base::WeakPtrFactory<ClientSideDetectionHost> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(ClientSideDetectionHost); @@ -120,4 +145,4 @@ } // namespace safe_browsing -#endif // CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_H_ +#endif // COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_CLIENT_SIDE_DETECTION_HOST_H_
diff --git a/chrome/browser/safe_browsing/client_side_detection_service.cc b/components/safe_browsing/content/browser/client_side_detection_service.cc similarity index 91% rename from chrome/browser/safe_browsing/client_side_detection_service.cc rename to components/safe_browsing/content/browser/client_side_detection_service.cc index 801c28a..39cef21 100644 --- a/chrome/browser/safe_browsing/client_side_detection_service.cc +++ b/components/safe_browsing/content/browser/client_side_detection_service.cc
@@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/safe_browsing/client_side_detection_service.h" +#include "components/safe_browsing/content/browser/client_side_detection_service.h" #include <algorithm> #include <memory> @@ -18,12 +18,8 @@ #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/policy/chrome_browser_policy_connector.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/safe_browsing/client_side_detection_host.h" -#include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" +#include "components/safe_browsing/content/browser/client_side_detection_host.h" #include "components/safe_browsing/content/common/safe_browsing.mojom.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/safe_browsing/core/common/utils.h" @@ -68,22 +64,17 @@ ClientSideDetectionService::CacheState::CacheState(bool phish, base::Time time) : is_phishing(phish), timestamp(time) {} -ClientSideDetectionService::ClientSideDetectionService(Profile* profile) - : profile_(profile), - enabled_(false), - extended_reporting_(false), - url_loader_factory_(nullptr) { - // |profile_| can be null in unit tests - if (!profile_) +ClientSideDetectionService::ClientSideDetectionService( + std::unique_ptr<Delegate> delegate) + : delegate_(std::move(delegate)) { + // delegate and prefs can be null in unit tests. + if (!delegate_ || !delegate_->GetPrefs()) { return; - - if (g_browser_process->safe_browsing_service()) { - url_loader_factory_ = - g_browser_process->safe_browsing_service()->GetURLLoaderFactory( - profile); } - pref_change_registrar_.Init(profile_->GetPrefs()); + url_loader_factory_ = delegate_->GetSafeBrowsingURLLoaderFactory(); + + pref_change_registrar_.Init(delegate_->GetPrefs()); pref_change_registrar_.Add( prefs::kSafeBrowsingEnabled, base::BindRepeating(&ClientSideDetectionService::OnPrefsUpdated, @@ -96,7 +87,6 @@ prefs::kSafeBrowsingScoutReportingEnabled, base::BindRepeating(&ClientSideDetectionService::OnPrefsUpdated, base::Unretained(this))); - // Do an initial check of the prefs. OnPrefsUpdated(); } @@ -111,10 +101,10 @@ void ClientSideDetectionService::OnPrefsUpdated() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - bool enabled = IsSafeBrowsingEnabled(*profile_->GetPrefs()); + bool enabled = IsSafeBrowsingEnabled(*delegate_->GetPrefs()); bool extended_reporting = - IsEnhancedProtectionEnabled(*profile_->GetPrefs()) || - IsExtendedReportingEnabled(*profile_->GetPrefs()); + IsEnhancedProtectionEnabled(*delegate_->GetPrefs()) || + IsExtendedReportingEnabled(*delegate_->GetPrefs()); if (enabled == enabled_ && extended_reporting_ == extended_reporting) return; @@ -128,7 +118,7 @@ model_loader_ = std::make_unique<ModelLoader>( base::BindRepeating(&ClientSideDetectionService::SendModelToRenderers, base::Unretained(this)), - profile_->GetURLLoaderFactory(), extended_reporting_); + delegate_->GetURLLoaderFactory(), extended_reporting_); } // Refresh the models when the service is enabled. This can happen when // either of the preferences are toggled, or early during startup if @@ -142,9 +132,8 @@ model_loader_->CancelFetcher(); } // Invoke pending callbacks with a false verdict. - for (auto it = client_phishing_reports_.begin(); - it != client_phishing_reports_.end(); ++it) { - ClientPhishingReportInfo* info = it->second.get(); + for (auto& client_phishing_report : client_phishing_reports_) { + ClientPhishingReportInfo* info = client_phishing_report.second.get(); if (!info->callback.is_null()) std::move(info->callback).Run(info->phishing_url, false); } @@ -242,8 +231,7 @@ ChromeUserPopulation::SAFE_BROWSING); } request->mutable_population()->set_profile_management_status( - GetProfileManagementStatus( - g_browser_process->browser_policy_connector())); + delegate_->GetManagementStatus()); std::string request_data; request->SerializeToString(&request_data);
diff --git a/chrome/browser/safe_browsing/client_side_detection_service.h b/components/safe_browsing/content/browser/client_side_detection_service.h similarity index 88% rename from chrome/browser/safe_browsing/client_side_detection_service.h rename to components/safe_browsing/content/browser/client_side_detection_service.h index baa0aa7c..782173b1 100644 --- a/chrome/browser/safe_browsing/client_side_detection_service.h +++ b/components/safe_browsing/content/browser/client_side_detection_service.h
@@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// 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. // @@ -10,8 +10,8 @@ // This class is not thread-safe and expects all calls to be made on the UI // thread. We also expect that the calling thread runs a message loop. -#ifndef CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_H_ -#define CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_H_ +#ifndef COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_CLIENT_SIDE_DETECTION_SERVICE_H_ +#define COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_CLIENT_SIDE_DETECTION_SERVICE_H_ #include <map> #include <memory> @@ -30,14 +30,13 @@ #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_change_registrar.h" #include "components/safe_browsing/content/browser/client_side_model_loader.h" +#include "components/safe_browsing/core/proto/csd.pb.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "url/gurl.h" -class Profile; - namespace network { class SimpleURLLoader; class SharedURLLoaderFactory; @@ -55,7 +54,24 @@ typedef base::OnceCallback<void(GURL, bool)> ClientReportPhishingRequestCallback; - explicit ClientSideDetectionService(Profile* profile); + // Delegate which allows to provide embedder specific implementations. + class Delegate { + public: + virtual ~Delegate() = default; + + // Returns the pref service associated with the current profile. + virtual PrefService* GetPrefs() = 0; + // Returns the main URLLoaderFactory. + virtual scoped_refptr<network::SharedURLLoaderFactory> + GetURLLoaderFactory() = 0; + virtual scoped_refptr<network::SharedURLLoaderFactory> + GetSafeBrowsingURLLoaderFactory() = 0; + // Returns the management status for current profile. + virtual ChromeUserPopulation::ProfileManagementStatus + GetManagementStatus() = 0; + }; + + explicit ClientSideDetectionService(std::unique_ptr<Delegate> delegate); ~ClientSideDetectionService() override; void Shutdown() override; @@ -111,8 +127,6 @@ // Sends a model to each renderer. virtual void SendModelToRenderers(); - base::WeakPtr<ClientSideDetectionService> GetWeakPtr(); - // Get the model status for the given client-side model. ModelLoader::ClientModelStatus GetLastModelStatus(); @@ -194,16 +208,13 @@ // Returns the URL that will be used for phishing requests. static GURL GetClientReportUrl(const std::string& report_url); - // The profile this ClientSideDetectionService is attached to. - Profile* profile_; - // Whether the service is running or not. When the service is not running, // it won't download the model nor report detected phishing URLs. - bool enabled_; + bool enabled_ = false; // Whether the service is in extended reporting mode or not. This affects the // choice of model. - bool extended_reporting_; + bool extended_reporting_ = false; std::unique_ptr<ModelLoader> model_loader_; @@ -238,6 +249,8 @@ // Factory used for constructing ModelLoaders base::RepeatingCallback<std::unique_ptr<ModelLoader>()> model_factory_; + std::unique_ptr<Delegate> delegate_; + // Used to asynchronously call the callbacks for // SendClientReportPhishingRequest. base::WeakPtrFactory<ClientSideDetectionService> weak_factory_{this}; @@ -247,4 +260,4 @@ } // namespace safe_browsing -#endif // CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_H_ +#endif // COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_CLIENT_SIDE_DETECTION_SERVICE_H_
diff --git a/components/signin/internal/identity_manager/accounts_mutator_impl.cc b/components/signin/internal/identity_manager/accounts_mutator_impl.cc index 5c683a8..e31505d3 100644 --- a/components/signin/internal/identity_manager/accounts_mutator_impl.cc +++ b/components/signin/internal/identity_manager/accounts_mutator_impl.cc
@@ -100,7 +100,7 @@ #endif DCHECK(primary_account_manager_->HasPrimaryAccount(ConsentLevel::kSync)); CoreAccountInfo primary_account_info = - primary_account_manager_->GetAuthenticatedAccountInfo(); + primary_account_manager_->GetPrimaryAccountInfo(ConsentLevel::kSync); AddOrUpdateAccount(primary_account_info.gaia, primary_account_info.email, GaiaConstants::kInvalidRefreshToken, primary_account_info.is_under_advanced_protection, source);
diff --git a/components/signin/internal/identity_manager/primary_account_manager.cc b/components/signin/internal/identity_manager/primary_account_manager.cc index 50a8037..c85f7433b 100644 --- a/components/signin/internal/identity_manager/primary_account_manager.cc +++ b/components/signin/internal/identity_manager/primary_account_manager.cc
@@ -113,10 +113,10 @@ account_tracker_service_->GetAccountInfo(account_id); if (consented) { DCHECK(!account_info.account_id.empty()); - // First reset the state, because SetAuthenticatedAccountInfo can only be - // called if the user is not already signed in. - SetPrimaryAccountInternal(CoreAccountInfo(), /*consented=*/false); - SetAuthenticatedAccountInfo(account_info); + // First reset the state, because SetSyncPrimaryAccountInternal() can + // only be called if there is no primary account. + SetPrimaryAccountInternal(CoreAccountInfo(), /*consented_to_sync=*/false); + SetSyncPrimaryAccountInternal(account_info); } else { SetPrimaryAccountInternal(account_info, consented); } @@ -127,50 +127,41 @@ // It is important to only load credentials after starting to observe the // token service. token_service_->AddObserver(this); - token_service_->LoadCredentials(GetAuthenticatedAccountId()); + token_service_->LoadCredentials( + GetPrimaryAccountId(signin::ConsentLevel::kSync)); } bool PrimaryAccountManager::IsInitialized() const { return initialized_; } -CoreAccountInfo PrimaryAccountManager::GetAuthenticatedAccountInfo() const { - if (!HasPrimaryAccount(signin::ConsentLevel::kSync)) +CoreAccountInfo PrimaryAccountManager::GetPrimaryAccountInfo( + signin::ConsentLevel consent_level) const { + if (!HasPrimaryAccount(consent_level)) return CoreAccountInfo(); return primary_account_info(); } -CoreAccountId PrimaryAccountManager::GetAuthenticatedAccountId() const { - return GetAuthenticatedAccountInfo().account_id; -} - -CoreAccountInfo PrimaryAccountManager::GetUnconsentedPrimaryAccountInfo() - const { - return primary_account_info(); +CoreAccountId PrimaryAccountManager::GetPrimaryAccountId( + signin::ConsentLevel consent_level) const { + return GetPrimaryAccountInfo(consent_level).account_id; } void PrimaryAccountManager::SetUnconsentedPrimaryAccountInfo( - CoreAccountInfo account_info) { + const CoreAccountInfo& account_info) { if (HasPrimaryAccount(signin::ConsentLevel::kSync)) { - DCHECK_EQ(account_info, GetAuthenticatedAccountInfo()); + DCHECK_EQ(account_info, GetPrimaryAccountInfo(signin::ConsentLevel::kSync)); return; } bool account_changed = account_info != primary_account_info(); - PrimaryAccountChangeEvent::State previous_state( - primary_account_info(), signin::ConsentLevel::kNotRequired); + PrimaryAccountChangeEvent::State previous_state = GetPrimaryAccountState(); SetPrimaryAccountInternal(account_info, /*consented_to_sync=*/false); - - if (account_changed) { - PrimaryAccountChangeEvent::State current_state( - account_info, signin::ConsentLevel::kNotRequired); - PrimaryAccountChangeEvent event_details(previous_state, current_state); - for (Observer& observer : observers_) - observer.UnconsentedPrimaryAccountChanged(event_details); - } + if (account_changed) + FirePrimaryAccountChanged(previous_state); } -void PrimaryAccountManager::SetAuthenticatedAccountInfo( +void PrimaryAccountManager::SetSyncPrimaryAccountInternal( const CoreAccountInfo& account_info) { DCHECK(!account_info.account_id.empty()); DCHECK(!HasPrimaryAccount(signin::ConsentLevel::kSync)); @@ -199,7 +190,7 @@ client_->GetPrefs()->SetString(prefs::kGoogleServicesLastUsername, account_info.email); - // Commit authenticated account info immediately so that it does not get lost + // Commit primary sync account info immediately so that it does not get lost // if Chrome crashes before the next commit interval. client_->GetPrefs()->CommitPendingWrite(); } @@ -237,38 +228,29 @@ } } -void PrimaryAccountManager::SignIn(const std::string& username) { - CoreAccountInfo info = - account_tracker_service_->FindAccountInfoByEmail(username); - DCHECK(!info.gaia.empty()); - DCHECK(!info.email.empty()); - DCHECK(!info.account_id.empty()); +void PrimaryAccountManager::SetSyncPrimaryAccountInfo( + const CoreAccountInfo& account_info) { +#if DCHECK_IS_ON() + DCHECK(!account_info.account_id.empty()); + DCHECK(!account_info.gaia.empty()); + DCHECK(!account_info.email.empty()); + DCHECK(!account_tracker_service_->GetAccountInfo(account_info.account_id) + .IsEmpty()) + << "Account should have been seeded before being set as primary account"; +#endif if (HasPrimaryAccount(signin::ConsentLevel::kSync)) { - DCHECK_EQ(info.account_id, GetAuthenticatedAccountId()) - << "Changing the authenticated account while it is not allowed."; + DCHECK_EQ(account_info.account_id, + GetPrimaryAccountId(signin::ConsentLevel::kSync)) + << "Changing the primary sync account is not allowed."; return; } - bool account_changed = info != primary_account_info(); - PrimaryAccountChangeEvent::State previous_state( - primary_account_info(), signin::ConsentLevel::kNotRequired); - PrimaryAccountChangeEvent::State current_state(info, - signin::ConsentLevel::kSync); - PrimaryAccountChangeEvent event_details(previous_state, current_state); - - SetAuthenticatedAccountInfo(info); - - for (Observer& observer : observers_) { - // TODO(https://crbug.com/1158855): Remove call to - // UnconsentedPrimaryAccountChanged() after IdentityManager::Observer - // migration has been completed. - if (account_changed) - observer.UnconsentedPrimaryAccountChanged(event_details); - observer.GoogleSigninSucceeded(event_details); - } + PrimaryAccountChangeEvent::State previous_state = GetPrimaryAccountState(); + SetSyncPrimaryAccountInternal(account_info); + FirePrimaryAccountChanged(previous_state); } -void PrimaryAccountManager::UpdateAuthenticatedAccountInfo() { +void PrimaryAccountManager::UpdateSyncPrimaryAccountInfo() { DCHECK(!primary_account_info().account_id.empty()); DCHECK(HasPrimaryAccount(signin::ConsentLevel::kSync)); const CoreAccountInfo info = account_tracker_service_->GetAccountInfo( @@ -350,39 +332,52 @@ return; } - const CoreAccountInfo account_info = primary_account_info(); - const bool has_sync_consent = HasPrimaryAccount(signin::ConsentLevel::kSync); + PrimaryAccountChangeEvent::State previous_state = GetPrimaryAccountState(); client_->GetPrefs()->ClearPref(prefs::kGoogleServicesHostedDomain); - // Revoke the sync consent. - if (has_sync_consent) - SetPrimaryAccountInternal(account_info, /*consented_to_sync=*/false); - DCHECK(!HasPrimaryAccount(signin::ConsentLevel::kSync)); // Revoke all tokens before sending signed_out notification, because there // may be components that don't listen for token service events when the // profile is not connected to an account. switch (remove_option) { case RemoveAccountsOption::kRemoveAllAccounts: VLOG(0) << "Revoking all refresh tokens on server. Reason: sign out"; - SetUnconsentedPrimaryAccountInfo(CoreAccountInfo()); + SetPrimaryAccountInternal(CoreAccountInfo(), /*consented_to_sync=*/false); token_service_->RevokeAllCredentials( signin_metrics::SourceForRefreshTokenOperation:: kPrimaryAccountManager_ClearAccount); break; case RemoveAccountsOption::kKeepAllAccounts: - // Do nothing. + SetPrimaryAccountInternal(primary_account_info(), + /*consented_to_sync=*/false); break; } - PrimaryAccountChangeEvent::State previous_state; - previous_state.primary_account = account_info; - previous_state.consent_level = has_sync_consent - ? signin::ConsentLevel::kSync - : signin::ConsentLevel::kNotRequired; - PrimaryAccountChangeEvent event_details(previous_state, - PrimaryAccountChangeEvent::State()); + DCHECK(!HasPrimaryAccount(signin::ConsentLevel::kSync)); + FirePrimaryAccountChanged(previous_state); +} + +PrimaryAccountChangeEvent::State PrimaryAccountManager::GetPrimaryAccountState() + const { + PrimaryAccountChangeEvent::State state(primary_account_info(), + signin::ConsentLevel::kNotRequired); + if (HasPrimaryAccount(signin::ConsentLevel::kSync)) + state.consent_level = signin::ConsentLevel::kSync; + return state; +} + +void PrimaryAccountManager::FirePrimaryAccountChanged( + const PrimaryAccountChangeEvent::State& previous_state) { + PrimaryAccountChangeEvent::State current_state = GetPrimaryAccountState(); + PrimaryAccountChangeEvent event_details(previous_state, current_state); + + DCHECK(event_details.GetEventTypeFor(signin::ConsentLevel::kSync) != + PrimaryAccountChangeEvent::Type::kNone || + event_details.GetEventTypeFor(signin::ConsentLevel::kNotRequired) != + PrimaryAccountChangeEvent::Type::kNone) + << "PrimaryAccountChangeEvent with no change: " << event_details; + for (Observer& observer : observers_) - observer.GoogleSignedOut(event_details); + observer.OnPrimaryAccountChanged(event_details); } void PrimaryAccountManager::OnRefreshTokensLoaded() { @@ -397,9 +392,10 @@ if (token_service_->HasLoadCredentialsFinishedWithNoErrors()) { std::vector<AccountInfo> accounts_in_tracker_service = account_tracker_service_->GetAccounts(); - const CoreAccountId authenticated_account_id = GetAuthenticatedAccountId(); + const CoreAccountId sync_account_id = + GetPrimaryAccountId(signin::ConsentLevel::kSync); for (const auto& account : accounts_in_tracker_service) { - if (authenticated_account_id != account.account_id && + if (sync_account_id != account.account_id && !token_service_->RefreshTokenIsAvailable(account.account_id)) { VLOG(0) << "Removed account from account tracker service: " << account.account_id;
diff --git a/components/signin/internal/identity_manager/primary_account_manager.h b/components/signin/internal/identity_manager/primary_account_manager.h index b05fb4c..52c3472 100644 --- a/components/signin/internal/identity_manager/primary_account_manager.h +++ b/components/signin/internal/identity_manager/primary_account_manager.h
@@ -47,19 +47,10 @@ public: class Observer : public base::CheckedObserver { public: - // Called whenever a user signs into Google services such as sync. - // Not called during a reauth. - virtual void GoogleSigninSucceeded( - const signin::PrimaryAccountChangeEvent& event_details) {} - - // Called whenever the unconsented primary account changes. This includes - // the changes for the consented primary account as well. - virtual void UnconsentedPrimaryAccountChanged( - const signin::PrimaryAccountChangeEvent& event_details) {} - - // Called whenever the currently signed-in user has been signed out. - virtual void GoogleSignedOut( - const signin::PrimaryAccountChangeEvent& event_details) {} + // Called when there is a change in the primary account or in the consent + // level for the primary account. + virtual void OnPrimaryAccountChanged( + const signin::PrimaryAccountChangeEvent& event_details) = 0; }; // Used to remove accounts from the token service and the account tracker. @@ -87,48 +78,52 @@ void Initialize(PrefService* local_state); bool IsInitialized() const; - // If a user has previously signed in (and has not signed out), this returns - // the know information of the account. Otherwise, it returns an empty struct. - CoreAccountInfo GetAuthenticatedAccountInfo() const; - - // If a user has previously signed in (and has not signed out), this returns - // the account id. Otherwise, it returns an empty CoreAccountId. This id is - // the G+/Focus obfuscated gaia id of the user. It can be used to uniquely - // identify an account, so for example as a key to map accounts to data. For - // code that needs a unique id to represent the connected account, call this - // method. Example: the AccountStatusMap type in - // MutableProfileOAuth2TokenService. For code that needs to know the - // normalized email address of the connected account, use - // GetAuthenticatedAccountInfo().email. Example: to show the string - // "Signed in as XXX" in the hotdog menu. - CoreAccountId GetAuthenticatedAccountId() const; - // Returns whether the user's primary account is available. If consent is // |ConsentLevel::kSync| then true implies that the user has blessed this // account for sync. bool HasPrimaryAccount(signin::ConsentLevel consent_level) const; + // Provides access to the core information of the user's primary account. + // The primary account may or may not be blessed with the sync consent. + // Returns an empty struct if no such info is available, either because there + // is no primary account yet or because the user signed out or the |consent| + // level required |ConsentLevel::kSync| was not granted. + // Returns a non-empty struct if the primary account exists and was granted + // the required consent level. + CoreAccountInfo GetPrimaryAccountInfo( + signin::ConsentLevel consent_level) const; + + // Provides access to the account ID of the user's primary account. Simple + // convenience wrapper over GetPrimaryAccountInfo().account_id. + CoreAccountId GetPrimaryAccountId(signin::ConsentLevel consent_level) const; + // Signs a user in. PrimaryAccountManager assumes that |username| can be used // to look up the corresponding account_id and gaia_id for this email. - void SignIn(const std::string& username); + void SetSyncPrimaryAccountInfo(const CoreAccountInfo& account_info); - // Updates the authenticated account information from AccountTrackerService. - void UpdateAuthenticatedAccountInfo(); + // Sets the unconsented primary account. The unconsented primary account can + // only be changed if the user has not consented for sync If the user has + // consented for sync already, then use ClearPrimaryAccount() or RevokeSync() + // instead. + void SetUnconsentedPrimaryAccountInfo(const CoreAccountInfo& account_info); + + // Updates the primary account information from AccountTrackerService. + void UpdateSyncPrimaryAccountInfo(); // Signout API surfaces (not supported on ChromeOS, where signout is not // permitted). #if !BUILDFLAG(IS_CHROMEOS_ASH) - // Signs a user out, removing the preference, erasing all keys - // associated with the authenticated user, and canceling all auth in progress. - // It removes all accounts from Chrome by revoking all refresh tokens. + // Clears the primary account, erasing all keys associated with the primary + // account (also cancels all auth in progress). + // It removes all accounts from the identity manager by revoking all refresh + // tokens. void ClearPrimaryAccount(signin_metrics::ProfileSignout signout_source_metric, signin_metrics::SignoutDelete signout_delete_metric); #endif // !BUILDFLAG(IS_CHROMEOS_ASH) - // Signs a user out, removing the preference, erasing all keys - // associated with the authenticated user, and canceling all auth in progress. - // Does not remove the accounts from the token service. + // Rovokes the sync consent but leaves the primary account and the rest of + // the accounts untouched. void RevokeSyncConsent(signin_metrics::ProfileSignout signout_source_metric, signin_metrics::SignoutDelete signout_delete_metric); @@ -136,25 +131,14 @@ void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); - // Provides access to the core information of the user's unconsented primary - // account. Returns an empty info, if there is no such account. - CoreAccountInfo GetUnconsentedPrimaryAccountInfo() const; - - // Sets the unconsented primary account. The unconsented primary account can - // only be changed if the user is not authenticated. If the user is - // authenticated, use Signout() instead. - void SetUnconsentedPrimaryAccountInfo(CoreAccountInfo account_info); - private: - // Sets the authenticated user's account id, when the user has consented to - // sync. - // If the user is already authenticated with the same account id, then this - // method is a no-op. - // It is forbidden to call this method if the user is already authenticated - // with a different account (this method will DCHECK in that case). - // |account_id| must not be empty. To log the user out, use - // ClearAuthenticatedAccountId() instead. - void SetAuthenticatedAccountInfo(const CoreAccountInfo& account_info); + // Sets the primary account id, when the user has consented to sync. + // If the user has consented for sync with the same account, then this method + // is a no-op. + // It is forbidden to call this method if the user has already consented for + // sync with a different account (this method will DCHECK in that case). + // |account_id| must not be empty. + void SetSyncPrimaryAccountInternal(const CoreAccountInfo& account_info); // Sets |primary_account_info_| and updates the associated preferences. void SetPrimaryAccountInternal(const CoreAccountInfo& account_info, @@ -175,6 +159,13 @@ bool assert_signout_allowed, SigninClient::SignoutDecision signout_decision); + // Returns the current state of the primary account. + signin::PrimaryAccountChangeEvent::State GetPrimaryAccountState() const; + + // Fires OnPrimaryAccountChanged() notifications on all observers. + void FirePrimaryAccountChanged( + const signin::PrimaryAccountChangeEvent::State& previous_state); + // ProfileOAuth2TokenServiceObserver: void OnRefreshTokensLoaded() override; @@ -191,8 +182,8 @@ bool initialized_ = false; - // Account id after successful authentication. The account may or may not be - // consented to Sync. + // The primary account information. The account may or may not be consented + // for Sync. // Must be kept in sync with prefs. Use SetPrimaryAccountInternal() to change // this field. CoreAccountInfo primary_account_info_;
diff --git a/components/signin/internal/identity_manager/primary_account_manager_unittest.cc b/components/signin/internal/identity_manager/primary_account_manager_unittest.cc index dd98841..89a4638 100644 --- a/components/signin/internal/identity_manager/primary_account_manager_unittest.cc +++ b/components/signin/internal/identity_manager/primary_account_manager_unittest.cc
@@ -111,24 +111,43 @@ void ExpectSignInWithRefreshTokenSuccess() { EXPECT_TRUE(manager_->HasPrimaryAccount(ConsentLevel::kSync)); - EXPECT_FALSE(manager_->GetAuthenticatedAccountId().empty()); - EXPECT_FALSE(manager_->GetAuthenticatedAccountInfo().email.empty()); + EXPECT_FALSE(manager_->GetPrimaryAccountId(ConsentLevel::kSync).empty()); + EXPECT_FALSE( + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email.empty()); EXPECT_TRUE(token_service_.RefreshTokenIsAvailable( - manager_->GetAuthenticatedAccountId())); + manager_->GetPrimaryAccountId(ConsentLevel::kSync))); // Should go into token service and stop. EXPECT_EQ(1, num_successful_signins_); } - void GoogleSigninSucceeded( - const signin::PrimaryAccountChangeEvent& account_info) override { - num_successful_signins_++; - } + void OnPrimaryAccountChanged( + const signin::PrimaryAccountChangeEvent& event_details) override { + DCHECK(event_details.GetEventTypeFor(signin::ConsentLevel::kSync) != + signin::PrimaryAccountChangeEvent::Type::kNone || + event_details.GetEventTypeFor(signin::ConsentLevel::kNotRequired) != + signin::PrimaryAccountChangeEvent::Type::kNone) + << "PrimaryAccountChangeEvent with no change: " << event_details; - void UnconsentedPrimaryAccountChanged( - const signin::PrimaryAccountChangeEvent& info) override { - num_unconsented_account_changed_++; + switch (event_details.GetEventTypeFor(ConsentLevel::kSync)) { + case signin::PrimaryAccountChangeEvent::Type::kSet: + num_successful_signins_++; + break; + case signin::PrimaryAccountChangeEvent::Type::kCleared: + // ignored + break; + case signin::PrimaryAccountChangeEvent::Type::kNone: + break; + } + switch (event_details.GetEventTypeFor(ConsentLevel::kNotRequired)) { + case signin::PrimaryAccountChangeEvent::Type::kSet: + case signin::PrimaryAccountChangeEvent::Type::kCleared: + num_unconsented_account_changed_++; + break; + case signin::PrimaryAccountChangeEvent::Type::kNone: + break; + } } base::test::TaskEnvironment task_environment_; @@ -153,20 +172,25 @@ CreatePrimaryAccountManager(); CoreAccountId main_account_id = AddToAccountTracker("account_id", "user@gmail.com"); - manager_->SignIn("user@gmail.com"); + manager_->SetSyncPrimaryAccountInfo( + account_tracker()->GetAccountInfo(main_account_id)); manager_->ClearPrimaryAccount(signin_metrics::SIGNOUT_TEST, signin_metrics::SignoutDelete::IGNORE_METRIC); EXPECT_FALSE(manager_->HasPrimaryAccount(ConsentLevel::kSync)); - EXPECT_TRUE(manager_->GetAuthenticatedAccountInfo().email.empty()); - EXPECT_TRUE(manager_->GetAuthenticatedAccountId().empty()); - EXPECT_TRUE(manager_->GetUnconsentedPrimaryAccountInfo().IsEmpty()); + EXPECT_TRUE( + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email.empty()); + EXPECT_TRUE(manager_->GetPrimaryAccountId(ConsentLevel::kSync).empty()); + EXPECT_TRUE( + manager_->GetPrimaryAccountInfo(ConsentLevel::kNotRequired).IsEmpty()); // Should not be persisted anymore ShutDownManager(); CreatePrimaryAccountManager(); EXPECT_FALSE(manager_->HasPrimaryAccount(ConsentLevel::kSync)); - EXPECT_TRUE(manager_->GetAuthenticatedAccountInfo().email.empty()); - EXPECT_TRUE(manager_->GetAuthenticatedAccountId().empty()); - EXPECT_TRUE(manager_->GetUnconsentedPrimaryAccountInfo().IsEmpty()); + EXPECT_TRUE( + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email.empty()); + EXPECT_TRUE(manager_->GetPrimaryAccountId(ConsentLevel::kSync).empty()); + EXPECT_TRUE( + manager_->GetPrimaryAccountInfo(ConsentLevel::kNotRequired).IsEmpty()); } TEST_F(PrimaryAccountManagerTest, SignOutRevoke) { @@ -177,9 +201,11 @@ AddToAccountTracker("other_id", "other@gmail.com"); token_service_.UpdateCredentials(main_account_id, "token"); token_service_.UpdateCredentials(other_account_id, "token"); - manager_->SignIn("user@gmail.com"); + manager_->SetSyncPrimaryAccountInfo( + account_tracker()->GetAccountInfo(main_account_id)); EXPECT_TRUE(manager_->HasPrimaryAccount(ConsentLevel::kSync)); - EXPECT_EQ(main_account_id, manager_->GetAuthenticatedAccountId()); + EXPECT_EQ(main_account_id, + manager_->GetPrimaryAccountId(ConsentLevel::kSync)); manager_->ClearPrimaryAccount(signin_metrics::SIGNOUT_TEST, signin_metrics::SignoutDelete::IGNORE_METRIC); @@ -192,11 +218,14 @@ TEST_F(PrimaryAccountManagerTest, SignOutWhileProhibited) { CreatePrimaryAccountManager(); EXPECT_FALSE(manager_->HasPrimaryAccount(ConsentLevel::kSync)); - EXPECT_TRUE(manager_->GetAuthenticatedAccountInfo().email.empty()); - EXPECT_TRUE(manager_->GetAuthenticatedAccountId().empty()); + EXPECT_TRUE( + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email.empty()); + EXPECT_TRUE(manager_->GetPrimaryAccountId(ConsentLevel::kSync).empty()); - AddToAccountTracker("gaia_id", "user@gmail.com"); - manager_->SignIn("user@gmail.com"); + CoreAccountId main_account_id = + AddToAccountTracker("gaia_id", "user@gmail.com"); + manager_->SetSyncPrimaryAccountInfo( + account_tracker()->GetAccountInfo(main_account_id)); signin_client()->set_is_signout_allowed(false); manager_->ClearPrimaryAccount(signin_metrics::SIGNOUT_TEST, signin_metrics::SignoutDelete::IGNORE_METRIC); @@ -210,8 +239,9 @@ TEST_F(PrimaryAccountManagerTest, UnconsentedSignOutWhileProhibited) { CreatePrimaryAccountManager(); EXPECT_FALSE(manager_->HasPrimaryAccount(ConsentLevel::kSync)); - EXPECT_TRUE(manager_->GetAuthenticatedAccountInfo().email.empty()); - EXPECT_TRUE(manager_->GetAuthenticatedAccountId().empty()); + EXPECT_TRUE( + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email.empty()); + EXPECT_TRUE(manager_->GetPrimaryAccountId(ConsentLevel::kSync).empty()); CoreAccountId account_id = AddToAccountTracker("gaia_id", "user@gmail.com"); CoreAccountInfo account_info = account_tracker()->GetAccountInfo(account_id); @@ -231,61 +261,72 @@ ".*@google.com"); CreatePrimaryAccountManager(); // Currently signed in user is prohibited by policy, so should be signed out. - EXPECT_EQ("", manager_->GetAuthenticatedAccountInfo().email); - EXPECT_EQ(CoreAccountId(), manager_->GetAuthenticatedAccountId()); + EXPECT_EQ("", manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email); + EXPECT_EQ(CoreAccountId(), + manager_->GetPrimaryAccountId(ConsentLevel::kSync)); } TEST_F(PrimaryAccountManagerTest, ProhibitedAfterStartup) { CoreAccountId account_id = AddToAccountTracker("gaia_id", "user@gmail.com"); user_prefs_.SetString(prefs::kGoogleServicesAccountId, account_id.ToString()); CreatePrimaryAccountManager(); - EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountInfo().email); - EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId()); + EXPECT_EQ("user@gmail.com", + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email); + EXPECT_EQ(account_id, manager_->GetPrimaryAccountId(ConsentLevel::kSync)); // Update the profile - user should be signed out. local_state_.SetString(prefs::kGoogleServicesUsernamePattern, ".*@google.com"); - EXPECT_EQ("", manager_->GetAuthenticatedAccountInfo().email); - EXPECT_EQ(CoreAccountId(), manager_->GetAuthenticatedAccountId()); + EXPECT_EQ("", manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email); + EXPECT_EQ(CoreAccountId(), + manager_->GetPrimaryAccountId(ConsentLevel::kSync)); } #endif TEST_F(PrimaryAccountManagerTest, SignIn) { CreatePrimaryAccountManager(); - EXPECT_EQ("", manager_->GetAuthenticatedAccountInfo().email); - EXPECT_EQ(CoreAccountId(), manager_->GetAuthenticatedAccountId()); + EXPECT_EQ("", manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email); + EXPECT_EQ(CoreAccountId(), + manager_->GetPrimaryAccountId(ConsentLevel::kSync)); EXPECT_EQ(0, num_successful_signins_); EXPECT_EQ(0, num_unconsented_account_changed_); CoreAccountId account_id = AddToAccountTracker("gaia_id", "user@gmail.com"); - manager_->SignIn("user@gmail.com"); + manager_->SetSyncPrimaryAccountInfo( + account_tracker()->GetAccountInfo(account_id)); EXPECT_EQ(1, num_successful_signins_); EXPECT_EQ(1, num_unconsented_account_changed_); - EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountInfo().email); - EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId()); - EXPECT_EQ(manager_->GetUnconsentedPrimaryAccountInfo(), - manager_->GetAuthenticatedAccountInfo()); + EXPECT_EQ("user@gmail.com", + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email); + EXPECT_EQ(account_id, manager_->GetPrimaryAccountId(ConsentLevel::kSync)); + EXPECT_EQ(manager_->GetPrimaryAccountInfo(ConsentLevel::kNotRequired), + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync)); } TEST_F(PrimaryAccountManagerTest, ExternalSignIn_ReauthShouldNotSendNotification) { CreatePrimaryAccountManager(); - EXPECT_EQ("", manager_->GetAuthenticatedAccountInfo().email); - EXPECT_EQ(CoreAccountId(), manager_->GetAuthenticatedAccountId()); + EXPECT_EQ("", manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email); + EXPECT_EQ(CoreAccountId(), + manager_->GetPrimaryAccountId(ConsentLevel::kSync)); EXPECT_EQ(0, num_successful_signins_); EXPECT_EQ(0, num_unconsented_account_changed_); CoreAccountId account_id = AddToAccountTracker("gaia_id", "user@gmail.com"); - manager_->SignIn("user@gmail.com"); + manager_->SetSyncPrimaryAccountInfo( + account_tracker()->GetAccountInfo(account_id)); EXPECT_EQ(1, num_successful_signins_); EXPECT_EQ(1, num_unconsented_account_changed_); - EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountInfo().email); - EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId()); + EXPECT_EQ("user@gmail.com", + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email); + EXPECT_EQ(account_id, manager_->GetPrimaryAccountId(ConsentLevel::kSync)); - manager_->SignIn("user@gmail.com"); + manager_->SetSyncPrimaryAccountInfo( + account_tracker()->GetAccountInfo(account_id)); EXPECT_EQ(1, num_successful_signins_); EXPECT_EQ(1, num_unconsented_account_changed_); - EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountInfo().email); - EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId()); + EXPECT_EQ("user@gmail.com", + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email); + EXPECT_EQ(account_id, manager_->GetPrimaryAccountId(ConsentLevel::kSync)); } #if !BUILDFLAG(IS_CHROMEOS_ASH) @@ -296,8 +337,8 @@ user_prefs_.SetBoolean(prefs::kSigninAllowed, false); CreatePrimaryAccountManager(); // Currently signing in is prohibited by policy, so should be signed out. - EXPECT_EQ("", manager_->GetAuthenticatedAccountInfo().email); - EXPECT_TRUE(manager_->GetAuthenticatedAccountId().empty()); + EXPECT_EQ("", manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email); + EXPECT_TRUE(manager_->GetPrimaryAccountId(ConsentLevel::kSync).empty()); } #endif @@ -330,7 +371,8 @@ CreatePrimaryAccountManager(); - EXPECT_EQ(CoreAccountId(gaia_id), manager_->GetAuthenticatedAccountId()); + EXPECT_EQ(CoreAccountId(gaia_id), + manager_->GetPrimaryAccountId(ConsentLevel::kSync)); EXPECT_EQ(gaia_id, user_prefs_.GetString(prefs::kGoogleServicesAccountId)); } @@ -362,7 +404,8 @@ client_prefs->SetString(prefs::kGoogleServicesAccountId, gaia_id); CreatePrimaryAccountManager(); - EXPECT_EQ(CoreAccountId(gaia_id), manager_->GetAuthenticatedAccountId()); + EXPECT_EQ(CoreAccountId(gaia_id), + manager_->GetPrimaryAccountId(ConsentLevel::kSync)); EXPECT_EQ(gaia_id, user_prefs_.GetString(prefs::kGoogleServicesAccountId)); base::RunLoop().RunUntilIdle(); @@ -375,10 +418,11 @@ user_prefs_.SetString(prefs::kGoogleServicesAccountId, account_id.ToString()); user_prefs_.SetBoolean(prefs::kGoogleServicesConsentedToSync, true); CreatePrimaryAccountManager(); - EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountInfo().email); - EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId()); - EXPECT_EQ(manager_->GetUnconsentedPrimaryAccountInfo(), - manager_->GetAuthenticatedAccountInfo()); + EXPECT_EQ("user@gmail.com", + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email); + EXPECT_EQ(account_id, manager_->GetPrimaryAccountId(ConsentLevel::kSync)); + EXPECT_EQ(manager_->GetPrimaryAccountInfo(ConsentLevel::kNotRequired), + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync)); } TEST_F(PrimaryAccountManagerTest, RestoreFromPrefsUnconsented) { @@ -387,10 +431,11 @@ user_prefs_.SetBoolean(prefs::kGoogleServicesConsentedToSync, false); CreatePrimaryAccountManager(); EXPECT_EQ("user@gmail.com", - manager_->GetUnconsentedPrimaryAccountInfo().email); - EXPECT_EQ(account_id, - manager_->GetUnconsentedPrimaryAccountInfo().account_id); - EXPECT_TRUE(manager_->GetAuthenticatedAccountInfo().IsEmpty()); + manager_->GetPrimaryAccountInfo(ConsentLevel::kNotRequired).email); + EXPECT_EQ( + account_id, + manager_->GetPrimaryAccountInfo(ConsentLevel::kNotRequired).account_id); + EXPECT_TRUE(manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).IsEmpty()); } // If kGoogleServicesConsentedToSync is missing, the account is fully @@ -406,15 +451,17 @@ CreatePrimaryAccountManager(); EXPECT_TRUE(user_prefs_.GetBoolean(prefs::kGoogleServicesConsentedToSync)); - EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountInfo().email); - EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId()); - EXPECT_EQ(manager_->GetUnconsentedPrimaryAccountInfo(), - manager_->GetAuthenticatedAccountInfo()); + EXPECT_EQ("user@gmail.com", + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync).email); + EXPECT_EQ(account_id, manager_->GetPrimaryAccountId(ConsentLevel::kSync)); + EXPECT_EQ(manager_->GetPrimaryAccountInfo(ConsentLevel::kNotRequired), + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync)); } TEST_F(PrimaryAccountManagerTest, SetUnconsentedPrimaryAccountInfo) { CreatePrimaryAccountManager(); - EXPECT_EQ(CoreAccountInfo(), manager_->GetUnconsentedPrimaryAccountInfo()); + EXPECT_EQ(CoreAccountInfo(), + manager_->GetPrimaryAccountInfo(ConsentLevel::kNotRequired)); EXPECT_EQ(0, num_unconsented_account_changed_); EXPECT_EQ(0, num_successful_signins_); @@ -426,15 +473,19 @@ manager_->SetUnconsentedPrimaryAccountInfo(account_info); EXPECT_EQ(0, num_successful_signins_); EXPECT_EQ(1, num_unconsented_account_changed_); - EXPECT_EQ(account_info, manager_->GetUnconsentedPrimaryAccountInfo()); - EXPECT_EQ(CoreAccountInfo(), manager_->GetAuthenticatedAccountInfo()); + EXPECT_EQ(account_info, + manager_->GetPrimaryAccountInfo(ConsentLevel::kNotRequired)); + EXPECT_EQ(CoreAccountInfo(), + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync)); // Set the same account again. manager_->SetUnconsentedPrimaryAccountInfo(account_info); EXPECT_EQ(0, num_successful_signins_); EXPECT_EQ(1, num_unconsented_account_changed_); - EXPECT_EQ(account_info, manager_->GetUnconsentedPrimaryAccountInfo()); - EXPECT_EQ(CoreAccountInfo(), manager_->GetAuthenticatedAccountInfo()); + EXPECT_EQ(account_info, + manager_->GetPrimaryAccountInfo(ConsentLevel::kNotRequired)); + EXPECT_EQ(CoreAccountInfo(), + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync)); // Change the email to another equivalent email. The account is updated but // observers are not notified. @@ -442,36 +493,43 @@ manager_->SetUnconsentedPrimaryAccountInfo(account_info); EXPECT_EQ(0, num_successful_signins_); EXPECT_EQ(1, num_unconsented_account_changed_); - EXPECT_EQ(account_info, manager_->GetUnconsentedPrimaryAccountInfo()); - EXPECT_EQ(CoreAccountInfo(), manager_->GetAuthenticatedAccountInfo()); + EXPECT_EQ(account_info, + manager_->GetPrimaryAccountInfo(ConsentLevel::kNotRequired)); + EXPECT_EQ(CoreAccountInfo(), + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync)); // Clear it. manager_->SetUnconsentedPrimaryAccountInfo(CoreAccountInfo()); EXPECT_EQ(0, num_successful_signins_); EXPECT_EQ(2, num_unconsented_account_changed_); - EXPECT_EQ(CoreAccountInfo(), manager_->GetUnconsentedPrimaryAccountInfo()); - EXPECT_EQ(CoreAccountInfo(), manager_->GetAuthenticatedAccountInfo()); + EXPECT_EQ(CoreAccountInfo(), + manager_->GetPrimaryAccountInfo(ConsentLevel::kNotRequired)); + EXPECT_EQ(CoreAccountInfo(), + manager_->GetPrimaryAccountInfo(ConsentLevel::kSync)); } TEST_F(PrimaryAccountManagerTest, RevokeSyncConsent) { CreatePrimaryAccountManager(); CoreAccountId account_id = AddToAccountTracker("gaia_id", "user@gmail.com"); - manager_->SignIn("user@gmail.com"); + manager_->SetSyncPrimaryAccountInfo( + account_tracker()->GetAccountInfo(account_id)); EXPECT_TRUE(manager_->HasPrimaryAccount(ConsentLevel::kSync)); manager_->RevokeSyncConsent(signin_metrics::ProfileSignout::SIGNOUT_TEST, signin_metrics::SignoutDelete::IGNORE_METRIC); EXPECT_FALSE(manager_->HasPrimaryAccount(ConsentLevel::kSync)); EXPECT_TRUE(manager_->HasPrimaryAccount(ConsentLevel::kNotRequired)); - EXPECT_EQ(account_id, - manager_->GetUnconsentedPrimaryAccountInfo().account_id); + EXPECT_EQ( + account_id, + manager_->GetPrimaryAccountInfo(ConsentLevel::kNotRequired).account_id); } #if !BUILDFLAG(IS_CHROMEOS_ASH) TEST_F(PrimaryAccountManagerTest, ClearPrimaryAccount) { CreatePrimaryAccountManager(); CoreAccountId account_id = AddToAccountTracker("gaia_id", "user@gmail.com"); - manager_->SignIn("user@gmail.com"); + manager_->SetSyncPrimaryAccountInfo( + account_tracker()->GetAccountInfo(account_id)); EXPECT_TRUE(manager_->HasPrimaryAccount(ConsentLevel::kSync)); manager_->ClearPrimaryAccount(signin_metrics::ProfileSignout::SIGNOUT_TEST,
diff --git a/components/signin/internal/identity_manager/primary_account_mutator_impl.cc b/components/signin/internal/identity_manager/primary_account_mutator_impl.cc index 1e6d2f8..fb06b6a 100644 --- a/components/signin/internal/identity_manager/primary_account_mutator_impl.cc +++ b/components/signin/internal/identity_manager/primary_account_mutator_impl.cc
@@ -62,7 +62,7 @@ // TODO(crbug.com/889899): should check that the account email is allowed. #endif - primary_account_manager_->SignIn(account_info.email); + primary_account_manager_->SetSyncPrimaryAccountInfo(account_info); return true; } @@ -101,7 +101,7 @@ // TODO(msarda): The logic in this function is platform specific and we // should consider moving it to |SigninManager|. return token_service_->RefreshTokenHasError( - primary_account_manager_->GetAuthenticatedAccountId()); + primary_account_manager_->GetPrimaryAccountId(ConsentLevel::kSync)); case AccountConsistencyMethod::kDisabled: case AccountConsistencyMethod::kMirror: return true;
diff --git a/components/signin/internal/identity_manager/primary_account_policy_manager_impl.cc b/components/signin/internal/identity_manager/primary_account_policy_manager_impl.cc index a272877..29c3c25 100644 --- a/components/signin/internal/identity_manager/primary_account_policy_manager_impl.cc +++ b/components/signin/internal/identity_manager/primary_account_policy_manager_impl.cc
@@ -40,8 +40,8 @@ &PrimaryAccountPolicyManagerImpl::OnSigninAllowedPrefChanged, base::Unretained(this), primary_account_manager)); - CoreAccountInfo account_info = - primary_account_manager->GetAuthenticatedAccountInfo(); + CoreAccountInfo account_info = primary_account_manager->GetPrimaryAccountInfo( + signin::ConsentLevel::kSync); if (!account_info.account_id.empty() && (!IsAllowedUsername(account_info.email) || !IsSigninAllowed())) { // User is signed in, but the username is invalid or signin is no longer @@ -73,7 +73,9 @@ PrimaryAccountManager* primary_account_manager) { if (primary_account_manager->HasPrimaryAccount(signin::ConsentLevel::kSync) && !IsAllowedUsername( - primary_account_manager->GetAuthenticatedAccountInfo().email)) { + primary_account_manager + ->GetPrimaryAccountInfo(signin::ConsentLevel::kSync) + .email)) { // Signed in user is invalid according to the current policy so sign // the user out. primary_account_manager->ClearPrimaryAccount(
diff --git a/components/signin/public/identity_manager/identity_manager.cc b/components/signin/public/identity_manager/identity_manager.cc index 53c6ee0..fedd035 100644 --- a/components/signin/public/identity_manager/identity_manager.cc +++ b/components/signin/public/identity_manager/identity_manager.cc
@@ -115,10 +115,7 @@ // TODO(862619) change return type to base::Optional<CoreAccountInfo> CoreAccountInfo IdentityManager::GetPrimaryAccountInfo( ConsentLevel consent) const { - if (consent == ConsentLevel::kNotRequired) { - return primary_account_manager_->GetUnconsentedPrimaryAccountInfo(); - } - return primary_account_manager_->GetAuthenticatedAccountInfo(); + return primary_account_manager_->GetPrimaryAccountInfo(consent); } CoreAccountId IdentityManager::GetPrimaryAccountId(ConsentLevel consent) const { @@ -479,35 +476,90 @@ return account_info; } -void IdentityManager::GoogleSigninSucceeded( +void IdentityManager::OnPrimaryAccountChanged( + const PrimaryAccountChangeEvent& event_details) { + // TODO(crbug.com/1158855): Remove this switch statement once all observers + // are converted to OnPrimaryAccountChanged(). + switch (event_details.GetEventTypeFor(ConsentLevel::kSync)) { + case PrimaryAccountChangeEvent::Type::kSet: + FirePrimaryAccountSet(event_details); + break; + case PrimaryAccountChangeEvent::Type::kCleared: + FirePrimaryAccountCleared(event_details); + break; + case PrimaryAccountChangeEvent::Type::kNone: + break; + } + switch (event_details.GetEventTypeFor(ConsentLevel::kNotRequired)) { + case PrimaryAccountChangeEvent::Type::kSet: + case PrimaryAccountChangeEvent::Type::kCleared: + FireUnconsentedPrimaryAccountChanged(event_details); + break; + case PrimaryAccountChangeEvent::Type::kNone: + break; + } + + for (auto& observer : observer_list_) + observer.OnPrimaryAccountChanged(event_details); + +#if defined(OS_ANDROID) + if (!java_identity_manager_) + return; + JNIEnv* env = base::android::AttachCurrentThread(); + switch (event_details.GetEventTypeFor(ConsentLevel::kSync)) { + case PrimaryAccountChangeEvent::Type::kSet: + Java_IdentityManager_onPrimaryAccountSet( + env, java_identity_manager_, + ConvertToJavaCoreAccountInfo( + env, event_details.GetCurrentState().primary_account)); + return; + case PrimaryAccountChangeEvent::Type::kCleared: + Java_IdentityManager_onPrimaryAccountCleared( + env, java_identity_manager_, + ConvertToJavaCoreAccountInfo( + env, event_details.GetPreviousState().primary_account)); + return; + case PrimaryAccountChangeEvent::Type::kNone: + break; + } + switch (event_details.GetEventTypeFor(ConsentLevel::kNotRequired)) { + // TODO(http://crbug.com/1158855): This is a hack as the Java code expects + // a call to onPrimaryAccountCleared() when the unconsented primary account + // is cleared. This does not match the intent of OnPrimaryAccountCleared + // which is supposed to be fired only when sync account is being cleared. + // This hack *must* be removed quickly as it has a high misusage risk. + case PrimaryAccountChangeEvent::Type::kCleared: + Java_IdentityManager_onPrimaryAccountCleared( + env, java_identity_manager_, + ConvertToJavaCoreAccountInfo( + env, event_details.GetPreviousState().primary_account)); + break; + case PrimaryAccountChangeEvent::Type::kSet: + case PrimaryAccountChangeEvent::Type::kNone: + break; + } +#endif +} + +void IdentityManager::FirePrimaryAccountSet( const PrimaryAccountChangeEvent& event_details) { const CoreAccountInfo& account_info = event_details.GetCurrentState().primary_account; for (auto& observer : observer_list_) { observer.OnPrimaryAccountSet(account_info); - observer.OnPrimaryAccountChanged(event_details); } -#if defined(OS_ANDROID) - if (java_identity_manager_) { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_IdentityManager_onPrimaryAccountSet( - env, java_identity_manager_, - ConvertToJavaCoreAccountInfo(env, account_info)); - } -#endif } -void IdentityManager::UnconsentedPrimaryAccountChanged( +void IdentityManager::FireUnconsentedPrimaryAccountChanged( const PrimaryAccountChangeEvent& event_details) { const CoreAccountInfo& account_info = event_details.GetCurrentState().primary_account; for (auto& observer : observer_list_) { observer.OnUnconsentedPrimaryAccountChanged(account_info); - observer.OnPrimaryAccountChanged(event_details); } } -void IdentityManager::GoogleSignedOut( +void IdentityManager::FirePrimaryAccountCleared( const PrimaryAccountChangeEvent& event_details) { const CoreAccountInfo& account_info = event_details.GetPreviousState().primary_account; @@ -519,17 +571,7 @@ for (auto& observer : observer_list_) { observer.OnPrimaryAccountCleared(account_info); - observer.OnPrimaryAccountChanged(event_details); } - -#if defined(OS_ANDROID) - if (java_identity_manager_) { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_IdentityManager_onPrimaryAccountCleared( - env, java_identity_manager_, - ConvertToJavaCoreAccountInfo(env, account_info)); - } -#endif } void IdentityManager::OnRefreshTokenAvailable(const CoreAccountId& account_id) { @@ -638,7 +680,7 @@ if (HasPrimaryAccount()) { const CoreAccountId primary_account_id = GetPrimaryAccountId(); if (primary_account_id == info.account_id) { - primary_account_manager_->UpdateAuthenticatedAccountInfo(); + primary_account_manager_->UpdateSyncPrimaryAccountInfo(); } }
diff --git a/components/signin/public/identity_manager/identity_manager.h b/components/signin/public/identity_manager/identity_manager.h index ece5290..2fe9f4bb 100644 --- a/components/signin/public/identity_manager/identity_manager.h +++ b/components/signin/public/identity_manager/identity_manager.h
@@ -635,11 +635,8 @@ const CoreAccountId& account_id) const; // PrimaryAccountManager::Observer: - void GoogleSigninSucceeded( + void OnPrimaryAccountChanged( const PrimaryAccountChangeEvent& event_details) override; - void UnconsentedPrimaryAccountChanged( - const PrimaryAccountChangeEvent& event_details) override; - void GoogleSignedOut(const PrimaryAccountChangeEvent& event_details) override; // ProfileOAuth2TokenServiceObserver: void OnRefreshTokenAvailable(const CoreAccountId& account_id) override; @@ -679,6 +676,14 @@ void OnAccountUpdated(const AccountInfo& info); void OnAccountRemoved(const AccountInfo& info); + // Fire the deprecated observer methods for settings and clearing the primary + // account. + void FirePrimaryAccountSet(const PrimaryAccountChangeEvent& event_details); + void FireUnconsentedPrimaryAccountChanged( + const PrimaryAccountChangeEvent& event_details); + void FirePrimaryAccountCleared( + const PrimaryAccountChangeEvent& event_details); + // Backing signin classes. std::unique_ptr<AccountTrackerService> account_tracker_service_; std::unique_ptr<ProfileOAuth2TokenService> token_service_;
diff --git a/components/signin/public/identity_manager/identity_manager_unittest.cc b/components/signin/public/identity_manager/identity_manager_unittest.cc index 99a1003..2170b44 100644 --- a/components/signin/public/identity_manager/identity_manager_unittest.cc +++ b/components/signin/public/identity_manager/identity_manager_unittest.cc
@@ -410,8 +410,10 @@ if (primary_account_manager_setup == PrimaryAccountManagerSetup::kWithAuthenticatedAccout) { - account_tracker_service->SeedAccountInfo(kTestGaiaId, kTestEmail); - primary_account_manager->SignIn(kTestEmail); + CoreAccountId account_id = + account_tracker_service->SeedAccountInfo(kTestGaiaId, kTestEmail); + primary_account_manager->SetSyncPrimaryAccountInfo( + account_tracker_service->GetAccountInfo(account_id)); } IdentityManager::InitParameters init_params; @@ -1219,7 +1221,8 @@ identity_manager()->GetAccountTrackerService()->SeedAccountInfo(kTestGaiaId, kTestEmail); - identity_manager()->GetPrimaryAccountManager()->SignIn(kTestEmail); + identity_manager()->GetPrimaryAccountMutator()->SetPrimaryAccount( + primary_account_id()); UpdateCredentials(primary_account_id(), kTestGaiaId, kTestEmail, "refresh_token"); @@ -1260,7 +1263,8 @@ identity_manager()->GetAccountTrackerService()->SeedAccountInfo(kTestGaiaId, kTestEmail); - identity_manager()->GetPrimaryAccountManager()->SignIn(kTestEmail); + identity_manager()->GetPrimaryAccountMutator()->SetPrimaryAccount( + primary_account_id()); UpdateCredentials(primary_account_id(), kTestGaiaId, kTestEmail, "refresh_token"); @@ -1352,7 +1356,8 @@ identity_manager()->GetAccountTrackerService()->SeedAccountInfo(kTestGaiaId, kTestEmail); - identity_manager()->GetPrimaryAccountManager()->SignIn(kTestEmail); + identity_manager()->GetPrimaryAccountMutator()->SetPrimaryAccount( + primary_account_id()); UpdateCredentials(primary_account_id(), kTestGaiaId, kTestEmail, "refresh_token"); @@ -1407,7 +1412,8 @@ identity_manager()->GetAccountTrackerService()->SeedAccountInfo(kTestGaiaId, kTestEmail); - identity_manager()->GetPrimaryAccountManager()->SignIn(kTestEmail); + identity_manager()->GetPrimaryAccountMutator()->SetPrimaryAccount( + primary_account_id()); UpdateCredentials(primary_account_id(), kTestGaiaId, kTestEmail, "refresh_token"); token_service()->set_auto_post_fetch_response_on_message_loop(true); @@ -2097,7 +2103,8 @@ BatchChangeObserversAreNotifiedOnCredentialsUpdate) { identity_manager()->GetAccountTrackerService()->SeedAccountInfo(kTestGaiaId, kTestEmail); - identity_manager()->GetPrimaryAccountManager()->SignIn(kTestEmail); + identity_manager()->GetPrimaryAccountMutator()->SetPrimaryAccount( + primary_account_id()); UpdateCredentials(primary_account_id(), kTestGaiaId, kTestEmail, "refresh_token");
diff --git a/components/signin/public/identity_manager/identity_test_environment.cc b/components/signin/public/identity_manager/identity_test_environment.cc index 0c0e623..23cc5f8 100644 --- a/components/signin/public/identity_manager/identity_test_environment.cc +++ b/components/signin/public/identity_manager/identity_test_environment.cc
@@ -398,11 +398,11 @@ AccountInfo account_info = MakeAccountAvailable(email); identity_manager()->GetPrimaryAccountMutator()->SetUnconsentedPrimaryAccount( account_info.account_id); -#elif defined(OS_IOS) || defined(OS_ANDROID) - // iOS and Android only support the primary account. +#elif defined(OS_IOS) + // iOS only support the primary account. AccountInfo account_info = MakePrimaryAccountAvailable(email); #else - // Desktop platforms. + // Android and Desktop platforms. AccountInfo account_info = MakeAccountAvailableWithCookies(email, GetTestGaiaIdForEmail(email)); base::RunLoop().RunUntilIdle();
diff --git a/components/signin/public/identity_manager/identity_test_utils.cc b/components/signin/public/identity_manager/identity_test_utils.cc index 5f68ed8..588ff69 100644 --- a/components/signin/public/identity_manager/identity_test_utils.cc +++ b/components/signin/public/identity_manager/identity_test_utils.cc
@@ -125,7 +125,7 @@ EnsureAccountExists(identity_manager->GetAccountTrackerService(), email); DCHECK(!account_info.gaia.empty()); - primary_account_manager->SignIn(email); + primary_account_manager->SetSyncPrimaryAccountInfo(account_info); DCHECK(primary_account_manager->HasPrimaryAccount(ConsentLevel::kSync)); DCHECK(identity_manager->HasPrimaryAccount());
diff --git a/components/signin/public/identity_manager/primary_account_change_event.cc b/components/signin/public/identity_manager/primary_account_change_event.cc index 890ef755..a89f5bb 100644 --- a/components/signin/public/identity_manager/primary_account_change_event.cc +++ b/components/signin/public/identity_manager/primary_account_change_event.cc
@@ -32,15 +32,14 @@ if (previous_state_ == current_state_) return Type::kNone; - if (previous_state_.consent_level == ConsentLevel::kSync) { - // Cannot change the Sync account without signing out first. - DCHECK(previous_state_.primary_account == current_state_.primary_account || - current_state_.primary_account.IsEmpty()); - } - if (previous_state_.primary_account == current_state_.primary_account) { - // Cannot change the consent level for the empty account. - DCHECK(!previous_state_.primary_account.IsEmpty()); - } + // Cannot change the Sync account without clearing the primary account first. + DCHECK(previous_state_.consent_level != ConsentLevel::kSync || + previous_state_.primary_account == current_state_.primary_account || + current_state_.primary_account.IsEmpty()); + + // Cannot change the consent level for the empty account. + DCHECK(previous_state_.primary_account != current_state_.primary_account || + !previous_state_.primary_account.IsEmpty()); switch (consent_level) { case ConsentLevel::kNotRequired: @@ -55,7 +54,8 @@ ? Type::kSet : Type::kCleared; } - // Cannot change the Sync account without signing out first. + // Cannot change the Sync account without clearing the primary account + // first. DCHECK_EQ(current_state_.consent_level, ConsentLevel::kNotRequired); return Type::kNone; } @@ -77,4 +77,21 @@ lhs.consent_level == rhs.consent_level; } +std::ostream& operator<<(std::ostream& os, + const PrimaryAccountChangeEvent::State& state) { + os << "{ primary_account: " << state.primary_account.account_id << ", " + << "consent_level:" + << (state.consent_level == ConsentLevel::kNotRequired ? "NotRequired" + : "Sync") + << " }"; + return os; +} + +std::ostream& operator<<(std::ostream& os, + const PrimaryAccountChangeEvent& event) { + os << "{ previous_state: " << event.GetPreviousState() << ", " + << "current_state: " << event.GetCurrentState() << " }"; + return os; +} + } // namespace signin \ No newline at end of file
diff --git a/components/signin/public/identity_manager/primary_account_change_event.h b/components/signin/public/identity_manager/primary_account_change_event.h index 8ca54ae..1da4052b 100644 --- a/components/signin/public/identity_manager/primary_account_change_event.h +++ b/components/signin/public/identity_manager/primary_account_change_event.h
@@ -55,6 +55,10 @@ bool operator==(const PrimaryAccountChangeEvent::State& lhs, const PrimaryAccountChangeEvent::State& rhs); +std::ostream& operator<<(std::ostream& os, + const PrimaryAccountChangeEvent::State& state); +std::ostream& operator<<(std::ostream& os, + const PrimaryAccountChangeEvent& event); } // namespace signin #endif // COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_PRIMARY_ACCOUNT_CHANGE_EVENT_H_
diff --git a/content/browser/tracing/background_tracing_active_scenario.cc b/content/browser/tracing/background_tracing_active_scenario.cc index 1d11ae2..da5210e1 100644 --- a/content/browser/tracing/background_tracing_active_scenario.cc +++ b/content/browser/tracing/background_tracing_active_scenario.cc
@@ -121,11 +121,13 @@ } void BeginFinalizing(base::OnceClosure on_success, - base::OnceClosure on_failure) { + base::OnceClosure on_failure, + bool is_crash_scenario) { // If the finalization was already in progress, ignore this call. if (!tracing_session_) return; - if (!BackgroundTracingManagerImpl::GetInstance()->IsAllowedFinalization()) { + if (!BackgroundTracingManagerImpl::GetInstance()->IsAllowedFinalization( + is_crash_scenario)) { auto on_failure_cb = base::MakeRefCounted<base::RefCountedData<base::OnceClosure>>( std::move(on_failure)); @@ -401,7 +403,8 @@ weak_ptr_factory_.GetWeakPtr(), run_callback); tracing_session_->BeginFinalizing(std::move(on_begin_finalization_success), - std::move(on_begin_finalization_failure)); + std::move(on_begin_finalization_failure), + last_triggered_rule_->is_crash()); } void BackgroundTracingActiveScenario::OnJSONDataComplete(
diff --git a/content/browser/tracing/background_tracing_manager_impl.cc b/content/browser/tracing/background_tracing_manager_impl.cc index 3f501d26..239c39b 100644 --- a/content/browser/tracing/background_tracing_manager_impl.cc +++ b/content/browser/tracing/background_tracing_manager_impl.cc
@@ -454,12 +454,14 @@ } } -bool BackgroundTracingManagerImpl::IsAllowedFinalization() const { +bool BackgroundTracingManagerImpl::IsAllowedFinalization( + bool is_crash_scenario) const { return !delegate_ || (active_scenario_ && delegate_->IsAllowedToEndBackgroundScenario( *active_scenario_->GetConfig(), - active_scenario_->GetConfig()->requires_anonymized_data())); + active_scenario_->GetConfig()->requires_anonymized_data(), + is_crash_scenario)); } std::unique_ptr<base::DictionaryValue>
diff --git a/content/browser/tracing/background_tracing_manager_impl.h b/content/browser/tracing/background_tracing_manager_impl.h index be3e560..4c6b78dc 100644 --- a/content/browser/tracing/background_tracing_manager_impl.h +++ b/content/browser/tracing/background_tracing_manager_impl.h
@@ -133,7 +133,7 @@ void AddMetadataGeneratorFunction(); - bool IsAllowedFinalization() const; + bool IsAllowedFinalization(bool is_crash_scenario) const; // Called by BackgroundTracingActiveScenario void OnStartTracingDone(BackgroundTracingConfigImpl::CategoryPreset preset);
diff --git a/content/browser/tracing/background_tracing_rule.cc b/content/browser/tracing/background_tracing_rule.cc index 8647c03b..eebbb6f 100644 --- a/content/browser/tracing/background_tracing_rule.cc +++ b/content/browser/tracing/background_tracing_rule.cc
@@ -34,6 +34,7 @@ "stop_tracing_on_repeated_reactive"; const char kConfigRuleArgsKey[] = "args"; const char kConfigRuleIdKey[] = "rule_id"; +const char kConfigIsCrashKey[] = "is_crash"; const char kConfigRuleHistogramNameKey[] = "histogram_name"; const char kConfigRuleHistogramValueOldKey[] = "histogram_value"; @@ -67,19 +68,11 @@ namespace content { -BackgroundTracingRule::BackgroundTracingRule() - : trigger_chance_(1.0), - trigger_delay_(-1), - stop_tracing_on_repeated_reactive_(false), - category_preset_(BackgroundTracingConfigImpl::CATEGORY_PRESET_UNSET) {} - +BackgroundTracingRule::BackgroundTracingRule() = default; BackgroundTracingRule::BackgroundTracingRule(int trigger_delay) - : trigger_chance_(1.0), - trigger_delay_(trigger_delay), - stop_tracing_on_repeated_reactive_(false), - category_preset_(BackgroundTracingConfigImpl::CATEGORY_PRESET_UNSET) {} + : trigger_delay_(trigger_delay) {} -BackgroundTracingRule::~BackgroundTracingRule() {} +BackgroundTracingRule::~BackgroundTracingRule() = default; bool BackgroundTracingRule::ShouldTriggerNamedEvent( const std::string& named_event) const { @@ -115,6 +108,10 @@ kConfigCategoryKey, BackgroundTracingConfigImpl::CategoryPresetToString(category_preset_)); } + + if (is_crash_) { + dict->SetBoolean(kConfigIsCrashKey, is_crash_); + } } void BackgroundTracingRule::GenerateMetadataProto( @@ -130,6 +127,7 @@ } else { rule_id_ = GetDefaultRuleId(); } + dict->GetBoolean(kConfigIsCrashKey, &is_crash_); } namespace {
diff --git a/content/browser/tracing/background_tracing_rule.h b/content/browser/tracing/background_tracing_rule.h index 299019b..0b6b0fc 100644 --- a/content/browser/tracing/background_tracing_rule.h +++ b/content/browser/tracing/background_tracing_rule.h
@@ -65,17 +65,21 @@ const std::string& rule_id() const { return rule_id_; } + bool is_crash() const { return is_crash_; } + protected: virtual std::string GetDefaultRuleId() const; private: DISALLOW_COPY_AND_ASSIGN(BackgroundTracingRule); - double trigger_chance_; - int trigger_delay_; - bool stop_tracing_on_repeated_reactive_; + double trigger_chance_ = 1.0; + int trigger_delay_ = -1; + bool stop_tracing_on_repeated_reactive_ = false; std::string rule_id_; - BackgroundTracingConfigImpl::CategoryPreset category_preset_; + BackgroundTracingConfigImpl::CategoryPreset category_preset_ = + BackgroundTracingConfigImpl::CATEGORY_PRESET_UNSET; + bool is_crash_ = false; std::unique_ptr<base::DictionaryValue> args_; };
diff --git a/content/public/browser/tracing_delegate.cc b/content/public/browser/tracing_delegate.cc index c216979..eb1e110 100644 --- a/content/public/browser/tracing_delegate.cc +++ b/content/public/browser/tracing_delegate.cc
@@ -16,7 +16,8 @@ bool TracingDelegate::IsAllowedToEndBackgroundScenario( const content::BackgroundTracingConfig& config, - bool requires_anonymized_data) { + bool requires_anonymized_data, + bool is_crash_scenario) { return false; }
diff --git a/content/public/browser/tracing_delegate.h b/content/public/browser/tracing_delegate.h index 0aede03..cd17a08 100644 --- a/content/public/browser/tracing_delegate.h +++ b/content/public/browser/tracing_delegate.h
@@ -40,7 +40,8 @@ virtual bool IsAllowedToEndBackgroundScenario( const content::BackgroundTracingConfig& config, - bool requires_anonymized_data); + bool requires_anonymized_data, + bool is_crash_scenario); virtual bool IsProfileLoaded();
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 index 2214ae2..d94fba5b 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -98740986d373cb954788b10f66dbce6f2fd921ba \ No newline at end of file +36b5262321411db1fde3fef494c819dff7ee1bce \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 index 25a51b2..94c3dd1 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -deaf9fa5754950cd3c6cc1add204c616f546b312 \ No newline at end of file +e6219d58d76eabdcfde3a4e4a64821cbbac00d0f \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 index daaeb53..597106f 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -d1c9346d6a428bc471837e7ff2805a6508283745 \ No newline at end of file +c21209e3f14d5f49551481b8a7cdcea317a2f78a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 index ea0eb784..c57bc18 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -b986e70d8be5ab9be5fafe51b55068d9e5fd6b84 \ No newline at end of file +de42fae3da12db766861111cf754385671552273 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 index 0f331fb..1dedc26c 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -85a310ae25145eb6195145788968f3aec83a6c5e \ No newline at end of file +3c0d9708365385b6badbb13255d6cb8fab95aa3d \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 index 7a315e5..0923327b 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -d486c191e0dbb93fc72dd8c74c8867d6196dae10 \ No newline at end of file +c3c4931568b06c2fe81a9f127a66aa68dadc9eef \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 index 221b2e2..4ccad41 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -a4be0f2eba02c425775de37328dc26517fbcaf2f \ No newline at end of file +701a0e408c9ca8f312881e5cc1f7600498e72e50 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 index 315d811..878622e8 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -c4270b410a20961de46ed32413b33795989abaff \ No newline at end of file +2adf62f62e95e284449fb069e432a3cb9f93d3e1 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 index 76e6c8f..851a3da 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -1899d265d945c71118d5e3f9f1301efecf0e8326 \ No newline at end of file +603e8ad156d67e9c8bce74c1b4626009c002912a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 index 492ce390..3114cce 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -3765977ed9b7b19280ba8c783746f202f3e0952d \ No newline at end of file +bf49209ebc31fd09f8fdde046c93af91d0258acf \ No newline at end of file
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index 8c9807b6..695dd49 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -240,11 +240,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.126" + "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.128" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.126", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.128", "resultdb": { "enable": true }, @@ -254,7 +254,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.126" + "revision": "version:87.0.4280.128" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -317,11 +317,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.60" + "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.62" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.60", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.62", "resultdb": { "enable": true }, @@ -331,7 +331,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.60" + "revision": "version:88.0.4324.62" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -394,11 +394,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.126" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.128" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.126", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.128", "resultdb": { "enable": true }, @@ -408,7 +408,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.126" + "revision": "version:87.0.4280.128" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -471,11 +471,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.60" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.62" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.60", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.62", "resultdb": { "enable": true }, @@ -485,7 +485,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.60" + "revision": "version:88.0.4324.62" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -769,11 +769,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.126" + "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.128" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.126", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.128", "resultdb": { "enable": true }, @@ -783,7 +783,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.126" + "revision": "version:87.0.4280.128" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -846,11 +846,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.60" + "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.62" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.60", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.62", "resultdb": { "enable": true }, @@ -860,7 +860,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.60" + "revision": "version:88.0.4324.62" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -923,11 +923,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.126" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.128" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.126", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.128", "resultdb": { "enable": true }, @@ -937,7 +937,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.126" + "revision": "version:87.0.4280.128" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1000,11 +1000,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.60" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.62" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.60", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.62", "resultdb": { "enable": true }, @@ -1014,7 +1014,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.60" + "revision": "version:88.0.4324.62" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1298,11 +1298,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.126" + "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.128" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.126", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.128", "resultdb": { "enable": true }, @@ -1312,7 +1312,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.126" + "revision": "version:87.0.4280.128" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1375,11 +1375,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.60" + "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.62" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.60", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.62", "resultdb": { "enable": true }, @@ -1389,7 +1389,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.60" + "revision": "version:88.0.4324.62" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1452,11 +1452,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.126" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.128" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.126", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.128", "resultdb": { "enable": true }, @@ -1466,7 +1466,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.126" + "revision": "version:87.0.4280.128" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1529,11 +1529,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.60" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.62" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.60", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.62", "resultdb": { "enable": true }, @@ -1543,7 +1543,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.60" + "revision": "version:88.0.4324.62" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1827,11 +1827,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.126" + "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.128" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.126", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 87.0.4280.128", "resultdb": { "enable": true }, @@ -1841,7 +1841,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.126" + "revision": "version:87.0.4280.128" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1904,11 +1904,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.60" + "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.62" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.60", + "name": "weblayer_instrumentation_test_versions_apk_Client Tests For 88.0.4324.62", "resultdb": { "enable": true }, @@ -1918,7 +1918,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.60" + "revision": "version:88.0.4324.62" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -1981,11 +1981,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.126" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.128" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.126", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 87.0.4280.128", "resultdb": { "enable": true }, @@ -1995,7 +1995,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M87", - "revision": "version:87.0.4280.126" + "revision": "version:87.0.4280.128" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -2058,11 +2058,11 @@ "--bucket", "chromium-result-details", "--test-name", - "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.60" + "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.62" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" }, - "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.60", + "name": "weblayer_instrumentation_test_versions_apk_Implementation Tests For 88.0.4324.62", "resultdb": { "enable": true }, @@ -2072,7 +2072,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M88", - "revision": "version:88.0.4324.60" + "revision": "version:88.0.4324.62" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 8a8eeed0..b79d107 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -319,13 +319,13 @@ '../../weblayer/browser/android/javatests/skew/expectations.txt', '--impl-version=88', ], - 'identifier': 'Implementation Tests For 88.0.4324.60', + 'identifier': 'Implementation Tests For 88.0.4324.62', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M88', - 'revision': 'version:88.0.4324.60', + 'revision': 'version:88.0.4324.62', } ], }, @@ -342,13 +342,13 @@ '../../weblayer/browser/android/javatests/skew/expectations.txt', '--impl-version=87', ], - 'identifier': 'Implementation Tests For 87.0.4280.126', + 'identifier': 'Implementation Tests For 87.0.4280.128', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M87', - 'revision': 'version:87.0.4280.126', + 'revision': 'version:87.0.4280.128', } ], }, @@ -388,13 +388,13 @@ '../../weblayer/browser/android/javatests/skew/expectations.txt', '--client-version=88', ], - 'identifier': 'Client Tests For 88.0.4324.60', + 'identifier': 'Client Tests For 88.0.4324.62', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M88', - 'revision': 'version:88.0.4324.60', + 'revision': 'version:88.0.4324.62', } ], }, @@ -411,13 +411,13 @@ '../../weblayer/browser/android/javatests/skew/expectations.txt', '--client-version=87', ], - 'identifier': 'Client Tests For 87.0.4280.126', + 'identifier': 'Client Tests For 87.0.4280.128', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M87', - 'revision': 'version:87.0.4280.126', + 'revision': 'version:87.0.4280.128', } ], },
diff --git a/third_party/blink/renderer/platform/heap/impl/member.h b/third_party/blink/renderer/platform/heap/impl/member.h index 66f2e23..17dd6db 100644 --- a/third_party/blink/renderer/platform/heap/impl/member.h +++ b/third_party/blink/renderer/platform/heap/impl/member.h
@@ -348,7 +348,7 @@ // heap allocated objects. // However instead of creating a strong pointer to the object, the WeakMember // creates a weak pointer, which does not keep the pointee alive. Hence if all -// pointers to to a heap allocated object are weak the object will be garbage +// pointers to a heap allocated object are weak the object will be garbage // collected. At the time of GC the weak pointers will automatically be set to // null. template <typename T>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 61e504f..00e45c7 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -46616,6 +46616,7 @@ <int value="3" label="Password entered login"/> <int value="4" label="Preloaded password sites list"/> <int value="5" label="Field trial logged-in site"/> + <int value="6" label="Password manager saved site"/> </enum> <enum name="LoginFailureReason">
diff --git a/tools/metrics/histograms/histograms_xml/login/histograms.xml b/tools/metrics/histograms/histograms_xml/login/histograms.xml index e354f999..b843f2ce 100644 --- a/tools/metrics/histograms/histograms_xml/login/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/login/histograms.xml
@@ -176,6 +176,18 @@ </summary> </histogram> +<histogram name="Login.PasswordStoreSites.InitializedBeforeQuery" + enum="Boolean" expires_after="2021-11-30"> + <owner>rajendrant@chromium.org</owner> + <owner>mcrouse@chromium.org</owner> + <summary> + Records whether the passworded sites list is initialized when the query for + sites happens. This is used to measure how many queries happened before the + list got populated the first time. Recorded on every query to the password + store. + </summary> +</histogram> + <histogram name="Login.PolicyFilesStatePerBoot" enum="LoginPolicyFilesState" expires_after="M81"> <owner>cmasone@chromium.org</owner>
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index c04bb9c95a..f7264ec2 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -294,7 +294,7 @@ <item id="safe_browsing_certificate_error_reporting" added_in_milestone="62" hash_code="66590631" type="0" content_hash_code="26108454" os_list="linux,windows" file_path="chrome/browser/ssl/certificate_error_reporter.cc"/> <item id="safe_browsing_chunk_backup_request" added_in_milestone="62" hash_code="79957943" type="0" deprecated="2018-08-14" content_hash_code="133850277" file_path=""/> <item id="safe_browsing_client_side_malware_detector" added_in_milestone="62" hash_code="102935425" type="0" deprecated="2019-12-07" content_hash_code="79591279" file_path=""/> - <item id="safe_browsing_client_side_phishing_detector" added_in_milestone="62" hash_code="1313982" type="0" content_hash_code="50199143" os_list="linux,windows" file_path="chrome/browser/safe_browsing/client_side_detection_service.cc"/> + <item id="safe_browsing_client_side_phishing_detector" added_in_milestone="62" hash_code="1313982" type="0" content_hash_code="50199143" os_list="linux,windows" file_path="components/safe_browsing/content/browser/client_side_detection_service.cc"/> <item id="safe_browsing_extended_reporting" added_in_milestone="62" hash_code="42848942" type="0" content_hash_code="81193513" os_list="linux,windows" file_path="components/safe_browsing/core/ping_manager.cc"/> <item id="safe_browsing_feedback" added_in_milestone="62" hash_code="44583821" type="0" content_hash_code="27116846" os_list="linux,windows" file_path="chrome/browser/safe_browsing/download_protection/download_feedback.cc"/> <item id="safe_browsing_get_full_hash" added_in_milestone="62" hash_code="68745894" type="0" deprecated="2018-08-14" content_hash_code="21739198" file_path=""/>
diff --git a/ui/accessibility/OWNERS b/ui/accessibility/OWNERS index 815bea4..717b0e5 100644 --- a/ui/accessibility/OWNERS +++ b/ui/accessibility/OWNERS
@@ -1,10 +1,10 @@ +abigailbklein@google.com +aboxhall@chromium.org +aleventhal@chromium.org dmazzoni@chromium.org dtseng@chromium.org -aboxhall@chromium.org -nektar@chromium.org -dougt@chromium.org -aleventhal@chromium.org katie@chromium.org +nektar@chromium.org per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/weblayer/BUILD.gn b/weblayer/BUILD.gn index a5bfc19..5e457ee2 100644 --- a/weblayer/BUILD.gn +++ b/weblayer/BUILD.gn
@@ -414,6 +414,7 @@ "//components/policy/core/browser", "//components/pref_registry:pref_registry", "//components/prefs", + "//components/safe_browsing/content/browser:client_side_detection", "//components/safe_browsing/content/common:interfaces", "//components/safe_browsing/content/renderer:throttles", "//components/safe_browsing/content/renderer/phishing_classifier", @@ -567,6 +568,12 @@ "browser/new_tab_callback_proxy.h", "browser/proxying_url_loader_factory_impl.cc", "browser/proxying_url_loader_factory_impl.h", + "browser/safe_browsing/client_side_detection_host_delegate.cc", + "browser/safe_browsing/client_side_detection_host_delegate.h", + "browser/safe_browsing/client_side_detection_service_delegate.cc", + "browser/safe_browsing/client_side_detection_service_delegate.h", + "browser/safe_browsing/client_side_detection_service_factory.cc", + "browser/safe_browsing/client_side_detection_service_factory.h", "browser/safe_browsing/real_time_url_lookup_service_factory.cc", "browser/safe_browsing/real_time_url_lookup_service_factory.h", "browser/safe_browsing/safe_browsing_blocking_page.cc", @@ -577,6 +584,8 @@ "browser/safe_browsing/safe_browsing_service.h", "browser/safe_browsing/safe_browsing_subresource_helper.cc", "browser/safe_browsing/safe_browsing_subresource_helper.h", + "browser/safe_browsing/safe_browsing_tab_observer.cc", + "browser/safe_browsing/safe_browsing_tab_observer.h", "browser/safe_browsing/safe_browsing_ui_manager.cc", "browser/safe_browsing/safe_browsing_ui_manager.h", "browser/safe_browsing/url_checker_delegate_impl.cc", @@ -641,11 +650,15 @@ "//components/safe_browsing/android:safe_browsing_api_handler", "//components/safe_browsing/content", "//components/safe_browsing/content/browser", + "//components/safe_browsing/content/browser:client_side_model_loader", + "//components/safe_browsing/core:client_model_proto", + "//components/safe_browsing/core:csd_proto", "//components/safe_browsing/core:ping_manager", "//components/safe_browsing/core:verdict_cache_manager", "//components/safe_browsing/core/browser", "//components/safe_browsing/core/browser:network_context", "//components/safe_browsing/core/common", + "//components/safe_browsing/core/db:allowlist_checker_client", "//components/safe_browsing/core/db:database_manager", "//components/safe_browsing/core/realtime:policy_engine", "//components/safe_browsing/core/realtime:url_lookup_service",
diff --git a/weblayer/browser/safe_browsing/DEPS b/weblayer/browser/safe_browsing/DEPS index 56c6be6..73c4bc5 100644 --- a/weblayer/browser/safe_browsing/DEPS +++ b/weblayer/browser/safe_browsing/DEPS
@@ -1,4 +1,3 @@ include_rules = [ "+components/safe_browsing", - ] - \ No newline at end of file +] \ No newline at end of file
diff --git a/weblayer/browser/safe_browsing/client_side_detection_host_delegate.cc b/weblayer/browser/safe_browsing/client_side_detection_host_delegate.cc new file mode 100644 index 0000000..7ef047a --- /dev/null +++ b/weblayer/browser/safe_browsing/client_side_detection_host_delegate.cc
@@ -0,0 +1,54 @@ +// 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 "weblayer/browser/safe_browsing/client_side_detection_host_delegate.h" + +#include "components/prefs/pref_service.h" +#include "components/safe_browsing/android/remote_database_manager.h" +#include "components/safe_browsing/content/browser/client_side_detection_service.h" +#include "weblayer/browser/browser_context_impl.h" +#include "weblayer/browser/browser_process.h" +#include "weblayer/browser/safe_browsing/client_side_detection_service_factory.h" +#include "weblayer/browser/safe_browsing/safe_browsing_service.h" + +namespace weblayer { + +ClientSideDetectionHostDelegate::ClientSideDetectionHostDelegate( + content::WebContents* web_contents) + : web_contents_(web_contents) {} + +ClientSideDetectionHostDelegate::~ClientSideDetectionHostDelegate() = default; + +bool ClientSideDetectionHostDelegate::HasSafeBrowsingUserInteractionObserver() { + return false; +} + +PrefService* ClientSideDetectionHostDelegate::GetPrefs() { + BrowserContextImpl* browser_context_impl = + static_cast<BrowserContextImpl*>(web_contents_->GetBrowserContext()); + DCHECK(browser_context_impl); + return browser_context_impl->pref_service(); +} + +scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> +ClientSideDetectionHostDelegate::GetSafeBrowsingDBManager() { + SafeBrowsingService* sb_service = + BrowserProcess::GetInstance()->GetSafeBrowsingService(); + return sb_service ? sb_service->GetSafeBrowsingDBManager() : nullptr; +} + +scoped_refptr<safe_browsing::BaseUIManager> +ClientSideDetectionHostDelegate::GetSafeBrowsingUIManager() { + SafeBrowsingService* sb_service = + BrowserProcess::GetInstance()->GetSafeBrowsingService(); + return sb_service ? sb_service->GetSafeBrowsingUIManager() : nullptr; +} + +safe_browsing::ClientSideDetectionService* +ClientSideDetectionHostDelegate::GetClientSideDetectionService() { + return ClientSideDetectionServiceFactory::GetForBrowserContext( + web_contents_->GetBrowserContext()); +} + +} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/client_side_detection_host_delegate.h b/weblayer/browser/safe_browsing/client_side_detection_host_delegate.h new file mode 100644 index 0000000..ed6b467 --- /dev/null +++ b/weblayer/browser/safe_browsing/client_side_detection_host_delegate.h
@@ -0,0 +1,36 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_DELEGATE_H_ +#define WEBLAYER_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_DELEGATE_H_ + +#include "components/safe_browsing/content/browser/client_side_detection_host.h" + +namespace weblayer { + +class ClientSideDetectionHostDelegate + : public safe_browsing::ClientSideDetectionHost::Delegate { + public: + explicit ClientSideDetectionHostDelegate(content::WebContents* web_contents); + ~ClientSideDetectionHostDelegate() override; + + // ClientSideDetectionHost::Delegate implementation. + bool HasSafeBrowsingUserInteractionObserver() override; + PrefService* GetPrefs() override; + scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> + GetSafeBrowsingDBManager() override; + scoped_refptr<safe_browsing::BaseUIManager> GetSafeBrowsingUIManager() + override; + safe_browsing::ClientSideDetectionService* GetClientSideDetectionService() + override; + + private: + content::WebContents* web_contents_; + + DISALLOW_COPY_AND_ASSIGN(ClientSideDetectionHostDelegate); +}; + +} // namespace weblayer + +#endif // WEBLAYER_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_DELEGATE_H_
diff --git a/weblayer/browser/safe_browsing/client_side_detection_service_browsertest.cc b/weblayer/browser/safe_browsing/client_side_detection_service_browsertest.cc new file mode 100644 index 0000000..c087e680 --- /dev/null +++ b/weblayer/browser/safe_browsing/client_side_detection_service_browsertest.cc
@@ -0,0 +1,123 @@ +// 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 "weblayer/browser/safe_browsing/client_side_detection_service_factory.h" + +#include "base/test/bind.h" +#include "base/test/scoped_feature_list.h" +#include "components/prefs/pref_service.h" +#include "components/safe_browsing/content/browser/client_side_detection_service.h" +#include "components/safe_browsing/content/common/safe_browsing.mojom.h" +#include "components/safe_browsing/core/common/safe_browsing_prefs.h" +#include "components/safe_browsing/core/proto/client_model.pb.h" +#include "content/public/test/browser_test.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "services/service_manager/public/cpp/interface_provider.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "weblayer/browser/browser_context_impl.h" +#include "weblayer/browser/profile_impl.h" +#include "weblayer/browser/tab_impl.h" +#include "weblayer/common/features.h" +#include "weblayer/shell/browser/shell.h" +#include "weblayer/test/weblayer_browser_test.h" +#include "weblayer/test/weblayer_browser_test_utils.h" + +namespace weblayer { + +using safe_browsing::ClientSideDetectionService; +using safe_browsing::ClientSideModel; +using safe_browsing::ModelLoader; +using ::testing::_; +using ::testing::ReturnRef; +using ::testing::StrictMock; + +namespace { + +class FakeModelLoader : public ModelLoader { + public: + explicit FakeModelLoader(const std::string& model_str) + : ModelLoader(base::RepeatingClosure(), + nullptr, + /*is_extended_reporting=*/false) { + model_str_ = model_str; + } + ~FakeModelLoader() override = default; + + void ScheduleFetch(int64_t delay) override {} + void CancelFetcher() override {} +}; + +std::unique_ptr<ModelLoader> CreateFakeModelLoader(std::string model_str) { + return std::make_unique<FakeModelLoader>(model_str); +} + +} // namespace + +class ClientSideDetectionServiceBrowserTest : public WebLayerBrowserTest { + public: + ClientSideDetectionServiceBrowserTest() { + feature_list_.InitAndEnableFeature( + features::kWebLayerClientSidePhishingDetection); + } + content::WebContents* GetWebContents() { + return static_cast<TabImpl*>(shell()->tab())->web_contents(); + } + + private: + void SetUpOnMainThread() override { + NavigateAndWaitForCompletion(GURL("about:blank"), shell()); + } + base::test::ScopedFeatureList feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(ClientSideDetectionServiceBrowserTest, + NewHostGetsModel) { + PrefService* prefs = GetProfile()->GetBrowserContext()->pref_service(); + prefs->SetBoolean(::prefs::kSafeBrowsingEnabled, false); + ClientSideDetectionService* csd_service = + ClientSideDetectionServiceFactory::GetForBrowserContext( + GetProfile()->GetBrowserContext()); + + ClientSideModel model; + model.set_max_words_per_term(0); + std::string model_str; + model.SerializeToString(&model_str); + + csd_service->SetModelLoaderFactoryForTesting( + base::BindRepeating(&CreateFakeModelLoader, model_str)); + + // Enable Safe Browsing and the CSD service. + prefs->SetBoolean(::prefs::kSafeBrowsingEnabled, true); + + base::RunLoop run_loop; + + content::RenderFrameHost* rfh = GetWebContents()->GetMainFrame(); + mojo::Remote<safe_browsing::mojom::PhishingDetector> phishing_detector; + rfh->GetRemoteInterfaces()->GetInterface( + phishing_detector.BindNewPipeAndPassReceiver()); + + safe_browsing::mojom::PhishingDetectorResult result; + std::string verdict; + phishing_detector->StartPhishingDetection( + GURL("about:blank"), + base::BindOnce( + [](base::RepeatingClosure quit_closure, + safe_browsing::mojom::PhishingDetectorResult* out_result, + std::string* out_verdict, + safe_browsing::mojom::PhishingDetectorResult result, + const std::string& verdict) { + *out_result = result; + *out_verdict = verdict; + quit_closure.Run(); + }, + run_loop.QuitClosure(), &result, &verdict)); + + run_loop.Run(); + + // The model classification will run, but will return an invalid score. + EXPECT_EQ(result, + safe_browsing::mojom::PhishingDetectorResult::INVALID_SCORE); +} + +} // namespace weblayer \ No newline at end of file
diff --git a/weblayer/browser/safe_browsing/client_side_detection_service_delegate.cc b/weblayer/browser/safe_browsing/client_side_detection_service_delegate.cc new file mode 100644 index 0000000..7aaeba0fd --- /dev/null +++ b/weblayer/browser/safe_browsing/client_side_detection_service_delegate.cc
@@ -0,0 +1,46 @@ +// 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 "weblayer/browser/safe_browsing/client_side_detection_service_delegate.h" + +#include "components/safe_browsing/core/common/utils.h" +#include "content/public/browser/storage_partition.h" +#include "weblayer/browser/browser_context_impl.h" +#include "weblayer/browser/browser_process.h" +#include "weblayer/browser/safe_browsing/safe_browsing_service.h" + +namespace weblayer { + +ClientSideDetectionServiceDelegate::ClientSideDetectionServiceDelegate( + BrowserContextImpl* browser_context) + : browser_context_(browser_context) {} + +ClientSideDetectionServiceDelegate::~ClientSideDetectionServiceDelegate() = + default; + +PrefService* ClientSideDetectionServiceDelegate::GetPrefs() { + DCHECK(browser_context_); + return browser_context_->pref_service(); +} + +scoped_refptr<network::SharedURLLoaderFactory> +ClientSideDetectionServiceDelegate::GetURLLoaderFactory() { + return content::BrowserContext::GetDefaultStoragePartition(browser_context_) + ->GetURLLoaderFactoryForBrowserProcess(); +} + +scoped_refptr<network::SharedURLLoaderFactory> +ClientSideDetectionServiceDelegate::GetSafeBrowsingURLLoaderFactory() { + SafeBrowsingService* sb_service = + BrowserProcess::GetInstance()->GetSafeBrowsingService(); + return sb_service ? sb_service->GetURLLoaderFactory() : nullptr; +} + +safe_browsing::ChromeUserPopulation::ProfileManagementStatus +ClientSideDetectionServiceDelegate::GetManagementStatus() { + // corresponds to unmanaged "unavailable" status on android + return safe_browsing::GetProfileManagementStatus(nullptr); +} + +} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/client_side_detection_service_delegate.h b/weblayer/browser/safe_browsing/client_side_detection_service_delegate.h new file mode 100644 index 0000000..afe14cc --- /dev/null +++ b/weblayer/browser/safe_browsing/client_side_detection_service_delegate.h
@@ -0,0 +1,35 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_DELEGATE_H_ +#define WEBLAYER_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_DELEGATE_H_ + +#include "components/safe_browsing/content/browser/client_side_detection_service.h" + +namespace weblayer { + +class ClientSideDetectionServiceDelegate + : public safe_browsing::ClientSideDetectionService::Delegate { + public: + explicit ClientSideDetectionServiceDelegate( + BrowserContextImpl* browser_context); + ~ClientSideDetectionServiceDelegate() override; + + // ClientSideDetectionService::Delegate implementation. + PrefService* GetPrefs() override; + scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; + scoped_refptr<network::SharedURLLoaderFactory> + GetSafeBrowsingURLLoaderFactory() override; + safe_browsing::ChromeUserPopulation::ProfileManagementStatus + GetManagementStatus() override; + + private: + BrowserContextImpl* browser_context_; + + DISALLOW_COPY_AND_ASSIGN(ClientSideDetectionServiceDelegate); +}; + +} // namespace weblayer + +#endif // WEBLAYER_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_DELEGATE_H_
diff --git a/weblayer/browser/safe_browsing/client_side_detection_service_factory.cc b/weblayer/browser/safe_browsing/client_side_detection_service_factory.cc new file mode 100644 index 0000000..9d22cabda --- /dev/null +++ b/weblayer/browser/safe_browsing/client_side_detection_service_factory.cc
@@ -0,0 +1,59 @@ +// 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 "weblayer/browser/safe_browsing/client_side_detection_service_factory.h" + +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/safe_browsing/content/browser/client_side_detection_service.h" +#include "content/public/browser/browser_context.h" +#include "weblayer/browser/browser_context_impl.h" +#include "weblayer/browser/browser_process.h" +#include "weblayer/browser/feature_list_creator.h" +#include "weblayer/browser/safe_browsing/client_side_detection_service_delegate.h" +#include "weblayer/common/features.h" + +namespace weblayer { + +// static +safe_browsing::ClientSideDetectionService* +ClientSideDetectionServiceFactory::GetForBrowserContext( + content::BrowserContext* browser_context) { + if (base::FeatureList::IsEnabled( + features::kWebLayerClientSidePhishingDetection)) { + return static_cast<safe_browsing::ClientSideDetectionService*>( + GetInstance()->GetServiceForBrowserContext(browser_context, + /* create= */ true)); + } + return nullptr; +} + +// static +ClientSideDetectionServiceFactory* +ClientSideDetectionServiceFactory::GetInstance() { + static base::NoDestructor<ClientSideDetectionServiceFactory> factory; + return factory.get(); +} + +ClientSideDetectionServiceFactory::ClientSideDetectionServiceFactory() + : BrowserContextKeyedServiceFactory( + "ClientSideDetectionService", + BrowserContextDependencyManager::GetInstance()) {} + +ClientSideDetectionServiceFactory::~ClientSideDetectionServiceFactory() = + default; + +KeyedService* ClientSideDetectionServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + return new safe_browsing::ClientSideDetectionService( + std::make_unique<ClientSideDetectionServiceDelegate>( + static_cast<BrowserContextImpl*>(context))); +} + +content::BrowserContext* +ClientSideDetectionServiceFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + return context; +} + +} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/client_side_detection_service_factory.h b/weblayer/browser/safe_browsing/client_side_detection_service_factory.h new file mode 100644 index 0000000..f8e491e --- /dev/null +++ b/weblayer/browser/safe_browsing/client_side_detection_service_factory.h
@@ -0,0 +1,56 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_FACTORY_H_ +#define WEBLAYER_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_FACTORY_H_ + +#include "base/no_destructor.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +class KeyedService; + +namespace content { +class BrowserContext; +} + +namespace safe_browsing { +class ClientSideDetectionService; +} + +namespace weblayer { + +// Singleton that owns ClientSideDetectionServiceFactory objects and associates +// them them with BrowserContextImpl instances. +class ClientSideDetectionServiceFactory + : public BrowserContextKeyedServiceFactory { + public: + ClientSideDetectionServiceFactory(const ClientSideDetectionServiceFactory&) = + delete; + ClientSideDetectionServiceFactory& operator=( + const ClientSideDetectionServiceFactory&) = delete; + + // Creates the service if it doesn't exist already for the given + // |browser_context|. If the service already exists, return its pointer. + static safe_browsing::ClientSideDetectionService* GetForBrowserContext( + content::BrowserContext* browser_context); + + // Get the singleton instance. + static ClientSideDetectionServiceFactory* GetInstance(); + + private: + friend class base::NoDestructor<ClientSideDetectionServiceFactory>; + + ClientSideDetectionServiceFactory(); + ~ClientSideDetectionServiceFactory() override; + + // BrowserContextKeyedServiceFactory: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; +}; + +} // namespace weblayer + +#endif // WEBLAYER_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_FACTORY_H_
diff --git a/weblayer/browser/safe_browsing/client_side_detection_service_factory_browsertest.cc b/weblayer/browser/safe_browsing/client_side_detection_service_factory_browsertest.cc new file mode 100644 index 0000000..29448aab --- /dev/null +++ b/weblayer/browser/safe_browsing/client_side_detection_service_factory_browsertest.cc
@@ -0,0 +1,34 @@ +// 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 "weblayer/browser/safe_browsing/client_side_detection_service_factory.h" + +#include "base/test/scoped_feature_list.h" +#include "weblayer/browser/browser_context_impl.h" +#include "weblayer/browser/profile_impl.h" +#include "weblayer/common/features.h" +#include "weblayer/test/weblayer_browser_test.h" + +namespace weblayer { + +class ClientSideDetectionServiceFactoryBrowserTest + : public WebLayerBrowserTest { + public: + ClientSideDetectionServiceFactoryBrowserTest() { + feature_list_.InitAndDisableFeature( + features::kWebLayerClientSidePhishingDetection); + } + + private: + void SetUpOnMainThread() override {} + base::test::ScopedFeatureList feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(ClientSideDetectionServiceFactoryBrowserTest, + ClientDetectionServiceNullWhenDisabled) { + EXPECT_EQ(nullptr, ClientSideDetectionServiceFactory::GetForBrowserContext( + GetProfile()->GetBrowserContext())); +} + +} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/safe_browsing_service.cc b/weblayer/browser/safe_browsing/safe_browsing_service.cc index adb19d19..c85d8bd 100644 --- a/weblayer/browser/safe_browsing/safe_browsing_service.cc +++ b/weblayer/browser/safe_browsing/safe_browsing_service.cc
@@ -127,7 +127,7 @@ SafeBrowsingService::CreateSafeBrowsingNavigationThrottle( content::NavigationHandle* handle) { return std::make_unique<SafeBrowsingNavigationThrottle>( - handle, GetSafeBrowsingUIManager()); + handle, GetSafeBrowsingUIManager().get()); } scoped_refptr<safe_browsing::UrlCheckerDelegate> @@ -142,16 +142,17 @@ return safe_browsing_url_checker_delegate_; } -safe_browsing::RemoteSafeBrowsingDatabaseManager* +scoped_refptr<safe_browsing::RemoteSafeBrowsingDatabaseManager> SafeBrowsingService::GetSafeBrowsingDBManager() { if (!safe_browsing_db_manager_) { CreateAndStartSafeBrowsingDBManager(); } - return safe_browsing_db_manager_.get(); + return safe_browsing_db_manager_; } -SafeBrowsingUIManager* SafeBrowsingService::GetSafeBrowsingUIManager() { - return ui_manager_.get(); +scoped_refptr<SafeBrowsingUIManager> +SafeBrowsingService::GetSafeBrowsingUIManager() { + return ui_manager_; } void SafeBrowsingService::CreateSafeBrowsingUIManager() {
diff --git a/weblayer/browser/safe_browsing/safe_browsing_service.h b/weblayer/browser/safe_browsing/safe_browsing_service.h index d6a55bd..2c006d07 100644 --- a/weblayer/browser/safe_browsing/safe_browsing_service.h +++ b/weblayer/browser/safe_browsing/safe_browsing_service.h
@@ -67,11 +67,12 @@ // May be called on the UI or IO thread. The instance returned should be // *accessed* only on the IO thread. - safe_browsing::RemoteSafeBrowsingDatabaseManager* GetSafeBrowsingDBManager(); + scoped_refptr<safe_browsing::RemoteSafeBrowsingDatabaseManager> + GetSafeBrowsingDBManager(); + + scoped_refptr<SafeBrowsingUIManager> GetSafeBrowsingUIManager(); private: - SafeBrowsingUIManager* GetSafeBrowsingUIManager(); - // Executed on IO thread scoped_refptr<safe_browsing::UrlCheckerDelegate> GetSafeBrowsingUrlCheckerDelegate();
diff --git a/weblayer/browser/safe_browsing/safe_browsing_tab_observer.cc b/weblayer/browser/safe_browsing/safe_browsing_tab_observer.cc new file mode 100644 index 0000000..15af219 --- /dev/null +++ b/weblayer/browser/safe_browsing/safe_browsing_tab_observer.cc
@@ -0,0 +1,75 @@ +// 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 "weblayer/browser/safe_browsing/safe_browsing_tab_observer.h" + +#include "base/bind.h" +#include "components/prefs/pref_service.h" +#include "components/safe_browsing/content/browser/client_side_detection_host.h" +#include "components/safe_browsing/content/browser/client_side_detection_service.h" +#include "content/public/browser/web_contents.h" +#include "weblayer/browser/browser_context_impl.h" +#include "weblayer/browser/browser_process.h" +#include "weblayer/browser/safe_browsing/client_side_detection_host_delegate.h" +#include "weblayer/browser/safe_browsing/client_side_detection_service_factory.h" + +namespace weblayer { + +SafeBrowsingTabObserver::SafeBrowsingTabObserver( + content::WebContents* web_contents) + : web_contents_(web_contents) { + BrowserContextImpl* browser_context = + static_cast<BrowserContextImpl*>(web_contents->GetBrowserContext()); + PrefService* prefs = browser_context->pref_service(); + if (prefs) { + pref_change_registrar_.Init(prefs); + pref_change_registrar_.Add( + ::prefs::kSafeBrowsingEnabled, + base::BindRepeating( + &SafeBrowsingTabObserver::UpdateSafebrowsingDetectionHost, + base::Unretained(this))); + + safe_browsing::ClientSideDetectionService* csd_service = + ClientSideDetectionServiceFactory::GetForBrowserContext( + browser_context); + if (safe_browsing::IsSafeBrowsingEnabled(*prefs) && + BrowserProcess::GetInstance()->GetSafeBrowsingService() && + csd_service) { + safebrowsing_detection_host_ = + safe_browsing::ClientSideDetectionHost::Create( + web_contents, + std::make_unique<ClientSideDetectionHostDelegate>(web_contents)); + csd_service->AddClientSideDetectionHost( + safebrowsing_detection_host_.get()); + } + } +} + +SafeBrowsingTabObserver::~SafeBrowsingTabObserver() {} + +void SafeBrowsingTabObserver::UpdateSafebrowsingDetectionHost() { + BrowserContextImpl* browser_context = + static_cast<BrowserContextImpl*>(web_contents_->GetBrowserContext()); + PrefService* prefs = browser_context->pref_service(); + + bool safe_browsing = safe_browsing::IsSafeBrowsingEnabled(*prefs); + safe_browsing::ClientSideDetectionService* csd_service = + ClientSideDetectionServiceFactory::GetForBrowserContext(browser_context); + if (safe_browsing && csd_service) { + if (!safebrowsing_detection_host_.get()) { + safebrowsing_detection_host_ = + safe_browsing::ClientSideDetectionHost::Create( + web_contents_, + std::make_unique<ClientSideDetectionHostDelegate>(web_contents_)); + csd_service->AddClientSideDetectionHost( + safebrowsing_detection_host_.get()); + } + } else { + safebrowsing_detection_host_.reset(); + } +} + +WEB_CONTENTS_USER_DATA_KEY_IMPL(SafeBrowsingTabObserver) + +} // namespace weblayer \ No newline at end of file
diff --git a/weblayer/browser/safe_browsing/safe_browsing_tab_observer.h b/weblayer/browser/safe_browsing/safe_browsing_tab_observer.h new file mode 100644 index 0000000..c4bac09 --- /dev/null +++ b/weblayer/browser/safe_browsing/safe_browsing_tab_observer.h
@@ -0,0 +1,54 @@ +// Copyright (c) 2012 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 WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_TAB_OBSERVER_H_ +#define WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_TAB_OBSERVER_H_ + +#include <memory> + +#include "base/macros.h" +#include "components/prefs/pref_change_registrar.h" +#include "content/public/browser/web_contents_user_data.h" + +namespace content { +class WebContents; +} + +namespace safe_browsing { +class ClientSideDetectionHost; +} + +namespace weblayer { + +// Per-tab class to handle safe-browsing functionality. +class SafeBrowsingTabObserver + : public content::WebContentsUserData<SafeBrowsingTabObserver> { + public: + ~SafeBrowsingTabObserver() override; + + private: + explicit SafeBrowsingTabObserver(content::WebContents* web_contents); + friend class content::WebContentsUserData<SafeBrowsingTabObserver>; + + // Create or destroy SafebrowsingDetectionHost as needed if the user's + // safe browsing preference has changed. + void UpdateSafebrowsingDetectionHost(); + + // Handles IPCs. + std::unique_ptr<safe_browsing::ClientSideDetectionHost> + safebrowsing_detection_host_; + + // Our owning WebContents. + content::WebContents* web_contents_; + + PrefChangeRegistrar pref_change_registrar_; + + WEB_CONTENTS_USER_DATA_KEY_DECL(); + + DISALLOW_COPY_AND_ASSIGN(SafeBrowsingTabObserver); +}; + +} // namespace weblayer + +#endif // WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_TAB_OBSERVER_H_ \ No newline at end of file
diff --git a/weblayer/browser/tab_impl.cc b/weblayer/browser/tab_impl.cc index 61e611a..6de70e8 100644 --- a/weblayer/browser/tab_impl.cc +++ b/weblayer/browser/tab_impl.cc
@@ -113,10 +113,12 @@ #include "weblayer/browser/java/jni/TabImpl_jni.h" #include "weblayer/browser/javascript_tab_modal_dialog_manager_delegate_android.h" #include "weblayer/browser/js_communication/web_message_host_factory_proxy.h" +#include "weblayer/browser/safe_browsing/safe_browsing_tab_observer.h" #include "weblayer/browser/translate_client_impl.h" #include "weblayer/browser/url_bar/trusted_cdn_observer.h" #include "weblayer/browser/weblayer_factory_impl_android.h" #include "weblayer/browser/webrtc/media_stream_manager.h" +#include "weblayer/common/features.h" #endif #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) @@ -355,6 +357,11 @@ web_contents_.get(), this); TrustedCDNObserver::CreateForWebContents(web_contents_.get()); + + if (base::FeatureList::IsEnabled( + features::kWebLayerClientSidePhishingDetection)) { + SafeBrowsingTabObserver::CreateForWebContents(web_contents_.get()); + } #endif #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
diff --git a/weblayer/test/BUILD.gn b/weblayer/test/BUILD.gn index d9d11dd10..551bdd9 100644 --- a/weblayer/test/BUILD.gn +++ b/weblayer/test/BUILD.gn
@@ -192,6 +192,8 @@ "../browser/android/metrics/metrics_test_helper.cc", "../browser/android/metrics/metrics_test_helper.h", "../browser/android/metrics/ukm_browsertest.cc", + "../browser/safe_browsing/client_side_detection_service_browsertest.cc", + "../browser/safe_browsing/client_side_detection_service_factory_browsertest.cc", "../browser/safe_browsing/safe_browsing_browsertest.cc", "../browser/url_bar/page_info_browsertest.cc", "../shell/android/browsertests_apk/translate_test_bridge.cc", @@ -211,7 +213,12 @@ "//components/page_info/android", "//components/safe_browsing/android:safe_browsing_api_handler", "//components/safe_browsing/content", + "//components/safe_browsing/content/browser:client_side_detection", + "//components/safe_browsing/content/browser:client_side_model_loader", + "//components/safe_browsing/content/common:interfaces", + "//components/safe_browsing/core:client_model_proto", "//components/safe_browsing/core:features", + "//components/safe_browsing/core/common", "//components/viz/service:service_java", "//content/public/test/android:android_test_message_pump_support_java", "//content/test:android_test_message_pump_support",