[invalidation] Port ProfileIdentityProvider to use IdentityManager

This CL ports ProfileIdentityProvider to talk to IdentityManager rather
than SigninManager and ProfileOAuth2TokenService. The conversion is
straightforward after a long line of preparatory work.

Bug: 809452
Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: Ifa638f1b7a9c77089bb87fd7215e60041c762d3a
Reviewed-on: https://chromium-review.googlesource.com/1118163
Commit-Queue: Colin Blundell <[email protected]>
Reviewed-by: Pavel Yatsuk <[email protected]>
Cr-Commit-Position: refs/heads/master@{#574865}
diff --git a/components/invalidation/impl/BUILD.gn b/components/invalidation/impl/BUILD.gn
index 4808c62..eeda43e9 100644
--- a/components/invalidation/impl/BUILD.gn
+++ b/components/invalidation/impl/BUILD.gn
@@ -52,10 +52,10 @@
     "//components/keyed_service/core",
     "//components/pref_registry",
     "//components/prefs",
-    "//components/signin/core/browser",
     "//google_apis",
     "//jingle:notifier",
     "//net:net",
+    "//services/identity/public/cpp",
     "//services/network/public/cpp",
     "//services/network/public/mojom",
 
@@ -181,6 +181,7 @@
       "//components/sync_preferences:test_support",
       "//google_apis:test_support",
       "//net",
+      "//services/identity/public/cpp:test_support",
     ]
   }
 }
diff --git a/components/invalidation/impl/DEPS b/components/invalidation/impl/DEPS
index edd9af0..cdd5ffb 100644
--- a/components/invalidation/impl/DEPS
+++ b/components/invalidation/impl/DEPS
@@ -5,7 +5,6 @@
   "+components/gcm_driver",
   "+components/keyed_service",
   "+components/pref_registry",
-  "+components/signin",
   "+components/sync_preferences",
 
   "+google_apis/gaia",
@@ -21,6 +20,7 @@
   "+net/url_request",
   "+net/base/load_flags.h",
 
+  "+services/identity/public",
   "+services/network/public",
   "+services/network/test",
 ]
diff --git a/components/invalidation/impl/gcm_invalidation_bridge_unittest.cc b/components/invalidation/impl/gcm_invalidation_bridge_unittest.cc
index 01643a2..08e94d0a 100644
--- a/components/invalidation/impl/gcm_invalidation_bridge_unittest.cc
+++ b/components/invalidation/impl/gcm_invalidation_bridge_unittest.cc
@@ -17,9 +17,9 @@
 #include "components/gcm_driver/fake_gcm_driver.h"
 #include "components/gcm_driver/gcm_driver.h"
 #include "components/invalidation/impl/profile_identity_provider.h"
-#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
 #include "google_apis/gaia/google_service_auth_error.h"
 #include "net/base/ip_endpoint.h"
+#include "services/identity/public/cpp/identity_test_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace invalidation {
@@ -55,12 +55,12 @@
   ~GCMInvalidationBridgeTest() override {}
 
   void SetUp() override {
-    token_service_.reset(new FakeProfileOAuth2TokenService());
-    token_service_->set_auto_post_fetch_response_on_message_loop(true);
-    token_service_->UpdateCredentials("", "fake_refresh_token");
     gcm_driver_.reset(new CustomFakeGCMDriver());
 
-    identity_provider_.reset(new ProfileIdentityProvider(token_service_.get()));
+    identity_test_env_.MakePrimaryAccountAvailable("[email protected]");
+
+    identity_provider_.reset(
+        new ProfileIdentityProvider(identity_test_env_.identity_manager()));
     bridge_.reset(new GCMInvalidationBridge(gcm_driver_.get(),
                                             identity_provider_.get()));
 
@@ -83,10 +83,13 @@
     registration_id_ = registration_id;
   }
 
-  void RequestTokenFinished(const GoogleServiceAuthError& error,
+  void RequestTokenFinished(const base::RepeatingClosure quit_callback,
+                            const GoogleServiceAuthError& error,
                             const std::string& token) {
     issued_tokens_.push_back(token);
     request_token_errors_.push_back(error);
+
+    quit_callback.Run();
   }
 
   void ConnectionStateChanged(bool online) {
@@ -94,7 +97,7 @@
   }
 
   base::MessageLoop message_loop_;
-  std::unique_ptr<FakeProfileOAuth2TokenService> token_service_;
+  identity::IdentityTestEnvironment identity_test_env_;
   std::unique_ptr<gcm::GCMDriver> gcm_driver_;
   std::unique_ptr<ProfileIdentityProvider> identity_provider_;
 
@@ -108,27 +111,48 @@
 };
 
 TEST_F(GCMInvalidationBridgeTest, RequestToken) {
+  base::RunLoop run_loop;
+
   // Make sure that call to RequestToken reaches OAuth2TokenService and gets
   // back to callback.
   delegate_->RequestToken(
       base::Bind(&GCMInvalidationBridgeTest::RequestTokenFinished,
-                 base::Unretained(this)));
-  RunLoop();
+                 base::Unretained(this), run_loop.QuitClosure()));
+
+  identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
+      "access_token", base::Time::Now() + base::TimeDelta::FromHours(1));
+
+  // GCMInvalidationBridge internally posts a task to invoke *its* consumer when
+  // it receives an access token, so spin the runloop until the consumer is
+  // invoked.
+  run_loop.Run();
+
   EXPECT_EQ(1U, issued_tokens_.size());
   EXPECT_NE("", issued_tokens_[0]);
   EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), request_token_errors_[0]);
 }
 
 TEST_F(GCMInvalidationBridgeTest, RequestTokenTwoConcurrentRequests) {
+  base::RunLoop run_loop;
+  base::RunLoop run_loop2;
+
   // First call should finish with REQUEST_CANCELLED error.
   delegate_->RequestToken(
       base::Bind(&GCMInvalidationBridgeTest::RequestTokenFinished,
-                 base::Unretained(this)));
+                 base::Unretained(this), run_loop.QuitClosure()));
   // Second request should succeed.
   delegate_->RequestToken(
       base::Bind(&GCMInvalidationBridgeTest::RequestTokenFinished,
-                 base::Unretained(this)));
-  RunLoop();
+                 base::Unretained(this), run_loop2.QuitClosure()));
+
+  identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
+      "access_token", base::Time::Now() + base::TimeDelta::FromHours(1));
+
+  // GCMInvalidationBridge internally posts a task to invoke *its* consumer when
+  // it either receives an access token or receives a new request while a
+  // request is ongoing, so spin the runloops until both consumers are invoked.
+  run_loop.Run();
+  run_loop2.Run();
 
   EXPECT_EQ(2U, issued_tokens_.size());
 
diff --git a/components/invalidation/impl/profile_identity_provider.cc b/components/invalidation/impl/profile_identity_provider.cc
index 6fa8f96..fcfbf75 100644
--- a/components/invalidation/impl/profile_identity_provider.cc
+++ b/components/invalidation/impl/profile_identity_provider.cc
@@ -5,47 +5,73 @@
 #include "components/invalidation/impl/profile_identity_provider.h"
 
 #include "components/invalidation/public/active_account_access_token_fetcher_impl.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
 
 namespace invalidation {
 
+namespace {
+
+// ActiveAccountAccessTokenFetcher implementation that is backed by
+// IdentityManager and wraps an AccessTokenFetcher internally.
+class AccessTokenFetcherAdaptor : public ActiveAccountAccessTokenFetcher {
+ public:
+  AccessTokenFetcherAdaptor(const std::string& active_account_id,
+                            const std::string& oauth_consumer_name,
+                            identity::IdentityManager* identity_manager,
+                            const OAuth2TokenService::ScopeSet& scopes,
+                            ActiveAccountAccessTokenCallback callback);
+  ~AccessTokenFetcherAdaptor() override = default;
+
+ private:
+  // Invokes |callback_| with (|access_token|, |error|).
+  void HandleTokenRequestCompletion(GoogleServiceAuthError error,
+                                    std::string access_token);
+
+  ActiveAccountAccessTokenCallback callback_;
+  std::unique_ptr<identity::AccessTokenFetcher> access_token_fetcher_;
+
+  DISALLOW_COPY_AND_ASSIGN(AccessTokenFetcherAdaptor);
+};
+
+AccessTokenFetcherAdaptor::AccessTokenFetcherAdaptor(
+    const std::string& active_account_id,
+    const std::string& oauth_consumer_name,
+    identity::IdentityManager* identity_manager,
+    const OAuth2TokenService::ScopeSet& scopes,
+    ActiveAccountAccessTokenCallback callback)
+    : callback_(std::move(callback)) {
+  access_token_fetcher_ = identity_manager->CreateAccessTokenFetcherForAccount(
+      active_account_id, oauth_consumer_name, scopes,
+      base::BindOnce(&AccessTokenFetcherAdaptor::HandleTokenRequestCompletion,
+                     base::Unretained(this)));
+}
+
+void AccessTokenFetcherAdaptor::HandleTokenRequestCompletion(
+    GoogleServiceAuthError error,
+    std::string access_token) {
+  access_token_fetcher_.reset();
+
+  std::move(callback_).Run(error, access_token);
+}
+
+}  // namespace
+
 ProfileIdentityProvider::ProfileIdentityProvider(
-    SigninManagerBase* signin_manager,
-    ProfileOAuth2TokenService* token_service)
-    : signin_manager_(signin_manager), token_service_(token_service) {
-  // TODO(blundell): Can |token_service_| ever actually be non-null?
-  if (token_service_)
-    token_service_->AddObserver(this);
-  signin_manager_->AddObserver(this);
+    identity::IdentityManager* identity_manager)
+    : identity_manager_(identity_manager) {
+  identity_manager_->AddObserver(this);
 }
 
 ProfileIdentityProvider::~ProfileIdentityProvider() {
-  // TODO(blundell): Can |token_service_| ever actually be non-null?
-  if (token_service_)
-    token_service_->RemoveObserver(this);
-
-  // In unittests |signin_manager_| is allowed to be null.
-  // TODO(809452): Eliminate this short-circuit when this class is converted to
-  // take in IdentityManager, at which point the tests can use
-  // IdentityTestEnvironment.
-  if (signin_manager_)
-    signin_manager_->RemoveObserver(this);
+  identity_manager_->RemoveObserver(this);
 }
 
 std::string ProfileIdentityProvider::GetActiveAccountId() {
-  // In unittests |signin_manager_| is allowed to be null.
-  // TODO(809452): Eliminate this short-circuit when this class is converted to
-  // take in IdentityManager, at which point the tests can use
-  // IdentityTestEnvironment.
-  if (!signin_manager_)
-    return std::string();
-
-  return signin_manager_->GetAuthenticatedAccountId();
+  return identity_manager_->GetPrimaryAccountInfo().account_id;
 }
 
 bool ProfileIdentityProvider::IsActiveAccountAvailable() {
-  if (GetActiveAccountId().empty() || !token_service_ ||
-      !token_service_->RefreshTokenIsAvailable(GetActiveAccountId()))
+  if (GetActiveAccountId().empty() || !identity_manager_ ||
+      !identity_manager_->HasAccountWithRefreshToken(GetActiveAccountId()))
     return false;
 
   return true;
@@ -56,37 +82,37 @@
     const std::string& oauth_consumer_name,
     const OAuth2TokenService::ScopeSet& scopes,
     ActiveAccountAccessTokenCallback callback) {
-  return std::make_unique<ActiveAccountAccessTokenFetcherImpl>(
-      GetActiveAccountId(), oauth_consumer_name, token_service_, scopes,
+  return std::make_unique<AccessTokenFetcherAdaptor>(
+      GetActiveAccountId(), oauth_consumer_name, identity_manager_, scopes,
       std::move(callback));
 }
 
 void ProfileIdentityProvider::InvalidateAccessToken(
     const OAuth2TokenService::ScopeSet& scopes,
     const std::string& access_token) {
-  token_service_->InvalidateAccessToken(GetActiveAccountId(), scopes,
-                                        access_token);
+  identity_manager_->RemoveAccessTokenFromCache(GetActiveAccountId(), scopes,
+                                                access_token);
 }
 
-void ProfileIdentityProvider::GoogleSigninSucceeded(
-    const std::string& account_id,
-    const std::string& username) {
+void ProfileIdentityProvider::OnPrimaryAccountSet(
+    const AccountInfo& primary_account_info) {
   FireOnActiveAccountLogin();
 }
 
-void ProfileIdentityProvider::GoogleSignedOut(const std::string& account_id,
-                                              const std::string& username) {
+void ProfileIdentityProvider::OnPrimaryAccountCleared(
+    const AccountInfo& previous_primary_account_info) {
   FireOnActiveAccountLogout();
 }
 
-void ProfileIdentityProvider::OnRefreshTokenAvailable(
-    const std::string& account_id) {
-  ProcessRefreshTokenUpdateForAccount(account_id);
+void ProfileIdentityProvider::OnRefreshTokenUpdatedForAccount(
+    const AccountInfo& account_info,
+    bool is_valid) {
+  ProcessRefreshTokenUpdateForAccount(account_info.account_id);
 }
 
-void ProfileIdentityProvider::OnRefreshTokenRevoked(
-    const std::string& account_id) {
-  ProcessRefreshTokenRemovalForAccount(account_id);
+void ProfileIdentityProvider::OnRefreshTokenRemovedForAccount(
+    const AccountInfo& account_info) {
+  ProcessRefreshTokenRemovalForAccount(account_info.account_id);
 }
 
 }  // namespace invalidation
diff --git a/components/invalidation/impl/profile_identity_provider.h b/components/invalidation/impl/profile_identity_provider.h
index 863ea1478..9ec720d 100644
--- a/components/invalidation/impl/profile_identity_provider.h
+++ b/components/invalidation/impl/profile_identity_provider.h
@@ -8,30 +8,16 @@
 #include "base/macros.h"
 #include "build/build_config.h"
 #include "components/invalidation/public/identity_provider.h"
-#include "components/signin/core/browser/signin_manager_base.h"
-
-class ProfileOAuth2TokenService;
+#include "services/identity/public/cpp/identity_manager.h"
 
 namespace invalidation {
 
 // An identity provider implementation that's backed by
 // ProfileOAuth2TokenService and SigninManager.
 class ProfileIdentityProvider : public IdentityProvider,
-                                public OAuth2TokenService::Observer,
-                                public SigninManagerBase::Observer {
+                                public identity::IdentityManager::Observer {
  public:
-  ProfileIdentityProvider(SigninManagerBase* signin_manager,
-                          ProfileOAuth2TokenService* token_service);
-#if defined(UNIT_TEST)
-  // Provide a testing constructor that allows for a null SigninManager instance
-  // to be passed, as there are tests that don't interact with the login
-  // functionality and it is a pain to set up FakeSigninManager(Base).
-  // TODO(809452): Eliminate this testing constructor when this class is
-  // converted to take in IdentityManager, at which point the tests can use
-  // IdentityTestEnvironment.
-  ProfileIdentityProvider(ProfileOAuth2TokenService* token_service)
-      : signin_manager_(nullptr), token_service_(token_service) {}
-#endif
+  ProfileIdentityProvider(identity::IdentityManager* identity_manager);
   ~ProfileIdentityProvider() override;
 
   // IdentityProvider:
@@ -44,19 +30,17 @@
   void InvalidateAccessToken(const OAuth2TokenService::ScopeSet& scopes,
                              const std::string& access_token) override;
 
-  // SigninManagerBase::Observer:
-  void GoogleSigninSucceeded(const std::string& account_id,
-                             const std::string& username) override;
-  void GoogleSignedOut(const std::string& account_id,
-                       const std::string& username) override;
-
-  // OAuth2TokenService::Observer:
-  void OnRefreshTokenAvailable(const std::string& account_id) override;
-  void OnRefreshTokenRevoked(const std::string& account_id) override;
+  // identity::IdentityManager::Observer:
+  void OnPrimaryAccountSet(const AccountInfo& primary_account_info) override;
+  void OnPrimaryAccountCleared(
+      const AccountInfo& previous_primary_account_info) override;
+  void OnRefreshTokenUpdatedForAccount(const AccountInfo& account_info,
+                                       bool is_valid) override;
+  void OnRefreshTokenRemovedForAccount(
+      const AccountInfo& account_info) override;
 
  private:
-  SigninManagerBase* const signin_manager_;
-  ProfileOAuth2TokenService* const token_service_;
+  identity::IdentityManager* const identity_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(ProfileIdentityProvider);
 };
diff --git a/components/invalidation/impl/ticl_invalidation_service_unittest.cc b/components/invalidation/impl/ticl_invalidation_service_unittest.cc
index 7ffc97ab..f55c814a 100644
--- a/components/invalidation/impl/ticl_invalidation_service_unittest.cc
+++ b/components/invalidation/impl/ticl_invalidation_service_unittest.cc
@@ -20,8 +20,8 @@
 #include "components/invalidation/impl/invalidation_state_tracker.h"
 #include "components/invalidation/impl/invalidator.h"
 #include "components/invalidation/impl/profile_identity_provider.h"
-#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
 #include "net/url_request/url_request_context_getter.h"
+#include "services/identity/public/cpp/identity_test_environment.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -69,7 +69,8 @@
     gcm_driver_.reset(new gcm::FakeGCMDriver());
     invalidation_service_.reset(new TiclInvalidationService(
         "TestUserAgent",
-        std::make_unique<ProfileIdentityProvider>(&token_service_),
+        std::make_unique<ProfileIdentityProvider>(
+            identity_test_env_.identity_manager()),
         std::unique_ptr<TiclSettingsProvider>(new FakeTiclSettingsProvider),
         gcm_driver_.get(), nullptr, nullptr));
   }
@@ -98,7 +99,7 @@
     fake_invalidator_->EmitOnIncomingInvalidation(invalidation_map);
   }
 
-  FakeProfileOAuth2TokenService token_service_;
+  identity::IdentityTestEnvironment identity_test_env_;
   std::unique_ptr<gcm::GCMDriver> gcm_driver_;
   syncer::FakeInvalidator* fake_invalidator_;  // Owned by the service.
 
diff --git a/components/invalidation/impl/ticl_profile_settings_provider_unittest.cc b/components/invalidation/impl/ticl_profile_settings_provider_unittest.cc
index f4ffbbc..d4ca7a2 100644
--- a/components/invalidation/impl/ticl_profile_settings_provider_unittest.cc
+++ b/components/invalidation/impl/ticl_profile_settings_provider_unittest.cc
@@ -19,10 +19,10 @@
 #include "components/invalidation/impl/ticl_invalidation_service.h"
 #include "components/invalidation/impl/ticl_settings_provider.h"
 #include "components/prefs/pref_service.h"
-#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "net/url_request/url_request_test_util.h"
+#include "services/identity/public/cpp/identity_test_environment.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -43,7 +43,7 @@
   scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
   gcm::FakeGCMDriver gcm_driver_;
   sync_preferences::TestingPrefServiceSyncable pref_service_;
-  FakeProfileOAuth2TokenService token_service_;
+  identity::IdentityTestEnvironment identity_test_env_;
 
   std::unique_ptr<TiclInvalidationService> invalidation_service_;
 
@@ -65,7 +65,7 @@
   invalidation_service_.reset(new TiclInvalidationService(
       "TestUserAgent",
       std::unique_ptr<IdentityProvider>(
-          new ProfileIdentityProvider(&token_service_)),
+          new ProfileIdentityProvider(identity_test_env_.identity_manager())),
       std::unique_ptr<TiclSettingsProvider>(
           new TiclProfileSettingsProvider(&pref_service_)),
       &gcm_driver_, request_context_getter_, nullptr /* url_loader_factory */));