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, SINGLETON_TAB, | |
xiyuan
2016/02/12 17:06:59
nit: SINGLETON_TAB -> NEW_WINDOW
WindowOpenDispos
khmel
2016/02/12 18:15:14
Thanks for explanation. I could not understand the
| |
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 |