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 |