From 364a6940b6dfaecd59a01a07a45d984e37dd8aff Mon Sep 17 00:00:00 2001 From: Sarah Zakarias Date: Fri, 23 Feb 2018 15:39:05 +0100 Subject: [PATCH 1/3] Read assets out of APK on Android --- assets/BUILD.gn | 1 + assets/asset_provider.h | 25 ++++++ assets/directory_asset_bundle.h | 7 +- lib/ui/text/font_collection.cc | 14 +-- lib/ui/text/font_collection.h | 6 +- runtime/asset_font_selector.cc | 18 ++-- runtime/asset_font_selector.h | 6 +- shell/common/engine.cc | 27 +++--- shell/common/engine.h | 2 + shell/common/platform_view.cc | 4 + shell/common/platform_view.h | 5 ++ shell/platform/android/BUILD.gn | 3 + shell/platform/android/apk_asset_provider.cc | 38 ++++++++ shell/platform/android/apk_asset_provider.h | 32 +++++++ .../android/io/flutter/view/FlutterMain.java | 12 ++- .../io/flutter/view/FlutterNativeView.java | 8 +- .../io/flutter/view/ResourceExtractor.java | 87 +++++++++---------- .../platform/android/platform_view_android.cc | 11 ++- .../platform/android/platform_view_android.h | 5 +- .../android/platform_view_android_jni.cc | 9 +- 20 files changed, 226 insertions(+), 94 deletions(-) create mode 100644 assets/asset_provider.h create mode 100644 shell/platform/android/apk_asset_provider.cc create mode 100644 shell/platform/android/apk_asset_provider.h diff --git a/assets/BUILD.gn b/assets/BUILD.gn index 6f9107929f971..c4901375ad810 100644 --- a/assets/BUILD.gn +++ b/assets/BUILD.gn @@ -4,6 +4,7 @@ source_set("assets") { sources = [ + "asset_provider.h", "directory_asset_bundle.cc", "directory_asset_bundle.h", "unzipper_provider.cc", diff --git a/assets/asset_provider.h b/assets/asset_provider.h new file mode 100644 index 0000000000000..68b7f5c2b7b9c --- /dev/null +++ b/assets/asset_provider.h @@ -0,0 +1,25 @@ +// Copyright 2018 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. + +#ifndef FLUTTER_ASSETS_ASSET_PROVIDER_H_ +#define FLUTTER_ASSETS_ASSET_PROVIDER_H_ + +#include +#include + +#include "lib/fxl/memory/ref_counted.h" + +namespace blink { + +class AssetProvider + : public fxl::RefCountedThreadSafe + { + public: + virtual bool GetAsBuffer(const std::string& asset_name, + std::vector* data) = 0; + virtual ~AssetProvider() = default; +}; + +} // namespace blink +#endif // FLUTTER_ASSETS_ASSET_PROVIDER_H diff --git a/assets/directory_asset_bundle.h b/assets/directory_asset_bundle.h index ddccd175c1230..a30b0a3f3ec19 100644 --- a/assets/directory_asset_bundle.h +++ b/assets/directory_asset_bundle.h @@ -8,6 +8,7 @@ #include #include +#include "flutter/assets/asset_provider.h" #include "lib/fxl/files/unique_fd.h" #include "lib/fxl/macros.h" #include "lib/fxl/memory/ref_counted.h" @@ -15,14 +16,14 @@ namespace blink { class DirectoryAssetBundle - : public fxl::RefCountedThreadSafe { + : public blink::AssetProvider { public: explicit DirectoryAssetBundle(std::string directory); // Expects fd to be valid, otherwise the file descriptor is ignored. explicit DirectoryAssetBundle(fxl::UniqueFD fd); - ~DirectoryAssetBundle(); + virtual ~DirectoryAssetBundle(); - bool GetAsBuffer(const std::string& asset_name, std::vector* data); + virtual bool GetAsBuffer(const std::string& asset_name, std::vector* data); std::string GetPathForAsset(const std::string& asset_name); diff --git a/lib/ui/text/font_collection.cc b/lib/ui/text/font_collection.cc index 5a8baa3d2538c..68e0c02349b6a 100644 --- a/lib/ui/text/font_collection.cc +++ b/lib/ui/text/font_collection.cc @@ -34,15 +34,15 @@ std::shared_ptr FontCollection::GetFontCollection() const { return collection_; } -void FontCollection::RegisterFontsFromDirectoryAssetBundle( - fxl::RefPtr directory_asset_bundle) { - if (!directory_asset_bundle) { +void FontCollection::RegisterFontsFromAssetProvider( + fxl::RefPtr asset_provider) { + + if (!asset_provider){ return; } std::vector manifest_data; - if (!directory_asset_bundle->GetAsBuffer("FontManifest.json", - &manifest_data)) { + if (!asset_provider->GetAsBuffer("FontManifest.json", &manifest_data)) { FXL_DLOG(WARNING) << "Could not find the font manifest in the asset store."; return; } @@ -92,8 +92,8 @@ void FontCollection::RegisterFontsFromDirectoryAssetBundle( // TODO: Handle weights and styles. std::vector font_data; - if (directory_asset_bundle->GetAsBuffer(font_asset->value.GetString(), - &font_data)) { + if (asset_provider->GetAsBuffer(font_asset->value.GetString(), + &font_data)) { // The data must be copied because it needs to be moved into the // typeface as a stream. auto data = diff --git a/lib/ui/text/font_collection.h b/lib/ui/text/font_collection.h index e99d6ef9227d8..fb393b1582b79 100644 --- a/lib/ui/text/font_collection.h +++ b/lib/ui/text/font_collection.h @@ -7,7 +7,7 @@ #include #include -#include "flutter/assets/directory_asset_bundle.h" +#include "flutter/assets/asset_provider.h" #include "lib/fxl/macros.h" #include "lib/fxl/memory/ref_ptr.h" #include "txt/asset_data_provider.h" @@ -21,9 +21,7 @@ class FontCollection { std::shared_ptr GetFontCollection() const; - void RegisterFontsFromDirectoryAssetBundle( - fxl::RefPtr directory_asset_bundle); - + void RegisterFontsFromAssetProvider(fxl::RefPtr asset_provider); void RegisterTestFonts(); private: diff --git a/runtime/asset_font_selector.cc b/runtime/asset_font_selector.cc index ad49fde46563d..abf4bf9874ddd 100644 --- a/runtime/asset_font_selector.cc +++ b/runtime/asset_font_selector.cc @@ -81,9 +81,9 @@ struct FontMatcher { } // namespace void AssetFontSelector::Install( - fxl::RefPtr directory_asset_bundle) { + fxl::RefPtr asset_provider) { RefPtr font_selector = - adoptRef(new AssetFontSelector(std::move(directory_asset_bundle))); + adoptRef(new AssetFontSelector(std::move(asset_provider))); font_selector->parseFontManifest(); UIDartState::Current()->set_font_selector(font_selector); } @@ -96,8 +96,8 @@ void AssetFontSelector::Install(fxl::RefPtr asset_store) { } AssetFontSelector::AssetFontSelector( - fxl::RefPtr directory_asset_bundle) - : directory_asset_bundle_(std::move(directory_asset_bundle)) {} + fxl::RefPtr asset_provider) + : asset_provider_(std::move(asset_provider)) {} AssetFontSelector::AssetFontSelector(fxl::RefPtr asset_store) : asset_store_(std::move(asset_store)) {} @@ -118,9 +118,9 @@ AssetFontSelector::FlutterFontAttributes::~FlutterFontAttributes() {} void AssetFontSelector::parseFontManifest() { std::vector font_manifest_data; - if (!directory_asset_bundle_ || - !directory_asset_bundle_->GetAsBuffer(kFontManifestAssetPath, - &font_manifest_data)) { + if (!asset_provider_ || + !asset_provider_->GetAsBuffer(kFontManifestAssetPath, + &font_manifest_data)) { if (!asset_store_ || !asset_store_->GetAsBuffer(kFontManifestAssetPath, &font_manifest_data)) return; @@ -239,8 +239,8 @@ sk_sp AssetFontSelector::getTypefaceAsset( } std::unique_ptr typeface_asset(new TypefaceAsset); - if (!directory_asset_bundle_ || !directory_asset_bundle_->GetAsBuffer( - asset_path, &typeface_asset->data)) { + if (!asset_provider_ || !asset_provider_->GetAsBuffer( + asset_path, &typeface_asset->data)) { if (!asset_store_ || !asset_store_->GetAsBuffer(asset_path, &typeface_asset->data)) { typeface_cache_.insert(std::make_pair(asset_path, nullptr)); diff --git a/runtime/asset_font_selector.h b/runtime/asset_font_selector.h index ced5ebc595041..921c0472dba78 100644 --- a/runtime/asset_font_selector.h +++ b/runtime/asset_font_selector.h @@ -24,7 +24,7 @@ class AssetFontSelector : public FontSelector { ~AssetFontSelector() override; - static void Install(fxl::RefPtr directory_asset_bundle); + static void Install(fxl::RefPtr asset_provider); // TODO(zarah): Remove this and related code using asset_store once flx is // removed. @@ -45,7 +45,7 @@ class AssetFontSelector : public FontSelector { struct TypefaceAsset; explicit AssetFontSelector( - fxl::RefPtr directory_asset_bundle); + fxl::RefPtr asset_provider); explicit AssetFontSelector(fxl::RefPtr asset_store); @@ -54,7 +54,7 @@ class AssetFontSelector : public FontSelector { sk_sp getTypefaceAsset(const FontDescription& font_description, const AtomicString& family_name); - fxl::RefPtr directory_asset_bundle_; + fxl::RefPtr asset_provider_; fxl::RefPtr asset_store_; diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 8d91e7d1d11e9..f7b606baf66d6 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -32,6 +32,7 @@ #include "flutter/assets/directory_asset_bundle.h" #include "flutter/assets/unzipper_provider.h" #include "flutter/assets/zip_asset_store.h" +#include "flutter/assets/asset_provider.h" #include "flutter/common/settings.h" #include "flutter/common/threads.h" #include "flutter/glue/trace_event.h" @@ -288,7 +289,6 @@ void Engine::Init(const std::string& bundle_path) { #else #error Unknown OS #endif - blink::InitRuntime(vm_snapshot_data, vm_snapshot_instr, default_isolate_snapshot_data, default_isolate_snapshot_instr, bundle_path); @@ -312,7 +312,7 @@ void Engine::RunBundle(const std::string& bundle_path, return; } std::vector snapshot; - if (!GetAssetAsBuffer(blink::kSnapshotAssetKey, &snapshot)) + if (!GetAssetAsBuffer(blink::kSnapshotAssetKey, &snapshot)) return; runtime_->dart_controller()->RunFromScriptSnapshot( snapshot.data(), snapshot.size(), entrypoint); @@ -573,6 +573,12 @@ void Engine::SetSemanticsEnabled(bool enabled) { } void Engine::ConfigureAssetBundle(const std::string& path) { + auto platform_view = platform_view_.lock(); + asset_provider_ = platform_view->GetAssetProvider(); + if (!asset_provider_) { + asset_provider_ = fxl::MakeRefCounted(path); + } + struct stat stat_result = {}; // TODO(abarth): We should reset directory_asset_bundle_, but that might break @@ -585,8 +591,6 @@ void Engine::ConfigureAssetBundle(const std::string& path) { std::string flx_path; if (S_ISDIR(stat_result.st_mode)) { - directory_asset_bundle_ = - fxl::MakeRefCounted(path); flx_path = files::GetDirectoryName(path) + "/app.flx"; } else if (S_ISREG(stat_result.st_mode)) { flx_path = path; @@ -618,11 +622,11 @@ void Engine::DidCreateMainIsolate(Dart_Isolate isolate) { blink::TestFontSelector::Install(); if (!blink::Settings::Get().using_blink) blink::FontCollection::ForProcess().RegisterTestFonts(); - } else if (directory_asset_bundle_) { - blink::AssetFontSelector::Install(directory_asset_bundle_); + } else if (asset_provider_) { + blink::AssetFontSelector::Install(asset_provider_); if (!blink::Settings::Get().using_blink) { - blink::FontCollection::ForProcess().RegisterFontsFromDirectoryAssetBundle( - directory_asset_bundle_); + blink::FontCollection::ForProcess().RegisterFontsFromAssetProvider( + asset_provider_); } } } @@ -693,7 +697,6 @@ void Engine::HandleAssetPlatformMessage( const auto& data = message->data(); std::string asset_name(reinterpret_cast(data.data()), data.size()); - std::vector asset_data; if (GetAssetAsBuffer(asset_name, &asset_data)) { response->Complete(std::move(asset_data)); @@ -704,9 +707,9 @@ void Engine::HandleAssetPlatformMessage( bool Engine::GetAssetAsBuffer(const std::string& name, std::vector* data) { - return (directory_asset_bundle_ && - directory_asset_bundle_->GetAsBuffer(name, data)) || - (asset_store_ && asset_store_->GetAsBuffer(name, data)); + return ((asset_provider_ && + asset_provider_->GetAsBuffer(name, data)) || + (asset_store_ && asset_store_->GetAsBuffer(name, data))); } } // namespace shell diff --git a/shell/common/engine.h b/shell/common/engine.h index fab9e47b66217..e5d327ae625cf 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -6,6 +6,7 @@ #define SHELL_COMMON_ENGINE_H_ #include "flutter/assets/zip_asset_store.h" +#include "flutter/assets/asset_provider.h" #include "flutter/lib/ui/window/platform_message.h" #include "flutter/lib/ui/window/viewport_metrics.h" #include "flutter/runtime/runtime_controller.h" @@ -109,6 +110,7 @@ class Engine : public blink::RuntimeDelegate { static const std::string main_entrypoint_; + fxl::RefPtr asset_provider_; std::weak_ptr platform_view_; std::unique_ptr animator_; std::unique_ptr runtime_; diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index 2d5715a1733bd..b015b8c4a115b 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -126,6 +126,10 @@ VsyncWaiter* PlatformView::GetVsyncWaiter() { return vsync_waiter_.get(); } +fxl::RefPtr PlatformView::GetAssetProvider() { + return asset_provider_; +} + void PlatformView::UpdateSemantics(blink::SemanticsNodeUpdates update) {} void PlatformView::HandlePlatformMessage( diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 1a21076f63f81..1f4cac3aa4a85 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -7,6 +7,7 @@ #include +#include "flutter/assets/asset_provider.h" #include "flutter/flow/texture.h" #include "flutter/lib/ui/semantics/semantics_node.h" #include "flutter/shell/common/engine.h" @@ -64,6 +65,8 @@ class PlatformView : public std::enable_shared_from_this { virtual void HandlePlatformMessage( fxl::RefPtr message); + virtual fxl::RefPtr GetAssetProvider(); + // Called once per texture, on the platform thread. void RegisterTexture(std::shared_ptr texture); @@ -97,6 +100,8 @@ class PlatformView : public std::enable_shared_from_this { flow::TextureRegistry texture_registry_; std::unique_ptr engine_; std::unique_ptr vsync_waiter_; + fxl::RefPtr asset_provider_; + SkISize size_; private: diff --git a/shell/platform/android/BUILD.gn b/shell/platform/android/BUILD.gn index 5de1308f408ba..d9744ad890caa 100644 --- a/shell/platform/android/BUILD.gn +++ b/shell/platform/android/BUILD.gn @@ -27,6 +27,8 @@ shared_library("flutter_shell_native") { "android_surface_gl.h", "android_surface_software.h", "android_surface_software.cc", + "apk_asset_provider.h", + "apk_asset_provider.cc", "flutter_main.cc", "flutter_main.h", "library_loader.cc", @@ -42,6 +44,7 @@ shared_library("flutter_shell_native") { "$flutter_root/common", "$flutter_root/flow", "$flutter_root/fml", + "$flutter_root/assets", "$flutter_root/lib/ui", "$flutter_root/runtime", "$flutter_root/shell/common", diff --git a/shell/platform/android/apk_asset_provider.cc b/shell/platform/android/apk_asset_provider.cc new file mode 100644 index 0000000000000..ae55a36b950a9 --- /dev/null +++ b/shell/platform/android/apk_asset_provider.cc @@ -0,0 +1,38 @@ +#include +#include +#include + +#include "flutter/shell/platform/android/apk_asset_provider.h" +#include "lib/fxl/logging.h" + +namespace blink { + +bool APKAssetProvider::GetAsBuffer(const std::string& asset_name, + std::vector* data) { + std::stringstream ss; + ss << directory_.c_str() << "/" << asset_name; + AAsset* asset = AAssetManager_open(assetManager_, ss.str().c_str(), AASSET_MODE_RANDOM); + if (!asset) { + return false; + } + + uint8_t* buffer = (uint8_t*)AAsset_getBuffer(asset); + if (!buffer) { + FXL_LOG(ERROR) << "Got null trying to acquire buffer for asset:" << asset; + return false; + } + + data->resize(AAsset_getLength(asset)); + std::copy(buffer, buffer + data->size() , data->begin()); + AAsset_close(asset); + return true; +} + +APKAssetProvider::~APKAssetProvider() {} + +APKAssetProvider::APKAssetProvider(JNIEnv* env, jobject jassetManager, std::string directory) + : directory_(std::move(directory)) { + assetManager_ = AAssetManager_fromJava(env, jassetManager); +} + +} // namespace blink diff --git a/shell/platform/android/apk_asset_provider.h b/shell/platform/android/apk_asset_provider.h new file mode 100644 index 0000000000000..c40b1ed2a1866 --- /dev/null +++ b/shell/platform/android/apk_asset_provider.h @@ -0,0 +1,32 @@ +// Copyright 2018 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. + +#ifndef FLUTTER_ASSETS_APK_ASSET_PROVIDER_H_ +#define FLUTTER_ASSETS_APK_ASSET_PROVIDER_H_ + +#include +#include + +#include "flutter/assets/asset_provider.h" +#include "lib/fxl/memory/ref_counted.h" + +namespace blink { + +class APKAssetProvider + : public AssetProvider { + public: + explicit APKAssetProvider(JNIEnv* env, jobject assetManager, std::string directory); + virtual ~APKAssetProvider(); + + virtual bool GetAsBuffer(const std::string& asset_name, + std::vector* data); + + private: + AAssetManager* assetManager_; + const std::string directory_; +}; + +} // namespace blink + +#endif // FLUTTER_ASSETS_APK_ASSET_PROVIDER_H \ No newline at end of file diff --git a/shell/platform/android/io/flutter/view/FlutterMain.java b/shell/platform/android/io/flutter/view/FlutterMain.java index 5fa613c865347..2ab81444a122f 100644 --- a/shell/platform/android/io/flutter/view/FlutterMain.java +++ b/shell/platform/android/io/flutter/view/FlutterMain.java @@ -66,10 +66,16 @@ public class FlutterMain { private static final String DEFAULT_AOT_ISOLATE_SNAPSHOT_INSTR = "isolate_snapshot_instr"; private static final String DEFAULT_FLX = "app.flx"; private static final String DEFAULT_SNAPSHOT_BLOB = "snapshot_blob.bin"; + private static final String DEFAULT_KERNEL_BLOB = "kernel_blob.bin"; + private static final String DEFAULT_PLATFORM_DILL = "platform.dill"; private static final String DEFAULT_FLUTTER_ASSETS_DIR = "flutter_assets"; private static final String MANIFEST = "flutter.yaml"; + private static String fromFlutterAssets(String filePath) { + return sFlutterAssetsDir + "/" + filePath; + } + private static final Set SKY_RESOURCES = ImmutableSetBuilder.newInstance() .add("icudtl.dat") .add(MANIFEST) @@ -244,8 +250,10 @@ private static void initResources(Context applicationContext) { new ResourceCleaner(context).start(); sResourceExtractor = new ResourceExtractor(context) .addResources(SKY_RESOURCES) - .addResource(sFlx) - .addResource(sFlutterAssetsDir); + .addResource(fromFlutterAssets(sFlx)) + .addResource(fromFlutterAssets(sSnapshotBlob)) + .addResource(fromFlutterAssets(DEFAULT_KERNEL_BLOB)) + .addResource(fromFlutterAssets(DEFAULT_PLATFORM_DILL)); if (sIsPrecompiledAsSharedLibrary) { sResourceExtractor .addResource(sAotSharedLibraryPath); diff --git a/shell/platform/android/io/flutter/view/FlutterNativeView.java b/shell/platform/android/io/flutter/view/FlutterNativeView.java index 83421c20b837c..034a86d09d91f 100644 --- a/shell/platform/android/io/flutter/view/FlutterNativeView.java +++ b/shell/platform/android/io/flutter/view/FlutterNativeView.java @@ -13,6 +13,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.HashMap; import java.util.Map; +import android.content.res.AssetManager; public class FlutterNativeView implements BinaryMessenger { private static final String TAG = "FlutterNativeView"; @@ -24,8 +25,10 @@ public class FlutterNativeView implements BinaryMessenger { private final FlutterPluginRegistry mPluginRegistry; private long mNativePlatformView; private FlutterView mFlutterView; + private final Context mContext; public FlutterNativeView(Context context) { + mContext = context; mPluginRegistry = new FlutterPluginRegistry(this, context); attach(this); assertAttached(); @@ -68,7 +71,7 @@ public void assertAttached() { public void runFromBundle(String bundlePath, String snapshotOverride, String entrypoint, boolean reuseRuntimeController) { assertAttached(); - nativeRunBundleAndSnapshot(mNativePlatformView, bundlePath, snapshotOverride, entrypoint, reuseRuntimeController); + nativeRunBundleAndSnapshot(mNativePlatformView, bundlePath, snapshotOverride, entrypoint, reuseRuntimeController, mContext.getResources().getAssets()); } public void runFromSource(final String assetsDirectory, final String main, final String packages) { @@ -194,7 +197,8 @@ private static native void nativeRunBundleAndSnapshot(long nativePlatformViewAnd String bundlePath, String snapshotOverride, String entrypoint, - boolean reuseRuntimeController); + boolean reuseRuntimeController, + AssetManager manager); private static native void nativeRunBundleAndSource(long nativePlatformViewAndroid, String bundlePath, diff --git a/shell/platform/android/io/flutter/view/ResourceExtractor.java b/shell/platform/android/io/flutter/view/ResourceExtractor.java index 0975e089cb273..40ea70e90198a 100644 --- a/shell/platform/android/io/flutter/view/ResourceExtractor.java +++ b/shell/platform/android/io/flutter/view/ResourceExtractor.java @@ -13,6 +13,7 @@ import java.io.File; import java.io.FileOutputStream; +import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; @@ -36,7 +37,7 @@ class ResourceExtractor { private class ExtractTask extends AsyncTask { private static final int BUFFER_SIZE = 16 * 1024; - ExtractTask() { } + ExtractTask() {} private void extractResources() { final File dataDir = new File(PathUtils.getDataDirectory(mContext)); @@ -47,48 +48,52 @@ private void extractResources() { } final AssetManager manager = mContext.getResources().getAssets(); - try { - byte[] buffer = null; - final String[] assets = manager.list(""); - LinkedList assetList = new LinkedList<>(Arrays.asList(assets)); - while(!assetList.isEmpty()) { - String asset = assetList.pop(); - if (!mResources.contains(asset)) - continue; - - if (manager.list(asset).length > 0) { - // The asset is a directory - for (String a: manager.list(asset)) { - assetList.add(asset + File.separator + a); - mResources.add(asset + File.separator + a); - } - continue; - } + byte[] buffer = null; + for (String asset : mResources) { + try { final File output = new File(dataDir, asset); - if (output.exists()) + + if (output.exists()) { continue; + } if (output.getParentFile() != null) { output.getParentFile().mkdirs(); } - try (InputStream is = manager.open(asset)) { - try (OutputStream os = new FileOutputStream(output)) { - if (buffer == null) { - buffer = new byte[BUFFER_SIZE]; - } - - int count = 0; - while ((count = is.read(buffer, 0, BUFFER_SIZE)) != -1) { - os.write(buffer, 0, count); + + OutputStream os = null; + InputStream is = null; + try { + os = new FileOutputStream(output); + is = manager.open(asset); + + if (buffer == null) { + buffer = new byte[BUFFER_SIZE]; + } + + int count = 0; + while ((count = is.read(buffer, 0, BUFFER_SIZE)) != -1) { + os.write(buffer, 0, count); + } + os.flush(); + } finally { + try { + if (os != null) { + os.close(); + } + } finally { + if (is != null) { + is.close(); } - os.flush(); - } - } + } + } + } catch (FileNotFoundException fnfe) { + continue; + } catch (IOException ioe) { + Log.w(TAG, "Exception unpacking resources: " + ioe.getMessage()); + deleteFiles(); + return; } - } catch (IOException e) { - Log.w(TAG, "Exception unpacking resources: " + e.getMessage()); - deleteFiles(); - return; } if (timestamp != null) { @@ -184,18 +189,10 @@ public boolean accept(File dir, String name) { private void deleteFiles() { final File dataDir = new File(PathUtils.getDataDirectory(mContext)); - LinkedList files = new LinkedList<>(mResources); - while (!files.isEmpty()) { - String resource = files.pop(); + for (String resource : mResources) { final File file = new File(dataDir, resource); if (file.exists()) { - if (file.isFile()) { - file.delete(); - } else { - for (String f : file.list()) { - files.add(resource + File.separator + f); - } - } + file.delete(); } } for (String timestamp : getExistingTimestamps(dataDir)) { diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index 5fc7fab00bbdb..7c1d115fc9f98 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -21,6 +21,7 @@ #include "flutter/shell/platform/android/android_external_texture_gl.h" #include "flutter/shell/platform/android/android_surface_gl.h" #include "flutter/shell/platform/android/android_surface_software.h" +#include "flutter/shell/platform/android/apk_asset_provider.h" #include "flutter/shell/platform/android/platform_view_android_jni.h" #include "flutter/shell/platform/android/vsync_waiter_android.h" #include "lib/fxl/functional/make_copyable.h" @@ -207,10 +208,16 @@ void PlatformViewAndroid::SurfaceDestroyed() { ReleaseSurface(); } -void PlatformViewAndroid::RunBundleAndSnapshot(std::string bundle_path, +void PlatformViewAndroid::RunBundleAndSnapshot(JNIEnv* env, std::string bundle_path, std::string snapshot_override, std::string entrypoint, - bool reuse_runtime_controller) { + bool reuse_runtime_controller, + jobject assetManager) { + // The flutter assets directory name is the last directory of the bundle_path and the path into the APK + size_t last_slash_idx = bundle_path.rfind("/", bundle_path.size()); + std::string flutter_assets_dir = bundle_path.substr(last_slash_idx+1, bundle_path.size()-last_slash_idx); + + asset_provider_ = fxl::MakeRefCounted(env, assetManager, flutter_assets_dir); blink::Threads::UI()->PostTask([ engine = engine_->GetWeakPtr(), bundle_path = std::move(bundle_path), snapshot_override = std::move(snapshot_override), diff --git a/shell/platform/android/platform_view_android.h b/shell/platform/android/platform_view_android.h index f207f65a870b1..4779ea16ab4a7 100644 --- a/shell/platform/android/platform_view_android.h +++ b/shell/platform/android/platform_view_android.h @@ -38,10 +38,11 @@ class PlatformViewAndroid : public PlatformView { void SurfaceDestroyed(); - void RunBundleAndSnapshot(std::string bundle_path, + void RunBundleAndSnapshot(JNIEnv* env, std::string bundle_path, std::string snapshot_override, std::string entrypoint, - bool reuse_isolate); + bool reuse_isolate, + jobject assetManager); void RunBundleAndSource(std::string bundle_path, std::string main, diff --git a/shell/platform/android/platform_view_android_jni.cc b/shell/platform/android/platform_view_android_jni.cc index 80f3d9626086a..c819f3bfb5e41 100644 --- a/shell/platform/android/platform_view_android_jni.cc +++ b/shell/platform/android/platform_view_android_jni.cc @@ -160,12 +160,15 @@ static void RunBundleAndSnapshot(JNIEnv* env, jstring bundlePath, jstring snapshotOverride, jstring entrypoint, - jboolean reuse_runtime_controller) { + jboolean reuse_runtime_controller, + jobject assetManager) { return PLATFORM_VIEW->RunBundleAndSnapshot( + env, fml::jni::JavaStringToString(env, bundlePath), // fml::jni::JavaStringToString(env, snapshotOverride), // fml::jni::JavaStringToString(env, entrypoint), // - reuse_runtime_controller // + reuse_runtime_controller, // + assetManager ); } @@ -351,7 +354,7 @@ bool PlatformViewAndroid::Register(JNIEnv* env) { { .name = "nativeRunBundleAndSnapshot", .signature = - "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", + "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLandroid/content/res/AssetManager;)V", .fnPtr = reinterpret_cast(&shell::RunBundleAndSnapshot), }, { From 74b456d554342da245146baa6710db629f552ec3 Mon Sep 17 00:00:00 2001 From: Sarah Zakarias Date: Mon, 5 Mar 2018 12:43:57 +0100 Subject: [PATCH 2/3] comments --- assets/directory_asset_bundle.h | 2 +- shell/common/engine.cc | 3 +- shell/common/platform_view.h | 2 +- shell/platform/android/apk_asset_provider.cc | 4 +-- .../io/flutter/view/ResourceExtractor.java | 33 ++++++------------- 5 files changed, 15 insertions(+), 29 deletions(-) diff --git a/assets/directory_asset_bundle.h b/assets/directory_asset_bundle.h index a30b0a3f3ec19..c710a513796ae 100644 --- a/assets/directory_asset_bundle.h +++ b/assets/directory_asset_bundle.h @@ -16,7 +16,7 @@ namespace blink { class DirectoryAssetBundle - : public blink::AssetProvider { + : public AssetProvider { public: explicit DirectoryAssetBundle(std::string directory); // Expects fd to be valid, otherwise the file descriptor is ignored. diff --git a/shell/common/engine.cc b/shell/common/engine.cc index f7b606baf66d6..e8994a5a1e2f7 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -302,7 +302,6 @@ void Engine::RunBundle(const std::string& bundle_path, TRACE_EVENT0("flutter", "Engine::RunBundle"); ConfigureAssetBundle(bundle_path); ConfigureRuntime(GetScriptUriFromPath(bundle_path), reuse_runtime_controller); - if (blink::IsRunningPrecompiledCode()) { runtime_->dart_controller()->RunFromPrecompiledSnapshot(entrypoint); } else { @@ -312,7 +311,7 @@ void Engine::RunBundle(const std::string& bundle_path, return; } std::vector snapshot; - if (!GetAssetAsBuffer(blink::kSnapshotAssetKey, &snapshot)) + if (!GetAssetAsBuffer(blink::kSnapshotAssetKey, &snapshot)) return; runtime_->dart_controller()->RunFromScriptSnapshot( snapshot.data(), snapshot.size(), entrypoint); diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 1f4cac3aa4a85..75e0124ba7c81 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -65,7 +65,7 @@ class PlatformView : public std::enable_shared_from_this { virtual void HandlePlatformMessage( fxl::RefPtr message); - virtual fxl::RefPtr GetAssetProvider(); + virtual fxl::RefPtr GetAssetProvider(); // Called once per texture, on the platform thread. void RegisterTexture(std::shared_ptr texture); diff --git a/shell/platform/android/apk_asset_provider.cc b/shell/platform/android/apk_asset_provider.cc index ae55a36b950a9..fdd4910a12f4c 100644 --- a/shell/platform/android/apk_asset_provider.cc +++ b/shell/platform/android/apk_asset_provider.cc @@ -11,7 +11,7 @@ bool APKAssetProvider::GetAsBuffer(const std::string& asset_name, std::vector* data) { std::stringstream ss; ss << directory_.c_str() << "/" << asset_name; - AAsset* asset = AAssetManager_open(assetManager_, ss.str().c_str(), AASSET_MODE_RANDOM); + AAsset* asset = AAssetManager_open(assetManager_, ss.str().c_str(), AASSET_MODE_BUFFER); if (!asset) { return false; } @@ -23,7 +23,7 @@ bool APKAssetProvider::GetAsBuffer(const std::string& asset_name, } data->resize(AAsset_getLength(asset)); - std::copy(buffer, buffer + data->size() , data->begin()); + std::copy(buffer, buffer + data->size(), data->begin()); AAsset_close(asset); return true; } diff --git a/shell/platform/android/io/flutter/view/ResourceExtractor.java b/shell/platform/android/io/flutter/view/ResourceExtractor.java index 40ea70e90198a..36bba7906ec1f 100644 --- a/shell/platform/android/io/flutter/view/ResourceExtractor.java +++ b/shell/platform/android/io/flutter/view/ResourceExtractor.java @@ -37,7 +37,7 @@ class ResourceExtractor { private class ExtractTask extends AsyncTask { private static final int BUFFER_SIZE = 16 * 1024; - ExtractTask() {} + ExtractTask() { } private void extractResources() { final File dataDir = new File(PathUtils.getDataDirectory(mContext)); @@ -61,30 +61,17 @@ private void extractResources() { output.getParentFile().mkdirs(); } - OutputStream os = null; - InputStream is = null; - try { - os = new FileOutputStream(output); - is = manager.open(asset); - - if (buffer == null) { - buffer = new byte[BUFFER_SIZE]; - } - - int count = 0; - while ((count = is.read(buffer, 0, BUFFER_SIZE)) != -1) { - os.write(buffer, 0, count); - } - os.flush(); - } finally { - try { - if (os != null) { - os.close(); + try (InputStream is = manager.open(asset)) { + try (OutputStream os = new FileOutputStream(output)) { + if (buffer == null) { + buffer = new byte[BUFFER_SIZE]; } - } finally { - if (is != null) { - is.close(); + + int count = 0; + while ((count = is.read(buffer, 0, BUFFER_SIZE)) != -1) { + os.write(buffer, 0, count); } + os.flush(); } } } catch (FileNotFoundException fnfe) { From b22f07bf4a3c1e6c4369166d0d0570337d8ae087 Mon Sep 17 00:00:00 2001 From: Sarah Zakarias Date: Mon, 5 Mar 2018 13:21:52 +0100 Subject: [PATCH 3/3] update license file --- travis/licenses_golden/licenses_flutter | 77 +++++++++++++------------ 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/travis/licenses_golden/licenses_flutter b/travis/licenses_golden/licenses_flutter index effa3f5a9117b..7de50c115fd76 100644 --- a/travis/licenses_golden/licenses_flutter +++ b/travis/licenses_golden/licenses_flutter @@ -1560,6 +1560,7 @@ FILE: ../../../flutter/lib/ui/natives.dart FILE: ../../../flutter/lib/ui/window/window.h FILE: ../../../flutter/runtime/platform_impl.h FILE: ../../../flutter/shell/common/skia_event_tracer_impl.cc +FILE: ../../../flutter/shell/platform/android/apk_asset_provider.cc FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/JSONUtil.java FILE: ../../../flutter/shell/platform/darwin/desktop/Info.plist FILE: ../../../flutter/shell/platform/darwin/desktop/flutter_mac.xib @@ -1635,6 +1636,45 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== +==================================================================================================== +LIBRARY: engine +ORIGIN: ../../../flutter/assets/asset_provider.h + ../../../LICENSE +TYPE: LicenseType.bsd +FILE: ../../../flutter/assets/asset_provider.h +FILE: ../../../flutter/flutter_kernel_transformers/lib/track_widget_constructor_locations.dart +FILE: ../../../flutter/shell/platform/android/apk_asset_provider.h +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.h +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.mm +---------------------------------------------------------------------------------------------------- +Copyright 2018 The Chromium Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +==================================================================================================== + ==================================================================================================== LIBRARY: engine ORIGIN: ../../../flutter/assets/directory_asset_bundle.cc + ../../../LICENSE @@ -1879,43 +1919,6 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== -==================================================================================================== -LIBRARY: engine -ORIGIN: ../../../flutter/flutter_kernel_transformers/lib/track_widget_constructor_locations.dart + ../../../LICENSE -TYPE: LicenseType.bsd -FILE: ../../../flutter/flutter_kernel_transformers/lib/track_widget_constructor_locations.dart -FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.h -FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.mm ----------------------------------------------------------------------------------------------------- -Copyright 2018 The Chromium Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==================================================================================================== - ==================================================================================================== LIBRARY: engine ORIGIN: ../../../flutter/fml/platform/darwin/scoped_block.h + ../../../LICENSE