Index: shell/android/url_response_disk_cache_delegate_impl.cc |
diff --git a/shell/android/url_response_disk_cache_delegate_impl.cc b/shell/android/url_response_disk_cache_delegate_impl.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..5e7d0acf3171e0d7697cf5cc3a6aeea9bed96702 |
--- /dev/null |
+++ b/shell/android/url_response_disk_cache_delegate_impl.cc |
@@ -0,0 +1,99 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "shell/android/url_response_disk_cache_delegate_impl.h" |
+ |
+#include <android/asset_manager.h> |
+#include <android/asset_manager_jni.h> |
+ |
+#include "base/android/jni_android.h" |
+#include "base/bind.h" |
+#include "base/callback_helpers.h" |
+#include "base/files/file.h" |
+#include "base/strings/string_util.h" |
+#include "base/task_runner_util.h" |
+ |
+namespace shell { |
+ |
+namespace { |
+const char kMojoApplicationSuffix[] = ".mojo"; |
+} // namespace |
+ |
+URLResponseDiskCacheDelegateImpl::URLResponseDiskCacheDelegateImpl( |
+ Context* context, |
+ jobject j_asset_manager) |
+ : context_(context), |
+ j_asset_manager_(base::android::AttachCurrentThread(), j_asset_manager), |
+ asset_manager_( |
+ AAssetManager_fromJava(base::android::AttachCurrentThread(), |
+ j_asset_manager_.obj())) {} |
+ |
+URLResponseDiskCacheDelegateImpl::~URLResponseDiskCacheDelegateImpl() {} |
+ |
+void URLResponseDiskCacheDelegateImpl::GetInitialPath( |
+ scoped_refptr<base::TaskRunner> task_runner, |
+ const std::string& url, |
+ const base::FilePath& target, |
+ const base::Callback<void(bool)>& callback) { |
+ PopulateAssetsIfNeeded(); |
+ if (url_to_asset_name_.find(url) == url_to_asset_name_.end()) { |
+ callback.Run(false); |
+ return; |
+ } |
+ |
+ PostTaskAndReplyWithResult( |
+ task_runner.get(), FROM_HERE, |
+ base::Bind(&URLResponseDiskCacheDelegateImpl::ExtractAsset, |
+ base::Unretained(this), url_to_asset_name_[url], target), |
+ callback); |
+} |
+ |
+bool URLResponseDiskCacheDelegateImpl::ExtractAsset( |
+ const std::string& asset_name, |
+ const base::FilePath& target) { |
+ AAsset* asset = AAssetManager_open(asset_manager_, asset_name.c_str(), |
+ AASSET_MODE_STREAMING); |
+ if (!asset) |
+ return false; |
+ base::ScopedClosureRunner cleanup( |
+ base::Bind(&AAsset_close, base::Unretained(asset))); |
+ base::File target_file(target, |
+ base::File::FLAG_CREATE | base::File::FLAG_WRITE); |
+ if (!target_file.IsValid()) |
+ return false; |
+ char buffer[4096]; |
+ int nb_read; |
+ do { |
+ nb_read = AAsset_read(asset, buffer, arraysize(buffer)); |
+ if (nb_read > 0) { |
+ if (target_file.WriteAtCurrentPos(buffer, nb_read) != nb_read) |
+ return false; |
+ } |
+ } while (nb_read > 0); |
+ return nb_read == 0; |
+} |
+ |
+void URLResponseDiskCacheDelegateImpl::PopulateAssetsIfNeeded() { |
+ if (url_to_asset_name_.empty()) { |
+ AAssetDir* dir = AAssetManager_openDir(asset_manager_, ""); |
+ if (!dir) |
+ return; |
+ base::ScopedClosureRunner cleanup( |
+ base::Bind(&AAssetDir_close, base::Unretained(dir))); |
+ while (const char* filename = AAssetDir_getNextFileName(dir)) { |
+ std::string file_name_string = filename; |
+ if (EndsWith(file_name_string, kMojoApplicationSuffix, true)) { |
+ std::string base_name = file_name_string.substr( |
+ 0, |
+ file_name_string.size() - (arraysize(kMojoApplicationSuffix) - 1)); |
+ std::string url = context_->url_resolver() |
+ ->ResolveMojoURL(GURL("mojo:" + base_name)) |
+ .spec(); |
+ url_to_asset_name_[url] = file_name_string; |
+ } |
+ } |
+ } |
+} |
+ |
+} // namespace shell |