Skip to content

Commit

Permalink
Run Fuchsia apps without flx (flutter#4550)
Browse files Browse the repository at this point in the history
  • Loading branch information
szakarias authored Jan 15, 2018
1 parent e7e94c6 commit 1e23d64
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 16 deletions.
40 changes: 35 additions & 5 deletions assets/directory_asset_bundle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,48 @@

#include <fcntl.h>

#if !defined(OS_WIN)
#include <unistd.h>
#endif

#include <utility>

#include "lib/fxl/files/eintr_wrapper.h"
#include "lib/fxl/files/file.h"
#include "lib/fxl/files/path.h"
#include "lib/fxl/files/unique_fd.h"
#include "lib/fxl/portable_unistd.h"

namespace blink {

bool DirectoryAssetBundle::GetAsBuffer(const std::string& asset_name,
std::vector<uint8_t>* data) {
if (fd_.is_valid()) {
#if defined(OS_WIN)
// This code path is not valid in a Windows environment.
return false;
#else
fxl::UniqueFD asset_file(openat(fd_.get(), asset_name.c_str(), O_RDONLY));
if (!asset_file.is_valid()) {
FXL_LOG(ERROR) << "Could not load asset " << asset_name;
return false;
}

constexpr size_t kBufferSize = 1 << 16;
size_t offset = 0;
ssize_t bytes_read = 0;
do {
offset += bytes_read;
data->resize(offset + kBufferSize);
bytes_read = read(asset_file.get(), &(*data)[offset], kBufferSize);
} while (bytes_read > 0);

if (bytes_read < 0) {
FXL_LOG(ERROR) << "Reading " << asset_name << " failed";
data->clear();
return false;
}

data->resize(offset + bytes_read);
return true;
#endif
}
std::string asset_path = GetPathForAsset(asset_name);
if (asset_path.empty())
return false;
Expand All @@ -31,7 +58,10 @@ bool DirectoryAssetBundle::GetAsBuffer(const std::string& asset_name,
DirectoryAssetBundle::~DirectoryAssetBundle() {}

DirectoryAssetBundle::DirectoryAssetBundle(std::string directory)
: directory_(std::move(directory)) {}
: directory_(std::move(directory)), fd_() {}

DirectoryAssetBundle::DirectoryAssetBundle(fxl::UniqueFD fd)
: fd_(std::move(fd)) {}

std::string DirectoryAssetBundle::GetPathForAsset(
const std::string& asset_name) {
Expand Down
4 changes: 4 additions & 0 deletions assets/directory_asset_bundle.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <string>
#include <vector>

#include "lib/fxl/files/unique_fd.h"
#include "lib/fxl/macros.h"
#include "lib/fxl/memory/ref_counted.h"

Expand All @@ -17,6 +18,8 @@ class DirectoryAssetBundle
: public fxl::RefCountedThreadSafe<DirectoryAssetBundle> {
public:
explicit DirectoryAssetBundle(std::string directory);
// Expects fd to be valid, otherwise the file descriptor is ignored.
explicit DirectoryAssetBundle(fxl::UniqueFD fd);
~DirectoryAssetBundle();

bool GetAsBuffer(const std::string& asset_name, std::vector<uint8_t>* data);
Expand All @@ -25,6 +28,7 @@ class DirectoryAssetBundle

private:
const std::string directory_;
fxl::UniqueFD fd_;

FXL_DISALLOW_COPY_AND_ASSIGN(DirectoryAssetBundle);
};
Expand Down
8 changes: 5 additions & 3 deletions content_handler/application_controller_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ ApplicationControllerImpl::ApplicationControllerImpl(
}

std::vector<char> bundle;
if (!fsl::VectorFromVmo(std::move(application->data), &bundle)) {
FXL_LOG(ERROR) << "Failed to receive bundle.";
return;
if (application->data) {
if (!fsl::VectorFromVmo(std::move(application->data), &bundle)) {
FXL_LOG(ERROR) << "Failed to receive bundle.";
return;
}
}

// TODO(jeffbrown): Decide what to do with command-line arguments and
Expand Down
47 changes: 39 additions & 8 deletions content_handler/runtime_holder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "flutter/content_handler/runtime_holder.h"

#include <dlfcn.h>
#include <fcntl.h>
#include <fdio/namespace.h>
#include <zircon/dlfcn.h>
#include <utility>
Expand All @@ -23,6 +24,7 @@
#include "flutter/runtime/runtime_init.h"
#include "lib/app/cpp/connect.h"
#include "lib/fsl/vmo/vector.h"
#include "lib/fxl/files/unique_fd.h"
#include "lib/fxl/functional/make_copyable.h"
#include "lib/fxl/logging.h"
#include "lib/fxl/time/time_delta.h"
Expand All @@ -45,6 +47,7 @@ constexpr char kAssetChannel[] = "flutter/assets";
constexpr char kKeyEventChannel[] = "flutter/keyevent";
constexpr char kTextInputChannel[] = "flutter/textinput";
constexpr char kFlutterPlatformChannel[] = "flutter/platform";
constexpr char kFuchsiaPackageResourceDirectory[] = "pkg/data";

void SetThreadName(fxl::RefPtr<fxl::TaskRunner> runner, std::string name) {
runner->PostTask([name]() {
Expand Down Expand Up @@ -117,6 +120,7 @@ void RuntimeHolder::Init(

context_->ConnectToEnvironmentService(view_manager_.NewRequest());

// TODO(zarah): remove bundle entirely once flx is removed.
InitRootBundle(std::move(bundle));

const uint8_t* vm_snapshot_data;
Expand All @@ -130,7 +134,7 @@ void RuntimeHolder::Init(
default_isolate_snapshot_instr = ::kDartIsolateCoreSnapshotInstructions;
} else {
std::vector<uint8_t> dylib_blob;
if (!asset_store_->GetAsBuffer(kDylibKey, &dylib_blob)) {
if (!GetAssetAsBuffer(kDylibKey, &dylib_blob)) {
FXL_LOG(ERROR) << "Failed to extract app dylib";
return;
}
Expand Down Expand Up @@ -193,8 +197,8 @@ void RuntimeHolder::CreateView(
std::vector<uint8_t> kernel;
std::vector<uint8_t> snapshot;
if (!Dart_IsPrecompiledRuntime()) {
if (!asset_store_->GetAsBuffer(kKernelKey, &kernel) &&
!asset_store_->GetAsBuffer(kSnapshotKey, &snapshot)) {
if (!GetAssetAsBuffer(kKernelKey, &kernel) &&
!GetAssetAsBuffer(kSnapshotKey, &snapshot)) {
FXL_LOG(ERROR) << "Unable to load kernel or snapshot from root bundle.";
return;
}
Expand Down Expand Up @@ -387,8 +391,11 @@ void RuntimeHolder::HandlePlatformMessage(
}

void RuntimeHolder::DidCreateMainIsolate(Dart_Isolate isolate) {
if (asset_store_)
if (directory_asset_bundle_) {
blink::AssetFontSelector::Install(directory_asset_bundle_);
} else if (asset_store_) {
blink::AssetFontSelector::Install(asset_store_);
}
InitDartIoInternal();
InitFuchsia();
InitMozartInternal();
Expand Down Expand Up @@ -448,9 +455,26 @@ void RuntimeHolder::InitMozartInternal() {
}

void RuntimeHolder::InitRootBundle(std::vector<char> bundle) {
root_bundle_data_ = std::move(bundle);
asset_store_ = fxl::MakeRefCounted<blink::ZipAssetStore>(
GetUnzipperProviderForRootBundle());
if (!bundle.empty()) {
root_bundle_data_ = std::move(bundle);
asset_store_ = fxl::MakeRefCounted<blink::ZipAssetStore>(
GetUnzipperProviderForRootBundle());
} else {
fxl::UniqueFD root_dir(fdio_ns_opendir(namespc_));
if (!root_dir.is_valid()) {
FXL_LOG(ERROR) << "Unable to load root dir";
return;
}
fxl::UniqueFD data_dir(openat(root_dir.get(),
kFuchsiaPackageResourceDirectory,
O_RDONLY | O_DIRECTORY));
if (!data_dir.is_valid()) {
FXL_LOG(ERROR) << "Unable to load data dir";
return;
}
directory_asset_bundle_ =
fxl::MakeRefCounted<blink::DirectoryAssetBundle>(std::move(data_dir));
}
}

mozart::View* RuntimeHolder::GetMozartView() {
Expand All @@ -466,14 +490,21 @@ bool RuntimeHolder::HandleAssetPlatformMessage(
std::string asset_name(reinterpret_cast<const char*>(data.data()),
data.size());
std::vector<uint8_t> asset_data;
if (asset_store_ && asset_store_->GetAsBuffer(asset_name, &asset_data)) {
if (GetAssetAsBuffer(asset_name, &asset_data)) {
response->Complete(std::move(asset_data));
} else {
response->CompleteEmpty();
}
return true;
}

bool RuntimeHolder::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));
}

bool RuntimeHolder::HandleFlutterPlatformMessage(
blink::PlatformMessage* message) {
const auto& data = message->data();
Expand Down
4 changes: 4 additions & 0 deletions content_handler/runtime_holder.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <unordered_set>

#include "dart-pkg/fuchsia/sdk_ext/fuchsia.h"
#include "flutter/assets/directory_asset_bundle.h"
#include "flutter/assets/unzipper_provider.h"
#include "flutter/assets/zip_asset_store.h"
#include "flutter/content_handler/accessibility_bridge.h"
Expand Down Expand Up @@ -92,6 +93,7 @@ class RuntimeHolder : public blink::RuntimeDelegate,
void InitRootBundle(std::vector<char> bundle);
blink::UnzipperProvider GetUnzipperProviderForRootBundle();
bool HandleAssetPlatformMessage(blink::PlatformMessage* message);
bool GetAssetAsBuffer(const std::string& name, std::vector<uint8_t>* data);
bool HandleTextInputPlatformMessage(blink::PlatformMessage* message);
bool HandleFlutterPlatformMessage(blink::PlatformMessage* message);

Expand All @@ -109,7 +111,9 @@ class RuntimeHolder : public blink::RuntimeDelegate,
std::unique_ptr<app::ApplicationContext> context_;
fidl::InterfaceRequest<app::ServiceProvider> outgoing_services_;
std::vector<char> root_bundle_data_;
// TODO(zarah): Remove asset_store_ when flx is completely removed
fxl::RefPtr<blink::ZipAssetStore> asset_store_;
fxl::RefPtr<blink::DirectoryAssetBundle> directory_asset_bundle_;
void* dylib_handle_ = nullptr;
std::unique_ptr<Rasterizer> rasterizer_;
std::unique_ptr<blink::RuntimeController> runtime_;
Expand Down

0 comments on commit 1e23d64

Please sign in to comment.