Commit 3843ac5c authored by Boris Sazonov's avatar Boris Sazonov Committed by Commit Bot

[Signin][Android] Remove code behind MobileIdentityConsistency

This CL removes unused code that was behind MobileIdentityConsistency
feature flag.

Bug: 980849
Change-Id: I78dd6b212ff011c9d2361874055783902d3619eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1976701
Commit-Queue: Boris Sazonov <bsazonov@chromium.org>
Reviewed-by: default avatarDavid Roger <droger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#728508}
parent 47bdc678
...@@ -269,7 +269,6 @@ public abstract class ChromeFeatureList { ...@@ -269,7 +269,6 @@ public abstract class ChromeFeatureList {
"SearchEnginePromo.ExistingDevice"; "SearchEnginePromo.ExistingDevice";
public static final String SEARCH_ENGINE_PROMO_NEW_DEVICE = "SearchEnginePromo.NewDevice"; public static final String SEARCH_ENGINE_PROMO_NEW_DEVICE = "SearchEnginePromo.NewDevice";
public static final String MARK_HTTP_AS = "MarkHttpAs"; public static final String MARK_HTTP_AS = "MarkHttpAs";
// TODO(crbug.com/980849) Remove ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY
public static final String MOBILE_IDENTITY_CONSISTENCY = "MobileIdentityConsistency"; public static final String MOBILE_IDENTITY_CONSISTENCY = "MobileIdentityConsistency";
public static final String MODAL_PERMISSION_PROMPTS = "ModalPermissionPrompts"; public static final String MODAL_PERMISSION_PROMPTS = "ModalPermissionPrompts";
public static final String MODAL_PERMISSION_DIALOG_VIEW = "ModalPermissionDialogView"; public static final String MODAL_PERMISSION_DIALOG_VIEW = "ModalPermissionDialogView";
......
...@@ -19,7 +19,6 @@ import com.google.android.gms.auth.GoogleAuthUtil; ...@@ -19,7 +19,6 @@ import com.google.android.gms.auth.GoogleAuthUtil;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
import org.chromium.base.Log; import org.chromium.base.Log;
import org.chromium.base.task.AsyncTask; import org.chromium.base.task.AsyncTask;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.signin.SigninManager.SignInCallback; import org.chromium.chrome.browser.signin.SigninManager.SignInCallback;
import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.chrome.browser.sync.ProfileSyncService;
import org.chromium.components.signin.AccountManagerFacade; import org.chromium.components.signin.AccountManagerFacade;
...@@ -138,10 +137,8 @@ public class SigninHelper { ...@@ -138,10 +137,8 @@ public class SigninHelper {
return; return;
} }
boolean mice_enabled =
ChromeFeatureList.isEnabled(ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY);
Account syncAccount = mChromeSigninController.getSignedInUser(); Account syncAccount = mChromeSigninController.getSignedInUser();
if (syncAccount == null && !mice_enabled) { if (syncAccount == null) {
return; return;
} }
......
...@@ -16,14 +16,10 @@ import androidx.annotation.Nullable; ...@@ -16,14 +16,10 @@ import androidx.annotation.Nullable;
import org.chromium.base.ThreadUtils; import org.chromium.base.ThreadUtils;
import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.NativeMethods; import org.chromium.base.annotations.NativeMethods;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.profiles.ProfileAccountManagementMetrics;
import org.chromium.chrome.browser.settings.ManagedPreferencesUtils; import org.chromium.chrome.browser.settings.ManagedPreferencesUtils;
import org.chromium.chrome.browser.settings.sync.AccountManagementFragment; import org.chromium.chrome.browser.settings.sync.AccountManagementFragment;
import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.chrome.browser.util.IntentUtils;
import org.chromium.components.signin.AccountManagerFacade;
import org.chromium.components.signin.GAIAServiceType; import org.chromium.components.signin.GAIAServiceType;
import org.chromium.components.signin.SigninActivityMonitor;
import org.chromium.components.signin.metrics.SigninAccessPoint; import org.chromium.components.signin.metrics.SigninAccessPoint;
import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.base.WindowAndroid;
...@@ -38,7 +34,6 @@ public class SigninUtils { ...@@ -38,7 +34,6 @@ public class SigninUtils {
/** /**
* Opens a Settings page to configure settings for a single account. * Opens a Settings page to configure settings for a single account.
* Note: on Android O+, this method is identical to {@link #openSettingsForAllAccounts}.
* @param context Context to use when starting the Activity. * @param context Context to use when starting the Activity.
* @param account The account for which the Settings page should be opened. * @param account The account for which the Settings page should be opened.
* @return Whether or not Android accepted the Intent. * @return Whether or not Android accepted the Intent.
...@@ -54,7 +49,6 @@ public class SigninUtils { ...@@ -54,7 +49,6 @@ public class SigninUtils {
return IntentUtils.safeStartActivity(context, intent); return IntentUtils.safeStartActivity(context, intent);
} }
// TODO(https://crbug.com/955501): Migrate all clients to WindowAndroid and remove this.
/** /**
* Opens a Settings page with all accounts on the device. * Opens a Settings page with all accounts on the device.
* @param context Context to use when starting the Activity. * @param context Context to use when starting the Activity.
...@@ -66,90 +60,13 @@ public class SigninUtils { ...@@ -66,90 +60,13 @@ public class SigninUtils {
return IntentUtils.safeStartActivity(context, intent); return IntentUtils.safeStartActivity(context, intent);
} }
/**
* Opens a Settings page with all accounts on the device.
* @param windowAndroid WindowAndroid to use when starting the Activity.
* @return Whether or not Android accepted the Intent.
*/
public static boolean openSettingsForAllAccounts(WindowAndroid windowAndroid) {
Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
return startActivity(windowAndroid, intent);
}
@CalledByNative @CalledByNative
private static void openAccountManagementScreen(WindowAndroid windowAndroid, private static void openAccountManagementScreen(WindowAndroid windowAndroid,
@GAIAServiceType int gaiaServiceType, @Nullable String email) { @GAIAServiceType int gaiaServiceType, @Nullable String email) {
ThreadUtils.assertOnUiThread(); ThreadUtils.assertOnUiThread();
if (ChromeFeatureList.isEnabled(ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY)) {
// If Mice is enabled, directly use the system account management flows.
switch (gaiaServiceType) {
case GAIAServiceType.GAIA_SERVICE_TYPE_SIGNUP:
case GAIAServiceType.GAIA_SERVICE_TYPE_ADDSESSION:
AccountManagerFacade accountManagerFacade = AccountManagerFacade.get();
@Nullable
Account account =
email == null ? null : accountManagerFacade.getAccountFromName(email);
if (account == null) {
// Empty or unknown account: add a new account.
// TODO(bsazonov): if email is not empty, pre-fill the account name.
startAddAccountActivity(windowAndroid, gaiaServiceType);
} else {
// Existing account indicates authentication error. Fix it.
accountManagerFacade.updateCredentials(
account, windowAndroid.getActivity().get(), null);
}
break;
default:
// Open generic accounts settings.
openSettingsForAllAccounts(windowAndroid);
break;
}
return;
}
// If Mice is not enabled, open Chrome's account management screen.
AccountManagementFragment.openAccountManagementScreen(gaiaServiceType); AccountManagementFragment.openAccountManagementScreen(gaiaServiceType);
} }
/**
* Tries starting an Activity to add a Google account to the device. If this activity cannot
* be started, opens "Accounts" page in the Android Settings app.
*/
private static void startAddAccountActivity(
WindowAndroid windowAndroid, @GAIAServiceType int gaiaServiceTypeSignup) {
logEvent(ProfileAccountManagementMetrics.DIRECT_ADD_ACCOUNT, gaiaServiceTypeSignup);
AccountManagerFacade.get().createAddAccountIntent((@Nullable Intent intent) -> {
if (intent != null && startActivity(windowAndroid, intent)) {
return;
}
// Failed to create or show an intent, open settings for all accounts so
// the user has a chance to create an account manually.
SigninUtils.openSettingsForAllAccounts(windowAndroid);
});
}
// TODO(https://crbug.com/953765): Move this to SigninActivityMonitor.
/**
* Starts an activity using the provided intent. The started activity will be tracked by
* {@link SigninActivityMonitor#hasOngoingActivity()}.
*
* @param windowAndroid The window to use when launching the intent.
* @param intent The intent to launch.
* @return Whether {@link WindowAndroid#showIntent} succeeded.
*/
private static boolean startActivity(WindowAndroid windowAndroid, Intent intent) {
SigninActivityMonitor signinActivityMonitor = SigninActivityMonitor.get();
WindowAndroid.IntentCallback intentCallback =
(window, resultCode, data) -> signinActivityMonitor.activityFinished();
if (windowAndroid.showIntent(intent, intentCallback, null)) {
signinActivityMonitor.activityStarted();
return true;
}
return false;
}
/** /**
* Launches the {@link SigninActivity} if signin is allowed. * Launches the {@link SigninActivity} if signin is allowed.
* @param accessPoint {@link SigninAccessPoint} for starting sign-in flow. * @param accessPoint {@link SigninAccessPoint} for starting sign-in flow.
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/signin/core/browser/account_reconcilor.h" #include "components/signin/core/browser/account_reconcilor.h"
#include "components/signin/core/browser/account_reconcilor_delegate.h" #include "components/signin/core/browser/account_reconcilor_delegate.h"
#include "components/signin/core/browser/consistency_cookie_manager_base.h"
#include "components/signin/core/browser/mirror_account_reconcilor_delegate.h" #include "components/signin/core/browser/mirror_account_reconcilor_delegate.h"
#include "components/signin/public/base/account_consistency_method.h" #include "components/signin/public/base/account_consistency_method.h"
#include "components/signin/public/base/signin_buildflags.h" #include "components/signin/public/base/signin_buildflags.h"
...@@ -35,11 +34,6 @@ ...@@ -35,11 +34,6 @@
#include "google_apis/gaia/google_service_auth_error.h" #include "google_apis/gaia/google_service_auth_error.h"
#endif #endif
#if defined(OS_ANDROID)
#include "components/signin/core/browser/consistency_cookie_manager_android.h"
#include "components/signin/core/browser/mice_account_reconcilor_delegate.h"
#endif
#if BUILDFLAG(ENABLE_DICE_SUPPORT) #if BUILDFLAG(ENABLE_DICE_SUPPORT)
#include "components/signin/core/browser/dice_account_reconcilor_delegate.h" #include "components/signin/core/browser/dice_account_reconcilor_delegate.h"
#endif #endif
...@@ -150,8 +144,6 @@ KeyedService* AccountReconcilorFactory::BuildServiceInstanceFor( ...@@ -150,8 +144,6 @@ KeyedService* AccountReconcilorFactory::BuildServiceInstanceFor(
new AccountReconcilor(identity_manager, signin_client, new AccountReconcilor(identity_manager, signin_client,
CreateAccountReconcilorDelegate(profile)); CreateAccountReconcilorDelegate(profile));
reconcilor->Initialize(true /* start_reconcile_if_tokens_available */); reconcilor->Initialize(true /* start_reconcile_if_tokens_available */);
reconcilor->SetConsistencyCookieManager(CreateConsistencyCookieManager(
identity_manager, signin_client, reconcilor));
return reconcilor; return reconcilor;
} }
...@@ -186,9 +178,6 @@ AccountReconcilorFactory::CreateAccountReconcilorDelegate(Profile* profile) { ...@@ -186,9 +178,6 @@ AccountReconcilorFactory::CreateAccountReconcilorDelegate(Profile* profile) {
IdentityManagerFactory::GetForProfile(profile), IdentityManagerFactory::GetForProfile(profile),
chromeos::AccountManagerMigratorFactory::GetForBrowserContext( chromeos::AccountManagerMigratorFactory::GetForBrowserContext(
profile)); profile));
#elif defined(OS_ANDROID)
if (base::FeatureList::IsEnabled(signin::kMiceFeature))
return std::make_unique<signin::MiceAccountReconcilorDelegate>();
#endif #endif
return std::make_unique<signin::MirrorAccountReconcilorDelegate>( return std::make_unique<signin::MirrorAccountReconcilorDelegate>(
IdentityManagerFactory::GetForProfile(profile)); IdentityManagerFactory::GetForProfile(profile));
...@@ -210,17 +199,3 @@ AccountReconcilorFactory::CreateAccountReconcilorDelegate(Profile* profile) { ...@@ -210,17 +199,3 @@ AccountReconcilorFactory::CreateAccountReconcilorDelegate(Profile* profile) {
NOTREACHED(); NOTREACHED();
return nullptr; return nullptr;
} }
std::unique_ptr<signin::ConsistencyCookieManagerBase>
AccountReconcilorFactory::CreateConsistencyCookieManager(
signin::IdentityManager* identity_manager,
SigninClient* signin_client,
AccountReconcilor* account_reconcilor) const {
#if defined(OS_ANDROID)
if (base::FeatureList::IsEnabled(signin::kMiceFeature)) {
return std::make_unique<signin::ConsistencyCookieManagerAndroid>(
identity_manager, signin_client, account_reconcilor);
}
#endif
return nullptr;
}
...@@ -16,7 +16,6 @@ class IdentityManager; ...@@ -16,7 +16,6 @@ class IdentityManager;
namespace signin { namespace signin {
class AccountReconcilorDelegate; class AccountReconcilorDelegate;
class ConsistencyCookieManagerBase;
} }
class AccountReconcilor; class AccountReconcilor;
...@@ -49,11 +48,6 @@ class AccountReconcilorFactory : public BrowserContextKeyedServiceFactory { ...@@ -49,11 +48,6 @@ class AccountReconcilorFactory : public BrowserContextKeyedServiceFactory {
// BrowserContextKeyedServiceFactory: // BrowserContextKeyedServiceFactory:
KeyedService* BuildServiceInstanceFor( KeyedService* BuildServiceInstanceFor(
content::BrowserContext* profile) const override; content::BrowserContext* profile) const override;
std::unique_ptr<signin::ConsistencyCookieManagerBase>
CreateConsistencyCookieManager(signin::IdentityManager* identity_manager,
SigninClient* signin_client,
AccountReconcilor* account_reconcilor) const;
}; };
#endif // CHROME_BROWSER_SIGNIN_ACCOUNT_RECONCILOR_FACTORY_H_ #endif // CHROME_BROWSER_SIGNIN_ACCOUNT_RECONCILOR_FACTORY_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/signin/core/browser/consistency_cookie_manager_base.h"
#include <memory>
#include <string>
#include <utility>
#include "base/callback.h"
#include "base/run_loop.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/account_reconcilor_factory.h"
#include "chrome/browser/signin/chrome_signin_client_factory.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/signin/core/browser/consistency_cookie_manager_base.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "google_apis/gaia/gaia_switches.h"
#include "google_apis/gaia/gaia_urls.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "net/cookies/canonical_cookie.h"
#include "net/test/embedded_test_server/default_handlers.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace {
const char kConsistencyCookieName[] = "CHROME_ID_CONSISTENCY_STATE";
// Subclass of ConsistencyCookieManagerBase allowing to manually control the
// value of the cookie.
class TestConsistencyCookieManager
: public signin::ConsistencyCookieManagerBase,
public network::mojom::CookieChangeListener {
public:
TestConsistencyCookieManager(SigninClient* client,
AccountReconcilor* reconcilor)
: signin::ConsistencyCookieManagerBase(client, reconcilor) {
// Listen to cookie changes.
client->GetCookieManager()->AddGlobalChangeListener(
cookie_listener_receiver_.BindNewPipeAndPassRemote());
// Subclasses have to call UpdateCookie() in the constructor.
UpdateCookie();
// Wait for the initial cookie to be set.
WaitForCookieChange();
}
// Sets a new value for the consistency cookie.
void SetValue(const std::string& value) {
value_ = value;
UpdateCookie();
WaitForCookieChange();
}
private:
// Waits until OnCookieChange is called.
void WaitForCookieChange() {
base::RunLoop loop;
run_loop_quit_closure_ = loop.QuitClosure();
loop.Run();
}
// CookieChangeListener:
void OnCookieChange(const net::CookieChangeInfo& change) override {
if (change.cookie.Name() != kConsistencyCookieName)
return;
if (!run_loop_quit_closure_.is_null())
std::move(run_loop_quit_closure_).Run();
}
// ConsistencyCookieManagerBase:
std::string CalculateCookieValue() override { return value_; }
std::string value_ = "initial_value";
mojo::Receiver<network::mojom::CookieChangeListener>
cookie_listener_receiver_{this};
base::OnceClosure run_loop_quit_closure_;
};
} // namespace
class ConsistencyCookieBrowserTest : public InProcessBrowserTest {
public:
ConsistencyCookieBrowserTest()
: https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
net::test_server::RegisterDefaultHandlers(&https_server_);
}
~ConsistencyCookieBrowserTest() override {}
// Updates the cookie through the consistency cookie manager and blocks until
// it completes.
void SetCookieValue(const std::string& cookie_value) {
consistency_cookie_manager_->SetValue(cookie_value);
}
// Checks the cookie both in HTTP and javascript.
void CheckCookieValue(const std::string& expected_cookie) {
// Check that the cookie is set in HTTP.
ui_test_utils::NavigateToURL(
browser(),
https_server_.GetURL(GaiaUrls::GetInstance()->gaia_url().host(),
"/echoheader?Cookie"));
std::string http_cookie =
content::EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
"document.body.innerText")
.ExtractString();
EXPECT_EQ(expected_cookie, http_cookie);
// Check that the cookie is available in javascript.
std::string javascript_cookie =
content::EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
"document.cookie")
.ExtractString();
EXPECT_EQ(expected_cookie, javascript_cookie);
}
private:
// InProcessBrowserTest:
void SetUp() override {
ASSERT_TRUE(https_server_.InitializeAndListen());
InProcessBrowserTest::SetUp();
}
void SetUpCommandLine(base::CommandLine* command_line) override {
const GURL& base_url = https_server_.base_url();
command_line->AppendSwitchASCII(switches::kGaiaUrl, base_url.spec());
}
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
https_server_.StartAcceptingConnections();
// Setup the CookieConsistencyCookieManager
Profile* profile = browser()->profile();
AccountReconcilor* reconcilor =
AccountReconcilorFactory::GetForProfile(profile);
std::unique_ptr<TestConsistencyCookieManager> consistency_cookie_manager =
std::make_unique<TestConsistencyCookieManager>(
ChromeSigninClientFactory::GetForProfile(profile), reconcilor);
consistency_cookie_manager_ = consistency_cookie_manager.get();
reconcilor->SetConsistencyCookieManager(
std::move(consistency_cookie_manager));
}
net::EmbeddedTestServer https_server_;
TestConsistencyCookieManager* consistency_cookie_manager_;
};
// Tests that the ConsistencyCookieManager can set and change the cookie in HTTP
// and javascript.
IN_PROC_BROWSER_TEST_F(ConsistencyCookieBrowserTest, Basic) {
// Check the initial value.
CheckCookieValue(std::string(kConsistencyCookieName) + "=initial_value");
// Change the cookie.
SetCookieValue("new_value");
CheckCookieValue(std::string(kConsistencyCookieName) + "=new_value");
}
...@@ -1161,7 +1161,6 @@ if (!is_android) { ...@@ -1161,7 +1161,6 @@ if (!is_android) {
"../browser/sessions/tab_restore_service_browsertest.cc", "../browser/sessions/tab_restore_service_browsertest.cc",
"../browser/sessions/tab_restore_service_load_waiter.cc", "../browser/sessions/tab_restore_service_load_waiter.cc",
"../browser/sessions/tab_restore_service_load_waiter.h", "../browser/sessions/tab_restore_service_load_waiter.h",
"../browser/signin/consistency_cookie_browsertest.cc",
"../browser/signin/e2e_tests/live_sign_in_test.cc", "../browser/signin/e2e_tests/live_sign_in_test.cc",
"../browser/signin/e2e_tests/live_test.cc", "../browser/signin/e2e_tests/live_test.cc",
"../browser/signin/e2e_tests/live_test.h", "../browser/signin/e2e_tests/live_test.h",
......
...@@ -21,8 +21,6 @@ static_library("browser") { ...@@ -21,8 +21,6 @@ static_library("browser") {
"account_reconcilor_delegate.h", "account_reconcilor_delegate.h",
"chrome_connected_header_helper.cc", "chrome_connected_header_helper.cc",
"chrome_connected_header_helper.h", "chrome_connected_header_helper.h",
"consistency_cookie_manager_base.cc",
"consistency_cookie_manager_base.h",
"cookie_reminter.cc", "cookie_reminter.cc",
"cookie_reminter.h", "cookie_reminter.h",
"cookie_settings_util.cc", "cookie_settings_util.cc",
...@@ -31,8 +29,6 @@ static_library("browser") { ...@@ -31,8 +29,6 @@ static_library("browser") {
"dice_account_reconcilor_delegate.h", "dice_account_reconcilor_delegate.h",
"dice_header_helper.cc", "dice_header_helper.cc",
"dice_header_helper.h", "dice_header_helper.h",
"mice_account_reconcilor_delegate.cc",
"mice_account_reconcilor_delegate.h",
"mirror_account_reconcilor_delegate.cc", "mirror_account_reconcilor_delegate.cc",
"mirror_account_reconcilor_delegate.h", "mirror_account_reconcilor_delegate.h",
"signin_error_controller.cc", "signin_error_controller.cc",
...@@ -93,14 +89,6 @@ static_library("browser") { ...@@ -93,14 +89,6 @@ static_library("browser") {
] ]
} }
if (is_android) {
sources += [
"consistency_cookie_manager_android.cc",
"consistency_cookie_manager_android.h",
]
deps += [ "android:jni_headers" ]
}
if (!enable_dice_support) { if (!enable_dice_support) {
sources -= [ sources -= [
"dice_account_reconcilor_delegate.cc", "dice_account_reconcilor_delegate.cc",
...@@ -117,7 +105,6 @@ source_set("unit_tests") { ...@@ -117,7 +105,6 @@ source_set("unit_tests") {
"account_investigator_unittest.cc", "account_investigator_unittest.cc",
"account_reconcilor_unittest.cc", "account_reconcilor_unittest.cc",
"dice_account_reconcilor_delegate_unittest.cc", "dice_account_reconcilor_delegate_unittest.cc",
"mice_account_reconcilor_delegate_unittest.cc",
"signin_error_controller_unittest.cc", "signin_error_controller_unittest.cc",
"signin_header_helper_unittest.cc", "signin_header_helper_unittest.cc",
"signin_investigator_unittest.cc", "signin_investigator_unittest.cc",
...@@ -154,10 +141,6 @@ source_set("unit_tests") { ...@@ -154,10 +141,6 @@ source_set("unit_tests") {
] ]
} }
if (is_android) {
sources += [ "consistency_cookie_manager_unittest.cc" ]
}
if (!enable_dice_support) { if (!enable_dice_support) {
sources -= [ "dice_account_reconcilor_delegate_unittest.cc" ] sources -= [ "dice_account_reconcilor_delegate_unittest.cc" ]
} }
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "components/signin/core/browser/account_reconcilor_delegate.h" #include "components/signin/core/browser/account_reconcilor_delegate.h"
#include "components/signin/core/browser/consistency_cookie_manager_base.h"
#include "components/signin/public/base/account_consistency_method.h" #include "components/signin/public/base/account_consistency_method.h"
#include "components/signin/public/base/signin_client.h" #include "components/signin/public/base/signin_client.h"
#include "components/signin/public/base/signin_metrics.h" #include "components/signin/public/base/signin_metrics.h"
...@@ -33,10 +32,6 @@ ...@@ -33,10 +32,6 @@
#include "google_apis/gaia/gaia_urls.h" #include "google_apis/gaia/gaia_urls.h"
#include "google_apis/gaia/google_service_auth_error.h" #include "google_apis/gaia/google_service_auth_error.h"
#if defined(OS_ANDROID)
#include "components/signin/core/browser/consistency_cookie_manager_android.h"
#endif
using signin::AccountReconcilorDelegate; using signin::AccountReconcilorDelegate;
using signin_metrics::AccountReconcilorState; using signin_metrics::AccountReconcilorState;
...@@ -282,12 +277,6 @@ void AccountReconcilor::Initialize(bool start_reconcile_if_tokens_available) { ...@@ -282,12 +277,6 @@ void AccountReconcilor::Initialize(bool start_reconcile_if_tokens_available) {
} }
} }
void AccountReconcilor::SetConsistencyCookieManager(
std::unique_ptr<signin::ConsistencyCookieManagerBase>
consistency_cookie_manager) {
consistency_cookie_manager_ = std::move(consistency_cookie_manager);
}
void AccountReconcilor::EnableReconcile() { void AccountReconcilor::EnableReconcile() {
SetState(AccountReconcilorState::ACCOUNT_RECONCILOR_SCHEDULED); SetState(AccountReconcilorState::ACCOUNT_RECONCILOR_SCHEDULED);
RegisterWithAllDependencies(); RegisterWithAllDependencies();
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
namespace signin { namespace signin {
class AccountReconcilorDelegate; class AccountReconcilorDelegate;
class ConsistencyCookieManagerBase;
enum class SetAccountsInCookieResult; enum class SetAccountsInCookieResult;
} }
...@@ -99,10 +98,6 @@ class AccountReconcilor : public KeyedService, ...@@ -99,10 +98,6 @@ class AccountReconcilor : public KeyedService,
// construction. // construction.
void Initialize(bool start_reconcile_if_tokens_available); void Initialize(bool start_reconcile_if_tokens_available);
void SetConsistencyCookieManager(
std::unique_ptr<signin::ConsistencyCookieManagerBase>
consistency_cookie_manager);
// Enables and disables the reconciliation. // Enables and disables the reconciliation.
void EnableReconcile(); void EnableReconcile();
void DisableReconcile(bool logout_all_gaia_accounts); void DisableReconcile(bool logout_all_gaia_accounts);
...@@ -373,9 +368,6 @@ class AccountReconcilor : public KeyedService, ...@@ -373,9 +368,6 @@ class AccountReconcilor : public KeyedService,
signin_metrics::AccountReconcilorState state_; signin_metrics::AccountReconcilorState state_;
std::unique_ptr<signin::ConsistencyCookieManagerBase>
consistency_cookie_manager_;
base::WeakPtrFactory<AccountReconcilor> weak_factory_{this}; base::WeakPtrFactory<AccountReconcilor> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(AccountReconcilor); DISALLOW_COPY_AND_ASSIGN(AccountReconcilor);
......
...@@ -9,7 +9,6 @@ generate_jni("jni_headers") { ...@@ -9,7 +9,6 @@ generate_jni("jni_headers") {
"java/src/org/chromium/components/signin/AccountManagerFacade.java", "java/src/org/chromium/components/signin/AccountManagerFacade.java",
"java/src/org/chromium/components/signin/AccountTrackerService.java", "java/src/org/chromium/components/signin/AccountTrackerService.java",
"java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java", "java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java",
"java/src/org/chromium/components/signin/ConsistencyCookieManager.java",
] ]
} }
...@@ -38,13 +37,11 @@ android_library("java") { ...@@ -38,13 +37,11 @@ android_library("java") {
"java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java", "java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java",
"java/src/org/chromium/components/signin/ChildAccountStatus.java", "java/src/org/chromium/components/signin/ChildAccountStatus.java",
"java/src/org/chromium/components/signin/ChromeSigninController.java", "java/src/org/chromium/components/signin/ChromeSigninController.java",
"java/src/org/chromium/components/signin/ConsistencyCookieManager.java",
"java/src/org/chromium/components/signin/GmsAvailabilityException.java", "java/src/org/chromium/components/signin/GmsAvailabilityException.java",
"java/src/org/chromium/components/signin/GmsJustUpdatedException.java", "java/src/org/chromium/components/signin/GmsJustUpdatedException.java",
"java/src/org/chromium/components/signin/MutableObservableValue.java", "java/src/org/chromium/components/signin/MutableObservableValue.java",
"java/src/org/chromium/components/signin/ObservableValue.java", "java/src/org/chromium/components/signin/ObservableValue.java",
"java/src/org/chromium/components/signin/ProfileDataSource.java", "java/src/org/chromium/components/signin/ProfileDataSource.java",
"java/src/org/chromium/components/signin/SigninActivityMonitor.java",
"java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java", "java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java",
"java/src/org/chromium/components/signin/util/PatternMatcher.java", "java/src/org/chromium/components/signin/util/PatternMatcher.java",
] ]
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.components.signin;
import androidx.annotation.MainThread;
import org.chromium.base.ThreadUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
/**
* Created by native code to get status of {@link AccountManagerFacade#isUpdatePending()} and
* notifications when it changes.
*/
public class ConsistencyCookieManager
implements ObservableValue.Observer, AccountTrackerService.OnSystemAccountsSeededListener {
private final long mNativeConsistencyCookieManager;
private final AccountTrackerService mAccountTrackerService;
private final AccountManagerFacade mAccountManagerFacade;
private final SigninActivityMonitor mSigninActivityMonitor;
private boolean mIsUpdatePending;
private ConsistencyCookieManager(
long nativeConsistencyCookieManager, AccountTrackerService accountTrackerService) {
ThreadUtils.assertOnUiThread();
mAccountTrackerService = accountTrackerService;
mNativeConsistencyCookieManager = nativeConsistencyCookieManager;
mAccountManagerFacade = AccountManagerFacade.get();
mSigninActivityMonitor = SigninActivityMonitor.get();
// For now, this class relies on the order of notifications sent by AccountManagerFacade and
// AccountTrackerService. Whenever the account list changes, this class will get
// notification from AccountManagerFacade.isUpdatePending(). This will change
// mIsUpdatePending to true. By the time AccountManagerFacade finishes updating account list
// and sets AccountManagerFacade.isUpdatePending() to false, AccountTrackerService should
// have already invalidate account seed status, so mIsUpdatePending will stay false until
// accounts are seeded to the native AccountTrackerService.
// TODO(https://crbug.com/831257): Simplify this after seeding is reimplemented.
mAccountTrackerService.addSystemAccountsSeededListener(this);
mAccountManagerFacade.isUpdatePending().addObserver(this);
mSigninActivityMonitor.hasOngoingActivity().addObserver(this);
mIsUpdatePending = calculateIsUpdatePending();
}
@Override
public void onSystemAccountsSeedingComplete() {
onValueChanged();
}
@Override
public void onValueChanged() {
boolean state = calculateIsUpdatePending();
if (mIsUpdatePending == state) return;
mIsUpdatePending = state;
ConsistencyCookieManagerJni.get().onIsUpdatePendingChanged(mNativeConsistencyCookieManager);
}
private boolean calculateIsUpdatePending() {
return mAccountManagerFacade.isUpdatePending().get()
|| mSigninActivityMonitor.hasOngoingActivity().get()
|| !mAccountTrackerService.areSystemAccountsSeeded();
}
@CalledByNative
@MainThread
private static ConsistencyCookieManager create(
long nativeConsistencyCookieManager, AccountTrackerService accountTrackerService) {
return new ConsistencyCookieManager(nativeConsistencyCookieManager, accountTrackerService);
}
@CalledByNative
@MainThread
private void destroy() {
ThreadUtils.assertOnUiThread();
mAccountTrackerService.removeSystemAccountsSeededListener(this);
mSigninActivityMonitor.hasOngoingActivity().removeObserver(this);
mAccountManagerFacade.isUpdatePending().removeObserver(this);
}
@CalledByNative
@MainThread
private boolean getIsUpdatePending() {
ThreadUtils.assertOnUiThread();
return mIsUpdatePending;
}
@JNINamespace("signin")
@NativeMethods
interface Natives {
void onIsUpdatePendingChanged(long nativeConsistencyCookieManagerAndroid);
}
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.components.signin;
import android.annotation.SuppressLint;
import androidx.annotation.MainThread;
import org.chromium.base.ThreadUtils;
/**
* Monitors external activities started from sign-in flows (for example, activity to add an account
* to the device). Activities have to be launched using {@link #startSigninActivity}.
*/
public class SigninActivityMonitor {
@SuppressLint("StaticFieldLeak")
private static SigninActivityMonitor sInstance;
private int mActivityCounter;
private MutableObservableValue<Boolean> mHasOngoingActivity =
new MutableObservableValue<>(false);
private SigninActivityMonitor() {}
/**
* Returns a singleton instance of the SigninActivityMonitor.
*/
@MainThread
public static SigninActivityMonitor get() {
ThreadUtils.assertOnUiThread();
if (sInstance == null) {
sInstance = new SigninActivityMonitor();
}
return sInstance;
}
/**
* Returns whether there are any ongoing sign-in activities.
*/
public ObservableValue<Boolean> hasOngoingActivity() {
return mHasOngoingActivity;
}
// TODO(https://crbug.com/953765): Make this private.
/**
* Should be invoked when a signin activity is started.
*/
public void activityStarted() {
assert mActivityCounter >= 0;
++mActivityCounter;
if (mActivityCounter == 1) mHasOngoingActivity.set(true);
}
// TODO(https://crbug.com/953765): Make this private.
/**
* Should be invoked when a signin activity is finished. There should be a strict parity between
* {@link #activityStarted()} and {@link #activityFinished()} calls.
*/
public void activityFinished() {
assert mActivityCounter > 0;
--mActivityCounter;
if (mActivityCounter == 0) mHasOngoingActivity.set(false);
}
}
...@@ -169,12 +169,6 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader( ...@@ -169,12 +169,6 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader(
const GURL& url, const GURL& url,
const std::string& gaia_id, const std::string& gaia_id,
int profile_mode_mask) { int profile_mode_mask) {
#if defined(OS_ANDROID)
bool is_mice_enabled = base::FeatureList::IsEnabled(kMiceFeature);
#else
bool is_mice_enabled = false;
#endif
// If we are on mobile or desktop, an empty |account_id| corresponds to the user // If we are on mobile or desktop, an empty |account_id| corresponds to the user
// not signed into Sync. Do not enforce account consistency, unless Mice is // not signed into Sync. Do not enforce account consistency, unless Mice is
// enabled on Android. // enabled on Android.
...@@ -183,7 +177,7 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader( ...@@ -183,7 +177,7 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader(
// filtered upstream and we want to enforce account consistency in Public // filtered upstream and we want to enforce account consistency in Public
// Sessions and Active Directory logins. // Sessions and Active Directory logins.
#if !defined(OS_CHROMEOS) #if !defined(OS_CHROMEOS)
if (gaia_id.empty() && !is_mice_enabled) if (gaia_id.empty())
return std::string(); return std::string();
#endif // !defined(OS_CHROMEOS) #endif // !defined(OS_CHROMEOS)
...@@ -201,9 +195,8 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader( ...@@ -201,9 +195,8 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader(
account_consistency_ == AccountConsistencyMethod::kMirror; account_consistency_ == AccountConsistencyMethod::kMirror;
parts.push_back(base::StringPrintf("%s=%s", kEnableAccountConsistencyAttrName, parts.push_back(base::StringPrintf("%s=%s", kEnableAccountConsistencyAttrName,
is_mirror_enabled ? "true" : "false")); is_mirror_enabled ? "true" : "false"));
parts.push_back(base::StringPrintf("%s=%s", parts.push_back(base::StringPrintf(
kConsistencyEnabledByDefaultAttrName, "%s=%s", kConsistencyEnabledByDefaultAttrName, "false"));
is_mice_enabled ? "true" : "false"));
return base::JoinString(parts, is_header_request ? "," : ":"); return base::JoinString(parts, is_header_request ? "," : ":");
} }
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/signin/core/browser/consistency_cookie_manager_android.h"
#include "components/signin/core/browser/android/jni_headers/ConsistencyCookieManager_jni.h"
#include "components/signin/public/identity_manager/identity_manager.h"
namespace signin {
ConsistencyCookieManagerAndroid::ConsistencyCookieManagerAndroid(
IdentityManager* identity_manager,
SigninClient* signin_client,
AccountReconcilor* reconcilor)
: ConsistencyCookieManagerBase(signin_client, reconcilor) {
JNIEnv* env = base::android::AttachCurrentThread();
base::android::ScopedJavaLocalRef<jobject> java_ref =
Java_ConsistencyCookieManager_create(
env, reinterpret_cast<intptr_t>(this),
identity_manager->LegacyGetAccountTrackerServiceJavaObject());
java_ref_.Reset(env, java_ref.obj());
is_update_pending_in_java_ =
Java_ConsistencyCookieManager_getIsUpdatePending(env, java_ref_);
UpdateCookie();
}
ConsistencyCookieManagerAndroid::~ConsistencyCookieManagerAndroid() {
JNIEnv* env = base::android::AttachCurrentThread();
Java_ConsistencyCookieManager_destroy(env, java_ref_);
}
void ConsistencyCookieManagerAndroid::OnIsUpdatePendingChanged(JNIEnv* env) {
bool is_update_pending_in_java =
Java_ConsistencyCookieManager_getIsUpdatePending(env, java_ref_);
if (is_update_pending_in_java == is_update_pending_in_java_)
return;
is_update_pending_in_java_ = is_update_pending_in_java;
UpdateCookie();
}
std::string ConsistencyCookieManagerAndroid::CalculateCookieValue() {
if (is_update_pending_in_java_) {
return kStateUpdating;
}
return ConsistencyCookieManagerBase::CalculateCookieValue();
}
} // namespace signin
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_CONSISTENCY_COOKIE_MANAGER_ANDROID_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_CONSISTENCY_COOKIE_MANAGER_ANDROID_H_
#include "base/android/scoped_java_ref.h"
#include "base/macros.h"
#include "components/signin/core/browser/consistency_cookie_manager_base.h"
class SigninClient;
namespace signin {
class IdentityManager;
// ConsistencyCookieManagerAndroid subclasses ConsistencyCookieManagerBase to
// watch whether there are pending updates to the account list on the Java side.
class ConsistencyCookieManagerAndroid : public ConsistencyCookieManagerBase {
public:
ConsistencyCookieManagerAndroid(IdentityManager* identity_manager,
SigninClient* signin_client,
AccountReconcilor* reconcilor);
~ConsistencyCookieManagerAndroid() override;
void OnIsUpdatePendingChanged(JNIEnv* env);
protected:
std::string CalculateCookieValue() override;
private:
bool is_update_pending_in_java_ = false;
base::android::ScopedJavaGlobalRef<jobject> java_ref_;
DISALLOW_COPY_AND_ASSIGN(ConsistencyCookieManagerAndroid);
};
} // namespace signin
#endif // COMPONENTS_SIGNIN_CORE_BROWSER_CONSISTENCY_COOKIE_MANAGER_ANDROID_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/signin/core/browser/consistency_cookie_manager_base.h"
#include "base/logging.h"
#include "base/time/time.h"
#include "components/signin/public/base/signin_client.h"
#include "google_apis/gaia/gaia_urls.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_options.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
#include "url/gurl.h"
namespace signin {
const char kCookieName[] = "CHROME_ID_CONSISTENCY_STATE";
const char ConsistencyCookieManagerBase::kStateConsistent[] = "Consistent";
const char ConsistencyCookieManagerBase::kStateInconsistent[] = "Inconsistent";
const char ConsistencyCookieManagerBase::kStateUpdating[] = "Updating";
ConsistencyCookieManagerBase::ConsistencyCookieManagerBase(
SigninClient* signin_client,
AccountReconcilor* reconcilor)
: account_reconcilor_state_(reconcilor->GetState()),
signin_client_(signin_client),
account_reconcilor_observer_(this) {
DCHECK(signin_client_);
DCHECK(reconcilor);
account_reconcilor_observer_.Add(reconcilor);
}
ConsistencyCookieManagerBase::~ConsistencyCookieManagerBase() = default;
void ConsistencyCookieManagerBase::OnStateChanged(
signin_metrics::AccountReconcilorState state) {
if (state == account_reconcilor_state_)
return;
account_reconcilor_state_ = state;
UpdateCookie();
}
std::string ConsistencyCookieManagerBase::CalculateCookieValue() {
switch (account_reconcilor_state_) {
case signin_metrics::ACCOUNT_RECONCILOR_OK:
return kStateConsistent;
case signin_metrics::ACCOUNT_RECONCILOR_RUNNING:
case signin_metrics::ACCOUNT_RECONCILOR_SCHEDULED:
return kStateUpdating;
case signin_metrics::ACCOUNT_RECONCILOR_ERROR:
return kStateInconsistent;
case signin_metrics::ACCOUNT_RECONCILOR_HISTOGRAM_COUNT:
NOTREACHED();
return {};
}
}
void ConsistencyCookieManagerBase::UpdateCookie() {
std::string cookie_value = CalculateCookieValue();
DCHECK(!cookie_value.empty());
// Update the cookie with the new value.
network::mojom::CookieManager* cookie_manager =
signin_client_->GetCookieManager();
base::Time now = base::Time::Now();
base::Time expiry = now + base::TimeDelta::FromDays(2 * 365); // Two years.
net::CanonicalCookie cookie(
kCookieName, cookie_value, GaiaUrls::GetInstance()->gaia_url().host(),
/*path=*/"/", /*creation=*/now, /*expiration=*/expiry,
/*last_access=*/now, /*secure=*/true, /*httponly=*/false,
net::CookieSameSite::LAX_MODE, net::COOKIE_PRIORITY_DEFAULT);
net::CookieOptions cookie_options;
// Permit to set SameSite cookies.
cookie_options.set_same_site_cookie_context(
net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
cookie_manager->SetCanonicalCookie(
cookie, "https", cookie_options,
network::mojom::CookieManager::SetCanonicalCookieCallback());
}
} // namespace signin
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_CONSISTENCY_COOKIE_MANAGER_BASE_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_CONSISTENCY_COOKIE_MANAGER_BASE_H_
#include "base/macros.h"
#include "base/scoped_observer.h"
#include "components/signin/core/browser/account_reconcilor.h"
#include "components/signin/public/base/signin_metrics.h"
class SigninClient;
namespace signin {
// The ConsistencyCookieManagerBase checks if:
// - the account reconcilor is running
// - the accounts on the device are updating
// - the user has started to interact with device account settings (from Chrome)
// If one of these conditions is true, then this object sets a cookie on Gaia
// with a "Updating" value.
//
// Otherwise the value of the cookie is "Consistent" if the accounts are
// consistent (web accounts match device accounts) or "Inconsistent".
//
// Subclasses have to call UpdateCookie() at the end of the constructor.
class ConsistencyCookieManagerBase : public AccountReconcilor::Observer {
public:
~ConsistencyCookieManagerBase() override;
protected:
static const char kStateConsistent[];
static const char kStateInconsistent[];
static const char kStateUpdating[];
ConsistencyCookieManagerBase(SigninClient* signin_client,
AccountReconcilor* reconcilor);
// Calculates the cookie value solely based on the reconcilor state.
virtual std::string CalculateCookieValue();
// Gets the new value using CalculateCookieValue and sets the cookie.
void UpdateCookie();
private:
// AccountReconcilor::Observer:
void OnStateChanged(signin_metrics::AccountReconcilorState state) override;
signin_metrics::AccountReconcilorState account_reconcilor_state_ =
signin_metrics::ACCOUNT_RECONCILOR_OK;
SigninClient* signin_client_ = nullptr;
ScopedObserver<AccountReconcilor, AccountReconcilor::Observer>
account_reconcilor_observer_;
DISALLOW_COPY_AND_ASSIGN(ConsistencyCookieManagerBase);
};
} // namespace signin
#endif // COMPONENTS_SIGNIN_CORE_BROWSER_CONSISTENCY_COOKIE_MANAGER_BASE_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/signin/core/browser/consistency_cookie_manager_base.h"
#include <memory>
#include <string>
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "components/signin/core/browser/account_reconcilor.h"
#include "components/signin/core/browser/account_reconcilor_delegate.h"
#include "components/signin/public/base/account_consistency_method.h"
#include "components/signin/public/base/test_signin_client.h"
#include "components/signin/public/identity_manager/identity_test_environment.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "google_apis/gaia/gaia_urls.h"
#include "services/network/test/test_cookie_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace signin {
namespace {
// GMock matcher that checks that the consistency cookie has the expected value.
MATCHER_P(CookieHasValueMatcher, value, "") {
net::CookieOptions cookie_options;
cookie_options.set_same_site_cookie_context(
net::CookieOptions::SameSiteCookieContext::SAME_SITE_LAX);
return arg.Name() == "CHROME_ID_CONSISTENCY_STATE" && arg.Value() == value &&
arg.IncludeForRequestURL(GaiaUrls::GetInstance()->gaia_url(),
cookie_options)
.IsInclude();
}
MATCHER(SetPermittedInContext, "") {
const net::CanonicalCookie& cookie = testing::get<0>(arg);
const net::CookieOptions& cookie_options = testing::get<1>(arg);
return cookie.IsSetPermittedInContext(cookie_options).IsInclude();
}
class MockCookieManager
: public testing::StrictMock<network::TestCookieManager> {
public:
// Adds a GMock expectation that the consistency cookie will be set with the
// specified value.
void ExpectSetCookieCall(const std::string& value) {
EXPECT_CALL(*this, SetCanonicalCookie(CookieHasValueMatcher(value), "https",
testing::_, testing::_))
.With(testing::Args<0, 2>(SetPermittedInContext()));
}
MOCK_METHOD4(
SetCanonicalCookie,
void(const net::CanonicalCookie& cookie,
const std::string& source_scheme,
const net::CookieOptions& cookie_options,
network::mojom::CookieManager::SetCanonicalCookieCallback callback));
};
class FakeConsistencyCookieManager : public ConsistencyCookieManagerBase {
public:
FakeConsistencyCookieManager(SigninClient* signin_client,
AccountReconcilor* reconcilor)
: ConsistencyCookieManagerBase(signin_client, reconcilor) {
UpdateCookie();
}
};
class ConsistencyCookieManagerTest : public ::testing::Test {
public:
ConsistencyCookieManagerTest()
: signin_client_(&pref_service_),
identity_test_env_(/*test_url_loader_factory=*/nullptr,
&pref_service_,
AccountConsistencyMethod::kMirror,
&signin_client_) {
scoped_feature_list_.InitAndEnableFeature(kMiceFeature);
std::unique_ptr<MockCookieManager> cookie_manager =
std::make_unique<MockCookieManager>();
mock_cookie_manager_ = cookie_manager.get();
signin_client_.set_cookie_manager(std::move(cookie_manager));
reconcilor_ = std::make_unique<AccountReconcilor>(
identity_test_env_.identity_manager(), &signin_client_,
std::make_unique<AccountReconcilorDelegate>());
reconcilor_->Initialize(/*start_reconcile_if_tokens_available=*/false);
}
~ConsistencyCookieManagerTest() override { reconcilor_->Shutdown(); }
SigninClient* signin_client() { return &signin_client_; }
AccountReconcilor* reconcilor() { return reconcilor_.get(); }
MockCookieManager* mock_cookie_manager() {
DCHECK_EQ(mock_cookie_manager_, signin_client_.GetCookieManager());
return mock_cookie_manager_;
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
base::test::TaskEnvironment task_environment_;
sync_preferences::TestingPrefServiceSyncable pref_service_;
// Owned by signin_client_.
MockCookieManager* mock_cookie_manager_ = nullptr;
TestSigninClient signin_client_;
IdentityTestEnvironment identity_test_env_;
std::unique_ptr<AccountReconcilor> reconcilor_;
};
// Tests that the cookie is updated when the account reconcilor state changes.
TEST_F(ConsistencyCookieManagerTest, AccountReconcilorState) {
// AccountReconcilor::Initialize() creates the ConsistencyCookieManager.
mock_cookie_manager()->ExpectSetCookieCall("Consistent");
reconcilor()->SetConsistencyCookieManager(
std::make_unique<FakeConsistencyCookieManager>(signin_client(),
reconcilor()));
testing::Mock::VerifyAndClearExpectations(mock_cookie_manager());
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor()->GetState());
// Trigger a state change in the reconcilor, and check that the cookie was
// updated accordingly. Calling EnableReconcile() will cause the reconcilor
// state to change to SCHEDULED then OK.
mock_cookie_manager()->ExpectSetCookieCall("Updating");
mock_cookie_manager()->ExpectSetCookieCall("Consistent");
reconcilor()->EnableReconcile();
}
} // namespace
} // namespace signin
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/signin/core/browser/mice_account_reconcilor_delegate.h"
#include "base/logging.h"
namespace signin {
MiceAccountReconcilorDelegate::MiceAccountReconcilorDelegate() = default;
MiceAccountReconcilorDelegate::~MiceAccountReconcilorDelegate() = default;
bool MiceAccountReconcilorDelegate::IsReconcileEnabled() const {
return true;
}
bool MiceAccountReconcilorDelegate::IsAccountConsistencyEnforced() const {
return true;
}
gaia::GaiaSource MiceAccountReconcilorDelegate::GetGaiaApiSource() const {
return gaia::GaiaSource::kAccountReconcilorMirror;
}
CoreAccountId MiceAccountReconcilorDelegate::GetFirstGaiaAccountForReconcile(
const std::vector<CoreAccountId>& chrome_accounts,
const std::vector<gaia::ListedAccount>& gaia_accounts,
const CoreAccountId& primary_account,
bool first_execution,
bool will_logout) const {
// This flow is deprecated and will be removed when multilogin is fully
// launched.
NOTREACHED() << "Mice requires multilogin";
return CoreAccountId();
}
std::vector<CoreAccountId>
MiceAccountReconcilorDelegate::GetChromeAccountsForReconcile(
const std::vector<CoreAccountId>& chrome_accounts,
const CoreAccountId& primary_account,
const std::vector<gaia::ListedAccount>& gaia_accounts,
const gaia::MultiloginMode mode) const {
if (chrome_accounts.empty())
return {};
// First account, by priority order:
// - primary account
// - first account on the device.
// Warning: As a result, the reconciliation may change the default Gaia
// account. It should be ensured that this is not surprising for the user.
CoreAccountId new_first_account =
base::Contains(chrome_accounts, primary_account) ? primary_account
: chrome_accounts[0];
// Minimize account shuffling and ensure that the number of accounts does not
// exceed the limit.
return ReorderChromeAccountsForReconcile(chrome_accounts, new_first_account,
gaia_accounts);
}
gaia::MultiloginMode MiceAccountReconcilorDelegate::CalculateModeForReconcile(
const std::vector<gaia::ListedAccount>& gaia_accounts,
const CoreAccountId& primary_account,
bool first_execution,
bool primary_has_error) const {
return gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER;
}
bool MiceAccountReconcilorDelegate::IsUnknownInvalidAccountInCookieAllowed()
const {
return false;
}
} // namespace signin
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_MICE_ACCOUNT_RECONCILOR_DELEGATE_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_MICE_ACCOUNT_RECONCILOR_DELEGATE_H_
#include <string>
#include <vector>
#include "base/macros.h"
#include "components/signin/core/browser/account_reconcilor_delegate.h"
namespace signin {
// AccountReconcilorDelegate specialized for Mice.
class MiceAccountReconcilorDelegate : public AccountReconcilorDelegate {
public:
MiceAccountReconcilorDelegate();
~MiceAccountReconcilorDelegate() override;
private:
// AccountReconcilorDelegate:
bool IsReconcileEnabled() const override;
bool IsAccountConsistencyEnforced() const override;
gaia::GaiaSource GetGaiaApiSource() const override;
CoreAccountId GetFirstGaiaAccountForReconcile(
const std::vector<CoreAccountId>& chrome_accounts,
const std::vector<gaia::ListedAccount>& gaia_accounts,
const CoreAccountId& primary_account,
bool first_execution,
bool will_logout) const override;
std::vector<CoreAccountId> GetChromeAccountsForReconcile(
const std::vector<CoreAccountId>& chrome_accounts,
const CoreAccountId& primary_account,
const std::vector<gaia::ListedAccount>& gaia_accounts,
const gaia::MultiloginMode mode) const override;
gaia::MultiloginMode CalculateModeForReconcile(
const std::vector<gaia::ListedAccount>& gaia_accounts,
const CoreAccountId& primary_account,
bool first_execution,
bool primary_has_error) const override;
bool IsUnknownInvalidAccountInCookieAllowed() const override;
DISALLOW_COPY_AND_ASSIGN(MiceAccountReconcilorDelegate);
};
} // namespace signin
#endif // COMPONENTS_SIGNIN_CORE_BROWSER_MICE_ACCOUNT_RECONCILOR_DELEGATE_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/signin/core/browser/mice_account_reconcilor_delegate.h"
#include <vector>
#include "google_apis/gaia/gaia_auth_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace signin {
namespace {
// Returns a gaia::ListedAccount with the specified account id.
gaia::ListedAccount BuildTestListedAccount(const std::string account_id,
bool valid) {
gaia::ListedAccount account;
account.id = CoreAccountId(account_id);
account.valid = valid;
return account;
}
// Returns vector of account_id created from value
std::vector<CoreAccountId> ToAccountIdList(
const std::vector<std::string>& account_ids_value) {
std::vector<CoreAccountId> account_ids;
for (const auto& account_id_value : account_ids_value)
account_ids.push_back(CoreAccountId(account_id_value));
return account_ids;
}
} // namespace
TEST(MiceAccountReconcilorDelegate, CalculateParametersForMultilogin) {
MiceAccountReconcilorDelegate mice_delegate;
const gaia::ListedAccount kA = BuildTestListedAccount("A", /*valid=*/true);
const gaia::ListedAccount kB = BuildTestListedAccount("B", /*valid=*/false);
struct TestParams {
std::vector<std::string> chrome_accounts;
std::string primary_account;
std::vector<gaia::ListedAccount> gaia_accounts;
std::vector<std::string> expected_accounts;
};
// clang-format off
TestParams cases[] = {
// chrome_accounts, primary_account, gaia_accounts, expected_accounts
{{}, "", {}, {}},
{{}, "", {kA, kB}, {}},
{{"A"}, "", {}, {"A"}},
{{"A"}, "", {kA, kB}, {"A"}},
{{"A"}, "", {kB, kA}, {"A"}},
{{"A", "B"}, "", {}, {"A", "B"}},
{{"A", "B"}, "", {kA}, {"A", "B"}},
{{"A", "B"}, "", {kB}, {"A", "B"}},
{{"B", "C"}, "", {kA}, {"B", "C"}},
{{"A", "B"}, "", {kA, kB}, {"A", "B"}},
{{"A", "B"}, "", {kB, kA}, {"A", "B"}},
{{"B", "C"}, "", {kA, kB}, {"B", "C"}},
// Tests the reordering: B remains in 2nd place.
{{"C", "D", "B"}, "", {kA, kB}, {"C", "B", "D"}},
// With primary account.
{{"A", "B"}, "B", {}, {"B", "A"}},
{{"B", "A"}, "A", {kB, kA}, {"A", "B"}},
{{"A", "B"}, "B", {kB, kA}, {"B", "A"}},
};
// clang-format on
for (const auto& test : cases) {
MultiloginParameters multilogin_parameters =
mice_delegate.CalculateParametersForMultilogin(
ToAccountIdList(test.chrome_accounts),
CoreAccountId(test.primary_account), test.gaia_accounts, false,
false);
EXPECT_EQ(gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER,
multilogin_parameters.mode);
EXPECT_EQ(ToAccountIdList(test.expected_accounts),
multilogin_parameters.accounts_to_send);
}
}
} // namespace signin
...@@ -142,31 +142,12 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdChromeOS) { ...@@ -142,31 +142,12 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdChromeOS) {
// Tests that no Mirror request is returned when the user is not signed in (no // Tests that no Mirror request is returned when the user is not signed in (no
// account id), for non Chrome OS platforms. // account id), for non Chrome OS platforms.
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestNoAccountId) { TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestNoAccountId) {
#if defined(OS_ANDROID)
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndDisableFeature(kMiceFeature);
#endif
account_consistency_ = AccountConsistencyMethod::kMirror; account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "", ""); CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "", "");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), "", ""); CheckMirrorCookieRequest(GURL("https://docs.google.com"), "", "");
} }
#endif #endif
#if defined(OS_ANDROID)
// Tests that Mirror request is returned on Android with Mice.
TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdMice) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(kMiceFeature);
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "",
"mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=true");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), "",
"mode=0:enable_account_consistency=true:"
"consistency_enabled_by_default=true");
}
#endif
// Tests that no Mirror request is returned when the cookies aren't allowed to // Tests that no Mirror request is returned when the cookies aren't allowed to
// be set. // be set.
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestCookieSettingBlocked) { TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestCookieSettingBlocked) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment