Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(362)

Side by Side Diff: chrome/browser/android/webapk/webapk_installer.cc

Issue 2791983003: Remove untrusted sources installation flow. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698