| 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" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 #include "net/base/load_flags.h" | 31 #include "net/base/load_flags.h" |
| 32 #include "net/http/http_status_code.h" | 32 #include "net/http/http_status_code.h" |
| 33 #include "net/url_request/url_fetcher.h" | 33 #include "net/url_request/url_fetcher.h" |
| 34 #include "ui/gfx/codec/png_codec.h" | 34 #include "ui/gfx/codec/png_codec.h" |
| 35 #include "url/gurl.h" | 35 #include "url/gurl.h" |
| 36 | 36 |
| 37 namespace { | 37 namespace { |
| 38 | 38 |
| 39 // The default WebAPK server URL. | 39 // The default WebAPK server URL. |
| 40 const char kDefaultServerUrl[] = | 40 const char kDefaultServerUrl[] = |
| 41 "https://webapk.googleapis.com/v1/webApks/?alt=proto&key=AIzaSyAoI6v-F31-3t9
NunLYEiKcPIqgTJIUZBw"; | 41 "https://webapk.googleapis.com/v1/webApks/" |
| 42 "?alt=proto&key=AIzaSyAoI6v-F31-3t9NunLYEiKcPIqgTJIUZBw"; |
| 42 | 43 |
| 43 // The MIME type of the POST data sent to the server. | 44 // The MIME type of the POST data sent to the server. |
| 44 const char kProtoMimeType[] = "application/x-protobuf"; | 45 const char kProtoMimeType[] = "application/x-protobuf"; |
| 45 | 46 |
| 46 // The default number of milliseconds to wait for the WebAPK download URL from | 47 // The default number of milliseconds to wait for the WebAPK download URL from |
| 47 // the WebAPK server. | 48 // the WebAPK server. |
| 48 const int kWebApkDownloadUrlTimeoutMs = 60000; | 49 const int kWebApkDownloadUrlTimeoutMs = 60000; |
| 49 | 50 |
| 50 // The default number of milliseconds to wait for the WebAPK download to | 51 // The default number of milliseconds to wait for the WebAPK download to |
| 51 // complete. | 52 // complete. |
| 52 const int kDownloadTimeoutMs = 60000; | 53 const int kDownloadTimeoutMs = 60000; |
| 53 | 54 |
| 54 const int kWorldReadableFilePermission = base::FILE_PERMISSION_READ_BY_USER | | 55 const int kWorldReadableFilePermission = base::FILE_PERMISSION_READ_BY_USER | |
| 55 base::FILE_PERMISSION_READ_BY_GROUP | | 56 base::FILE_PERMISSION_READ_BY_GROUP | |
| 56 base::FILE_PERMISSION_READ_BY_OTHERS; | 57 base::FILE_PERMISSION_READ_BY_OTHERS; |
| 57 | 58 |
| 58 // Returns the WebAPK server URL based on the command line. | 59 // Returns the WebAPK server URL based on the command line. |
| 59 GURL GetServerUrl() { | 60 GURL GetServerUrl() { |
| 60 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 61 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 61 GURL command_line_url( | 62 GURL command_line_url( |
| 62 command_line->GetSwitchValueASCII(switches::kWebApkServerUrl)); | 63 command_line->GetSwitchValueASCII(switches::kWebApkServerUrl)); |
| 63 return command_line_url.is_valid() ? command_line_url | 64 return command_line_url.is_valid() ? command_line_url |
| 64 : GURL(kDefaultServerUrl); | 65 : GURL(kDefaultServerUrl); |
| 65 } | 66 } |
| 66 | 67 |
| 67 // Returns the scope from |info| if it is specified. Otherwise, returns the | 68 // Returns the scope from |info| if it is specified. Otherwise, returns the |
| 68 // default scope. | 69 // default scope. |
| 69 GURL GetScope(const ShortcutInfo& info) { | 70 GURL GetScope(const ShortcutInfo& info) { |
| 70 return (info.scope.is_valid()) | 71 return (info.scope.is_valid()) ? info.scope |
| 71 ? info.scope | 72 : ShortcutHelper::GetScopeFromURL(info.url); |
| 72 : ShortcutHelper::GetScopeFromURL(info.url); | |
| 73 } | 73 } |
| 74 | 74 |
| 75 // Converts a color from the format specified in content::Manifest to a CSS | 75 // Converts a color from the format specified in content::Manifest to a CSS |
| 76 // string. | 76 // string. |
| 77 std::string ColorToString(int64_t color) { | 77 std::string ColorToString(int64_t color) { |
| 78 if (color == content::Manifest::kInvalidOrMissingColor) | 78 if (color == content::Manifest::kInvalidOrMissingColor) |
| 79 return ""; | 79 return ""; |
| 80 | 80 |
| 81 SkColor sk_color = reinterpret_cast<uint32_t&>(color); | 81 SkColor sk_color = reinterpret_cast<uint32_t&>(color); |
| 82 int r = SkColorGetR(sk_color); | 82 int r = SkColorGetR(sk_color); |
| 83 int g = SkColorGetG(sk_color); | 83 int g = SkColorGetG(sk_color); |
| 84 int b = SkColorGetB(sk_color); | 84 int b = SkColorGetB(sk_color); |
| 85 double a = SkColorGetA(sk_color) / 255.0; | 85 double a = SkColorGetA(sk_color) / 255.0; |
| 86 return base::StringPrintf("rgba(%d,%d,%d,%.2f)", r, g, b, a); | 86 return base::StringPrintf("rgba(%d,%d,%d,%.2f)", r, g, b, a); |
| 87 } | 87 } |
| 88 | 88 |
| 89 // Get Chrome's current ABI. It depends on whether Chrome is running as a 32 bit | 89 // Get Chrome's current ABI. It depends on whether Chrome is running as a 32 bit |
| 90 // app or 64 bit, and the device's cpu architecture as well. Note: please keep | 90 // app or 64 bit, and the device's cpu architecture as well. Note: please keep |
| 91 // this function stay in sync with |chromium_android_linker::GetCpuAbi()|. | 91 // this function stay in sync with |chromium_android_linker::GetCpuAbi()|. |
| 92 std::string getCurrentAbi() { | 92 std::string getCurrentAbi() { |
| 93 #if defined(__arm__) && defined(__ARM_ARCH_7A__) | 93 #if defined(__arm__) && defined(__ARM_ARCH_7A__) |
| 94 return "armeabi-v7a"; | 94 return "armeabi-v7a"; |
| 95 #elif defined(__arm__) | 95 #elif defined(__arm__) |
| 96 return "armeabi"; | 96 return "armeabi"; |
| 97 #elif defined(__i386__) | 97 #elif defined(__i386__) |
| 98 return "x86"; | 98 return "x86"; |
| 99 #elif defined(__mips__) | 99 #elif defined(__mips__) |
| 100 return "mips"; | 100 return "mips"; |
| 101 #elif defined(__x86_64__) | 101 #elif defined(__x86_64__) |
| 102 return "x86_64"; | 102 return "x86_64"; |
| 103 #elif defined(__aarch64__) | 103 #elif defined(__aarch64__) |
| 104 return "arm64-v8a"; | 104 return "arm64-v8a"; |
| 105 #else | 105 #else |
| 106 #error "Unsupported target abi" | 106 #error "Unsupported target abi" |
| 107 #endif | 107 #endif |
| 108 } | 108 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 119 std::unique_ptr<webapk::WebApk> webapk(new webapk::WebApk); | 119 std::unique_ptr<webapk::WebApk> webapk(new webapk::WebApk); |
| 120 webapk->set_manifest_url(shortcut_info.manifest_url.spec()); | 120 webapk->set_manifest_url(shortcut_info.manifest_url.spec()); |
| 121 webapk->set_requester_application_package( | 121 webapk->set_requester_application_package( |
| 122 base::android::BuildInfo::GetInstance()->package_name()); | 122 base::android::BuildInfo::GetInstance()->package_name()); |
| 123 webapk->set_requester_application_version(version_info::GetVersionNumber()); | 123 webapk->set_requester_application_version(version_info::GetVersionNumber()); |
| 124 webapk->set_android_abi(getCurrentAbi()); | 124 webapk->set_android_abi(getCurrentAbi()); |
| 125 webapk->set_stale_manifest(is_manifest_stale); | 125 webapk->set_stale_manifest(is_manifest_stale); |
| 126 | 126 |
| 127 webapk::WebAppManifest* web_app_manifest = webapk->mutable_manifest(); | 127 webapk::WebAppManifest* web_app_manifest = webapk->mutable_manifest(); |
| 128 web_app_manifest->set_name(base::UTF16ToUTF8(shortcut_info.name)); | 128 web_app_manifest->set_name(base::UTF16ToUTF8(shortcut_info.name)); |
| 129 web_app_manifest->set_short_name( | 129 web_app_manifest->set_short_name(base::UTF16ToUTF8(shortcut_info.short_name)); |
| 130 base::UTF16ToUTF8(shortcut_info.short_name)); | |
| 131 web_app_manifest->set_start_url(shortcut_info.url.spec()); | 130 web_app_manifest->set_start_url(shortcut_info.url.spec()); |
| 132 web_app_manifest->set_orientation( | 131 web_app_manifest->set_orientation( |
| 133 content::WebScreenOrientationLockTypeToString( | 132 content::WebScreenOrientationLockTypeToString(shortcut_info.orientation)); |
| 134 shortcut_info.orientation)); | |
| 135 web_app_manifest->set_display_mode( | 133 web_app_manifest->set_display_mode( |
| 136 content::WebDisplayModeToString(shortcut_info.display)); | 134 content::WebDisplayModeToString(shortcut_info.display)); |
| 137 web_app_manifest->set_background_color( | 135 web_app_manifest->set_background_color( |
| 138 ColorToString(shortcut_info.background_color)); | 136 ColorToString(shortcut_info.background_color)); |
| 139 web_app_manifest->set_theme_color(ColorToString(shortcut_info.theme_color)); | 137 web_app_manifest->set_theme_color(ColorToString(shortcut_info.theme_color)); |
| 140 | 138 |
| 141 std::string* scope = web_app_manifest->add_scopes(); | 139 std::string* scope = web_app_manifest->add_scopes(); |
| 142 scope->assign(GetScope(shortcut_info).spec()); | 140 scope->assign(GetScope(shortcut_info).spec()); |
| 143 | 141 |
| 144 webapk::Image* best_image = web_app_manifest->add_icons(); | 142 webapk::Image* best_image = web_app_manifest->add_icons(); |
| 145 std::string best_icon_url = shortcut_info.best_icon_url.spec(); | 143 std::string best_primary_icon_url = |
| 146 best_image->set_src(best_icon_url); | 144 shortcut_info.best_primary_icon_url.spec(); |
| 147 auto it = icon_url_to_murmur2_hash.find(best_icon_url); | 145 best_image->set_src(best_primary_icon_url); |
| 146 auto it = icon_url_to_murmur2_hash.find(best_primary_icon_url); |
| 148 if (it != icon_url_to_murmur2_hash.end()) | 147 if (it != icon_url_to_murmur2_hash.end()) |
| 149 best_image->set_hash(it->second); | 148 best_image->set_hash(it->second); |
| 150 std::vector<unsigned char> png_bytes; | 149 std::vector<unsigned char> png_bytes; |
| 151 gfx::PNGCodec::EncodeBGRASkBitmap(shortcut_icon, false, &png_bytes); | 150 gfx::PNGCodec::EncodeBGRASkBitmap(shortcut_icon, false, &png_bytes); |
| 152 best_image->set_image_data(&png_bytes.front(), png_bytes.size()); | 151 best_image->set_image_data(&png_bytes.front(), png_bytes.size()); |
| 153 | 152 |
| 154 for (const auto& entry : icon_url_to_murmur2_hash) { | 153 for (const auto& entry : icon_url_to_murmur2_hash) { |
| 155 if (entry.first == shortcut_info.best_icon_url.spec()) | 154 if (entry.first == shortcut_info.best_primary_icon_url.spec()) |
| 156 continue; | 155 continue; |
| 157 webapk::Image* image = web_app_manifest->add_icons(); | 156 webapk::Image* image = web_app_manifest->add_icons(); |
| 158 image->set_src(entry.first); | 157 image->set_src(entry.first); |
| 159 image->set_hash(entry.second); | 158 image->set_hash(entry.second); |
| 160 } | 159 } |
| 161 | 160 |
| 162 return webapk; | 161 return webapk; |
| 163 } | 162 } |
| 164 | 163 |
| 165 // Calls the callback when the |webapk| request is created. | 164 // Calls the callback when the |webapk| request is created. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 const ShortcutInfo& shortcut_info, | 232 const ShortcutInfo& shortcut_info, |
| 234 const SkBitmap& shortcut_icon, | 233 const SkBitmap& shortcut_icon, |
| 235 const std::string& webapk_package, | 234 const std::string& webapk_package, |
| 236 int webapk_version, | 235 int webapk_version, |
| 237 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, | 236 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, |
| 238 bool is_manifest_stale, | 237 bool is_manifest_stale, |
| 239 const FinishCallback& finish_callback) { | 238 const FinishCallback& finish_callback) { |
| 240 // The installer will delete itself when it is done. | 239 // The installer will delete itself when it is done. |
| 241 WebApkInstaller* installer = | 240 WebApkInstaller* installer = |
| 242 new WebApkInstaller(context, shortcut_info, shortcut_icon); | 241 new WebApkInstaller(context, shortcut_info, shortcut_icon); |
| 243 installer->UpdateAsync( | 242 installer->UpdateAsync(webapk_package, webapk_version, |
| 244 webapk_package, webapk_version, icon_url_to_murmur2_hash, | 243 icon_url_to_murmur2_hash, is_manifest_stale, |
| 245 is_manifest_stale, finish_callback); | 244 finish_callback); |
| 246 } | 245 } |
| 247 | 246 |
| 248 // staic | 247 // staic |
| 249 void WebApkInstaller::InstallAsyncForTesting( | 248 void WebApkInstaller::InstallAsyncForTesting( |
| 250 WebApkInstaller* installer, | 249 WebApkInstaller* installer, |
| 251 const FinishCallback& finish_callback) { | 250 const FinishCallback& finish_callback) { |
| 252 installer->InstallAsync(finish_callback); | 251 installer->InstallAsync(finish_callback); |
| 253 } | 252 } |
| 254 | 253 |
| 255 // static | 254 // static |
| 256 void WebApkInstaller::UpdateAsyncForTesting( | 255 void WebApkInstaller::UpdateAsyncForTesting( |
| 257 WebApkInstaller* installer, | 256 WebApkInstaller* installer, |
| 258 const std::string& webapk_package, | 257 const std::string& webapk_package, |
| 259 int webapk_version, | 258 int webapk_version, |
| 260 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, | 259 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, |
| 261 bool is_manifest_stale, | 260 bool is_manifest_stale, |
| 262 const FinishCallback& finish_callback) { | 261 const FinishCallback& finish_callback) { |
| 263 installer->UpdateAsync( | 262 installer->UpdateAsync(webapk_package, webapk_version, |
| 264 webapk_package, webapk_version, icon_url_to_murmur2_hash, | 263 icon_url_to_murmur2_hash, is_manifest_stale, |
| 265 is_manifest_stale, finish_callback); | 264 finish_callback); |
| 266 } | 265 } |
| 267 | 266 |
| 268 void WebApkInstaller::SetTimeoutMs(int timeout_ms) { | 267 void WebApkInstaller::SetTimeoutMs(int timeout_ms) { |
| 269 webapk_download_url_timeout_ms_ = timeout_ms; | 268 webapk_download_url_timeout_ms_ = timeout_ms; |
| 270 download_timeout_ms_ = timeout_ms; | 269 download_timeout_ms_ = timeout_ms; |
| 271 } | 270 } |
| 272 | 271 |
| 273 void WebApkInstaller::OnInstallFinished( | 272 void WebApkInstaller::OnInstallFinished( |
| 274 JNIEnv* env, | 273 JNIEnv* env, |
| 275 const base::android::JavaParamRef<jobject>& obj, | 274 const base::android::JavaParamRef<jobject>& obj, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 300 JNIEnv* env, | 299 JNIEnv* env, |
| 301 const base::android::ScopedJavaLocalRef<jstring>& java_file_path, | 300 const base::android::ScopedJavaLocalRef<jstring>& java_file_path, |
| 302 const base::android::ScopedJavaLocalRef<jstring>& java_package_name) { | 301 const base::android::ScopedJavaLocalRef<jstring>& java_package_name) { |
| 303 return Java_WebApkInstaller_installAsyncAndMonitorInstallationFromNative( | 302 return Java_WebApkInstaller_installAsyncAndMonitorInstallationFromNative( |
| 304 env, java_ref_, java_file_path, java_package_name); | 303 env, java_ref_, java_file_path, java_package_name); |
| 305 } | 304 } |
| 306 | 305 |
| 307 bool WebApkInstaller::StartUpdateUsingDownloadedWebApk( | 306 bool WebApkInstaller::StartUpdateUsingDownloadedWebApk( |
| 308 JNIEnv* env, | 307 JNIEnv* env, |
| 309 const base::android::ScopedJavaLocalRef<jstring>& java_file_path) { | 308 const base::android::ScopedJavaLocalRef<jstring>& java_file_path) { |
| 310 return Java_WebApkInstaller_updateAsyncFromNative( | 309 return Java_WebApkInstaller_updateAsyncFromNative(env, java_ref_, |
| 311 env, java_ref_, java_file_path); | 310 java_file_path); |
| 312 } | 311 } |
| 313 | 312 |
| 314 bool WebApkInstaller::CanUseGooglePlayInstallService() { | 313 bool WebApkInstaller::CanUseGooglePlayInstallService() { |
| 315 JNIEnv* env = base::android::AttachCurrentThread(); | 314 JNIEnv* env = base::android::AttachCurrentThread(); |
| 316 return Java_WebApkInstaller_canUseGooglePlayInstallService( | 315 return Java_WebApkInstaller_canUseGooglePlayInstallService(env, java_ref_); |
| 317 env, java_ref_); | |
| 318 } | 316 } |
| 319 | 317 |
| 320 bool WebApkInstaller::InstallOrUpdateWebApkFromGooglePlay( | 318 bool WebApkInstaller::InstallOrUpdateWebApkFromGooglePlay( |
| 321 const std::string& package_name, | 319 const std::string& package_name, |
| 322 int version, | 320 int version, |
| 323 const std::string& token) { | 321 const std::string& token) { |
| 324 webapk_package_ = package_name; | 322 webapk_package_ = package_name; |
| 325 | 323 |
| 326 JNIEnv* env = base::android::AttachCurrentThread(); | 324 JNIEnv* env = base::android::AttachCurrentThread(); |
| 327 base::android::ScopedJavaLocalRef<jstring> java_webapk_package = | 325 base::android::ScopedJavaLocalRef<jstring> java_webapk_package = |
| (...skipping 26 matching lines...) Expand all Loading... |
| 354 server_url_(GetServerUrl()), | 352 server_url_(GetServerUrl()), |
| 355 webapk_download_url_timeout_ms_(kWebApkDownloadUrlTimeoutMs), | 353 webapk_download_url_timeout_ms_(kWebApkDownloadUrlTimeoutMs), |
| 356 download_timeout_ms_(kDownloadTimeoutMs), | 354 download_timeout_ms_(kDownloadTimeoutMs), |
| 357 task_type_(UNDEFINED), | 355 task_type_(UNDEFINED), |
| 358 weak_ptr_factory_(this) { | 356 weak_ptr_factory_(this) { |
| 359 CreateJavaRef(); | 357 CreateJavaRef(); |
| 360 } | 358 } |
| 361 | 359 |
| 362 void WebApkInstaller::CreateJavaRef() { | 360 void WebApkInstaller::CreateJavaRef() { |
| 363 JNIEnv* env = base::android::AttachCurrentThread(); | 361 JNIEnv* env = base::android::AttachCurrentThread(); |
| 364 java_ref_.Reset(Java_WebApkInstaller_create( | 362 java_ref_.Reset( |
| 365 env, reinterpret_cast<intptr_t>(this))); | 363 Java_WebApkInstaller_create(env, reinterpret_cast<intptr_t>(this))); |
| 366 } | 364 } |
| 367 | 365 |
| 368 void WebApkInstaller::InstallAsync(const FinishCallback& finish_callback) { | 366 void WebApkInstaller::InstallAsync(const FinishCallback& finish_callback) { |
| 369 finish_callback_ = finish_callback; | 367 finish_callback_ = finish_callback; |
| 370 task_type_ = INSTALL; | 368 task_type_ = INSTALL; |
| 371 | 369 |
| 372 // We need to take the hash of the bitmap at the icon URL prior to any | 370 // We need to take the hash of the bitmap at the icon URL prior to any |
| 373 // transformations being applied to the bitmap (such as encoding/decoding | 371 // transformations being applied to the bitmap (such as encoding/decoding |
| 374 // the bitmap). The icon hash is used to determine whether the icon that | 372 // the bitmap). The icon hash is used to determine whether the icon that |
| 375 // the user sees matches the icon of a WebAPK that the WebAPK server | 373 // the user sees matches the icon of a WebAPK that the WebAPK server |
| (...skipping 13 matching lines...) Expand all Loading... |
| 389 webapk_package_ = webapk_package; | 387 webapk_package_ = webapk_package; |
| 390 webapk_version_ = webapk_version; | 388 webapk_version_ = webapk_version; |
| 391 finish_callback_ = finish_callback; | 389 finish_callback_ = finish_callback; |
| 392 task_type_ = UPDATE; | 390 task_type_ = UPDATE; |
| 393 | 391 |
| 394 base::PostTaskAndReplyWithResult( | 392 base::PostTaskAndReplyWithResult( |
| 395 GetBackgroundTaskRunner().get(), FROM_HERE, | 393 GetBackgroundTaskRunner().get(), FROM_HERE, |
| 396 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_, | 394 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_, |
| 397 icon_url_to_murmur2_hash, is_manifest_stale), | 395 icon_url_to_murmur2_hash, is_manifest_stale), |
| 398 base::Bind(&WebApkInstaller::SendUpdateWebApkRequest, | 396 base::Bind(&WebApkInstaller::SendUpdateWebApkRequest, |
| 399 weak_ptr_factory_.GetWeakPtr())); | 397 weak_ptr_factory_.GetWeakPtr())); |
| 400 } | 398 } |
| 401 | 399 |
| 402 void WebApkInstaller::OnURLFetchComplete(const net::URLFetcher* source) { | 400 void WebApkInstaller::OnURLFetchComplete(const net::URLFetcher* source) { |
| 403 timer_.Stop(); | 401 timer_.Stop(); |
| 404 | 402 |
| 405 if (!source->GetStatus().is_success() || | 403 if (!source->GetStatus().is_success() || |
| 406 source->GetResponseCode() != net::HTTP_OK) { | 404 source->GetResponseCode() != net::HTTP_OK) { |
| 407 OnFailure(); | 405 OnFailure(); |
| 408 return; | 406 return; |
| 409 } | 407 } |
| 410 | 408 |
| 411 std::string response_string; | 409 std::string response_string; |
| 412 source->GetResponseAsString(&response_string); | 410 source->GetResponseAsString(&response_string); |
| 413 | 411 |
| 414 std::unique_ptr<webapk::WebApkResponse> response( | 412 std::unique_ptr<webapk::WebApkResponse> response(new webapk::WebApkResponse); |
| 415 new webapk::WebApkResponse); | |
| 416 if (!response->ParseFromString(response_string)) { | 413 if (!response->ParseFromString(response_string)) { |
| 417 OnFailure(); | 414 OnFailure(); |
| 418 return; | 415 return; |
| 419 } | 416 } |
| 420 | 417 |
| 421 GURL signed_download_url(response->signed_download_url()); | 418 GURL signed_download_url(response->signed_download_url()); |
| 422 if (!signed_download_url.is_valid() || response->package_name().empty()) { | 419 if (!signed_download_url.is_valid() || response->package_name().empty()) { |
| 423 OnFailure(); | 420 OnFailure(); |
| 424 return; | 421 return; |
| 425 } | 422 } |
| 426 | 423 |
| 427 if (CanUseGooglePlayInstallService()) { | 424 if (CanUseGooglePlayInstallService()) { |
| 428 int version = 1; | 425 int version = 1; |
| 429 base::StringToInt(response->version(), &version); | 426 base::StringToInt(response->version(), &version); |
| 430 if (!InstallOrUpdateWebApkFromGooglePlay( | 427 if (!InstallOrUpdateWebApkFromGooglePlay(response->package_name(), version, |
| 431 response->package_name(), version, response->token())) { | 428 response->token())) { |
| 432 OnFailure(); | 429 OnFailure(); |
| 433 } | 430 } |
| 434 return; | 431 return; |
| 435 } | 432 } |
| 436 | 433 |
| 437 OnGotWebApkDownloadUrl(signed_download_url, response->package_name()); | 434 OnGotWebApkDownloadUrl(signed_download_url, response->package_name()); |
| 438 } | 435 } |
| 439 | 436 |
| 440 void WebApkInstaller::DownloadAppIconAndComputeMurmur2Hash() { | 437 void WebApkInstaller::DownloadAppIconAndComputeMurmur2Hash() { |
| 441 // Safeguard. WebApkIconHasher crashes if asked to fetch an invalid URL. | 438 // Safeguard. WebApkIconHasher crashes if asked to fetch an invalid URL. |
| 442 if (!shortcut_info_.best_icon_url.is_valid()) { | 439 if (!shortcut_info_.best_primary_icon_url.is_valid()) { |
| 443 OnFailure(); | 440 OnFailure(); |
| 444 return; | 441 return; |
| 445 } | 442 } |
| 446 | 443 |
| 447 timer_.Start( | 444 timer_.Start( |
| 448 FROM_HERE, base::TimeDelta::FromMilliseconds(download_timeout_ms_), | 445 FROM_HERE, base::TimeDelta::FromMilliseconds(download_timeout_ms_), |
| 449 base::Bind(&WebApkInstaller::OnTimeout, weak_ptr_factory_.GetWeakPtr())); | 446 base::Bind(&WebApkInstaller::OnTimeout, weak_ptr_factory_.GetWeakPtr())); |
| 450 | 447 |
| 451 icon_hasher_.reset(new WebApkIconHasher()); | 448 icon_hasher_.reset(new WebApkIconHasher()); |
| 452 icon_hasher_->DownloadAndComputeMurmur2Hash( | 449 icon_hasher_->DownloadAndComputeMurmur2Hash( |
| 453 request_context_getter_, shortcut_info_.best_icon_url, | 450 request_context_getter_, shortcut_info_.best_primary_icon_url, |
| 454 base::Bind(&WebApkInstaller::OnGotIconMurmur2Hash, | 451 base::Bind(&WebApkInstaller::OnGotIconMurmur2Hash, |
| 455 weak_ptr_factory_.GetWeakPtr())); | 452 weak_ptr_factory_.GetWeakPtr())); |
| 456 } | 453 } |
| 457 | 454 |
| 458 void WebApkInstaller::OnGotIconMurmur2Hash( | 455 void WebApkInstaller::OnGotIconMurmur2Hash( |
| 459 const std::string& icon_murmur2_hash) { | 456 const std::string& icon_murmur2_hash) { |
| 460 timer_.Stop(); | 457 timer_.Stop(); |
| 461 icon_hasher_.reset(); | 458 icon_hasher_.reset(); |
| 462 | 459 |
| 463 // An empty hash indicates that |icon_hasher_| encountered an error. | 460 // An empty hash indicates that |icon_hasher_| encountered an error. |
| 464 if (icon_murmur2_hash.empty()) { | 461 if (icon_murmur2_hash.empty()) { |
| 465 OnFailure(); | 462 OnFailure(); |
| 466 return; | 463 return; |
| 467 } | 464 } |
| 468 | 465 |
| 469 std::map<std::string, std::string> icon_url_to_murmur2_hash; | 466 std::map<std::string, std::string> icon_url_to_murmur2_hash; |
| 470 for (const std::string& icon_url : shortcut_info_.icon_urls) { | 467 for (const std::string& icon_url : shortcut_info_.icon_urls) { |
| 471 if (icon_url != shortcut_info_.best_icon_url.spec()) | 468 if (icon_url != shortcut_info_.best_primary_icon_url.spec()) |
| 472 icon_url_to_murmur2_hash[icon_url] = ""; | 469 icon_url_to_murmur2_hash[icon_url] = ""; |
| 473 else | 470 else |
| 474 icon_url_to_murmur2_hash[icon_url] = icon_murmur2_hash; | 471 icon_url_to_murmur2_hash[icon_url] = icon_murmur2_hash; |
| 475 } | 472 } |
| 476 | 473 |
| 477 base::PostTaskAndReplyWithResult( | 474 base::PostTaskAndReplyWithResult( |
| 478 GetBackgroundTaskRunner().get(), FROM_HERE, | 475 GetBackgroundTaskRunner().get(), FROM_HERE, |
| 479 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_, | 476 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_, |
| 480 icon_url_to_murmur2_hash, false /* is_manifest_stale */), | 477 icon_url_to_murmur2_hash, false /* is_manifest_stale */), |
| 481 base::Bind(&WebApkInstaller::SendCreateWebApkRequest, | 478 base::Bind(&WebApkInstaller::SendCreateWebApkRequest, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 501 FROM_HERE, | 498 FROM_HERE, |
| 502 base::TimeDelta::FromMilliseconds(webapk_download_url_timeout_ms_), | 499 base::TimeDelta::FromMilliseconds(webapk_download_url_timeout_ms_), |
| 503 base::Bind(&WebApkInstaller::OnTimeout, weak_ptr_factory_.GetWeakPtr())); | 500 base::Bind(&WebApkInstaller::OnTimeout, weak_ptr_factory_.GetWeakPtr())); |
| 504 | 501 |
| 505 url_fetcher_ = | 502 url_fetcher_ = |
| 506 net::URLFetcher::Create(server_url, net::URLFetcher::POST, this); | 503 net::URLFetcher::Create(server_url, net::URLFetcher::POST, this); |
| 507 url_fetcher_->SetRequestContext(request_context_getter_); | 504 url_fetcher_->SetRequestContext(request_context_getter_); |
| 508 std::string serialized_request; | 505 std::string serialized_request; |
| 509 request_proto->SerializeToString(&serialized_request); | 506 request_proto->SerializeToString(&serialized_request); |
| 510 url_fetcher_->SetUploadData(kProtoMimeType, serialized_request); | 507 url_fetcher_->SetUploadData(kProtoMimeType, serialized_request); |
| 511 url_fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE | | 508 url_fetcher_->SetLoadFlags( |
| 512 net::LOAD_DO_NOT_SEND_COOKIES | | 509 net::LOAD_DISABLE_CACHE | net::LOAD_DO_NOT_SEND_COOKIES | |
| 513 net::LOAD_DO_NOT_SAVE_COOKIES | | 510 net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_AUTH_DATA); |
| 514 net::LOAD_DO_NOT_SEND_AUTH_DATA); | |
| 515 url_fetcher_->Start(); | 511 url_fetcher_->Start(); |
| 516 } | 512 } |
| 517 | 513 |
| 518 void WebApkInstaller::OnGotWebApkDownloadUrl(const GURL& download_url, | 514 void WebApkInstaller::OnGotWebApkDownloadUrl(const GURL& download_url, |
| 519 const std::string& package_name) { | 515 const std::string& package_name) { |
| 520 webapk_package_ = package_name; | 516 webapk_package_ = package_name; |
| 521 | 517 |
| 522 base::PostTaskAndReplyWithResult( | 518 base::PostTaskAndReplyWithResult( |
| 523 GetBackgroundTaskRunner().get(), FROM_HERE, | 519 GetBackgroundTaskRunner().get(), FROM_HERE, |
| 524 base::Bind(&CreateSubDirAndSetPermissionsInBackground, | 520 base::Bind(&CreateSubDirAndSetPermissionsInBackground, |
| 525 task_type_ == WebApkInstaller::INSTALL ? "install" : "update", | 521 task_type_ == WebApkInstaller::INSTALL ? "install" : "update", |
| 526 package_name), | 522 package_name), |
| 527 base::Bind(&WebApkInstaller::OnCreatedSubDirAndSetPermissions, | 523 base::Bind(&WebApkInstaller::OnCreatedSubDirAndSetPermissions, |
| 528 weak_ptr_factory_.GetWeakPtr(), download_url)); | 524 weak_ptr_factory_.GetWeakPtr(), download_url)); |
| 529 } | 525 } |
| 530 | 526 |
| 531 void WebApkInstaller::OnCreatedSubDirAndSetPermissions( | 527 void WebApkInstaller::OnCreatedSubDirAndSetPermissions( |
| 532 const GURL& download_url, const base::FilePath& output_dir) { | 528 const GURL& download_url, |
| 529 const base::FilePath& output_dir) { |
| 533 if (output_dir.empty()) { | 530 if (output_dir.empty()) { |
| 534 OnFailure(); | 531 OnFailure(); |
| 535 return; | 532 return; |
| 536 } | 533 } |
| 537 | 534 |
| 538 DownloadWebApk(output_dir.AppendASCII(webapk_package_ + ".apk"), | 535 DownloadWebApk(output_dir.AppendASCII(webapk_package_ + ".apk"), download_url, |
| 539 download_url, true); | 536 true); |
| 540 } | 537 } |
| 541 | 538 |
| 542 void WebApkInstaller::DownloadWebApk(const base::FilePath& output_path, | 539 void WebApkInstaller::DownloadWebApk(const base::FilePath& output_path, |
| 543 const GURL& download_url, | 540 const GURL& download_url, |
| 544 bool retry_if_fails) { | 541 bool retry_if_fails) { |
| 545 timer_.Start( | 542 timer_.Start( |
| 546 FROM_HERE, base::TimeDelta::FromMilliseconds(download_timeout_ms_), | 543 FROM_HERE, base::TimeDelta::FromMilliseconds(download_timeout_ms_), |
| 547 base::Bind(&WebApkInstaller::OnTimeout, weak_ptr_factory_.GetWeakPtr())); | 544 base::Bind(&WebApkInstaller::OnTimeout, weak_ptr_factory_.GetWeakPtr())); |
| 548 | 545 |
| 549 downloader_.reset(new FileDownloader( | 546 downloader_.reset(new FileDownloader( |
| 550 download_url, output_path, true, request_context_getter_, | 547 download_url, output_path, true, request_context_getter_, |
| 551 base::Bind(&WebApkInstaller::OnWebApkDownloaded, | 548 base::Bind(&WebApkInstaller::OnWebApkDownloaded, |
| 552 weak_ptr_factory_.GetWeakPtr(), | 549 weak_ptr_factory_.GetWeakPtr(), output_path, download_url, |
| 553 output_path, download_url, retry_if_fails))); | 550 retry_if_fails))); |
| 554 } | 551 } |
| 555 | 552 |
| 556 void WebApkInstaller::OnWebApkDownloaded(const base::FilePath& file_path, | 553 void WebApkInstaller::OnWebApkDownloaded(const base::FilePath& file_path, |
| 557 const GURL& download_url, | 554 const GURL& download_url, |
| 558 bool retry_if_fails, | 555 bool retry_if_fails, |
| 559 FileDownloader::Result result) { | 556 FileDownloader::Result result) { |
| 560 timer_.Stop(); | 557 timer_.Stop(); |
| 561 | 558 |
| 562 if (result != FileDownloader::DOWNLOADED) { | 559 if (result != FileDownloader::DOWNLOADED) { |
| 563 if (!retry_if_fails) { | 560 if (!retry_if_fails) { |
| 564 OnFailure(); | 561 OnFailure(); |
| 565 return; | 562 return; |
| 566 } | 563 } |
| 567 | 564 |
| 568 content::BrowserThread::PostDelayedTask( | 565 content::BrowserThread::PostDelayedTask( |
| 569 content::BrowserThread::UI, FROM_HERE, | 566 content::BrowserThread::UI, FROM_HERE, |
| 570 base::Bind(&WebApkInstaller::DownloadWebApk, | 567 base::Bind(&WebApkInstaller::DownloadWebApk, |
| 571 weak_ptr_factory_.GetWeakPtr(), | 568 weak_ptr_factory_.GetWeakPtr(), file_path, download_url, |
| 572 file_path, download_url, false), | 569 false), |
| 573 base::TimeDelta::FromSeconds(2)); | 570 base::TimeDelta::FromSeconds(2)); |
| 574 return; | 571 return; |
| 575 } | 572 } |
| 576 | 573 |
| 577 int posix_permissions = kWorldReadableFilePermission | | 574 int posix_permissions = kWorldReadableFilePermission | |
| 578 base::FILE_PERMISSION_WRITE_BY_USER | | 575 base::FILE_PERMISSION_WRITE_BY_USER | |
| 579 base::FILE_PERMISSION_EXECUTE_BY_USER; | 576 base::FILE_PERMISSION_EXECUTE_BY_USER; |
| 580 base::PostTaskAndReplyWithResult( | 577 base::PostTaskAndReplyWithResult( |
| 581 GetBackgroundTaskRunner().get(), FROM_HERE, | 578 GetBackgroundTaskRunner().get(), FROM_HERE, |
| 582 base::Bind(&base::SetPosixFilePermissions, file_path, posix_permissions), | 579 base::Bind(&base::SetPosixFilePermissions, file_path, posix_permissions), |
| 583 base::Bind(&WebApkInstaller::OnWebApkMadeWorldReadable, | 580 base::Bind(&WebApkInstaller::OnWebApkMadeWorldReadable, |
| 584 weak_ptr_factory_.GetWeakPtr(), file_path)); | 581 weak_ptr_factory_.GetWeakPtr(), file_path)); |
| 585 } | 582 } |
| 586 | 583 |
| 587 void WebApkInstaller::OnWebApkMadeWorldReadable( | 584 void WebApkInstaller::OnWebApkMadeWorldReadable( |
| 588 const base::FilePath& file_path, | 585 const base::FilePath& file_path, |
| 589 bool change_permission_success) { | 586 bool change_permission_success) { |
| 590 if (!change_permission_success) { | 587 if (!change_permission_success) { |
| 591 OnFailure(); | 588 OnFailure(); |
| 592 return; | 589 return; |
| 593 } | 590 } |
| 594 | 591 |
| 595 JNIEnv* env = base::android::AttachCurrentThread(); | 592 JNIEnv* env = base::android::AttachCurrentThread(); |
| 596 base::android::ScopedJavaLocalRef<jstring> java_file_path = | 593 base::android::ScopedJavaLocalRef<jstring> java_file_path = |
| 597 base::android::ConvertUTF8ToJavaString(env, file_path.value()); | 594 base::android::ConvertUTF8ToJavaString(env, file_path.value()); |
| 598 base::android::ScopedJavaLocalRef<jstring> java_package_name = | 595 base::android::ScopedJavaLocalRef<jstring> java_package_name = |
| 599 base::android::ConvertUTF8ToJavaString(env, webapk_package_); | 596 base::android::ConvertUTF8ToJavaString(env, webapk_package_); |
| 600 bool success = false; | 597 bool success = false; |
| 601 if (task_type_ == INSTALL) { | 598 if (task_type_ == INSTALL) { |
| 602 success = StartInstallingDownloadedWebApk(env, java_file_path, | 599 success = |
| 603 java_package_name); | 600 StartInstallingDownloadedWebApk(env, java_file_path, java_package_name); |
| 604 } else if (task_type_ == UPDATE) { | 601 } else if (task_type_ == UPDATE) { |
| 605 success = StartUpdateUsingDownloadedWebApk(env, java_file_path); | 602 success = StartUpdateUsingDownloadedWebApk(env, java_file_path); |
| 606 if (success) { | 603 if (success) { |
| 607 // Since WebApkInstaller doesn't listen to WebAPKs' update events | 604 // Since WebApkInstaller doesn't listen to WebAPKs' update events |
| 608 // we call OnSuccess() as long as the update started successfully. | 605 // we call OnSuccess() as long as the update started successfully. |
| 609 OnSuccess(); | 606 OnSuccess(); |
| 610 return; | 607 return; |
| 611 } | 608 } |
| 612 } | 609 } |
| 613 if (!success) | 610 if (!success) |
| 614 OnFailure(); | 611 OnFailure(); |
| 615 } | 612 } |
| 616 | 613 |
| 617 void WebApkInstaller::OnTimeout() { | 614 void WebApkInstaller::OnTimeout() { |
| 618 OnFailure(); | 615 OnFailure(); |
| 619 } | 616 } |
| 620 | 617 |
| 621 void WebApkInstaller::OnSuccess() { | 618 void WebApkInstaller::OnSuccess() { |
| 622 finish_callback_.Run(true, webapk_package_); | 619 finish_callback_.Run(true, webapk_package_); |
| 623 delete this; | 620 delete this; |
| 624 } | 621 } |
| 625 | 622 |
| 626 void WebApkInstaller::OnFailure() { | 623 void WebApkInstaller::OnFailure() { |
| 627 finish_callback_.Run(false, webapk_package_); | 624 finish_callback_.Run(false, webapk_package_); |
| 628 delete this; | 625 delete this; |
| 629 } | 626 } |
| OLD | NEW |