OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/app_mode/kiosk_app_launcher.h" | 5 #include "chrome/browser/chromeos/app_mode/kiosk_profile_loader.h" |
6 | 6 |
7 #include "base/chromeos/chromeos_version.h" | 7 #include "base/chromeos/chromeos_version.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/weak_ptr.h" | 9 #include "base/memory/weak_ptr.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" | 11 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" |
12 #include "chrome/browser/chromeos/app_mode/startup_app_launcher.h" | |
13 #include "chrome/browser/chromeos/login/login_display_host_impl.h" | 12 #include "chrome/browser/chromeos/login/login_display_host_impl.h" |
14 #include "chrome/browser/chromeos/login/login_utils.h" | 13 #include "chrome/browser/chromeos/login/login_utils.h" |
15 #include "chrome/browser/chromeos/login/user_manager.h" | 14 #include "chrome/browser/chromeos/login/user_manager.h" |
16 #include "chrome/browser/chromeos/settings/cros_settings.h" | 15 #include "chrome/browser/chromeos/settings/cros_settings.h" |
17 #include "chrome/browser/chromeos/ui/app_launch_view.h" | 16 #include "chrome/browser/chromeos/ui/app_launch_view.h" |
18 #include "chrome/browser/lifetime/application_lifetime.h" | 17 #include "chrome/browser/lifetime/application_lifetime.h" |
19 #include "chromeos/cryptohome/async_method_caller.h" | 18 #include "chromeos/cryptohome/async_method_caller.h" |
20 #include "chromeos/cryptohome/cryptohome_library.h" | 19 #include "chromeos/cryptohome/cryptohome_library.h" |
21 #include "chromeos/dbus/cryptohome_client.h" | 20 #include "chromeos/dbus/cryptohome_client.h" |
22 #include "chromeos/dbus/dbus_thread_manager.h" | 21 #include "chromeos/dbus/dbus_thread_manager.h" |
23 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
24 | 23 |
25 using content::BrowserThread; | 24 using content::BrowserThread; |
26 | 25 |
27 namespace chromeos { | 26 namespace chromeos { |
28 | 27 |
29 namespace { | 28 namespace { |
30 | 29 |
31 void IgnoreResult(bool mount_success, cryptohome::MountError mount_error) {} | 30 void IgnoreResult(bool mount_success, cryptohome::MountError mount_error) {} |
32 | 31 |
33 } // namespace | 32 } // namespace |
34 | 33 |
35 // static | |
36 KioskAppLauncher* KioskAppLauncher::running_instance_ = NULL; | |
37 | |
38 //////////////////////////////////////////////////////////////////////////////// | 34 //////////////////////////////////////////////////////////////////////////////// |
39 // KioskAppLauncher::CryptohomedChecker ensures cryptohome daemon is up | 35 // KioskProfileLoader::CryptohomedChecker ensures cryptohome daemon is up |
40 // and running by issuing an IsMounted call. If the call does not go through | 36 // and running by issuing an IsMounted call. If the call does not go through |
41 // and chromeos::DBUS_METHOD_CALL_SUCCESS is not returned, it will retry after | 37 // and chromeos::DBUS_METHOD_CALL_SUCCESS is not returned, it will retry after |
42 // some time out and at the maximum five times before it gives up. Upon | 38 // some time out and at the maximum five times before it gives up. Upon |
43 // success, it resumes the launch by calling KioskAppLauncher::StartMount. | 39 // success, it resumes the launch by calling KioskProfileLoader::StartMount. |
44 | 40 |
45 class KioskAppLauncher::CryptohomedChecker | 41 class KioskProfileLoader::CryptohomedChecker |
46 : public base::SupportsWeakPtr<CryptohomedChecker> { | 42 : public base::SupportsWeakPtr<CryptohomedChecker> { |
47 public: | 43 public: |
48 explicit CryptohomedChecker(KioskAppLauncher* launcher) | 44 explicit CryptohomedChecker(KioskProfileLoader* loader) |
49 : launcher_(launcher), | 45 : loader_(loader), |
50 retry_count_(0) { | 46 retry_count_(0) { |
51 } | 47 } |
52 ~CryptohomedChecker() {} | 48 ~CryptohomedChecker() {} |
53 | 49 |
54 void StartCheck() { | 50 void StartCheck() { |
55 chromeos::DBusThreadManager::Get()->GetCryptohomeClient()->IsMounted( | 51 chromeos::DBusThreadManager::Get()->GetCryptohomeClient()->IsMounted( |
56 base::Bind(&CryptohomedChecker::OnCryptohomeIsMounted, | 52 base::Bind(&CryptohomedChecker::OnCryptohomeIsMounted, |
57 AsWeakPtr())); | 53 AsWeakPtr())); |
58 } | 54 } |
59 | 55 |
(...skipping 22 matching lines...) Expand all Loading... |
82 | 78 |
83 // Proceed only when cryptohome is not mounded or running on dev box. | 79 // Proceed only when cryptohome is not mounded or running on dev box. |
84 if (!is_mounted || !base::chromeos::IsRunningOnChromeOS()) | 80 if (!is_mounted || !base::chromeos::IsRunningOnChromeOS()) |
85 ReportCheckResult(KioskAppLaunchError::NONE); | 81 ReportCheckResult(KioskAppLaunchError::NONE); |
86 else | 82 else |
87 ReportCheckResult(KioskAppLaunchError::ALREADY_MOUNTED); | 83 ReportCheckResult(KioskAppLaunchError::ALREADY_MOUNTED); |
88 } | 84 } |
89 | 85 |
90 void ReportCheckResult(KioskAppLaunchError::Error error) { | 86 void ReportCheckResult(KioskAppLaunchError::Error error) { |
91 if (error == KioskAppLaunchError::NONE) | 87 if (error == KioskAppLaunchError::NONE) |
92 launcher_->StartMount(); | 88 loader_->StartMount(); |
93 else | 89 else |
94 launcher_->ReportLaunchResult(error); | 90 loader_->ReportLaunchResult(error); |
95 } | 91 } |
96 | 92 |
97 KioskAppLauncher* launcher_; | 93 KioskProfileLoader* loader_; |
98 int retry_count_; | 94 int retry_count_; |
99 | 95 |
100 DISALLOW_COPY_AND_ASSIGN(CryptohomedChecker); | 96 DISALLOW_COPY_AND_ASSIGN(CryptohomedChecker); |
101 }; | 97 }; |
102 | 98 |
103 //////////////////////////////////////////////////////////////////////////////// | 99 //////////////////////////////////////////////////////////////////////////////// |
104 // KioskAppLauncher::ProfileLoader creates or loads the app profile. | 100 // KioskProfileLoader::ProfileLoader actually creates or loads the app profile. |
105 | 101 |
106 class KioskAppLauncher::ProfileLoader : public LoginUtils::Delegate { | 102 class KioskProfileLoader::ProfileLoader : public LoginUtils::Delegate { |
107 public: | 103 public: |
108 ProfileLoader(KioskAppManager* kiosk_app_manager, | 104 ProfileLoader(KioskAppManager* kiosk_app_manager, |
109 KioskAppLauncher* kiosk_app_launcher) | 105 KioskProfileLoader* kiosk_profile_loader) |
110 : kiosk_app_launcher_(kiosk_app_launcher), | 106 : kiosk_profile_loader_(kiosk_profile_loader), |
111 user_id_(kiosk_app_launcher->user_id_) { | 107 user_id_(kiosk_profile_loader->user_id_) { |
112 CHECK(!user_id_.empty()); | 108 CHECK(!user_id_.empty()); |
113 } | 109 } |
114 | 110 |
115 virtual ~ProfileLoader() { | 111 virtual ~ProfileLoader() { |
116 LoginUtils::Get()->DelegateDeleted(this); | 112 LoginUtils::Get()->DelegateDeleted(this); |
117 } | 113 } |
118 | 114 |
119 void Start() { | 115 void Start() { |
120 cryptohome::AsyncMethodCaller::GetInstance()->AsyncGetSanitizedUsername( | 116 cryptohome::AsyncMethodCaller::GetInstance()->AsyncGetSanitizedUsername( |
121 user_id_, | 117 user_id_, |
122 base::Bind(&ProfileLoader::OnUsernameHashRetrieved, | 118 base::Bind(&ProfileLoader::OnUsernameHashRetrieved, |
123 base::Unretained(this))); | 119 base::Unretained(this))); |
124 } | 120 } |
125 | 121 |
126 private: | 122 private: |
127 void OnUsernameHashRetrieved(bool success, | 123 void OnUsernameHashRetrieved(bool success, |
128 const std::string& username_hash) { | 124 const std::string& username_hash) { |
129 if (!success) { | 125 if (!success) { |
130 LOG(ERROR) << "Unable to retrieve username hash for user '" << user_id_ | 126 LOG(ERROR) << "Unable to retrieve username hash for user '" << user_id_ |
131 << "'."; | 127 << "'."; |
132 kiosk_app_launcher_->ReportLaunchResult( | 128 kiosk_profile_loader_->ReportLaunchResult( |
133 KioskAppLaunchError::UNABLE_TO_RETRIEVE_HASH); | 129 KioskAppLaunchError::UNABLE_TO_RETRIEVE_HASH); |
134 return; | 130 return; |
135 } | 131 } |
136 LoginUtils::Get()->PrepareProfile( | 132 LoginUtils::Get()->PrepareProfile( |
137 UserContext(user_id_, | 133 UserContext(user_id_, |
138 std::string(), // password | 134 std::string(), // password |
139 std::string(), // auth_code | 135 std::string(), // auth_code |
140 username_hash), | 136 username_hash), |
141 std::string(), // display email | 137 std::string(), // display email |
142 false, // using_oauth | 138 false, // using_oauth |
143 false, // has_cookies | 139 false, // has_cookies |
144 false, // has_active_session | 140 false, // has_active_session |
145 this); | 141 this); |
146 } | 142 } |
147 | 143 |
148 // LoginUtils::Delegate overrides: | 144 // LoginUtils::Delegate overrides: |
149 virtual void OnProfilePrepared(Profile* profile) OVERRIDE { | 145 virtual void OnProfilePrepared(Profile* profile) OVERRIDE { |
150 kiosk_app_launcher_->OnProfilePrepared(profile); | 146 kiosk_profile_loader_->OnProfilePrepared(profile); |
151 } | 147 } |
152 | 148 |
153 KioskAppLauncher* kiosk_app_launcher_; | 149 KioskProfileLoader* kiosk_profile_loader_; |
154 std::string user_id_; | 150 std::string user_id_; |
155 | 151 |
156 DISALLOW_COPY_AND_ASSIGN(ProfileLoader); | 152 DISALLOW_COPY_AND_ASSIGN(ProfileLoader); |
157 }; | 153 }; |
158 | 154 |
159 //////////////////////////////////////////////////////////////////////////////// | 155 //////////////////////////////////////////////////////////////////////////////// |
160 // KioskAppLauncher | 156 // KioskProfileLoader |
161 | 157 |
162 KioskAppLauncher::KioskAppLauncher(KioskAppManager* kiosk_app_manager, | 158 KioskProfileLoader::KioskProfileLoader(KioskAppManager* kiosk_app_manager, |
163 const std::string& app_id) | 159 const std::string& app_id, |
| 160 Delegate* delegate) |
164 : kiosk_app_manager_(kiosk_app_manager), | 161 : kiosk_app_manager_(kiosk_app_manager), |
165 app_id_(app_id), | 162 app_id_(app_id), |
| 163 delegate_(delegate), |
166 remove_attempted_(false) { | 164 remove_attempted_(false) { |
167 KioskAppManager::App app; | 165 KioskAppManager::App app; |
168 CHECK(kiosk_app_manager_->GetApp(app_id_, &app)); | 166 CHECK(kiosk_app_manager_->GetApp(app_id_, &app)); |
169 user_id_ = app.user_id; | 167 user_id_ = app.user_id; |
170 } | 168 } |
171 | 169 |
172 KioskAppLauncher::~KioskAppLauncher() {} | 170 KioskProfileLoader::~KioskProfileLoader() {} |
173 | 171 |
174 void KioskAppLauncher::Start() { | 172 void KioskProfileLoader::Start() { |
175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
176 | 174 |
177 if (running_instance_) { | |
178 LOG(WARNING) << "Unable to launch " << app_id_ << "with a pending launch."; | |
179 ReportLaunchResult(KioskAppLaunchError::HAS_PENDING_LAUNCH); | |
180 return; | |
181 } | |
182 | |
183 running_instance_ = this; // Reset in ReportLaunchResult. | |
184 | |
185 // Show app launch splash. The spash is removed either after a successful | |
186 // launch or chrome exit because of launch failure. | |
187 chromeos::ShowAppLaunchSplashScreen(app_id_); | |
188 | |
189 // Check cryptohomed. If all goes good, flow goes to StartMount. Otherwise | 175 // Check cryptohomed. If all goes good, flow goes to StartMount. Otherwise |
190 // it goes to ReportLaunchResult with failure. | 176 // it goes to ReportLaunchResult with failure. |
191 crytohomed_checker.reset(new CryptohomedChecker(this)); | 177 crytohomed_checker.reset(new CryptohomedChecker(this)); |
192 crytohomed_checker->StartCheck(); | 178 crytohomed_checker->StartCheck(); |
193 } | 179 } |
194 | 180 |
195 void KioskAppLauncher::ReportLaunchResult(KioskAppLaunchError::Error error) { | 181 void KioskProfileLoader::ReportLaunchResult(KioskAppLaunchError::Error error) { |
196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
197 | 183 |
198 running_instance_ = NULL; | |
199 | |
200 if (error != KioskAppLaunchError::NONE) { | 184 if (error != KioskAppLaunchError::NONE) { |
201 // Saves the error and ends the session to go back to login screen. | |
202 KioskAppLaunchError::Save(error); | 185 KioskAppLaunchError::Save(error); |
203 chrome::AttemptUserExit(); | 186 delegate_->OnProfileLoadFailed(error); |
204 } | 187 } |
205 | 188 |
206 delete this; | 189 delete this; |
207 } | 190 } |
208 | 191 |
209 void KioskAppLauncher::StartMount() { | 192 void KioskProfileLoader::StartMount() { |
210 // Nuke old home that uses |app_id_| as cryptohome user id. | 193 // Nuke old home that uses |app_id_| as cryptohome user id. |
211 // TODO(xiyuan): Remove this after all clients migrated to new home. | 194 // TODO(xiyuan): Remove this after all clients migrated to new home. |
212 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( | 195 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( |
213 app_id_, | 196 app_id_, |
214 base::Bind(&IgnoreResult)); | 197 base::Bind(&IgnoreResult)); |
215 | 198 |
216 cryptohome::AsyncMethodCaller::GetInstance()->AsyncMountPublic( | 199 cryptohome::AsyncMethodCaller::GetInstance()->AsyncMountPublic( |
217 user_id_, | 200 user_id_, |
218 cryptohome::CREATE_IF_MISSING, | 201 cryptohome::CREATE_IF_MISSING, |
219 base::Bind(&KioskAppLauncher::MountCallback, | 202 base::Bind(&KioskProfileLoader::MountCallback, |
220 base::Unretained(this))); | 203 base::Unretained(this))); |
221 } | 204 } |
222 | 205 |
223 void KioskAppLauncher::MountCallback(bool mount_success, | 206 void KioskProfileLoader::MountCallback(bool mount_success, |
224 cryptohome::MountError mount_error) { | 207 cryptohome::MountError mount_error) { |
225 if (mount_success) { | 208 if (mount_success) { |
226 profile_loader_.reset(new ProfileLoader(kiosk_app_manager_, this)); | 209 profile_loader_.reset(new ProfileLoader(kiosk_app_manager_, this)); |
227 profile_loader_->Start(); | 210 profile_loader_->Start(); |
228 return; | 211 return; |
229 } | 212 } |
230 | 213 |
231 if (!remove_attempted_) { | 214 if (!remove_attempted_) { |
232 LOG(ERROR) << "Attempt to remove app cryptohome because of mount failure" | 215 LOG(ERROR) << "Attempt to remove app cryptohome because of mount failure" |
233 << ", mount error=" << mount_error; | 216 << ", mount error=" << mount_error; |
234 | 217 |
235 remove_attempted_ = true; | 218 remove_attempted_ = true; |
236 AttemptRemove(); | 219 AttemptRemove(); |
237 return; | 220 return; |
238 } | 221 } |
239 | 222 |
240 LOG(ERROR) << "Failed to mount app cryptohome, error=" << mount_error; | 223 LOG(ERROR) << "Failed to mount app cryptohome, error=" << mount_error; |
241 ReportLaunchResult(KioskAppLaunchError::UNABLE_TO_MOUNT); | 224 ReportLaunchResult(KioskAppLaunchError::UNABLE_TO_MOUNT); |
242 } | 225 } |
243 | 226 |
244 void KioskAppLauncher::AttemptRemove() { | 227 void KioskProfileLoader::AttemptRemove() { |
245 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( | 228 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( |
246 user_id_, | 229 user_id_, |
247 base::Bind(&KioskAppLauncher::RemoveCallback, | 230 base::Bind(&KioskProfileLoader::RemoveCallback, |
248 base::Unretained(this))); | 231 base::Unretained(this))); |
249 } | 232 } |
250 | 233 |
251 void KioskAppLauncher::RemoveCallback(bool success, | 234 void KioskProfileLoader::RemoveCallback(bool success, |
252 cryptohome::MountError return_code) { | 235 cryptohome::MountError return_code) { |
253 if (success) { | 236 if (success) { |
254 StartMount(); | 237 StartMount(); |
255 return; | 238 return; |
256 } | 239 } |
257 | 240 |
258 LOG(ERROR) << "Failed to remove app cryptohome, erro=" << return_code; | 241 LOG(ERROR) << "Failed to remove app cryptohome, error=" << return_code; |
259 ReportLaunchResult(KioskAppLaunchError::UNABLE_TO_REMOVE); | 242 ReportLaunchResult(KioskAppLaunchError::UNABLE_TO_REMOVE); |
260 } | 243 } |
261 | 244 |
262 void KioskAppLauncher::OnProfilePrepared(Profile* profile) { | 245 void KioskProfileLoader::OnProfilePrepared(Profile* profile) { |
263 // StartupAppLauncher deletes itself when done. | |
264 (new chromeos::StartupAppLauncher(profile, app_id_))->Start(); | |
265 | |
266 if (LoginDisplayHostImpl::default_host()) | |
267 LoginDisplayHostImpl::default_host()->Finalize(); | |
268 UserManager::Get()->SessionStarted(); | 246 UserManager::Get()->SessionStarted(); |
269 | 247 delegate_->OnProfileLoaded(profile); |
270 ReportLaunchResult(KioskAppLaunchError::NONE); | 248 ReportLaunchResult(KioskAppLaunchError::NONE); |
271 } | 249 } |
272 | 250 |
273 } // namespace chromeos | 251 } // namespace chromeos |
OLD | NEW |