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