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

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

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

Powered by Google App Engine
This is Rietveld 408576698