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