| OLD | NEW | 
|    1 // Copyright 2015 The Chromium Authors. All rights reserved. |    1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "chrome/browser/chromeos/arc/arc_auth_service.h" |    5 #include "chrome/browser/chromeos/arc/arc_auth_service.h" | 
|    6  |    6  | 
|    7 #include <utility> |    7 #include <utility> | 
|    8  |    8  | 
|    9 #include "base/command_line.h" |    9 #include "base/command_line.h" | 
|   10 #include "chrome/browser/chromeos/arc/arc_auth_ui.h" |   10 #include "base/strings/stringprintf.h" | 
 |   11 #include "chrome/browser/extensions/extension_util.h" | 
|   11 #include "chrome/browser/profiles/profile.h" |   12 #include "chrome/browser/profiles/profile.h" | 
 |   13 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" | 
 |   14 #include "chrome/browser/signin/signin_manager_factory.h" | 
 |   15 #include "chrome/browser/ui/extensions/app_launch_params.h" | 
 |   16 #include "chrome/browser/ui/extensions/application_launch.h" | 
|   12 #include "chrome/common/pref_names.h" |   17 #include "chrome/common/pref_names.h" | 
|   13 #include "chromeos/chromeos_switches.h" |   18 #include "chromeos/chromeos_switches.h" | 
|   14 #include "components/arc/arc_bridge_service.h" |   19 #include "components/arc/arc_bridge_service.h" | 
|   15 #include "components/pref_registry/pref_registry_syncable.h" |   20 #include "components/pref_registry/pref_registry_syncable.h" | 
|   16 #include "components/prefs/pref_service.h" |   21 #include "components/prefs/pref_service.h" | 
 |   22 #include "components/signin/core/browser/profile_oauth2_token_service.h" | 
 |   23 #include "components/signin/core/browser/signin_manager_base.h" | 
 |   24 #include "content/public/browser/storage_partition.h" | 
 |   25 #include "content/public/common/url_constants.h" | 
 |   26 #include "extensions/browser/extension_registry.h" | 
 |   27 #include "google_apis/gaia/gaia_constants.h" | 
|   17  |   28  | 
|   18 namespace arc { |   29 namespace arc { | 
|   19  |   30  | 
|   20 namespace { |   31 namespace { | 
|   21  |   32  | 
|   22 // Weak pointer.  This class is owned by ArcServiceManager. |   33 // Weak pointer.  This class is owned by ArcServiceManager. | 
|   23 ArcAuthService* arc_auth_service = nullptr; |   34 ArcAuthService* arc_auth_service = nullptr; | 
|   24  |   35  | 
 |   36 const char kArcSupportExtensionId[] = "cnbgggchhmkkdmeppjobngjoejnihlei"; | 
 |   37 const char kArcSupportStorageId[] = "arc_support"; | 
 |   38  | 
|   25 // Skip creating UI in unit tests |   39 // Skip creating UI in unit tests | 
|   26 bool disable_ui_for_testing = false; |   40 bool disable_ui_for_testing = false; | 
|   27  |   41  | 
|   28 const char kStateDisable[] = "DISABLE"; |   42 const char kStateDisable[] = "DISABLE"; | 
|   29 const char kStateFetchingCode[] = "FETCHING_CODE"; |   43 const char kStateFetchingCode[] = "FETCHING_CODE"; | 
|   30 const char kStateNoCode[] = "NO_CODE"; |   44 const char kStateNoCode[] = "NO_CODE"; | 
|   31 const char kStateEnable[] = "ENABLE"; |   45 const char kStateEnable[] = "ENABLE"; | 
|   32 }  // namespace |   46 }  // namespace | 
|   33  |   47  | 
|   34 ArcAuthService::ArcAuthService(ArcBridgeService* bridge_service) |   48 ArcAuthService::ArcAuthService(ArcBridgeService* bridge_service) | 
|   35     : ArcService(bridge_service), binding_(this) { |   49     : ArcService(bridge_service), binding_(this) { | 
|   36   DCHECK(!arc_auth_service); |   50   DCHECK(!arc_auth_service); | 
|   37   arc_auth_service = this; |   51   arc_auth_service = this; | 
|   38  |   52  | 
|   39   arc_bridge_service()->AddObserver(this); |   53   arc_bridge_service()->AddObserver(this); | 
|   40 } |   54 } | 
|   41  |   55  | 
|   42 ArcAuthService::~ArcAuthService() { |   56 ArcAuthService::~ArcAuthService() { | 
|   43   DCHECK(!auth_ui_ && !profile_); |   57   DCHECK(!profile_); | 
|   44   arc_bridge_service()->RemoveObserver(this); |   58   arc_bridge_service()->RemoveObserver(this); | 
|   45  |   59  | 
|   46   DCHECK(arc_auth_service == this); |   60   DCHECK(arc_auth_service == this); | 
|   47   arc_auth_service = nullptr; |   61   arc_auth_service = nullptr; | 
|   48 } |   62 } | 
|   49  |   63  | 
|   50 // static |   64 // static | 
|   51 ArcAuthService* ArcAuthService::Get() { |   65 ArcAuthService* ArcAuthService::Get() { | 
|   52   DCHECK(arc_auth_service); |   66   DCHECK(arc_auth_service); | 
|   53   DCHECK(arc_auth_service->thread_checker_.CalledOnValidThread()); |   67   DCHECK(arc_auth_service->thread_checker_.CalledOnValidThread()); | 
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  105   FOR_EACH_OBSERVER(Observer, observer_list_, OnOptInChanged(state_)); |  119   FOR_EACH_OBSERVER(Observer, observer_list_, OnOptInChanged(state_)); | 
|  106 } |  120 } | 
|  107  |  121  | 
|  108 void ArcAuthService::OnPrimaryUserProfilePrepared(Profile* profile) { |  122 void ArcAuthService::OnPrimaryUserProfilePrepared(Profile* profile) { | 
|  109   DCHECK(profile && profile != profile_); |  123   DCHECK(profile && profile != profile_); | 
|  110   DCHECK(thread_checker_.CalledOnValidThread()); |  124   DCHECK(thread_checker_.CalledOnValidThread()); | 
|  111  |  125  | 
|  112   Shutdown(); |  126   Shutdown(); | 
|  113  |  127  | 
|  114   profile_ = profile; |  128   profile_ = profile; | 
 |  129   // Reuse storage used in ARC OptIn platform app. | 
 |  130   const std::string site_url = | 
 |  131       base::StringPrintf("%s://%s/persist?%s", content::kGuestScheme, | 
 |  132                          kArcSupportExtensionId, kArcSupportStorageId); | 
 |  133   storage_partition_ = content::BrowserContext::GetStoragePartitionForSite( | 
 |  134       profile_, GURL(site_url)); | 
 |  135   CHECK(storage_partition_); | 
|  115  |  136  | 
|  116   // In case UI is disabled we assume that ARC is opted-in. |  137   // In case UI is disabled we assume that ARC is opted-in. | 
|  117   if (!IsOptInVerificationDisabled()) { |  138   if (!IsOptInVerificationDisabled()) { | 
|  118     pref_change_registrar_.Init(profile_->GetPrefs()); |  139     pref_change_registrar_.Init(profile_->GetPrefs()); | 
|  119     pref_change_registrar_.Add( |  140     pref_change_registrar_.Add( | 
|  120         prefs::kArcEnabled, |  141         prefs::kArcEnabled, | 
|  121         base::Bind(&ArcAuthService::OnOptInPreferenceChanged, |  142         base::Bind(&ArcAuthService::OnOptInPreferenceChanged, | 
|  122                    base::Unretained(this))); |  143                    base::Unretained(this))); | 
|  123     OnOptInPreferenceChanged(); |  144     OnOptInPreferenceChanged(); | 
|  124   } else { |  145   } else { | 
|  125     SetAuthCodeAndStartArc(std::string()); |  146     auth_code_.clear(); | 
 |  147     ArcBridgeService::Get()->HandleStartup(); | 
 |  148     SetState(State::ENABLE); | 
|  126   } |  149   } | 
|  127 } |  150 } | 
|  128  |  151  | 
|  129 void ArcAuthService::Shutdown() { |  152 void ArcAuthService::Shutdown() { | 
|  130   ShutdownBridgeAndCloseUI(); |  153   ShutdownBridgeAndCloseUI(); | 
|  131   profile_ = nullptr; |  154   profile_ = nullptr; | 
|  132   pref_change_registrar_.RemoveAll(); |  155   pref_change_registrar_.RemoveAll(); | 
|  133 } |  156 } | 
|  134  |  157  | 
 |  158 void ArcAuthService::OnMergeSessionSuccess(const std::string& data) { | 
 |  159   DCHECK(thread_checker_.CalledOnValidThread()); | 
 |  160  | 
 |  161   const extensions::Extension* extension = | 
 |  162       extensions::ExtensionRegistry::Get(profile_)->GetInstalledExtension( | 
 |  163           kArcSupportExtensionId); | 
 |  164   CHECK(extension && | 
 |  165         extensions::util::IsAppLaunchable(kArcSupportExtensionId, profile_)); | 
 |  166  | 
 |  167   AppLaunchParams params(profile_, extension, NEW_WINDOW, | 
 |  168                          extensions::SOURCE_CHROME_INTERNAL); | 
 |  169   OpenApplication(params); | 
 |  170 } | 
 |  171  | 
 |  172 void ArcAuthService::OnMergeSessionFailure( | 
 |  173     const GoogleServiceAuthError& error) { | 
 |  174   DCHECK(thread_checker_.CalledOnValidThread()); | 
 |  175   VLOG(2) << "Failed to merge gaia session " << error.ToString() << "."; | 
 |  176   OnAuthCodeFailed(); | 
 |  177 } | 
 |  178  | 
 |  179 void ArcAuthService::OnUbertokenSuccess(const std::string& token) { | 
 |  180   DCHECK(thread_checker_.CalledOnValidThread()); | 
 |  181   merger_fetcher_.reset( | 
 |  182       new GaiaAuthFetcher(this, GaiaConstants::kChromeOSSource, | 
 |  183                           storage_partition_->GetURLRequestContext())); | 
 |  184   merger_fetcher_->StartMergeSession(token, std::string()); | 
 |  185 } | 
 |  186  | 
 |  187 void ArcAuthService::OnUbertokenFailure(const GoogleServiceAuthError& error) { | 
 |  188   DCHECK(thread_checker_.CalledOnValidThread()); | 
 |  189   VLOG(2) << "Failed to get ubertoken " << error.ToString() << "."; | 
 |  190   OnAuthCodeFailed(); | 
 |  191 } | 
 |  192  | 
|  135 void ArcAuthService::OnOptInPreferenceChanged() { |  193 void ArcAuthService::OnOptInPreferenceChanged() { | 
|  136   DCHECK(thread_checker_.CalledOnValidThread()); |  194   DCHECK(thread_checker_.CalledOnValidThread()); | 
|  137   DCHECK(profile_); |  195   DCHECK(profile_); | 
|  138  |  196  | 
|  139   if (profile_->GetPrefs()->GetBoolean(prefs::kArcEnabled)) { |  197   if (profile_->GetPrefs()->GetBoolean(prefs::kArcEnabled)) { | 
|  140     switch (state_) { |  198     if (state_ != State::ENABLE) { | 
|  141       case State::DISABLE: |  199       CloseUI(); | 
|  142         FetchAuthCode(); |  200       auth_code_.clear(); | 
|  143         break; |  201       SetState(State::FETCHING_CODE); | 
|  144       case State::NO_CODE:  // Retry |  202       FetchAuthCode(); | 
|  145         FetchAuthCode(); |  | 
|  146         break; |  | 
|  147       default: |  | 
|  148         break; |  | 
|  149     } |  203     } | 
|  150   } else { |  204   } else { | 
|  151     ShutdownBridgeAndCloseUI(); |  205     ShutdownBridgeAndCloseUI(); | 
|  152   } |  206   } | 
|  153 } |  207 } | 
|  154  |  208  | 
|  155 void ArcAuthService::ShutdownBridgeAndCloseUI() { |  209 void ArcAuthService::ShutdownBridgeAndCloseUI() { | 
|  156   CloseUI(); |  210   CloseUI(); | 
|  157   auth_fetcher_.reset(); |  211   auth_fetcher_.reset(); | 
 |  212   ubertoken_fethcher_.reset(); | 
 |  213   merger_fetcher_.reset(); | 
|  158   ArcBridgeService::Get()->Shutdown(); |  214   ArcBridgeService::Get()->Shutdown(); | 
|  159   SetState(State::DISABLE); |  215   SetState(State::DISABLE); | 
|  160 } |  216 } | 
|  161  |  217  | 
|  162 void ArcAuthService::AddObserver(Observer* observer) { |  218 void ArcAuthService::AddObserver(Observer* observer) { | 
|  163   DCHECK(thread_checker_.CalledOnValidThread()); |  219   DCHECK(thread_checker_.CalledOnValidThread()); | 
|  164   observer_list_.AddObserver(observer); |  220   observer_list_.AddObserver(observer); | 
|  165 } |  221 } | 
|  166  |  222  | 
|  167 void ArcAuthService::RemoveObserver(Observer* observer) { |  223 void ArcAuthService::RemoveObserver(Observer* observer) { | 
|  168   DCHECK(thread_checker_.CalledOnValidThread()); |  224   DCHECK(thread_checker_.CalledOnValidThread()); | 
|  169   observer_list_.RemoveObserver(observer); |  225   observer_list_.RemoveObserver(observer); | 
|  170 } |  226 } | 
|  171  |  227  | 
|  172 void ArcAuthService::CloseUI() { |  228 void ArcAuthService::CloseUI() { | 
|  173   if (auth_ui_) { |  229   FOR_EACH_OBSERVER(Observer, observer_list_, OnOptInUINeedToClose()); | 
|  174     auth_ui_->Close(); |  | 
|  175     DCHECK(!auth_ui_); |  | 
|  176   } |  | 
|  177 } |  230 } | 
|  178  |  231  | 
|  179 void ArcAuthService::SetAuthCodeAndStartArc(const std::string& auth_code) { |  232 void ArcAuthService::SetAuthCodeAndStartArc(const std::string& auth_code) { | 
|  180   DCHECK(thread_checker_.CalledOnValidThread()); |  233   DCHECK(thread_checker_.CalledOnValidThread()); | 
|  181   DCHECK(!auth_code.empty() || IsOptInVerificationDisabled()); |  234   DCHECK(!auth_code.empty()); | 
|  182   DCHECK_NE(state_, State::ENABLE); |  235  | 
 |  236   State state = state_; | 
|  183  |  237  | 
|  184   ShutdownBridgeAndCloseUI(); |  238   ShutdownBridgeAndCloseUI(); | 
|  185  |  239  | 
 |  240   if (state != State::FETCHING_CODE) | 
 |  241     return; | 
 |  242  | 
|  186   auth_code_ = auth_code; |  243   auth_code_ = auth_code; | 
|  187   ArcBridgeService::Get()->HandleStartup(); |  244   ArcBridgeService::Get()->HandleStartup(); | 
|  188  |  | 
|  189   SetState(State::ENABLE); |  245   SetState(State::ENABLE); | 
|  190 } |  246 } | 
|  191  |  247  | 
|  192 void ArcAuthService::FetchAuthCode() { |  248 void ArcAuthService::FetchAuthCode() { | 
|  193   DCHECK(thread_checker_.CalledOnValidThread()); |  249   DCHECK(thread_checker_.CalledOnValidThread()); | 
|  194   DCHECK(state_ == State::DISABLE || state_ == State::NO_CODE); |  | 
|  195  |  250  | 
|  196   CloseUI(); |  251   if (state_ != State::FETCHING_CODE) | 
|  197   auth_code_.clear(); |  252     return; | 
|  198  |  253  | 
|  199   SetState(State::FETCHING_CODE); |  254   auth_fetcher_.reset( | 
 |  255       new ArcAuthFetcher(storage_partition_->GetURLRequestContext(), this)); | 
 |  256 } | 
|  200  |  257  | 
|  201   auth_fetcher_.reset(new ArcAuthFetcher(profile_->GetRequestContext(), this)); |  258 void ArcAuthService::CancelAuthCode() { | 
 |  259   DCHECK(thread_checker_.CalledOnValidThread()); | 
 |  260  | 
 |  261   if (state_ != State::FETCHING_CODE) | 
 |  262     return; | 
 |  263  | 
 |  264   ShutdownBridgeAndCloseUI(); | 
 |  265  | 
 |  266   profile_->GetPrefs()->SetBoolean(prefs::kArcEnabled, false); | 
|  202 } |  267 } | 
|  203  |  268  | 
|  204 void ArcAuthService::OnAuthCodeFetched(const std::string& auth_code) { |  269 void ArcAuthService::OnAuthCodeFetched(const std::string& auth_code) { | 
|  205   DCHECK_EQ(state_, State::FETCHING_CODE); |  270   DCHECK_EQ(state_, State::FETCHING_CODE); | 
|  206   SetAuthCodeAndStartArc(auth_code); |  271   SetAuthCodeAndStartArc(auth_code); | 
|  207 } |  272 } | 
|  208  |  273  | 
 |  274 void ArcAuthService::ShowUI() { | 
 |  275   DCHECK(thread_checker_.CalledOnValidThread()); | 
 |  276  | 
 |  277   // Get auth token to continue. | 
 |  278   ProfileOAuth2TokenService* token_service = | 
 |  279       ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); | 
 |  280   SigninManagerBase* signin_manager = | 
 |  281       SigninManagerFactory::GetForProfile(profile_); | 
 |  282   CHECK(token_service && signin_manager); | 
 |  283   const std::string& account_id = signin_manager->GetAuthenticatedAccountId(); | 
 |  284   ubertoken_fethcher_.reset( | 
 |  285       new UbertokenFetcher(token_service, this, GaiaConstants::kChromeOSSource, | 
 |  286                            storage_partition_->GetURLRequestContext())); | 
 |  287   ubertoken_fethcher_->StartFetchingToken(account_id); | 
 |  288 } | 
 |  289  | 
|  209 void ArcAuthService::OnAuthCodeNeedUI() { |  290 void ArcAuthService::OnAuthCodeNeedUI() { | 
|  210   CloseUI(); |  291   DCHECK(thread_checker_.CalledOnValidThread()); | 
|  211   if (!disable_ui_for_testing && !IsOptInVerificationDisabled()) |  292  | 
|  212     auth_ui_ = new ArcAuthUI(profile_, this); |  293   if (disable_ui_for_testing || IsOptInVerificationDisabled()) | 
 |  294     return; | 
 |  295  | 
 |  296   ShowUI(); | 
|  213 } |  297 } | 
|  214  |  298  | 
|  215 void ArcAuthService::OnAuthCodeFailed() { |  299 void ArcAuthService::OnAuthCodeFailed() { | 
|  216   DCHECK_EQ(state_, State::FETCHING_CODE); |  300   DCHECK_EQ(state_, State::FETCHING_CODE); | 
|  217   CloseUI(); |  301   CloseUI(); | 
|  218  |  302  | 
|  219   SetState(State::NO_CODE); |  303   SetState(State::NO_CODE); | 
|  220 } |  304 } | 
|  221  |  305  | 
|  222 void ArcAuthService::OnAuthUIClosed() { |  | 
|  223   DCHECK(auth_ui_); |  | 
|  224   auth_ui_ = nullptr; |  | 
|  225 } |  | 
|  226  |  | 
|  227 std::ostream& operator<<(std::ostream& os, const ArcAuthService::State& state) { |  306 std::ostream& operator<<(std::ostream& os, const ArcAuthService::State& state) { | 
|  228   switch (state) { |  307   switch (state) { | 
|  229     case ArcAuthService::State::DISABLE: |  308     case ArcAuthService::State::DISABLE: | 
|  230       return os << kStateDisable; |  309       return os << kStateDisable; | 
|  231     case ArcAuthService::State::FETCHING_CODE: |  310     case ArcAuthService::State::FETCHING_CODE: | 
|  232       return os << kStateFetchingCode; |  311       return os << kStateFetchingCode; | 
|  233     case ArcAuthService::State::NO_CODE: |  312     case ArcAuthService::State::NO_CODE: | 
|  234       return os << kStateNoCode; |  313       return os << kStateNoCode; | 
|  235     case ArcAuthService::State::ENABLE: |  314     case ArcAuthService::State::ENABLE: | 
|  236       return os << kStateEnable; |  315       return os << kStateEnable; | 
|  237     default: |  316     default: | 
|  238       NOTREACHED(); |  317       NOTREACHED(); | 
|  239       return os; |  318       return os; | 
|  240   } |  319   } | 
|  241 } |  320 } | 
|  242  |  321  | 
|  243 }  // namespace arc |  322 }  // namespace arc | 
| OLD | NEW |