OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "shell/android/url_response_disk_cache_delegate_impl.h" |
| 6 |
| 7 #include <android/asset_manager.h> |
| 8 #include <android/asset_manager_jni.h> |
| 9 |
| 10 #include "base/android/jni_android.h" |
| 11 #include "base/bind.h" |
| 12 #include "base/callback_helpers.h" |
| 13 #include "base/files/file.h" |
| 14 #include "base/strings/string_util.h" |
| 15 #include "base/task_runner_util.h" |
| 16 |
| 17 namespace shell { |
| 18 |
| 19 namespace { |
| 20 const char kMojoApplicationSuffix[] = ".mojo"; |
| 21 } // namespace |
| 22 |
| 23 URLResponseDiskCacheDelegateImpl::URLResponseDiskCacheDelegateImpl( |
| 24 Context* context, |
| 25 jobject j_asset_manager) |
| 26 : context_(context), |
| 27 j_asset_manager_(base::android::AttachCurrentThread(), j_asset_manager), |
| 28 asset_manager_( |
| 29 AAssetManager_fromJava(base::android::AttachCurrentThread(), |
| 30 j_asset_manager_.obj())) {} |
| 31 |
| 32 URLResponseDiskCacheDelegateImpl::~URLResponseDiskCacheDelegateImpl() {} |
| 33 |
| 34 void URLResponseDiskCacheDelegateImpl::GetInitialPath( |
| 35 scoped_refptr<base::TaskRunner> task_runner, |
| 36 const std::string& url, |
| 37 const base::FilePath& target, |
| 38 const base::Callback<void(bool)>& callback) { |
| 39 PopulateAssetsIfNeeded(); |
| 40 if (url_to_asset_name_.find(url) == url_to_asset_name_.end()) { |
| 41 callback.Run(false); |
| 42 return; |
| 43 } |
| 44 |
| 45 PostTaskAndReplyWithResult( |
| 46 task_runner.get(), FROM_HERE, |
| 47 base::Bind(&URLResponseDiskCacheDelegateImpl::ExtractAsset, |
| 48 base::Unretained(this), url_to_asset_name_[url], target), |
| 49 callback); |
| 50 } |
| 51 |
| 52 bool URLResponseDiskCacheDelegateImpl::ExtractAsset( |
| 53 const std::string& asset_name, |
| 54 const base::FilePath& target) { |
| 55 AAsset* asset = AAssetManager_open(asset_manager_, asset_name.c_str(), |
| 56 AASSET_MODE_STREAMING); |
| 57 if (!asset) |
| 58 return false; |
| 59 base::ScopedClosureRunner cleanup( |
| 60 base::Bind(&AAsset_close, base::Unretained(asset))); |
| 61 base::File target_file(target, |
| 62 base::File::FLAG_CREATE | base::File::FLAG_WRITE); |
| 63 if (!target_file.IsValid()) |
| 64 return false; |
| 65 char buffer[4096]; |
| 66 int nb_read; |
| 67 do { |
| 68 nb_read = AAsset_read(asset, buffer, arraysize(buffer)); |
| 69 if (nb_read > 0) { |
| 70 if (target_file.WriteAtCurrentPos(buffer, nb_read) != nb_read) |
| 71 return false; |
| 72 } |
| 73 } while (nb_read > 0); |
| 74 return nb_read == 0; |
| 75 } |
| 76 |
| 77 void URLResponseDiskCacheDelegateImpl::PopulateAssetsIfNeeded() { |
| 78 if (url_to_asset_name_.empty()) { |
| 79 AAssetDir* dir = AAssetManager_openDir(asset_manager_, ""); |
| 80 if (!dir) |
| 81 return; |
| 82 base::ScopedClosureRunner cleanup( |
| 83 base::Bind(&AAssetDir_close, base::Unretained(dir))); |
| 84 while (const char* filename = AAssetDir_getNextFileName(dir)) { |
| 85 std::string file_name_string = filename; |
| 86 if (EndsWith(file_name_string, kMojoApplicationSuffix, true)) { |
| 87 std::string base_name = file_name_string.substr( |
| 88 0, |
| 89 file_name_string.size() - (arraysize(kMojoApplicationSuffix) - 1)); |
| 90 std::string url = context_->url_resolver() |
| 91 ->ResolveMojoURL(GURL("mojo:" + base_name)) |
| 92 .spec(); |
| 93 url_to_asset_name_[url] = file_name_string; |
| 94 } |
| 95 } |
| 96 } |
| 97 } |
| 98 |
| 99 } // namespace shell |
OLD | NEW |