| 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" | |
| 14 #include "base/files/file_util.h" | |
| 15 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
| 16 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 17 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 18 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 20 #include "base/task_runner_util.h" | 18 #include "base/task_runner_util.h" |
| 21 #include "base/threading/sequenced_worker_pool.h" | 19 #include "base/threading/sequenced_worker_pool.h" |
| 22 #include "base/timer/elapsed_timer.h" | 20 #include "base/timer/elapsed_timer.h" |
| 23 #include "chrome/browser/android/shortcut_helper.h" | 21 #include "chrome/browser/android/shortcut_helper.h" |
| 24 #include "chrome/browser/android/webapk/chrome_webapk_host.h" | 22 #include "chrome/browser/android/webapk/chrome_webapk_host.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 47 "https://webapk.googleapis.com/v1/webApks/" | 45 "https://webapk.googleapis.com/v1/webApks/" |
| 48 "?alt=proto&key=AIzaSyAoI6v-F31-3t9NunLYEiKcPIqgTJIUZBw"; | 46 "?alt=proto&key=AIzaSyAoI6v-F31-3t9NunLYEiKcPIqgTJIUZBw"; |
| 49 | 47 |
| 50 // The MIME type of the POST data sent to the server. | 48 // The MIME type of the POST data sent to the server. |
| 51 const char kProtoMimeType[] = "application/x-protobuf"; | 49 const char kProtoMimeType[] = "application/x-protobuf"; |
| 52 | 50 |
| 53 // The default number of milliseconds to wait for the WebAPK download URL from | 51 // The default number of milliseconds to wait for the WebAPK download URL from |
| 54 // the WebAPK server. | 52 // the WebAPK server. |
| 55 const int kWebApkDownloadUrlTimeoutMs = 60000; | 53 const int kWebApkDownloadUrlTimeoutMs = 60000; |
| 56 | 54 |
| 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. | 55 // Returns the WebAPK server URL based on the command line. |
| 67 GURL GetServerUrl() { | 56 GURL GetServerUrl() { |
| 68 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 57 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 69 GURL command_line_url( | 58 GURL command_line_url( |
| 70 command_line->GetSwitchValueASCII(switches::kWebApkServerUrl)); | 59 command_line->GetSwitchValueASCII(switches::kWebApkServerUrl)); |
| 71 return command_line_url.is_valid() ? command_line_url | 60 return command_line_url.is_valid() ? command_line_url |
| 72 : GURL(kDefaultServerUrl); | 61 : GURL(kDefaultServerUrl); |
| 73 } | 62 } |
| 74 | 63 |
| 75 // Returns the scope from |info| if it is specified. Otherwise, returns the | 64 // 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)); | 159 callback.Run(std::move(webapk)); |
| 171 } | 160 } |
| 172 | 161 |
| 173 // Returns task runner for running background tasks. | 162 // Returns task runner for running background tasks. |
| 174 scoped_refptr<base::TaskRunner> GetBackgroundTaskRunner() { | 163 scoped_refptr<base::TaskRunner> GetBackgroundTaskRunner() { |
| 175 return content::BrowserThread::GetBlockingPool() | 164 return content::BrowserThread::GetBlockingPool() |
| 176 ->GetTaskRunnerWithShutdownBehavior( | 165 ->GetTaskRunnerWithShutdownBehavior( |
| 177 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); | 166 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
| 178 } | 167 } |
| 179 | 168 |
| 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 | 169 } // anonymous namespace |
| 213 | 170 |
| 214 WebApkInstaller::~WebApkInstaller() { | 171 WebApkInstaller::~WebApkInstaller() { |
| 215 JNIEnv* env = base::android::AttachCurrentThread(); | 172 JNIEnv* env = base::android::AttachCurrentThread(); |
| 216 Java_WebApkInstaller_destroy(env, java_ref_); | 173 Java_WebApkInstaller_destroy(env, java_ref_); |
| 217 java_ref_.Reset(); | 174 java_ref_.Reset(); |
| 218 } | 175 } |
| 219 | 176 |
| 220 // static | 177 // static |
| 221 void WebApkInstaller::InstallAsync(content::BrowserContext* context, | 178 void WebApkInstaller::InstallAsync(content::BrowserContext* context, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 int webapk_version, | 217 int webapk_version, |
| 261 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, | 218 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, |
| 262 bool is_manifest_stale, | 219 bool is_manifest_stale, |
| 263 const FinishCallback& finish_callback) { | 220 const FinishCallback& finish_callback) { |
| 264 installer->UpdateAsync(webapk_package, webapk_version, | 221 installer->UpdateAsync(webapk_package, webapk_version, |
| 265 icon_url_to_murmur2_hash, is_manifest_stale, | 222 icon_url_to_murmur2_hash, is_manifest_stale, |
| 266 finish_callback); | 223 finish_callback); |
| 267 } | 224 } |
| 268 | 225 |
| 269 void WebApkInstaller::SetTimeoutMs(int timeout_ms) { | 226 void WebApkInstaller::SetTimeoutMs(int timeout_ms) { |
| 270 webapk_download_url_timeout_ms_ = timeout_ms; | 227 webapk_server_timeout_ms_ = timeout_ms; |
| 271 download_timeout_ms_ = timeout_ms; | |
| 272 } | 228 } |
| 273 | 229 |
| 274 void WebApkInstaller::OnInstallFinished( | 230 void WebApkInstaller::OnInstallFinished( |
| 275 JNIEnv* env, | 231 JNIEnv* env, |
| 276 const base::android::JavaParamRef<jobject>& obj, | 232 const base::android::JavaParamRef<jobject>& obj, |
| 277 jint result) { | 233 jint result) { |
| 278 OnResult(static_cast<WebApkInstallResult>(result)); | 234 OnResult(static_cast<WebApkInstallResult>(result)); |
| 279 } | 235 } |
| 280 | 236 |
| 281 void WebApkInstaller::BuildWebApkProtoInBackgroundForTesting( | 237 void WebApkInstaller::BuildWebApkProtoInBackgroundForTesting( |
| 282 const base::Callback<void(std::unique_ptr<webapk::WebApk>)>& callback, | 238 const base::Callback<void(std::unique_ptr<webapk::WebApk>)>& callback, |
| 283 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, | 239 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, |
| 284 bool is_manifest_stale) { | 240 bool is_manifest_stale) { |
| 285 base::PostTaskAndReplyWithResult( | 241 base::PostTaskAndReplyWithResult( |
| 286 GetBackgroundTaskRunner().get(), FROM_HERE, | 242 GetBackgroundTaskRunner().get(), FROM_HERE, |
| 287 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_, | 243 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_, |
| 288 icon_url_to_murmur2_hash, is_manifest_stale), | 244 icon_url_to_murmur2_hash, is_manifest_stale), |
| 289 base::Bind(&OnWebApkProtoBuilt, callback)); | 245 base::Bind(&OnWebApkProtoBuilt, callback)); |
| 290 } | 246 } |
| 291 | 247 |
| 292 // static | 248 // static |
| 293 bool WebApkInstaller::Register(JNIEnv* env) { | 249 bool WebApkInstaller::Register(JNIEnv* env) { |
| 294 return RegisterNativesImpl(env); | 250 return RegisterNativesImpl(env); |
| 295 } | 251 } |
| 296 | 252 |
| 297 void WebApkInstaller::InstallDownloadedWebApk( | 253 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() == | 254 return ChromeWebApkHost::GetGooglePlayInstallState() == |
| 314 GooglePlayInstallState::SUPPORTED; | 255 GooglePlayInstallState::SUPPORTED; |
| 315 } | 256 } |
| 316 | 257 |
| 317 void WebApkInstaller::InstallOrUpdateWebApkFromGooglePlay( | 258 void WebApkInstaller::InstallOrUpdateWebApk(const std::string& package_name, |
| 318 const std::string& package_name, | 259 int version, |
| 319 int version, | 260 const std::string& token) { |
| 320 const std::string& token) { | |
| 321 webapk_package_ = package_name; | 261 webapk_package_ = package_name; |
| 322 | 262 |
| 323 JNIEnv* env = base::android::AttachCurrentThread(); | 263 JNIEnv* env = base::android::AttachCurrentThread(); |
| 324 base::android::ScopedJavaLocalRef<jstring> java_webapk_package = | 264 base::android::ScopedJavaLocalRef<jstring> java_webapk_package = |
| 325 base::android::ConvertUTF8ToJavaString(env, webapk_package_); | 265 base::android::ConvertUTF8ToJavaString(env, webapk_package_); |
| 326 base::android::ScopedJavaLocalRef<jstring> java_title = | 266 base::android::ScopedJavaLocalRef<jstring> java_title = |
| 327 base::android::ConvertUTF16ToJavaString(env, shortcut_info_.user_title); | 267 base::android::ConvertUTF16ToJavaString(env, shortcut_info_.user_title); |
| 328 base::android::ScopedJavaLocalRef<jstring> java_token = | 268 base::android::ScopedJavaLocalRef<jstring> java_token = |
| 329 base::android::ConvertUTF8ToJavaString(env, token); | 269 base::android::ConvertUTF8ToJavaString(env, token); |
| 330 base::android::ScopedJavaLocalRef<jstring> java_url = | 270 base::android::ScopedJavaLocalRef<jstring> java_url = |
| 331 base::android::ConvertUTF8ToJavaString(env, shortcut_info_.url.spec()); | 271 base::android::ConvertUTF8ToJavaString(env, shortcut_info_.url.spec()); |
| 332 | 272 |
| 333 if (task_type_ == WebApkInstaller::INSTALL) { | 273 if (task_type_ == WebApkInstaller::INSTALL) { |
| 334 Java_WebApkInstaller_installWebApkFromGooglePlayAsync( | 274 Java_WebApkInstaller_installWebApkAsync(env, java_ref_, java_webapk_package, |
| 335 env, java_ref_, java_webapk_package, version, java_title, java_token, | 275 version, java_title, java_token, |
| 336 java_url); | 276 java_url); |
| 337 } else { | 277 } else { |
| 338 Java_WebApkInstaller_updateAsyncFromGooglePlay( | 278 Java_WebApkInstaller_updateAsync(env, java_ref_, java_webapk_package, |
| 339 env, java_ref_, java_webapk_package, version, java_title, java_token, | 279 version, java_title, java_token, java_url); |
| 340 java_url); | |
| 341 } | 280 } |
| 342 } | 281 } |
| 343 | 282 |
| 344 void WebApkInstaller::OnResult(WebApkInstallResult result) { | 283 void WebApkInstaller::OnResult(WebApkInstallResult result) { |
| 345 weak_ptr_factory_.InvalidateWeakPtrs(); | 284 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 346 finish_callback_.Run(result, relax_updates_, webapk_package_); | 285 finish_callback_.Run(result, relax_updates_, webapk_package_); |
| 347 | 286 |
| 348 if (task_type_ == WebApkInstaller::INSTALL) { | 287 if (task_type_ == WebApkInstaller::INSTALL) { |
| 349 if (result == WebApkInstallResult::SUCCESS) { | 288 if (result == WebApkInstallResult::SUCCESS) { |
| 350 webapk::TrackInstallDuration(install_duration_timer_->Elapsed()); | 289 webapk::TrackInstallDuration(install_duration_timer_->Elapsed()); |
| 351 webapk::TrackInstallEvent(webapk::INSTALL_COMPLETED); | 290 webapk::TrackInstallEvent(webapk::INSTALL_COMPLETED); |
| 352 } else { | 291 } else { |
| 353 DVLOG(1) << "The WebAPK installation failed."; | 292 DVLOG(1) << "The WebAPK installation failed."; |
| 354 webapk::TrackInstallEvent(webapk::INSTALL_FAILED); | 293 webapk::TrackInstallEvent(webapk::INSTALL_FAILED); |
| 355 } | 294 } |
| 356 } | 295 } |
| 357 | 296 |
| 358 delete this; | 297 delete this; |
| 359 } | 298 } |
| 360 | 299 |
| 361 WebApkInstaller::WebApkInstaller(content::BrowserContext* browser_context, | 300 WebApkInstaller::WebApkInstaller(content::BrowserContext* browser_context, |
| 362 const ShortcutInfo& shortcut_info, | 301 const ShortcutInfo& shortcut_info, |
| 363 const SkBitmap& shortcut_icon) | 302 const SkBitmap& shortcut_icon) |
| 364 : request_context_getter_( | 303 : request_context_getter_( |
| 365 Profile::FromBrowserContext(browser_context)->GetRequestContext()), | 304 Profile::FromBrowserContext(browser_context)->GetRequestContext()), |
| 366 shortcut_info_(shortcut_info), | 305 shortcut_info_(shortcut_info), |
| 367 shortcut_icon_(shortcut_icon), | 306 shortcut_icon_(shortcut_icon), |
| 368 server_url_(GetServerUrl()), | 307 server_url_(GetServerUrl()), |
| 369 webapk_download_url_timeout_ms_(kWebApkDownloadUrlTimeoutMs), | 308 webapk_server_timeout_ms_(kWebApkDownloadUrlTimeoutMs), |
| 370 download_timeout_ms_(kDownloadTimeoutMs), | |
| 371 relax_updates_(false), | 309 relax_updates_(false), |
| 372 webapk_version_(kDefaultWebApkVersion), | |
| 373 task_type_(UNDEFINED), | 310 task_type_(UNDEFINED), |
| 374 weak_ptr_factory_(this) { | 311 weak_ptr_factory_(this) { |
| 375 CreateJavaRef(); | 312 CreateJavaRef(); |
| 376 } | 313 } |
| 377 | 314 |
| 378 void WebApkInstaller::CreateJavaRef() { | 315 void WebApkInstaller::CreateJavaRef() { |
| 379 JNIEnv* env = base::android::AttachCurrentThread(); | 316 JNIEnv* env = base::android::AttachCurrentThread(); |
| 380 java_ref_.Reset( | 317 java_ref_.Reset( |
| 381 Java_WebApkInstaller_create(env, reinterpret_cast<intptr_t>(this))); | 318 Java_WebApkInstaller_create(env, reinterpret_cast<intptr_t>(this))); |
| 382 } | 319 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 401 weak_ptr_factory_.GetWeakPtr())); | 338 weak_ptr_factory_.GetWeakPtr())); |
| 402 } | 339 } |
| 403 | 340 |
| 404 void WebApkInstaller::UpdateAsync( | 341 void WebApkInstaller::UpdateAsync( |
| 405 const std::string& webapk_package, | 342 const std::string& webapk_package, |
| 406 int webapk_version, | 343 int webapk_version, |
| 407 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, | 344 const std::map<std::string, std::string>& icon_url_to_murmur2_hash, |
| 408 bool is_manifest_stale, | 345 bool is_manifest_stale, |
| 409 const FinishCallback& finish_callback) { | 346 const FinishCallback& finish_callback) { |
| 410 webapk_package_ = webapk_package; | 347 webapk_package_ = webapk_package; |
| 411 webapk_version_ = webapk_version; | |
| 412 finish_callback_ = finish_callback; | 348 finish_callback_ = finish_callback; |
| 413 task_type_ = UPDATE; | 349 task_type_ = UPDATE; |
| 414 | 350 |
| 415 base::PostTaskAndReplyWithResult( | 351 base::PostTaskAndReplyWithResult( |
| 416 GetBackgroundTaskRunner().get(), FROM_HERE, | 352 GetBackgroundTaskRunner().get(), FROM_HERE, |
| 417 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_, | 353 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_, |
| 418 icon_url_to_murmur2_hash, is_manifest_stale), | 354 icon_url_to_murmur2_hash, is_manifest_stale), |
| 419 base::Bind(&WebApkInstaller::SendUpdateWebApkRequest, | 355 base::Bind(&WebApkInstaller::SendUpdateWebApkRequest, |
| 420 weak_ptr_factory_.GetWeakPtr())); | 356 weak_ptr_factory_.GetWeakPtr(), webapk_version)); |
| 421 } | 357 } |
| 422 | 358 |
| 423 void WebApkInstaller::OnURLFetchComplete(const net::URLFetcher* source) { | 359 void WebApkInstaller::OnURLFetchComplete(const net::URLFetcher* source) { |
| 424 timer_.Stop(); | 360 timer_.Stop(); |
| 425 | 361 |
| 426 if (!source->GetStatus().is_success() || | 362 if (!source->GetStatus().is_success() || |
| 427 source->GetResponseCode() != net::HTTP_OK) { | 363 source->GetResponseCode() != net::HTTP_OK) { |
| 428 LOG(WARNING) << base::StringPrintf( | 364 LOG(WARNING) << base::StringPrintf( |
| 429 "WebAPK server returned response code %d.", source->GetResponseCode()); | 365 "WebAPK server returned response code %d.", source->GetResponseCode()); |
| 430 OnResult(WebApkInstallResult::FAILURE); | 366 OnResult(WebApkInstallResult::FAILURE); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 449 OnResult(WebApkInstallResult::SUCCESS); | 385 OnResult(WebApkInstallResult::SUCCESS); |
| 450 return; | 386 return; |
| 451 } | 387 } |
| 452 | 388 |
| 453 if (!signed_download_url.is_valid() || response->package_name().empty()) { | 389 if (!signed_download_url.is_valid() || response->package_name().empty()) { |
| 454 LOG(WARNING) << "WebAPK server returned incomplete proto."; | 390 LOG(WARNING) << "WebAPK server returned incomplete proto."; |
| 455 OnResult(WebApkInstallResult::FAILURE); | 391 OnResult(WebApkInstallResult::FAILURE); |
| 456 return; | 392 return; |
| 457 } | 393 } |
| 458 | 394 |
| 459 if (CanUseGooglePlayInstallService()) { | 395 if (!CanInstallWebApks()) { |
| 460 int version = 1; | 396 OnResult(WebApkInstallResult::FAILURE); |
| 461 base::StringToInt(response->version(), &version); | |
| 462 InstallOrUpdateWebApkFromGooglePlay(response->package_name(), version, | |
| 463 response->token()); | |
| 464 return; | 397 return; |
| 465 } | 398 } |
| 466 | 399 |
| 467 OnGotWebApkDownloadUrl(signed_download_url, response->package_name()); | 400 int version = 1; |
| 401 base::StringToInt(response->version(), &version); |
| 402 InstallOrUpdateWebApk(response->package_name(), version, response->token()); |
| 468 } | 403 } |
| 469 | 404 |
| 470 void WebApkInstaller::OnGotIconMurmur2Hash( | 405 void WebApkInstaller::OnGotIconMurmur2Hash( |
| 471 const std::string& icon_murmur2_hash) { | 406 const std::string& icon_murmur2_hash) { |
| 472 // An empty hash indicates that |icon_hasher_| encountered an error. | 407 // An empty hash indicates that |icon_hasher_| encountered an error. |
| 473 if (icon_murmur2_hash.empty()) { | 408 if (icon_murmur2_hash.empty()) { |
| 474 OnResult(WebApkInstallResult::FAILURE); | 409 OnResult(WebApkInstallResult::FAILURE); |
| 475 return; | 410 return; |
| 476 } | 411 } |
| 477 | 412 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 490 base::Bind(&WebApkInstaller::SendCreateWebApkRequest, | 425 base::Bind(&WebApkInstaller::SendCreateWebApkRequest, |
| 491 weak_ptr_factory_.GetWeakPtr())); | 426 weak_ptr_factory_.GetWeakPtr())); |
| 492 } | 427 } |
| 493 | 428 |
| 494 void WebApkInstaller::SendCreateWebApkRequest( | 429 void WebApkInstaller::SendCreateWebApkRequest( |
| 495 std::unique_ptr<webapk::WebApk> webapk) { | 430 std::unique_ptr<webapk::WebApk> webapk) { |
| 496 SendRequest(std::move(webapk), server_url_); | 431 SendRequest(std::move(webapk), server_url_); |
| 497 } | 432 } |
| 498 | 433 |
| 499 void WebApkInstaller::SendUpdateWebApkRequest( | 434 void WebApkInstaller::SendUpdateWebApkRequest( |
| 435 int webapk_version, |
| 500 std::unique_ptr<webapk::WebApk> webapk) { | 436 std::unique_ptr<webapk::WebApk> webapk) { |
| 501 webapk->set_package_name(webapk_package_); | 437 webapk->set_package_name(webapk_package_); |
| 502 webapk->set_version(std::to_string(webapk_version_)); | 438 webapk->set_version(std::to_string(webapk_version)); |
| 503 | 439 |
| 504 SendRequest(std::move(webapk), server_url_); | 440 SendRequest(std::move(webapk), server_url_); |
| 505 } | 441 } |
| 506 | 442 |
| 507 void WebApkInstaller::SendRequest(std::unique_ptr<webapk::WebApk> request_proto, | 443 void WebApkInstaller::SendRequest(std::unique_ptr<webapk::WebApk> request_proto, |
| 508 const GURL& server_url) { | 444 const GURL& server_url) { |
| 509 timer_.Start( | 445 timer_.Start( |
| 510 FROM_HERE, | 446 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(), | 447 base::Bind(&WebApkInstaller::OnResult, weak_ptr_factory_.GetWeakPtr(), |
| 513 WebApkInstallResult::FAILURE)); | 448 WebApkInstallResult::FAILURE)); |
| 514 | 449 |
| 515 url_fetcher_ = | 450 url_fetcher_ = |
| 516 net::URLFetcher::Create(server_url, net::URLFetcher::POST, this); | 451 net::URLFetcher::Create(server_url, net::URLFetcher::POST, this); |
| 517 url_fetcher_->SetRequestContext(request_context_getter_); | 452 url_fetcher_->SetRequestContext(request_context_getter_); |
| 518 std::string serialized_request; | 453 std::string serialized_request; |
| 519 request_proto->SerializeToString(&serialized_request); | 454 request_proto->SerializeToString(&serialized_request); |
| 520 url_fetcher_->SetUploadData(kProtoMimeType, serialized_request); | 455 url_fetcher_->SetUploadData(kProtoMimeType, serialized_request); |
| 521 url_fetcher_->SetLoadFlags( | 456 url_fetcher_->SetLoadFlags( |
| 522 net::LOAD_DISABLE_CACHE | net::LOAD_DO_NOT_SEND_COOKIES | | 457 net::LOAD_DISABLE_CACHE | net::LOAD_DO_NOT_SEND_COOKIES | |
| 523 net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_AUTH_DATA); | 458 net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_AUTH_DATA); |
| 524 url_fetcher_->Start(); | 459 url_fetcher_->Start(); |
| 525 } | 460 } |
| 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 |