Skip to content

Commit

Permalink
Read assets out of APK on Android (flutter#4742)
Browse files Browse the repository at this point in the history
  • Loading branch information
szakarias authored Mar 5, 2018
1 parent b2807f8 commit a00f8e8
Show file tree
Hide file tree
Showing 21 changed files with 242 additions and 121 deletions.
1 change: 1 addition & 0 deletions assets/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

source_set("assets") {
sources = [
"asset_provider.h",
"directory_asset_bundle.cc",
"directory_asset_bundle.h",
"unzipper_provider.cc",
Expand Down
25 changes: 25 additions & 0 deletions assets/asset_provider.h
Original file line number Diff line number Diff line change
@@ -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 <string>
#include <vector>

#include "lib/fxl/memory/ref_counted.h"

namespace blink {

class AssetProvider
: public fxl::RefCountedThreadSafe<AssetProvider>
{
public:
virtual bool GetAsBuffer(const std::string& asset_name,
std::vector<uint8_t>* data) = 0;
virtual ~AssetProvider() = default;
};

} // namespace blink
#endif // FLUTTER_ASSETS_ASSET_PROVIDER_H
7 changes: 4 additions & 3 deletions assets/directory_asset_bundle.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@
#include <string>
#include <vector>

#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"

namespace blink {

class DirectoryAssetBundle
: public fxl::RefCountedThreadSafe<DirectoryAssetBundle> {
: public 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<uint8_t>* data);
virtual bool GetAsBuffer(const std::string& asset_name, std::vector<uint8_t>* data);

std::string GetPathForAsset(const std::string& asset_name);

Expand Down
14 changes: 7 additions & 7 deletions lib/ui/text/font_collection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ std::shared_ptr<txt::FontCollection> FontCollection::GetFontCollection() const {
return collection_;
}

void FontCollection::RegisterFontsFromDirectoryAssetBundle(
fxl::RefPtr<blink::DirectoryAssetBundle> directory_asset_bundle) {
if (!directory_asset_bundle) {
void FontCollection::RegisterFontsFromAssetProvider(
fxl::RefPtr<blink::AssetProvider> asset_provider) {

if (!asset_provider){
return;
}

std::vector<uint8_t> 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;
}
Expand Down Expand Up @@ -92,8 +92,8 @@ void FontCollection::RegisterFontsFromDirectoryAssetBundle(

// TODO: Handle weights and styles.
std::vector<uint8_t> 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 =
Expand Down
6 changes: 2 additions & 4 deletions lib/ui/text/font_collection.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#include <memory>
#include <vector>
#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"
Expand All @@ -21,9 +21,7 @@ class FontCollection {

std::shared_ptr<txt::FontCollection> GetFontCollection() const;

void RegisterFontsFromDirectoryAssetBundle(
fxl::RefPtr<blink::DirectoryAssetBundle> directory_asset_bundle);

void RegisterFontsFromAssetProvider(fxl::RefPtr<blink::AssetProvider> asset_provider);
void RegisterTestFonts();

private:
Expand Down
18 changes: 9 additions & 9 deletions runtime/asset_font_selector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ struct FontMatcher {
} // namespace

void AssetFontSelector::Install(
fxl::RefPtr<DirectoryAssetBundle> directory_asset_bundle) {
fxl::RefPtr<AssetProvider> asset_provider) {
RefPtr<AssetFontSelector> 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);
}
Expand All @@ -96,8 +96,8 @@ void AssetFontSelector::Install(fxl::RefPtr<ZipAssetStore> asset_store) {
}

AssetFontSelector::AssetFontSelector(
fxl::RefPtr<DirectoryAssetBundle> directory_asset_bundle)
: directory_asset_bundle_(std::move(directory_asset_bundle)) {}
fxl::RefPtr<AssetProvider> asset_provider)
: asset_provider_(std::move(asset_provider)) {}

AssetFontSelector::AssetFontSelector(fxl::RefPtr<ZipAssetStore> asset_store)
: asset_store_(std::move(asset_store)) {}
Expand All @@ -118,9 +118,9 @@ AssetFontSelector::FlutterFontAttributes::~FlutterFontAttributes() {}

void AssetFontSelector::parseFontManifest() {
std::vector<uint8_t> 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;
Expand Down Expand Up @@ -239,8 +239,8 @@ sk_sp<SkTypeface> AssetFontSelector::getTypefaceAsset(
}

std::unique_ptr<TypefaceAsset> 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));
Expand Down
6 changes: 3 additions & 3 deletions runtime/asset_font_selector.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class AssetFontSelector : public FontSelector {

~AssetFontSelector() override;

static void Install(fxl::RefPtr<DirectoryAssetBundle> directory_asset_bundle);
static void Install(fxl::RefPtr<AssetProvider> asset_provider);

// TODO(zarah): Remove this and related code using asset_store once flx is
// removed.
Expand All @@ -45,7 +45,7 @@ class AssetFontSelector : public FontSelector {
struct TypefaceAsset;

explicit AssetFontSelector(
fxl::RefPtr<DirectoryAssetBundle> directory_asset_bundle);
fxl::RefPtr<AssetProvider> asset_provider);

explicit AssetFontSelector(fxl::RefPtr<ZipAssetStore> asset_store);

Expand All @@ -54,7 +54,7 @@ class AssetFontSelector : public FontSelector {
sk_sp<SkTypeface> getTypefaceAsset(const FontDescription& font_description,
const AtomicString& family_name);

fxl::RefPtr<DirectoryAssetBundle> directory_asset_bundle_;
fxl::RefPtr<AssetProvider> asset_provider_;

fxl::RefPtr<ZipAssetStore> asset_store_;

Expand Down
26 changes: 14 additions & 12 deletions shell/common/engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand All @@ -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 {
Expand Down Expand Up @@ -573,6 +572,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<blink::DirectoryAssetBundle>(path);
}

struct stat stat_result = {};

// TODO(abarth): We should reset directory_asset_bundle_, but that might break
Expand All @@ -585,8 +590,6 @@ void Engine::ConfigureAssetBundle(const std::string& path) {

std::string flx_path;
if (S_ISDIR(stat_result.st_mode)) {
directory_asset_bundle_ =
fxl::MakeRefCounted<blink::DirectoryAssetBundle>(path);
flx_path = files::GetDirectoryName(path) + "/app.flx";
} else if (S_ISREG(stat_result.st_mode)) {
flx_path = path;
Expand Down Expand Up @@ -618,11 +621,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_);
}
}
}
Expand Down Expand Up @@ -693,7 +696,6 @@ void Engine::HandleAssetPlatformMessage(
const auto& data = message->data();
std::string asset_name(reinterpret_cast<const char*>(data.data()),
data.size());

std::vector<uint8_t> asset_data;
if (GetAssetAsBuffer(asset_name, &asset_data)) {
response->Complete(std::move(asset_data));
Expand All @@ -704,9 +706,9 @@ void Engine::HandleAssetPlatformMessage(

bool Engine::GetAssetAsBuffer(const std::string& name,
std::vector<uint8_t>* 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
2 changes: 2 additions & 0 deletions shell/common/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -109,6 +110,7 @@ class Engine : public blink::RuntimeDelegate {

static const std::string main_entrypoint_;

fxl::RefPtr<blink::AssetProvider> asset_provider_;
std::weak_ptr<PlatformView> platform_view_;
std::unique_ptr<Animator> animator_;
std::unique_ptr<blink::RuntimeController> runtime_;
Expand Down
4 changes: 4 additions & 0 deletions shell/common/platform_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ VsyncWaiter* PlatformView::GetVsyncWaiter() {
return vsync_waiter_.get();
}

fxl::RefPtr<blink::AssetProvider> PlatformView::GetAssetProvider() {
return asset_provider_;
}

void PlatformView::UpdateSemantics(blink::SemanticsNodeUpdates update) {}

void PlatformView::HandlePlatformMessage(
Expand Down
5 changes: 5 additions & 0 deletions shell/common/platform_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <memory>

#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"
Expand Down Expand Up @@ -64,6 +65,8 @@ class PlatformView : public std::enable_shared_from_this<PlatformView> {
virtual void HandlePlatformMessage(
fxl::RefPtr<blink::PlatformMessage> message);

virtual fxl::RefPtr<blink::AssetProvider> GetAssetProvider();

// Called once per texture, on the platform thread.
void RegisterTexture(std::shared_ptr<flow::Texture> texture);

Expand Down Expand Up @@ -97,6 +100,8 @@ class PlatformView : public std::enable_shared_from_this<PlatformView> {
flow::TextureRegistry texture_registry_;
std::unique_ptr<Engine> engine_;
std::unique_ptr<VsyncWaiter> vsync_waiter_;
fxl::RefPtr<blink::AssetProvider> asset_provider_;

SkISize size_;

private:
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
38 changes: 38 additions & 0 deletions shell/platform/android/apk_asset_provider.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <unistd.h>
#include <algorithm>
#include <sstream>

#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<uint8_t>* data) {
std::stringstream ss;
ss << directory_.c_str() << "/" << asset_name;
AAsset* asset = AAssetManager_open(assetManager_, ss.str().c_str(), AASSET_MODE_BUFFER);
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
Loading

0 comments on commit a00f8e8

Please sign in to comment.