Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read assets out of APK on Android #4742

Merged
merged 3 commits into from Mar 5, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions assets/BUILD.gn
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
@@ -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
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 blink::AssetProvider {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we leave out blink:: here?

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
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
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
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
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
27 changes: 15 additions & 12 deletions shell/common/engine.cc
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 @@ -312,7 +312,7 @@ void Engine::RunBundle(const std::string& bundle_path,
return;
}
std::vector<uint8_t> snapshot;
if (!GetAssetAsBuffer(blink::kSnapshotAssetKey, &snapshot))
if (!GetAssetAsBuffer(blink::kSnapshotAssetKey, &snapshot))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation seems off here.

return;
runtime_->dart_controller()->RunFromScriptSnapshot(
snapshot.data(), snapshot.size(), entrypoint);
Expand Down Expand Up @@ -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<blink::DirectoryAssetBundle>(path);
}

struct stat stat_result = {};

// TODO(abarth): We should reset directory_asset_bundle_, but that might break
Expand All @@ -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<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 +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_);
}
}
}
Expand Down Expand Up @@ -693,7 +697,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 +707,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
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
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
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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra space after virtual


// 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
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
@@ -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_RANDOM);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need random access to the asset bytes. We only want to fill a buffer, right?
So I'd expect this to be AASSET_MODE_BUFFER (though I haven't tried it).

https://developer.android.com/ndk/reference/group___asset.html

if (!asset) {
return false;
}

uint8_t* buffer = (uint8_t*)AAsset_getBuffer(asset);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reinterpret_cast as specified in the style guide.

if (!buffer) {
FXL_LOG(ERROR) << "Got null trying to acquire buffer for asset:" << asset;
return false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing AAset_close in case of this error. The idiom is to use fxl::UniqueObject for such calls but I can certainly understand if you don't want to write that for this one-of case and just add the close call manually here.

}

data->resize(AAsset_getLength(asset));
std::copy(buffer, buffer + data->size() , data->begin());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove space before ,

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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe hold a VM reference to the jobject here and release it in the destructor so that we can be sure that the object doesn't become invalid while this native asset provider is in use.

}

} // namespace blink