OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/android/webapk/webapk_installer.h" | 5 #include "chrome/browser/android/webapk/webapk_installer.h" |
6 | 6 |
7 #include "base/android/build_info.h" | 7 #include "base/android/build_info.h" |
8 #include "base/android/jni_android.h" | 8 #include "base/android/jni_android.h" |
9 #include "base/android/jni_string.h" | 9 #include "base/android/jni_string.h" |
10 #include "base/android/path_utils.h" | 10 #include "base/android/path_utils.h" |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
pkotwicz
2017/04/04 19:06:07
Nit: You can remove this include
Yaron
2017/04/04 19:49:08
Done.
| |
14 #include "base/files/file_util.h" | 14 #include "base/files/file_util.h" |
pkotwicz
2017/04/04 19:06:07
Nit: You can remove this include
Yaron
2017/04/04 19:49:08
Done.
| |
15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
16 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
17 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
18 #include "base/strings/stringprintf.h" | 18 #include "base/strings/stringprintf.h" |
19 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
20 #include "base/task_runner_util.h" | 20 #include "base/task_runner_util.h" |
21 #include "base/threading/sequenced_worker_pool.h" | 21 #include "base/threading/sequenced_worker_pool.h" |
22 #include "base/timer/elapsed_timer.h" | 22 #include "base/timer/elapsed_timer.h" |
23 #include "chrome/browser/android/shortcut_helper.h" | 23 #include "chrome/browser/android/shortcut_helper.h" |
24 #include "chrome/browser/android/webapk/chrome_webapk_host.h" | 24 #include "chrome/browser/android/webapk/chrome_webapk_host.h" |
(...skipping 22 matching lines...) Expand all Loading... | |
47 "https://webapk.googleapis.com/v1/webApks/" | 47 "https://webapk.googleapis.com/v1/webApks/" |
48 "?alt=proto&key=AIzaSyAoI6v-F31-3t9NunLYEiKcPIqgTJIUZBw"; | 48 "?alt=proto&key=AIzaSyAoI6v-F31-3t9NunLYEiKcPIqgTJIUZBw"; |
49 | 49 |
50 // The MIME type of the POST data sent to the server. | 50 // The MIME type of the POST data sent to the server. |
51 const char kProtoMimeType[] = "application/x-protobuf"; | 51 const char kProtoMimeType[] = "application/x-protobuf"; |
52 | 52 |
53 // The default number of milliseconds to wait for the WebAPK download URL from | 53 // The default number of milliseconds to wait for the WebAPK download URL from |
54 // the WebAPK server. | 54 // the WebAPK server. |
55 const int kWebApkDownloadUrlTimeoutMs = 60000; | 55 const int kWebApkDownloadUrlTimeoutMs = 60000; |
56 | 56 |
57 // The default number of milliseconds to wait for the WebAPK download to | |
58 // complete. | |
59 const int kDownloadTimeoutMs = 60000; | |
60 | |
61 const int kWorldReadableFilePermission = base::FILE_PERMISSION_READ_BY_USER | | |
62 base::FILE_PERMISSION_READ_BY_GROUP | | |
63 base::FILE_PERMISSION_READ_BY_OTHERS; | |
64 const int kDefaultWebApkVersion = 1; | |
65 | |
66 // Returns the WebAPK server URL based on the command line. | 57 // Returns the WebAPK server URL based on the command line. |
67 GURL GetServerUrl() { | 58 GURL GetServerUrl() { |
68 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 59 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
69 GURL command_line_url( | 60 GURL command_line_url( |
70 command_line->GetSwitchValueASCII(switches::kWebApkServerUrl)); | 61 command_line->GetSwitchValueASCII(switches::kWebApkServerUrl)); |
71 return command_line_url.is_valid() ? command_line_url | 62 return command_line_url.is_valid() ? command_line_url |
72 : GURL(kDefaultServerUrl); | 63 : GURL(kDefaultServerUrl); |
73 } | 64 } |
74 | 65 |
75 // Returns the scope from |info| if it is specified. Otherwise, returns the | 66 // Returns the scope from |info| if it is specified. Otherwise, returns the |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
170 callback.Run(std::move(webapk)); | 161 callback.Run(std::move(webapk)); |
171 } | 162 } |
172 | 163 |
173 // Returns task runner for running background tasks. | 164 // Returns task runner for running background tasks. |
174 scoped_refptr<base::TaskRunner> GetBackgroundTaskRunner() { | 165 scoped_refptr<base::TaskRunner> GetBackgroundTaskRunner() { |
175 return content::BrowserThread::GetBlockingPool() | 166 return content::BrowserThread::GetBlockingPool() |
176 ->GetTaskRunnerWithShutdownBehavior( | 167 ->GetTaskRunnerWithShutdownBehavior( |
177 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); | 168 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
178 } | 169 } |
179 | 170 |
180 // Creates a directory depending on the type of the task, and set permissions. | |
181 // It also creates any parent directory along the path if doesn't exist, | |
182 // and sets permissions as well. | |
183 // The previously downloaded APKs are deleted in order to clean up unused cached | |
184 // data. | |
185 base::FilePath CreateSubDirAndSetPermissionsInBackground( | |
186 const base::StringPiece& output_dir_name, | |
187 const std::string& package_name) { | |
188 base::FilePath output_root_dir; | |
189 base::android::GetCacheDirectory(&output_root_dir); | |
190 base::FilePath webapk_dir = output_root_dir.AppendASCII("webapks"); | |
191 // Creating different downloaded directory for install/update cases is | |
192 // to prevent deleting the APK which is still in use when an install and an | |
193 // update happen at the same time. However, it doesn't help the cases of when | |
194 // mutiple installs (or multiple updates) happen at the same time. | |
195 base::FilePath output_dir = webapk_dir.AppendASCII(output_dir_name); | |
196 int posix_permissions = kWorldReadableFilePermission | | |
197 base::FILE_PERMISSION_WRITE_BY_USER | | |
198 base::FILE_PERMISSION_EXECUTE_BY_USER | | |
199 base::FILE_PERMISSION_EXECUTE_BY_OTHERS; | |
200 if (base::PathExists(output_dir)) | |
201 base::DeleteFile(output_dir, true); | |
202 | |
203 // Creates the directory to download and sets permissions. | |
204 if (!base::CreateDirectory(output_dir) || | |
205 !base::SetPosixFilePermissions(webapk_dir, posix_permissions) || | |
206 !base::SetPosixFilePermissions(output_dir, posix_permissions)) | |
207 return base::FilePath(); | |
208 | |
209 return output_dir; | |
210 } | |
211 | |
212 } // anonymous namespace | 171 } // anonymous namespace |
213 | 172 |
214 WebApkInstaller::~WebApkInstaller() { | 173 WebApkInstaller::~WebApkInstaller() { |
215 JNIEnv* env = base::android::AttachCurrentThread(); | 174 JNIEnv* env = base::android::AttachCurrentThread(); |
216 Java_WebApkInstaller_destroy(env, java_ref_); | 175 Java_WebApkInstaller_destroy(env, java_ref_); |
217 java_ref_.Reset(); | 176 java_ref_.Reset(); |
218 } | 177 } |
219 | 178 |
220 // static | 179 // static |
221 void WebApkInstaller::InstallAsync(content::BrowserContext* context, | 180 void WebApkInstaller::InstallAsync(content::BrowserContext* context, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
260 int webapk_version, | 219 int webapk_version, |
261 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, | 220 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, |
262 bool is_manifest_stale, | 221 bool is_manifest_stale, |
263 const FinishCallback& finish_callback) { | 222 const FinishCallback& finish_callback) { |
264 installer->UpdateAsync(webapk_package, webapk_version, | 223 installer->UpdateAsync(webapk_package, webapk_version, |
265 icon_url_to_murmur2_hash, is_manifest_stale, | 224 icon_url_to_murmur2_hash, is_manifest_stale, |
266 finish_callback); | 225 finish_callback); |
267 } | 226 } |
268 | 227 |
269 void WebApkInstaller::SetTimeoutMs(int timeout_ms) { | 228 void WebApkInstaller::SetTimeoutMs(int timeout_ms) { |
270 webapk_download_url_timeout_ms_ = timeout_ms; | 229 webapk_server_timeout_ms_ = timeout_ms; |
271 download_timeout_ms_ = timeout_ms; | |
272 } | 230 } |
273 | 231 |
274 void WebApkInstaller::OnInstallFinished( | 232 void WebApkInstaller::OnInstallFinished( |
275 JNIEnv* env, | 233 JNIEnv* env, |
276 const base::android::JavaParamRef<jobject>& obj, | 234 const base::android::JavaParamRef<jobject>& obj, |
277 jint result) { | 235 jint result) { |
278 OnResult(static_cast<WebApkInstallResult>(result)); | 236 OnResult(static_cast<WebApkInstallResult>(result)); |
279 } | 237 } |
280 | 238 |
281 void WebApkInstaller::BuildWebApkProtoInBackgroundForTesting( | 239 void WebApkInstaller::BuildWebApkProtoInBackgroundForTesting( |
282 const base::Callback<void(std::unique_ptr<webapk::WebApk>)>& callback, | 240 const base::Callback<void(std::unique_ptr<webapk::WebApk>)>& callback, |
283 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, | 241 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, |
284 bool is_manifest_stale) { | 242 bool is_manifest_stale) { |
285 base::PostTaskAndReplyWithResult( | 243 base::PostTaskAndReplyWithResult( |
286 GetBackgroundTaskRunner().get(), FROM_HERE, | 244 GetBackgroundTaskRunner().get(), FROM_HERE, |
287 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_, | 245 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_, |
288 icon_url_to_murmur2_hash, is_manifest_stale), | 246 icon_url_to_murmur2_hash, is_manifest_stale), |
289 base::Bind(&OnWebApkProtoBuilt, callback)); | 247 base::Bind(&OnWebApkProtoBuilt, callback)); |
290 } | 248 } |
291 | 249 |
292 // static | 250 // static |
293 bool WebApkInstaller::Register(JNIEnv* env) { | 251 bool WebApkInstaller::Register(JNIEnv* env) { |
294 return RegisterNativesImpl(env); | 252 return RegisterNativesImpl(env); |
295 } | 253 } |
296 | 254 |
297 void WebApkInstaller::InstallDownloadedWebApk( | 255 bool WebApkInstaller::CanInstallWebApks() { |
298 JNIEnv* env, | |
299 const base::android::ScopedJavaLocalRef<jstring>& java_file_path, | |
300 const base::android::ScopedJavaLocalRef<jstring>& java_package_name) { | |
301 Java_WebApkInstaller_installDownloadedWebApkAsync( | |
302 env, java_ref_, java_file_path, java_package_name); | |
303 } | |
304 | |
305 void WebApkInstaller::UpdateUsingDownloadedWebApk( | |
306 JNIEnv* env, | |
307 const base::android::ScopedJavaLocalRef<jstring>& java_file_path) { | |
308 Java_WebApkInstaller_updateUsingDownloadedWebApkAsync(env, java_ref_, | |
309 java_file_path); | |
310 } | |
311 | |
312 bool WebApkInstaller::CanUseGooglePlayInstallService() { | |
313 return ChromeWebApkHost::GetGooglePlayInstallState() == | 256 return ChromeWebApkHost::GetGooglePlayInstallState() == |
314 GooglePlayInstallState::SUPPORTED; | 257 GooglePlayInstallState::SUPPORTED; |
315 } | 258 } |
316 | 259 |
317 void WebApkInstaller::InstallOrUpdateWebApkFromGooglePlay( | 260 void WebApkInstaller::InstallOrUpdateWebApk(const std::string& package_name, |
318 const std::string& package_name, | 261 int version, |
319 int version, | 262 const std::string& token) { |
320 const std::string& token) { | |
321 webapk_package_ = package_name; | 263 webapk_package_ = package_name; |
322 | 264 |
323 JNIEnv* env = base::android::AttachCurrentThread(); | 265 JNIEnv* env = base::android::AttachCurrentThread(); |
324 base::android::ScopedJavaLocalRef<jstring> java_webapk_package = | 266 base::android::ScopedJavaLocalRef<jstring> java_webapk_package = |
325 base::android::ConvertUTF8ToJavaString(env, webapk_package_); | 267 base::android::ConvertUTF8ToJavaString(env, webapk_package_); |
326 base::android::ScopedJavaLocalRef<jstring> java_title = | 268 base::android::ScopedJavaLocalRef<jstring> java_title = |
327 base::android::ConvertUTF16ToJavaString(env, shortcut_info_.user_title); | 269 base::android::ConvertUTF16ToJavaString(env, shortcut_info_.user_title); |
328 base::android::ScopedJavaLocalRef<jstring> java_token = | 270 base::android::ScopedJavaLocalRef<jstring> java_token = |
329 base::android::ConvertUTF8ToJavaString(env, token); | 271 base::android::ConvertUTF8ToJavaString(env, token); |
330 base::android::ScopedJavaLocalRef<jstring> java_url = | 272 base::android::ScopedJavaLocalRef<jstring> java_url = |
331 base::android::ConvertUTF8ToJavaString(env, shortcut_info_.url.spec()); | 273 base::android::ConvertUTF8ToJavaString(env, shortcut_info_.url.spec()); |
332 | 274 |
333 if (task_type_ == WebApkInstaller::INSTALL) { | 275 if (task_type_ == WebApkInstaller::INSTALL) { |
334 Java_WebApkInstaller_installWebApkFromGooglePlayAsync( | 276 Java_WebApkInstaller_installWebApkAsync(env, java_ref_, java_webapk_package, |
335 env, java_ref_, java_webapk_package, version, java_title, java_token, | 277 version, java_title, java_token, |
336 java_url); | 278 java_url); |
337 } else { | 279 } else { |
338 Java_WebApkInstaller_updateAsyncFromGooglePlay( | 280 Java_WebApkInstaller_updateAsync(env, java_ref_, java_webapk_package, |
339 env, java_ref_, java_webapk_package, version, java_title, java_token, | 281 version, java_title, java_token, java_url); |
340 java_url); | |
341 } | 282 } |
342 } | 283 } |
343 | 284 |
344 void WebApkInstaller::OnResult(WebApkInstallResult result) { | 285 void WebApkInstaller::OnResult(WebApkInstallResult result) { |
345 weak_ptr_factory_.InvalidateWeakPtrs(); | 286 weak_ptr_factory_.InvalidateWeakPtrs(); |
346 finish_callback_.Run(result, relax_updates_, webapk_package_); | 287 finish_callback_.Run(result, relax_updates_, webapk_package_); |
347 | 288 |
348 if (task_type_ == WebApkInstaller::INSTALL) { | 289 if (task_type_ == WebApkInstaller::INSTALL) { |
349 if (result == WebApkInstallResult::SUCCESS) { | 290 if (result == WebApkInstallResult::SUCCESS) { |
350 webapk::TrackInstallDuration(install_duration_timer_->Elapsed()); | 291 webapk::TrackInstallDuration(install_duration_timer_->Elapsed()); |
351 webapk::TrackInstallEvent(webapk::INSTALL_COMPLETED); | 292 webapk::TrackInstallEvent(webapk::INSTALL_COMPLETED); |
352 } else { | 293 } else { |
353 DVLOG(1) << "The WebAPK installation failed."; | 294 DVLOG(1) << "The WebAPK installation failed."; |
354 webapk::TrackInstallEvent(webapk::INSTALL_FAILED); | 295 webapk::TrackInstallEvent(webapk::INSTALL_FAILED); |
355 } | 296 } |
356 } | 297 } |
357 | 298 |
358 delete this; | 299 delete this; |
359 } | 300 } |
360 | 301 |
361 WebApkInstaller::WebApkInstaller(content::BrowserContext* browser_context, | 302 WebApkInstaller::WebApkInstaller(content::BrowserContext* browser_context, |
362 const ShortcutInfo& shortcut_info, | 303 const ShortcutInfo& shortcut_info, |
363 const SkBitmap& shortcut_icon) | 304 const SkBitmap& shortcut_icon) |
364 : request_context_getter_( | 305 : request_context_getter_( |
365 Profile::FromBrowserContext(browser_context)->GetRequestContext()), | 306 Profile::FromBrowserContext(browser_context)->GetRequestContext()), |
366 shortcut_info_(shortcut_info), | 307 shortcut_info_(shortcut_info), |
367 shortcut_icon_(shortcut_icon), | 308 shortcut_icon_(shortcut_icon), |
368 server_url_(GetServerUrl()), | 309 server_url_(GetServerUrl()), |
369 webapk_download_url_timeout_ms_(kWebApkDownloadUrlTimeoutMs), | 310 webapk_server_timeout_ms_(kWebApkDownloadUrlTimeoutMs), |
370 download_timeout_ms_(kDownloadTimeoutMs), | |
371 relax_updates_(false), | 311 relax_updates_(false), |
372 webapk_version_(kDefaultWebApkVersion), | |
373 task_type_(UNDEFINED), | 312 task_type_(UNDEFINED), |
374 weak_ptr_factory_(this) { | 313 weak_ptr_factory_(this) { |
375 CreateJavaRef(); | 314 CreateJavaRef(); |
376 } | 315 } |
377 | 316 |
378 void WebApkInstaller::CreateJavaRef() { | 317 void WebApkInstaller::CreateJavaRef() { |
379 JNIEnv* env = base::android::AttachCurrentThread(); | 318 JNIEnv* env = base::android::AttachCurrentThread(); |
380 java_ref_.Reset( | 319 java_ref_.Reset( |
381 Java_WebApkInstaller_create(env, reinterpret_cast<intptr_t>(this))); | 320 Java_WebApkInstaller_create(env, reinterpret_cast<intptr_t>(this))); |
382 } | 321 } |
(...skipping 18 matching lines...) Expand all Loading... | |
401 weak_ptr_factory_.GetWeakPtr())); | 340 weak_ptr_factory_.GetWeakPtr())); |
402 } | 341 } |
403 | 342 |
404 void WebApkInstaller::UpdateAsync( | 343 void WebApkInstaller::UpdateAsync( |
405 const std::string& webapk_package, | 344 const std::string& webapk_package, |
406 int webapk_version, | 345 int webapk_version, |
407 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, | 346 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, |
408 bool is_manifest_stale, | 347 bool is_manifest_stale, |
409 const FinishCallback& finish_callback) { | 348 const FinishCallback& finish_callback) { |
410 webapk_package_ = webapk_package; | 349 webapk_package_ = webapk_package; |
411 webapk_version_ = webapk_version; | |
412 finish_callback_ = finish_callback; | 350 finish_callback_ = finish_callback; |
413 task_type_ = UPDATE; | 351 task_type_ = UPDATE; |
414 | 352 |
415 base::PostTaskAndReplyWithResult( | 353 base::PostTaskAndReplyWithResult( |
416 GetBackgroundTaskRunner().get(), FROM_HERE, | 354 GetBackgroundTaskRunner().get(), FROM_HERE, |
417 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_, | 355 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_, |
418 icon_url_to_murmur2_hash, is_manifest_stale), | 356 icon_url_to_murmur2_hash, is_manifest_stale), |
419 base::Bind(&WebApkInstaller::SendUpdateWebApkRequest, | 357 base::Bind(&WebApkInstaller::SendUpdateWebApkRequest, |
420 weak_ptr_factory_.GetWeakPtr())); | 358 weak_ptr_factory_.GetWeakPtr(), webapk_version)); |
421 } | 359 } |
422 | 360 |
423 void WebApkInstaller::OnURLFetchComplete(const net::URLFetcher* source) { | 361 void WebApkInstaller::OnURLFetchComplete(const net::URLFetcher* source) { |
424 timer_.Stop(); | 362 timer_.Stop(); |
425 | 363 |
426 if (!source->GetStatus().is_success() || | 364 if (!source->GetStatus().is_success() || |
427 source->GetResponseCode() != net::HTTP_OK) { | 365 source->GetResponseCode() != net::HTTP_OK) { |
428 LOG(WARNING) << base::StringPrintf( | 366 LOG(WARNING) << base::StringPrintf( |
429 "WebAPK server returned response code %d.", source->GetResponseCode()); | 367 "WebAPK server returned response code %d.", source->GetResponseCode()); |
430 OnResult(WebApkInstallResult::FAILURE); | 368 OnResult(WebApkInstallResult::FAILURE); |
431 return; | 369 return; |
432 } | 370 } |
433 | 371 |
434 std::string response_string; | 372 std::string response_string; |
435 source->GetResponseAsString(&response_string); | 373 source->GetResponseAsString(&response_string); |
436 | 374 |
437 std::unique_ptr<webapk::WebApkResponse> response(new webapk::WebApkResponse); | 375 std::unique_ptr<webapk::WebApkResponse> response(new webapk::WebApkResponse); |
438 if (!response->ParseFromString(response_string)) { | 376 if (!response->ParseFromString(response_string)) { |
439 LOG(WARNING) << "WebAPK server did not return proto."; | 377 LOG(WARNING) << "WebAPK server did not return proto."; |
440 OnResult(WebApkInstallResult::FAILURE); | 378 OnResult(WebApkInstallResult::FAILURE); |
441 return; | 379 return; |
442 } | 380 } |
443 | 381 |
444 GURL signed_download_url(response->signed_download_url()); | 382 GURL signed_download_url(response->signed_download_url()); |
445 if (task_type_ == UPDATE && signed_download_url.is_empty()) { | 383 if (task_type_ == UPDATE && signed_download_url.is_empty()) { |
pkotwicz
2017/04/04 19:06:07
In a separate CL, we should clean this up. Does th
Yaron
2017/04/04 19:49:08
I know it sends an empty URL but don't know about
hartmanng
2017/04/04 19:53:33
Yes, the server will send both an empty URL and an
Yaron
2017/04/04 19:56:58
Err but actually I don't expect play client to bac
| |
446 // https://crbug.com/680131. The server sends an empty URL if the server | 384 // https://crbug.com/680131. The server sends an empty URL if the server |
447 // does not have a newer WebAPK to update to. | 385 // does not have a newer WebAPK to update to. |
448 relax_updates_ = response->relax_updates(); | 386 relax_updates_ = response->relax_updates(); |
449 OnResult(WebApkInstallResult::SUCCESS); | 387 OnResult(WebApkInstallResult::SUCCESS); |
450 return; | 388 return; |
451 } | 389 } |
452 | 390 |
453 if (!signed_download_url.is_valid() || response->package_name().empty()) { | 391 if (!signed_download_url.is_valid() || response->package_name().empty()) { |
454 LOG(WARNING) << "WebAPK server returned incomplete proto."; | 392 LOG(WARNING) << "WebAPK server returned incomplete proto."; |
455 OnResult(WebApkInstallResult::FAILURE); | 393 OnResult(WebApkInstallResult::FAILURE); |
456 return; | 394 return; |
457 } | 395 } |
458 | 396 |
459 if (CanUseGooglePlayInstallService()) { | 397 if (!CanInstallWebApks()) { |
460 int version = 1; | 398 OnResult(WebApkInstallResult::FAILURE); |
461 base::StringToInt(response->version(), &version); | |
462 InstallOrUpdateWebApkFromGooglePlay(response->package_name(), version, | |
463 response->token()); | |
464 return; | 399 return; |
465 } | 400 } |
466 | 401 |
467 OnGotWebApkDownloadUrl(signed_download_url, response->package_name()); | 402 int version = 1; |
403 base::StringToInt(response->version(), &version); | |
404 InstallOrUpdateWebApk(response->package_name(), version, response->token()); | |
468 } | 405 } |
469 | 406 |
470 void WebApkInstaller::OnGotIconMurmur2Hash( | 407 void WebApkInstaller::OnGotIconMurmur2Hash( |
471 const std::string& icon_murmur2_hash) { | 408 const std::string& icon_murmur2_hash) { |
472 // An empty hash indicates that |icon_hasher_| encountered an error. | 409 // An empty hash indicates that |icon_hasher_| encountered an error. |
473 if (icon_murmur2_hash.empty()) { | 410 if (icon_murmur2_hash.empty()) { |
474 OnResult(WebApkInstallResult::FAILURE); | 411 OnResult(WebApkInstallResult::FAILURE); |
475 return; | 412 return; |
476 } | 413 } |
477 | 414 |
(...skipping 12 matching lines...) Expand all Loading... | |
490 base::Bind(&WebApkInstaller::SendCreateWebApkRequest, | 427 base::Bind(&WebApkInstaller::SendCreateWebApkRequest, |
491 weak_ptr_factory_.GetWeakPtr())); | 428 weak_ptr_factory_.GetWeakPtr())); |
492 } | 429 } |
493 | 430 |
494 void WebApkInstaller::SendCreateWebApkRequest( | 431 void WebApkInstaller::SendCreateWebApkRequest( |
495 std::unique_ptr<webapk::WebApk> webapk) { | 432 std::unique_ptr<webapk::WebApk> webapk) { |
496 SendRequest(std::move(webapk), server_url_); | 433 SendRequest(std::move(webapk), server_url_); |
497 } | 434 } |
498 | 435 |
499 void WebApkInstaller::SendUpdateWebApkRequest( | 436 void WebApkInstaller::SendUpdateWebApkRequest( |
437 int webapk_version, | |
500 std::unique_ptr<webapk::WebApk> webapk) { | 438 std::unique_ptr<webapk::WebApk> webapk) { |
501 webapk->set_package_name(webapk_package_); | 439 webapk->set_package_name(webapk_package_); |
502 webapk->set_version(std::to_string(webapk_version_)); | 440 webapk->set_version(std::to_string(webapk_version)); |
503 | 441 |
504 SendRequest(std::move(webapk), server_url_); | 442 SendRequest(std::move(webapk), server_url_); |
505 } | 443 } |
506 | 444 |
507 void WebApkInstaller::SendRequest(std::unique_ptr<webapk::WebApk> request_proto, | 445 void WebApkInstaller::SendRequest(std::unique_ptr<webapk::WebApk> request_proto, |
508 const GURL& server_url) { | 446 const GURL& server_url) { |
509 timer_.Start( | 447 timer_.Start( |
510 FROM_HERE, | 448 FROM_HERE, base::TimeDelta::FromMilliseconds(webapk_server_timeout_ms_), |
511 base::TimeDelta::FromMilliseconds(webapk_download_url_timeout_ms_), | |
512 base::Bind(&WebApkInstaller::OnResult, weak_ptr_factory_.GetWeakPtr(), | 449 base::Bind(&WebApkInstaller::OnResult, weak_ptr_factory_.GetWeakPtr(), |
513 WebApkInstallResult::FAILURE)); | 450 WebApkInstallResult::FAILURE)); |
514 | 451 |
515 url_fetcher_ = | 452 url_fetcher_ = |
516 net::URLFetcher::Create(server_url, net::URLFetcher::POST, this); | 453 net::URLFetcher::Create(server_url, net::URLFetcher::POST, this); |
517 url_fetcher_->SetRequestContext(request_context_getter_); | 454 url_fetcher_->SetRequestContext(request_context_getter_); |
518 std::string serialized_request; | 455 std::string serialized_request; |
519 request_proto->SerializeToString(&serialized_request); | 456 request_proto->SerializeToString(&serialized_request); |
520 url_fetcher_->SetUploadData(kProtoMimeType, serialized_request); | 457 url_fetcher_->SetUploadData(kProtoMimeType, serialized_request); |
521 url_fetcher_->SetLoadFlags( | 458 url_fetcher_->SetLoadFlags( |
522 net::LOAD_DISABLE_CACHE | net::LOAD_DO_NOT_SEND_COOKIES | | 459 net::LOAD_DISABLE_CACHE | net::LOAD_DO_NOT_SEND_COOKIES | |
523 net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_AUTH_DATA); | 460 net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_AUTH_DATA); |
524 url_fetcher_->Start(); | 461 url_fetcher_->Start(); |
525 } | 462 } |
526 | |
527 void WebApkInstaller::OnGotWebApkDownloadUrl(const GURL& download_url, | |
528 const std::string& package_name) { | |
529 webapk_package_ = package_name; | |
530 | |
531 base::PostTaskAndReplyWithResult( | |
532 GetBackgroundTaskRunner().get(), FROM_HERE, | |
533 base::Bind(&CreateSubDirAndSetPermissionsInBackground, | |
534 task_type_ == WebApkInstaller::INSTALL ? "install" : "update", | |
535 package_name), | |
536 base::Bind(&WebApkInstaller::OnCreatedSubDirAndSetPermissions, | |
537 weak_ptr_factory_.GetWeakPtr(), download_url)); | |
538 } | |
539 | |
540 void WebApkInstaller::OnCreatedSubDirAndSetPermissions( | |
541 const GURL& download_url, | |
542 const base::FilePath& output_dir) { | |
543 if (output_dir.empty()) { | |
544 OnResult(WebApkInstallResult::FAILURE); | |
545 return; | |
546 } | |
547 | |
548 DownloadWebApk(output_dir.AppendASCII(webapk_package_ + ".apk"), download_url, | |
549 true); | |
550 } | |
551 | |
552 void WebApkInstaller::DownloadWebApk(const base::FilePath& output_path, | |
553 const GURL& download_url, | |
554 bool retry_if_fails) { | |
555 timer_.Start( | |
556 FROM_HERE, base::TimeDelta::FromMilliseconds(download_timeout_ms_), | |
557 base::Bind(&WebApkInstaller::OnResult, weak_ptr_factory_.GetWeakPtr(), | |
558 WebApkInstallResult::FAILURE)); | |
559 | |
560 downloader_.reset(new FileDownloader( | |
561 download_url, output_path, true, request_context_getter_, | |
562 base::Bind(&WebApkInstaller::OnWebApkDownloaded, | |
563 weak_ptr_factory_.GetWeakPtr(), output_path, download_url, | |
564 retry_if_fails), | |
565 NO_TRAFFIC_ANNOTATION_YET)); | |
566 } | |
567 | |
568 void WebApkInstaller::OnWebApkDownloaded(const base::FilePath& file_path, | |
569 const GURL& download_url, | |
570 bool retry_if_fails, | |
571 FileDownloader::Result result) { | |
572 timer_.Stop(); | |
573 | |
574 if (result != FileDownloader::DOWNLOADED) { | |
575 if (!retry_if_fails) { | |
576 OnResult(WebApkInstallResult::FAILURE); | |
577 return; | |
578 } | |
579 | |
580 content::BrowserThread::PostDelayedTask( | |
581 content::BrowserThread::UI, FROM_HERE, | |
582 base::Bind(&WebApkInstaller::DownloadWebApk, | |
583 weak_ptr_factory_.GetWeakPtr(), file_path, download_url, | |
584 false), | |
585 base::TimeDelta::FromSeconds(2)); | |
586 return; | |
587 } | |
588 | |
589 int posix_permissions = kWorldReadableFilePermission | | |
590 base::FILE_PERMISSION_WRITE_BY_USER | | |
591 base::FILE_PERMISSION_EXECUTE_BY_USER; | |
592 base::PostTaskAndReplyWithResult( | |
593 GetBackgroundTaskRunner().get(), FROM_HERE, | |
594 base::Bind(&base::SetPosixFilePermissions, file_path, posix_permissions), | |
595 base::Bind(&WebApkInstaller::OnWebApkMadeWorldReadable, | |
596 weak_ptr_factory_.GetWeakPtr(), file_path)); | |
597 } | |
598 | |
599 void WebApkInstaller::OnWebApkMadeWorldReadable( | |
600 const base::FilePath& file_path, | |
601 bool change_permission_success) { | |
602 if (!change_permission_success) { | |
603 OnResult(WebApkInstallResult::FAILURE); | |
604 return; | |
605 } | |
606 | |
607 JNIEnv* env = base::android::AttachCurrentThread(); | |
608 base::android::ScopedJavaLocalRef<jstring> java_file_path = | |
609 base::android::ConvertUTF8ToJavaString(env, file_path.value()); | |
610 if (task_type_ == INSTALL) { | |
611 base::android::ScopedJavaLocalRef<jstring> java_package_name = | |
612 base::android::ConvertUTF8ToJavaString(env, webapk_package_); | |
613 InstallDownloadedWebApk(env, java_file_path, java_package_name); | |
614 } else if (task_type_ == UPDATE) { | |
615 UpdateUsingDownloadedWebApk(env, java_file_path); | |
616 } | |
617 } | |
OLD | NEW |