提交 13af58bf 编写于 作者: A Adam Barth 提交者: GitHub

Remove //base dependency from asset system (#2885)

This patch centralizes the asset bundle processing in //flutter/assets and
removes the //base dependency from the code.
上级 cb40b67f
......@@ -4,18 +4,30 @@
import("//mojo/public/mojo_application.gni")
source_set("lib") {
source_set("assets") {
sources = [
"directory_asset_bundle.cc",
"directory_asset_bundle.h",
"unique_unzipper.cc",
"unique_unzipper.h",
"unzip_job.cc",
"unzip_job.h",
"zip_asset_bundle.cc",
"zip_asset_bundle.h",
"zip_asset_store.cc",
"zip_asset_store.h",
]
deps = [
"//base",
"//mojo/data_pipe_utils",
"//glue",
"//lib/ftl",
"//mojo/public/cpp/bindings:callback",
"//mojo/public/cpp/system",
"//mojo/public/cpp/bindings:utility",
"//third_party/zlib:minizip",
]
public_deps = [
"//mojo/services/asset_bundle/interfaces",
"//third_party/zlib:zip",
]
}
// Copyright 2016 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 "flutter/assets/directory_asset_bundle.h"
#include <fcntl.h>
#include <unistd.h>
#include <utility>
#include "glue/data_pipe_utils.h"
#include "lib/ftl/files/eintr_wrapper.h"
#include "lib/ftl/files/path.h"
#include "lib/ftl/files/unique_fd.h"
namespace blink {
void DirectoryAssetBundle::GetAsStream(
const mojo::String& asset_name,
const mojo::Callback<void(mojo::ScopedDataPipeConsumerHandle)>& callback) {
mojo::DataPipe pipe;
callback.Run(std::move(pipe.consumer_handle));
std::string asset_path =
files::SimplifyPath(directory_ + "/" + asset_name.get());
if (asset_path.find(directory_) != 0u) {
FTL_LOG(ERROR) << "Asset name '" << asset_name
<< "' attempted to traverse outside asset bundle.";
return;
}
// TODO(abarth): Consider moving the |open| call to task_runner_.
ftl::UniqueFD fd(HANDLE_EINTR(open(asset_path.c_str(), O_RDONLY)));
if (fd.get() < 0)
return;
glue::CopyFromFileDescriptor(std::move(fd), std::move(pipe.producer_handle),
task_runner_.get(), [](bool ignored) {});
}
DirectoryAssetBundle::~DirectoryAssetBundle() {}
DirectoryAssetBundle::DirectoryAssetBundle(
mojo::InterfaceRequest<AssetBundle> request,
std::string directory,
ftl::RefPtr<ftl::TaskRunner> task_runner)
: binding_(this, std::move(request)),
directory_(std::move(directory)),
task_runner_(std::move(task_runner)) {}
} // namespace blink
......@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKY_ENGINE_CORE_SCRIPT_DIRECTORY_ASSET_BUNDLE_H_
#define SKY_ENGINE_CORE_SCRIPT_DIRECTORY_ASSET_BUNDLE_H_
#ifndef FLUTTER_ASSETS_DIRECTORY_ASSET_BUNDLE_H_
#define FLUTTER_ASSETS_DIRECTORY_ASSET_BUNDLE_H_
#include "base/files/file_path.h"
#include "lib/ftl/macros.h"
#include "lib/ftl/tasks/task_runner.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/environment/async_waiter.h"
......@@ -14,28 +15,28 @@
namespace blink {
// A mojo service that serves assets out of a directory.
class DirectoryAssetBundleService : public mojo::asset_bundle::AssetBundle {
class DirectoryAssetBundle : public mojo::asset_bundle::AssetBundle {
public:
static void Create(
mojo::InterfaceRequest<mojo::asset_bundle::AssetBundle> request,
const base::FilePath& directory);
DirectoryAssetBundle(mojo::InterfaceRequest<AssetBundle> request,
std::string directory,
ftl::RefPtr<ftl::TaskRunner> task_runner);
public:
// mojo::assert_bundle::AssetBundle implementation:
void GetAsStream(
const mojo::String& asset_name,
const mojo::Callback<
void(mojo::ScopedDataPipeConsumerHandle)>& callback) override;
~DirectoryAssetBundleService() override;
const mojo::Callback<void(mojo::ScopedDataPipeConsumerHandle)>& callback)
override;
private:
DirectoryAssetBundleService(mojo::InterfaceRequest<AssetBundle> request,
const base::FilePath& directory);
~DirectoryAssetBundle() override;
mojo::StrongBinding<mojo::asset_bundle::AssetBundle> binding_;
const std::string directory_;
ftl::RefPtr<ftl::TaskRunner> task_runner_;
mojo::StrongBinding<AssetBundle> binding_;
const base::FilePath directory_;
FTL_DISALLOW_COPY_AND_ASSIGN(DirectoryAssetBundle);
};
} // namespace blink
#endif // SKY_ENGINE_CORE_SCRIPT_DIRECTORY_ASSET_BUNDLE_H_
#endif // FLUTTER_ASSETS_DIRECTORY_ASSET_BUNDLE_H_
// Copyright 2016 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 "flutter/assets/unique_unzipper.h"
#include "third_party/zlib/contrib/minizip/unzip.h"
namespace blink {
void UniqueUnzipperTraits::Free(void* file) {
unzClose(file);
}
} // namespace blink
// Copyright 2016 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_UNIQUE_UNZIPPER_H_
#define FLUTTER_ASSETS_UNIQUE_UNZIPPER_H_
#include "lib/ftl/memory/unique_object.h"
namespace blink {
struct UniqueUnzipperTraits {
static inline void* InvalidValue() { return nullptr; }
static inline bool IsValid(void* value) { return value != InvalidValue(); }
static void Free(void* file);
};
using UniqueUnzipper = ftl::UniqueObject<void*, UniqueUnzipperTraits>;
} // namespace blink
#endif // FLUTTER_ASSETS_UNIQUE_UNZIPPER_H_
// Copyright 2016 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 "flutter/assets/unzip_job.h"
#include <utility>
#include "mojo/public/cpp/environment/environment.h"
#include "third_party/zlib/contrib/minizip/unzip.h"
namespace blink {
UnzipJob::UnzipJob(std::string zip_path,
std::string asset_name,
mojo::ScopedDataPipeProducerHandle producer,
ftl::RefPtr<ftl::TaskRunner> task_runner)
: zip_path_(std::move(zip_path)),
asset_name_(std::move(asset_name)),
producer_(std::move(producer)),
task_runner_(std::move(task_runner)),
waiter_(mojo::Environment::GetDefaultAsyncWaiter()),
wait_id_(0) {
task_runner_->PostTask([this]() { Start(); });
}
UnzipJob::~UnzipJob() {}
void UnzipJob::Start() {
zip_file_.reset(unzOpen2(zip_path_.c_str(), nullptr));
if (!zip_file_.is_valid()) {
FTL_LOG(ERROR) << "Unable to open ZIP file: " << zip_path_;
delete this;
return;
}
int result = unzLocateFile(zip_file_.get(), asset_name_.c_str(), 0);
if (result != UNZ_OK) {
FTL_LOG(WARNING) << "Requested asset '" << asset_name_
<< "' does not exist.";
delete this;
return;
}
result = unzOpenCurrentFile(zip_file_.get());
if (result != UNZ_OK) {
FTL_LOG(WARNING) << "unzOpenCurrentFile failed, error=" << result;
delete this;
return;
}
OnHandleReady(MOJO_RESULT_OK);
}
void UnzipJob::OnHandleReady(MojoResult result) {
if (result == MOJO_RESULT_OK) {
void* buffer = nullptr;
uint32_t size = 0;
result = mojo::BeginWriteDataRaw(producer_.get(), &buffer, &size,
MOJO_WRITE_DATA_FLAG_NONE);
if (result == MOJO_RESULT_OK) {
FTL_DCHECK(size < static_cast<uint32_t>(std::numeric_limits<int>::max()));
ssize_t bytes_read = unzReadCurrentFile(zip_file_.get(), buffer, size);
result = mojo::EndWriteDataRaw(producer_.get(),
std::max<ssize_t>(0l, bytes_read));
if (bytes_read < 0) {
FTL_LOG(WARNING) << "Asset unzip failed, error=" << bytes_read;
delete this;
} else if (result != MOJO_RESULT_OK) {
FTL_LOG(WARNING) << "Mojo EndWrite failed, error=" << result;
delete this;
} else if (bytes_read < size) {
// Reached EOF. Stop the process.
delete this;
} else {
task_runner_->PostTask([this]() { OnHandleReady(MOJO_RESULT_OK); });
}
return;
}
}
if (result == MOJO_RESULT_SHOULD_WAIT) {
wait_id_ =
waiter_->AsyncWait(producer_.get().value(), MOJO_HANDLE_SIGNAL_WRITABLE,
MOJO_DEADLINE_INDEFINITE, &WaitComplete, this);
return;
}
delete this;
}
void UnzipJob::WaitComplete(void* context, MojoResult result) {
UnzipJob* job = static_cast<UnzipJob*>(context);
job->wait_id_ = 0;
job->OnHandleReady(result);
}
} // namespace blink
// Copyright 2016 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_UNZIP_JOB_H_
#define FLUTTER_ASSETS_UNZIP_JOB_H_
#include <map>
#include <vector>
#include "flutter/assets/unique_unzipper.h"
#include "lib/ftl/macros.h"
#include "lib/ftl/memory/ref_counted.h"
#include "lib/ftl/tasks/task_runner.h"
#include "mojo/public/cpp/environment/async_waiter.h"
#include "mojo/services/asset_bundle/interfaces/asset_bundle.mojom.h"
namespace blink {
class UnzipJob {
public:
UnzipJob(std::string zip_path,
std::string asset_name,
mojo::ScopedDataPipeProducerHandle producer,
ftl::RefPtr<ftl::TaskRunner> task_runner);
~UnzipJob();
private:
void Start();
void OnHandleReady(MojoResult result);
static void WaitComplete(void* context, MojoResult result);
const std::string zip_path_;
const std::string asset_name_;
mojo::ScopedDataPipeProducerHandle producer_;
ftl::RefPtr<ftl::TaskRunner> task_runner_;
UniqueUnzipper zip_file_;
const MojoAsyncWaiter* waiter_;
MojoAsyncWaitID wait_id_;
FTL_DISALLOW_COPY_AND_ASSIGN(UnzipJob);
};
} // namespace blink
#endif // FLUTTER_ASSETS_UNZIP_JOB_H_
// Copyright 2016 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 "flutter/assets/zip_asset_bundle.h"
#include <utility>
namespace blink {
void ZipAssetBundle::GetAsStream(
const mojo::String& asset_name,
const mojo::Callback<void(mojo::ScopedDataPipeConsumerHandle)>& callback) {
mojo::DataPipe pipe;
callback.Run(std::move(pipe.consumer_handle));
store_->GetAsStream(asset_name.get(), std::move(pipe.producer_handle));
}
ZipAssetBundle::ZipAssetBundle(
mojo::InterfaceRequest<mojo::asset_bundle::AssetBundle> request,
ftl::RefPtr<ZipAssetStore> store)
: binding_(this, std::move(request)), store_(std::move(store)) {}
ZipAssetBundle::~ZipAssetBundle() {}
} // namespace blink
// Copyright 2016 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_ZIP_ASSET_BUNDLE_H_
#define FLUTTER_ASSETS_ZIP_ASSET_BUNDLE_H_
#include "flutter/assets/zip_asset_store.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/services/asset_bundle/interfaces/asset_bundle.mojom.h"
namespace blink {
class ZipAssetBundle : public mojo::asset_bundle::AssetBundle {
public:
ZipAssetBundle(
mojo::InterfaceRequest<mojo::asset_bundle::AssetBundle> request,
ftl::RefPtr<ZipAssetStore> store);
// mojo::assert_bundle::AssetBundle implementation:
void GetAsStream(
const mojo::String& asset_name,
const mojo::Callback<void(mojo::ScopedDataPipeConsumerHandle)>& callback)
override;
private:
~ZipAssetBundle() override;
mojo::StrongBinding<mojo::asset_bundle::AssetBundle> binding_;
ftl::RefPtr<ZipAssetStore> store_;
};
} // namespace blink
#endif // FLUTTER_ASSETS_ZIP_ASSET_BUNDLE_H_
// Copyright 2016 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 "flutter/assets/zip_asset_store.h"
#include <fcntl.h>
#include <unistd.h>
#include <utility>
#include "flutter/assets/unique_unzipper.h"
#include "flutter/assets/unzip_job.h"
#include "glue/data_pipe_utils.h"
#include "lib/ftl/files/eintr_wrapper.h"
#include "lib/ftl/files/unique_fd.h"
#include "third_party/zlib/contrib/minizip/unzip.h"
namespace blink {
ZipAssetStore::ZipAssetStore(std::string zip_path,
ftl::RefPtr<ftl::TaskRunner> task_runner)
: zip_path_(std::move(zip_path)), task_runner_(std::move(task_runner)) {}
ZipAssetStore::~ZipAssetStore() {}
void ZipAssetStore::AddOverlayFile(std::string asset_name,
std::string file_path) {
overlay_files_.emplace(std::move(asset_name), std::move(file_path));
}
void ZipAssetStore::GetAsStream(const std::string& asset_name,
mojo::ScopedDataPipeProducerHandle producer) {
auto overlay = overlay_files_.find(asset_name);
if (overlay != overlay_files_.end()) {
// TODO(abarth): Consider moving the |open| call to task_runner_.
ftl::UniqueFD fd(HANDLE_EINTR(open(overlay->second.c_str(), O_RDONLY)));
if (fd.get() < 0)
return;
glue::CopyFromFileDescriptor(std::move(fd), std::move(producer),
task_runner_.get(), [](bool ignored) {});
} else {
new UnzipJob(zip_path_, asset_name, std::move(producer), task_runner_);
}
}
bool ZipAssetStore::GetAsBuffer(const std::string& asset_name,
std::vector<uint8_t>* data) {
UniqueUnzipper zip_file(unzOpen2(zip_path_.c_str(), nullptr));
if (!zip_file.is_valid()) {
FTL_LOG(ERROR) << "Unable to open ZIP file: " << zip_path_;
return false;
}
int result = unzLocateFile(zip_file.get(), asset_name.c_str(), 0);
if (result != UNZ_OK) {
return false;
}
unz_file_info file_info;
result = unzGetCurrentFileInfo(zip_file.get(), &file_info, nullptr, 0,
nullptr, 0, nullptr, 0);
if (result != UNZ_OK) {
FTL_LOG(WARNING) << "unzGetCurrentFileInfo failed, error=" << result;
return false;
}
result = unzOpenCurrentFile(zip_file.get());
if (result != UNZ_OK) {
FTL_LOG(WARNING) << "unzOpenCurrentFile failed, error=" << result;
return false;
}
data->resize(file_info.uncompressed_size);
int total_read = 0;
while (total_read < static_cast<int>(data->size())) {
int bytes_read = unzReadCurrentFile(
zip_file.get(), data->data() + total_read, data->size() - total_read);
if (bytes_read <= 0)
return false;
total_read += bytes_read;
}
return true;
}
} // namespace blink
// Copyright 2016 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_ZIP_ASSET_STORE_H_
#define FLUTTER_ASSETS_ZIP_ASSET_STORE_H_
#include <map>
#include <vector>
#include "lib/ftl/macros.h"
#include "lib/ftl/memory/ref_counted.h"
#include "lib/ftl/tasks/task_runner.h"
#include "mojo/public/cpp/system/data_pipe.h"
namespace blink {
class ZipAssetStore : public ftl::RefCountedThreadSafe<ZipAssetStore> {
public:
ZipAssetStore(std::string zip_path, ftl::RefPtr<ftl::TaskRunner> task_runner);
~ZipAssetStore();
// Serve this asset from another file instead of using the ZIP contents.
void AddOverlayFile(std::string asset_name, std::string file_path);
void GetAsStream(const std::string& asset_name,
mojo::ScopedDataPipeProducerHandle producer);
bool GetAsBuffer(const std::string& asset_name, std::vector<uint8_t>* data);
private:
const std::string zip_path_;
ftl::RefPtr<ftl::TaskRunner> task_runner_;
std::map<std::string, std::string> overlay_files_;
FTL_DISALLOW_COPY_AND_ASSIGN(ZipAssetStore);
};
} // namespace blink
#endif // FLUTTER_ASSETS_ZIP_ASSET_STORE_H_
......@@ -4,6 +4,8 @@
source_set("glue") {
sources = [
"data_pipe_utils.cc",
"data_pipe_utils.h",
"drain_data_pipe_job.cc",
"drain_data_pipe_job.h",
"movable_wrapper.h",
......@@ -20,5 +22,6 @@ source_set("glue") {
"//base",
"//lib/ftl",
"//mojo/data_pipe_utils",
"//mojo/public/cpp/environment",
]
}
// Copyright 2016 The Fuchsia 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 "glue/data_pipe_utils.h"
#include <stdio.h>
#include <unistd.h>
#include <algorithm>
#include <limits>
#include <utility>
#include "lib/ftl/files/file_descriptor.h"
#include "mojo/public/cpp/environment/async_waiter.h"
#include "mojo/public/cpp/environment/environment.h"
namespace glue {
namespace {
// CopyToFileHandler -----------------------------------------------------------
class CopyToFileHandler {
public:
CopyToFileHandler(mojo::ScopedDataPipeConsumerHandle source,
ftl::UniqueFD destination,
ftl::TaskRunner* task_runner,
const std::function<void(bool)>& callback);
private:
~CopyToFileHandler();
void SendCallback(bool value);
void OnHandleReady(MojoResult result);
static void WaitComplete(void* context, MojoResult result);
mojo::ScopedDataPipeConsumerHandle source_;
ftl::UniqueFD destination_;
ftl::RefPtr<ftl::TaskRunner> task_runner_;
std::function<void(bool)> callback_;
const MojoAsyncWaiter* waiter_;
MojoAsyncWaitID wait_id_;
FTL_DISALLOW_COPY_AND_ASSIGN(CopyToFileHandler);
};
CopyToFileHandler::CopyToFileHandler(mojo::ScopedDataPipeConsumerHandle source,
ftl::UniqueFD destination,
ftl::TaskRunner* task_runner,
const std::function<void(bool)>& callback)
: source_(std::move(source)),
destination_(std::move(destination)),
task_runner_(task_runner),
callback_(callback),
waiter_(mojo::Environment::GetDefaultAsyncWaiter()),
wait_id_(0) {
task_runner_->PostTask([this]() { OnHandleReady(MOJO_RESULT_OK); });
}
CopyToFileHandler::~CopyToFileHandler() {}
void CopyToFileHandler::SendCallback(bool value) {
FTL_DCHECK(!wait_id_);
auto callback = callback_;
delete this;
callback(value);
}
void CopyToFileHandler::OnHandleReady(MojoResult result) {
if (result == MOJO_RESULT_OK) {
const void* buffer = nullptr;
uint32_t size = 0;
result = BeginReadDataRaw(source_.get(), &buffer, &size,
MOJO_READ_DATA_FLAG_NONE);
if (result == MOJO_RESULT_OK) {
bool write_success = ftl::WriteFileDescriptor(
destination_.get(), static_cast<const char*>(buffer), size);
result = EndReadDataRaw(source_.get(), size);
if (!write_success || result != MOJO_RESULT_OK) {
SendCallback(false);
} else {
task_runner_->PostTask([this]() { OnHandleReady(MOJO_RESULT_OK); });
}
return;
}
}
if (result == MOJO_RESULT_FAILED_PRECONDITION) {
SendCallback(true);
return;
}
if (result == MOJO_RESULT_SHOULD_WAIT) {
wait_id_ =
waiter_->AsyncWait(source_.get().value(), MOJO_HANDLE_SIGNAL_READABLE,
MOJO_DEADLINE_INDEFINITE, &WaitComplete, this);
return;
}
SendCallback(false);
}
void CopyToFileHandler::WaitComplete(void* context, MojoResult result) {
CopyToFileHandler* handler = static_cast<CopyToFileHandler*>(context);
handler->wait_id_ = 0;
handler->OnHandleReady(result);
}
// CopyFromFileHandler ---------------------------------------------------------
class CopyFromFileHandler {
public:
CopyFromFileHandler(ftl::UniqueFD source,
mojo::ScopedDataPipeProducerHandle destination,
ftl::TaskRunner* task_runner,
const std::function<void(bool)>& callback);
private:
~CopyFromFileHandler();
void SendCallback(bool value);
void OnHandleReady(MojoResult result);
static void WaitComplete(void* context, MojoResult result);
ftl::UniqueFD source_;
mojo::ScopedDataPipeProducerHandle destination_;
ftl::RefPtr<ftl::TaskRunner> task_runner_;
std::function<void(bool)> callback_;
const MojoAsyncWaiter* waiter_;
MojoAsyncWaitID wait_id_;
FTL_DISALLOW_COPY_AND_ASSIGN(CopyFromFileHandler);
};
CopyFromFileHandler::CopyFromFileHandler(
ftl::UniqueFD source,
mojo::ScopedDataPipeProducerHandle destination,
ftl::TaskRunner* task_runner,
const std::function<void(bool)>& callback)
: source_(std::move(source)),
destination_(std::move(destination)),
task_runner_(task_runner),
callback_(callback),
waiter_(mojo::Environment::GetDefaultAsyncWaiter()),
wait_id_(0) {
task_runner_->PostTask([this]() { OnHandleReady(MOJO_RESULT_OK); });
}
CopyFromFileHandler::~CopyFromFileHandler() {}
void CopyFromFileHandler::SendCallback(bool value) {
FTL_DCHECK(!wait_id_);
auto callback = callback_;
delete this;
callback(value);
}
void CopyFromFileHandler::OnHandleReady(MojoResult result) {
if (result == MOJO_RESULT_OK) {
void* buffer = nullptr;
uint32_t size = 0;
result = BeginWriteDataRaw(destination_.get(), &buffer, &size,
MOJO_WRITE_DATA_FLAG_NONE);
if (result == MOJO_RESULT_OK) {
FTL_DCHECK(size < static_cast<uint32_t>(std::numeric_limits<int>::max()));
ssize_t bytes_read = ftl::ReadFileDescriptor(
source_.get(), static_cast<char*>(buffer), size);
result = EndWriteDataRaw(destination_.get(),
std::max<ssize_t>(0l, bytes_read));
if (bytes_read == -1 || result != MOJO_RESULT_OK) {
SendCallback(false);
} else if (bytes_read < size) {
// Reached EOF. Stop the process.
SendCallback(true);
} else {
task_runner_->PostTask([this]() { OnHandleReady(MOJO_RESULT_OK); });
}
return;
}
}
if (result == MOJO_RESULT_SHOULD_WAIT) {
wait_id_ = waiter_->AsyncWait(
destination_.get().value(), MOJO_HANDLE_SIGNAL_WRITABLE,
MOJO_DEADLINE_INDEFINITE, &WaitComplete, this);
return;
}
SendCallback(false);
}
void CopyFromFileHandler::WaitComplete(void* context, MojoResult result) {
CopyFromFileHandler* handler = static_cast<CopyFromFileHandler*>(context);
handler->wait_id_ = 0;
handler->OnHandleReady(result);
}
} // namespace
void CopyToFileDescriptor(mojo::ScopedDataPipeConsumerHandle source,
ftl::UniqueFD destination,
ftl::TaskRunner* task_runner,
const std::function<void(bool)>& callback) {
new CopyToFileHandler(std::move(source), std::move(destination), task_runner,
callback);
}
void CopyFromFileDescriptor(ftl::UniqueFD source,
mojo::ScopedDataPipeProducerHandle destination,
ftl::TaskRunner* task_runner,
const std::function<void(bool)>& callback) {
new CopyFromFileHandler(std::move(source), std::move(destination),
task_runner, callback);
}
} // namespace glue
// Copyright 2016 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 GLUE_DATA_PIPE_FILES_H_
#define GLUE_DATA_PIPE_FILES_H_
#include <stdio.h>
#include <string>
#include "lib/ftl/files/unique_fd.h"
#include "lib/ftl/tasks/task_runner.h"
#include "mojo/public/cpp/system/data_pipe.h"
namespace glue {
// Asynchronously copies data from source to the destination file descriptor.
// The given |callback| is run upon completion. File writes and |callback| will
// be scheduled on the given |task_runner|.
void CopyToFileDescriptor(
mojo::ScopedDataPipeConsumerHandle source,
ftl::UniqueFD destination,
ftl::TaskRunner* task_runner,
const std::function<void(bool /*success*/)>& callback);
// Asynchronously copies data from source file to the destination. The given
// |callback| is run upon completion. File reads and |callback| will be
// scheduled to the given |task_runner|.
void CopyFromFileDescriptor(
ftl::UniqueFD source,
mojo::ScopedDataPipeProducerHandle destination,
ftl::TaskRunner* task_runner,
const std::function<void(bool /*success*/)>& callback);
} // namespace glue
#endif // GLUE_DATA_PIPE_FILES_H_
// Copyright 2016 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 "services/asset_bundle/zip_asset_bundle.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/task_runner.h"
#include "base/message_loop/message_loop.h"
#include "mojo/data_pipe_utils/data_pipe_utils.h"
#include "third_party/zlib/contrib/minizip/unzip.h"
namespace mojo {
namespace asset_bundle {
namespace {
void Ignored(bool) {
}
} // namespace
void* ScopedUnzFileTraits::InvalidValue() {
return nullptr;
}
void ScopedUnzFileTraits::Free(void* file) {
unzClose(file);
}
void ZipAssetService::Create(
InterfaceRequest<AssetBundle> request,
const scoped_refptr<ZipAssetBundle>& zip_asset_bundle) {
new ZipAssetService(request.Pass(), zip_asset_bundle);
}
ZipAssetService::ZipAssetService(
InterfaceRequest<AssetBundle> request,
const scoped_refptr<ZipAssetBundle>& zip_asset_bundle)
: binding_(this, request.Pass()),
zip_asset_bundle_(zip_asset_bundle) {
}
ZipAssetService::~ZipAssetService() {
}
void ZipAssetService::GetAsStream(
const String& asset_name,
const Callback<void(ScopedDataPipeConsumerHandle)>& callback) {
zip_asset_bundle_->GetAsStream(asset_name, callback);
}
ZipAssetBundle::ZipAssetBundle(
const base::FilePath& zip_path,
scoped_refptr<base::TaskRunner> worker_runner)
: zip_path_(zip_path),
worker_runner_(worker_runner.Pass()) {
}
ZipAssetBundle::~ZipAssetBundle() {
}
void ZipAssetBundle::AddOverlayFile(const std::string& asset_name,
const base::FilePath& file_path) {
overlay_files_.insert(std::make_pair(String(asset_name), file_path));
}
void ZipAssetBundle::GetAsStream(
const String& asset_name,
const Callback<void(ScopedDataPipeConsumerHandle)>& callback) {
DataPipe pipe;
callback.Run(pipe.consumer_handle.Pass());
auto overlay = overlay_files_.find(asset_name);
if (overlay != overlay_files_.end()) {
common::CopyFromFile(overlay->second,
pipe.producer_handle.Pass(),
0,
worker_runner_.get(),
base::Bind(&Ignored));
return;
}
ZipAssetHandler* handler = new ZipAssetHandler(
zip_path_,
asset_name.To<std::string>(),
pipe.producer_handle.Pass(),
worker_runner_);
worker_runner_->PostTask(
FROM_HERE,
base::Bind(&ZipAssetHandler::Start, base::Unretained(handler)));
}
bool ZipAssetBundle::GetAsBuffer(const std::string& asset_name,
std::vector<uint8_t>* data) {
ScopedUnzFile zip_file(unzOpen2(zip_path_.AsUTF8Unsafe().c_str(), NULL));
if (!zip_file.is_valid()) {
LOG(ERROR) << "Unable to open ZIP file: " << zip_path_.value();
return false;
}
int result = unzLocateFile(zip_file.get(), asset_name.c_str(), 0);
if (result != UNZ_OK) {
return false;
}
unz_file_info file_info;
result = unzGetCurrentFileInfo(zip_file.get(), &file_info, nullptr, 0,
nullptr, 0, nullptr, 0);
if (result != UNZ_OK) {
LOG(WARNING) << "unzGetCurrentFileInfo failed, error=" << result;
return false;
}
result = unzOpenCurrentFile(zip_file.get());
if (result != UNZ_OK) {
LOG(WARNING) << "unzOpenCurrentFile failed, error=" << result;
return false;
}
data->resize(file_info.uncompressed_size);
int total_read = 0;
while (total_read < static_cast<int>(data->size())) {
int bytes_read = unzReadCurrentFile(zip_file.get(),
data->data() + total_read,
data->size() - total_read);
if (bytes_read <= 0) {
return false;
}
total_read += bytes_read;
}
return true;
}
ZipAssetHandler::ZipAssetHandler(
const base::FilePath& zip_path,
const std::string& asset_name,
ScopedDataPipeProducerHandle producer,
scoped_refptr<base::TaskRunner> worker_runner)
: zip_path_(zip_path),
asset_name_(asset_name),
producer_(producer.Pass()),
main_runner_(base::MessageLoop::current()->task_runner()),
worker_runner_(worker_runner.Pass()),
buffer_(nullptr),
buffer_size_(0) {
}
ZipAssetHandler::~ZipAssetHandler() {
}
void ZipAssetHandler::Start() {
zip_file_.reset(unzOpen2(zip_path_.AsUTF8Unsafe().c_str(), NULL));
if (!zip_file_.is_valid()) {
LOG(ERROR) << "Unable to open ZIP file: " << zip_path_.value();
delete this;
return;
}
int result = unzLocateFile(zip_file_.get(), asset_name_.c_str(), 0);
if (result != UNZ_OK) {
LOG(WARNING) << "Requested asset '" << asset_name_ << "' does not exist.";
delete this;
return;
}
result = unzOpenCurrentFile(zip_file_.get());
if (result != UNZ_OK) {
LOG(WARNING) << "unzOpenCurrentFile failed, error=" << result;
delete this;
return;
}
CopyData();
}
void ZipAssetHandler::CopyData() {
while (true) {
MojoResult mojo_result = BeginWriteDataRaw(producer_.get(),
&buffer_, &buffer_size_,
MOJO_WRITE_DATA_FLAG_NONE);
if (mojo_result == MOJO_RESULT_SHOULD_WAIT) {
main_runner_->PostTask(FROM_HERE,
base::Bind(&ZipAssetHandler::WaitForWritable,
base::Unretained(this)));
return;
} else if (mojo_result != MOJO_RESULT_OK) {
LOG(WARNING) << "Mojo BeginWrite failed, error=" << mojo_result;
delete this;
return;
}
int bytes_read = unzReadCurrentFile(zip_file_.get(), buffer_, buffer_size_);
mojo_result = EndWriteDataRaw(producer_.get(), std::max(0, bytes_read));
if (bytes_read == 0) {
// Unzip is complete.
delete this;
return;
}
if (bytes_read < 0) {
LOG(WARNING) << "Asset unzip failed, error=" << bytes_read;
delete this;
return;
}
if (mojo_result != MOJO_RESULT_OK) {
LOG(WARNING) << "Mojo EndWrite failed, error=" << mojo_result;
delete this;
return;
}
}
}
void ZipAssetHandler::WaitForWritable() {
waiter_.reset(new AsyncWaiter(
producer_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
base::Bind(&ZipAssetHandler::OnWritable, base::Unretained(this))));
}
void ZipAssetHandler::OnWritable(MojoResult mojo_result) {
if (mojo_result == MOJO_RESULT_OK) {
worker_runner_->PostTask(FROM_HERE,
base::Bind(&ZipAssetHandler::CopyData,
base::Unretained(this)));
} else {
delete this;
}
}
} // namespace asset_bundle
} // namespace mojo
// Copyright 2016 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 <map>
#include <vector>
#include "base/scoped_generic.h"
#include "base/task_runner.h"
#include "base/files/file_path.h"
#include "base/memory/weak_ptr.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/environment/async_waiter.h"
#include "mojo/services/asset_bundle/interfaces/asset_bundle.mojom.h"
namespace mojo {
namespace asset_bundle {
// An implementation of AssetBundle that serves assets directly out of a
// ZIP archive.
class ZipAssetBundle : public base::RefCountedThreadSafe<ZipAssetBundle> {
friend class ZipAssetService;
public:
ZipAssetBundle(const base::FilePath& zip_path,
scoped_refptr<base::TaskRunner> worker_runner);
// AssetBundle implementation
void GetAsStream(
const String& asset_name,
const Callback<void(ScopedDataPipeConsumerHandle)>& callback);
// Serve this asset from another file instead of using the ZIP contents.
void AddOverlayFile(const std::string& asset_name,
const base::FilePath& file_path);
// Read the asset into a buffer.
bool GetAsBuffer(const std::string& asset_name, std::vector<uint8_t>* data);
protected:
friend class base::RefCountedThreadSafe<ZipAssetBundle>;
virtual ~ZipAssetBundle();
const base::FilePath zip_path_;
scoped_refptr<base::TaskRunner> worker_runner_;
std::map<String, base::FilePath> overlay_files_;
DISALLOW_COPY_AND_ASSIGN(ZipAssetBundle);
};
// Wrapper that exposes the ZipAssetBundle as a Mojo service.
class ZipAssetService : public AssetBundle {
public:
static void Create(
InterfaceRequest<AssetBundle> request,
const scoped_refptr<ZipAssetBundle>& zip_asset_bundle);
public:
void GetAsStream(
const String& asset_name,
const Callback<void(ScopedDataPipeConsumerHandle)>& callback) override;
~ZipAssetService() override;
private:
ZipAssetService(InterfaceRequest<AssetBundle> request,
const scoped_refptr<ZipAssetBundle>& zip_asset_bundle);
StrongBinding<AssetBundle> binding_;
scoped_refptr<ZipAssetBundle> zip_asset_bundle_;
};
struct ScopedUnzFileTraits {
static void* InvalidValue();
static void Free(void* unz_file);
};
typedef base::ScopedGeneric<void*, ScopedUnzFileTraits> ScopedUnzFile;
// Reads an asset from a ZIP archive and writes it to a Mojo pipe.
class ZipAssetHandler {
friend class ZipAssetBundle;
public:
ZipAssetHandler(const base::FilePath& zip_path,
const std::string& asset_name,
ScopedDataPipeProducerHandle producer,
scoped_refptr<base::TaskRunner> worker_runner);
~ZipAssetHandler();
void Start();
private:
void CopyData();
void OnWritable(MojoResult result);
void WaitForWritable();
const base::FilePath zip_path_;
const std::string asset_name_;
ScopedDataPipeProducerHandle producer_;
scoped_refptr<base::SingleThreadTaskRunner> main_runner_;
scoped_refptr<base::TaskRunner> worker_runner_;
ScopedUnzFile zip_file_;
void* buffer_;
uint32_t buffer_size_;
scoped_ptr<AsyncWaiter> waiter_;
DISALLOW_COPY_AND_ASSIGN(ZipAssetHandler);
};
} // namespace asset_bundle
} // namespace mojo
......@@ -28,6 +28,7 @@ source_set("bindings") {
"//base",
"//dart/runtime:libdart",
"//dart/runtime/bin:embedded_dart_io",
"//flutter/assets",
"//flutter/lib/ui",
"//flutter/tonic",
"//lib/tonic",
......@@ -37,8 +38,6 @@ source_set("bindings") {
"//mojo/public/cpp/system",
"//mojo/public/interfaces/application",
"//mojo/public/platform/dart:mojo_internal_impl",
"//mojo/services/asset_bundle/interfaces",
"//services/asset_bundle:lib",
"//sky/engine/core:prerequisites",
"//sky/engine/platform:platform",
"//sky/engine/wtf",
......
......@@ -76,16 +76,15 @@ static_library("core") {
":generate_sky_embedder_service_isolate_resources_cc",
":libraries",
":prerequisites",
"//services/asset_bundle:lib",
"//sky/engine/platform",
"//sky/engine/bindings",
"//sky/services/engine:interfaces",
"//sky/services/pointer:interfaces",
"//dart/runtime/bin:embedded_dart_io",
"//dart/runtime:libdart",
"//dart/runtime/bin:embedded_dart_io",
"//dart/runtime/vm:libdart_platform",
"//mojo/services/asset_bundle/interfaces:interfaces",
"//flutter/assets",
"//mojo/services/navigation/interfaces",
"//sky/engine/bindings",
"//sky/engine/platform",
"//sky/services/engine:interfaces",
"//sky/services/pointer:interfaces",
]
if (!flutter_product_mode) {
......
......@@ -156,8 +156,6 @@ sky_core_files = [
"script/dart_init.h",
"script/dart_service_isolate.cc",
"script/dart_service_isolate.h",
"script/directory_asset_bundle.cc",
"script/directory_asset_bundle.h",
"script/embedder_resources.cc",
"script/embedder_resources.h",
"script/ui_dart_state.cc",
......
......@@ -10,21 +10,20 @@
#include <sys/stat.h>
#include <sys/types.h>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/single_thread_task_runner.h"
#include "base/trace_event/trace_event.h"
#include "dart/runtime/bin/embedded_dart_io.h"
#include "dart/runtime/include/dart_mirrors_api.h"
#include "flutter/assets/zip_asset_store.h"
#include "flutter/tonic/dart_debugger.h"
#include "flutter/tonic/dart_dependency_catcher.h"
#include "flutter/tonic/dart_io.h"
#include "flutter/tonic/dart_library_loader.h"
#include "flutter/tonic/dart_snapshot_loader.h"
#include "flutter/tonic/dart_state.h"
#include "glue/trace_event.h"
#include "lib/ftl/logging.h"
#include "lib/tonic/dart_class_library.h"
#include "lib/tonic/dart_wrappable.h"
......@@ -34,7 +33,6 @@
#include "lib/tonic/scopes/dart_isolate_scope.h"
#include "lib/tonic/typed_data/uint8_list.h"
#include "mojo/public/platform/dart/dart_handle_watcher.h"
#include "services/asset_bundle/zip_asset_bundle.h"
#include "sky/engine/bindings/dart_mojo_internal.h"
#include "sky/engine/bindings/dart_runtime_hooks.h"
#include "sky/engine/bindings/dart_ui.h"
......@@ -69,8 +67,6 @@ extern const uint8_t* observatory_assets_archive;
namespace blink {
using mojo::asset_bundle::ZipAssetBundle;
const char kSnapshotAssetKey[] = "snapshot_blob.bin";
Dart_Handle DartLibraryTagHandler(Dart_LibraryTag tag,
......@@ -237,12 +233,13 @@ Dart_Isolate IsolateCreateCallback(const char* script_uri,
std::vector<uint8_t> snapshot_data;
if (!IsRunningPrecompiledCode()) {
FTL_CHECK(base::StartsWith(script_uri, kFileUriPrefix,
base::CompareCase::SENSITIVE));
base::FilePath bundle_path(script_uri + strlen(kFileUriPrefix));
scoped_refptr<ZipAssetBundle> zip_asset_bundle(
new ZipAssetBundle(bundle_path, nullptr));
FTL_CHECK(zip_asset_bundle->GetAsBuffer(kSnapshotAssetKey, &snapshot_data));
std::string uri = script_uri;
FTL_CHECK(uri.find(kFileUriPrefix) == 0u);
std::string bundle_path(script_uri + strlen(kFileUriPrefix));
ftl::RefPtr<ZipAssetStore> zip_asset_store =
ftl::MakeRefCounted<ZipAssetStore>(std::move(bundle_path),
ftl::RefPtr<ftl::TaskRunner>());
FTL_CHECK(zip_asset_store->GetAsBuffer(kSnapshotAssetKey, &snapshot_data));
}
FlutterDartState* parent_dart_state =
......
// Copyright 2016 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 "sky/engine/core/script/directory_asset_bundle.h"
#include "base/bind.h"
#include "base/task_runner.h"
#include "base/threading/worker_pool.h"
#include "mojo/data_pipe_utils/data_pipe_utils.h"
namespace blink {
namespace {
void Ignored(bool) {
}
} // namespace
void DirectoryAssetBundleService::Create(
mojo::InterfaceRequest<mojo::asset_bundle::AssetBundle> request,
const base::FilePath& directory) {
new DirectoryAssetBundleService(request.Pass(), directory);
}
void DirectoryAssetBundleService::GetAsStream(
const mojo::String& asset_name,
const mojo::Callback<void(mojo::ScopedDataPipeConsumerHandle)>& callback) {
mojo::DataPipe pipe;
callback.Run(pipe.consumer_handle.Pass());
base::FilePath asset_path(asset_name.data());
base::FilePath file_path = directory_.Append(asset_path);
scoped_refptr<base::TaskRunner> worker_runner =
base::WorkerPool::GetTaskRunner(true);
mojo::common::CopyFromFile(file_path,
pipe.producer_handle.Pass(),
0,
worker_runner.get(),
base::Bind(&Ignored));
}
DirectoryAssetBundleService::~DirectoryAssetBundleService() {
}
DirectoryAssetBundleService::DirectoryAssetBundleService(
mojo::InterfaceRequest<AssetBundle> request,
const base::FilePath& directory)
: binding_(this, request.Pass()),
directory_(directory) {
}
} // namespace blink
......@@ -66,8 +66,8 @@ class Platform {
// Returns a value such as "en-US".
virtual std::string defaultLocale() { return std::string(); }
virtual ftl::TaskRunner* GetUITaskRunner() { return 0; }
virtual ftl::TaskRunner* GetIOTaskRunner() { return 0; }
virtual ftl::TaskRunner* GetUITaskRunner() { return nullptr; }
virtual ftl::TaskRunner* GetIOTaskRunner() { return nullptr; }
protected:
virtual ~Platform() {}
......
......@@ -52,6 +52,7 @@ source_set("common") {
"//build/config/sanitizers:deps",
"//dart/runtime:libdart",
"//flow",
"//flutter/assets",
"//flutter/lib/ui",
"//flutter/tonic",
"//glue",
......@@ -67,7 +68,6 @@ source_set("common") {
"//mojo/services/gfx/composition/interfaces",
"//mojo/services/navigation/interfaces",
"//mojo/services/vsync/interfaces",
"//services/asset_bundle:lib",
"//skia",
"//sky/engine",
"//sky/engine/bindings",
......
......@@ -31,13 +31,11 @@ mojo_native_application("mojo") {
"//mojo/public/cpp/system",
"//mojo/public/cpp/utility",
"//mojo/public/interfaces/application",
"//mojo/services/asset_bundle/interfaces",
"//mojo/services/content_handler/interfaces",
"//mojo/services/gfx/composition/interfaces",
"//mojo/services/input_events/interfaces",
"//mojo/services/ui/input/interfaces",
"//mojo/services/ui/views/interfaces",
"//services/asset_bundle:lib",
"//services/icu",
"//skia",
"//sky/engine/public/sky",
......
......@@ -70,13 +70,12 @@ class Shell {
// These APIs must only be accessed on UI thread.
void AddPlatformView(const base::WeakPtr<PlatformView>& platform_view);
void PurgePlatformViews();
void GetPlatformViews(std::vector<base::WeakPtr<PlatformView>>*
platform_views);
void GetPlatformViews(
std::vector<base::WeakPtr<PlatformView>>* platform_views);
// These APIs can be called from any thread.
// Return the list of platform view ids at the time of this call.
void WaitForPlatformViewIds(
std::vector<uintptr_t>* platform_view_ids);
void WaitForPlatformViewIds(std::vector<uintptr_t>* platform_view_ids);
// Attempt to run a script inside a flutter view indicated by |view_id|.
// Will set |view_existed| to true if the view was found and false otherwise.
void RunInPlatformView(uintptr_t view_id,
......@@ -91,9 +90,8 @@ class Shell {
void InitGpuThread();
void InitUIThread();
void WaitForPlatformViewsIdsUIThread(
std::vector<uintptr_t>* platform_views,
base::WaitableEvent* latch);
void WaitForPlatformViewsIdsUIThread(std::vector<uintptr_t>* platform_views,
base::WaitableEvent* latch);
void RunInPlatformViewUIThread(uintptr_t view_id,
const std::string& main,
......
......@@ -7,16 +7,15 @@
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/threading/worker_pool.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "mojo/data_pipe_utils/data_pipe_utils.h"
#include "flutter/assets/directory_asset_bundle.h"
#include "flutter/assets/zip_asset_bundle.h"
#include "mojo/public/cpp/application/connect.h"
#include "services/asset_bundle/zip_asset_bundle.h"
#include "sky/engine/bindings/mojo_services.h"
#include "sky/engine/core/script/dart_init.h"
#include "sky/engine/core/script/directory_asset_bundle.h"
#include "sky/engine/core/script/ui_dart_state.h"
#include "sky/engine/public/platform/Platform.h"
#include "sky/engine/public/web/Sky.h"
#include "sky/shell/dart/dart_library_provider_files.h"
#include "sky/shell/shell.h"
......@@ -34,9 +33,6 @@ PlatformImpl* g_platform_impl = nullptr;
} // namespace
using mojo::asset_bundle::ZipAssetBundle;
using mojo::asset_bundle::ZipAssetService;
Engine::Config::Config() {}
Engine::Config::~Config() {}
......@@ -74,8 +70,7 @@ void Engine::RunFromSource(const std::string& main,
const std::string& assets_directory) {
TRACE_EVENT0("flutter", "Engine::RunFromSource");
// Assets.
base::FilePath assets_directory_path = base::FilePath(assets_directory);
ConfigureDirectoryAssetBundle(assets_directory_path);
ConfigureDirectoryAssetBundle(assets_directory);
// .packages.
base::FilePath packages_path = base::FilePath(std::string(packages));
if (packages_path.empty()) {
......@@ -198,14 +193,17 @@ void Engine::RunFromSnapshotStream(
}
void Engine::ConfigureZipAssetBundle(const mojo::String& path) {
zip_asset_bundle_ = new ZipAssetBundle(base::FilePath(std::string{path}),
base::WorkerPool::GetTaskRunner(true));
ZipAssetService::Create(mojo::GetProxy(&root_bundle_), zip_asset_bundle_);
asset_store_ = ftl::MakeRefCounted<blink::ZipAssetStore>(
path.get(), ftl::RefPtr<ftl::TaskRunner>(
blink::Platform::current()->GetIOTaskRunner()));
new blink::ZipAssetBundle(mojo::GetProxy(&root_bundle_), asset_store_);
}
void Engine::ConfigureDirectoryAssetBundle(const base::FilePath& path) {
blink::DirectoryAssetBundleService::Create(
mojo::GetProxy(&root_bundle_), path);
void Engine::ConfigureDirectoryAssetBundle(const std::string& path) {
new blink::DirectoryAssetBundle(
mojo::GetProxy(&root_bundle_), path,
ftl::RefPtr<ftl::TaskRunner>(
blink::Platform::current()->GetIOTaskRunner()));
}
void Engine::RunFromPrecompiledSnapshot(const mojo::String& bundle_path) {
......@@ -267,10 +265,7 @@ void Engine::RunFromBundleAndSnapshot(const mojo::String& script_uri,
ConfigureZipAssetBundle(bundle_path);
std::string snapshot_path_str = snapshot_path;
zip_asset_bundle_->AddOverlayFile(blink::kSnapshotAssetKey,
base::FilePath(snapshot_path_str));
asset_store_->AddOverlayFile(blink::kSnapshotAssetKey, snapshot_path);
root_bundle_->GetAsStream(blink::kSnapshotAssetKey,
base::Bind(&Engine::RunFromSnapshotStream,
weak_factory_.GetWeakPtr(), script_uri));
......@@ -314,9 +309,8 @@ void Engine::DidCreateMainIsolate(Dart_Isolate isolate) {
services_from_embedder.Pass(),
root_bundle_.Pass());
if (zip_asset_bundle_) {
FlutterFontSelector::install(zip_asset_bundle_);
}
if (asset_store_)
FlutterFontSelector::Install(asset_store_);
}
void Engine::DidCreateSecondaryIsolate(Dart_Isolate isolate) {
......
......@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "flutter/assets/zip_asset_store.h"
#include "mojo/public/cpp/application/service_provider_impl.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/binding_set.h"
......@@ -16,21 +17,14 @@
#include "mojo/public/cpp/system/handle.h"
#include "mojo/public/interfaces/application/service_provider.mojom.h"
#include "mojo/services/asset_bundle/interfaces/asset_bundle.mojom.h"
#include "sky/engine/public/sky/sky_view.h"
#include "sky/engine/public/sky/sky_view_client.h"
#include "sky/engine/core/script/directory_asset_bundle.h"
#include "sky/engine/public/sky/sky_view.h"
#include "sky/services/engine/sky_engine.mojom.h"
#include "sky/services/rasterizer/rasterizer.mojom.h"
#include "sky/shell/rasterizer.h"
#include "sky/shell/ui_delegate.h"
#include "third_party/skia/include/core/SkPicture.h"
namespace mojo {
namespace asset_bundle {
class ZipAssetBundle;
}
}
namespace sky {
class PlatformImpl;
namespace shell {
......@@ -106,7 +100,7 @@ class Engine : public UIDelegate,
void StartAnimatorIfPossible();
void ConfigureZipAssetBundle(const mojo::String& path);
void ConfigureDirectoryAssetBundle(const base::FilePath& path);
void ConfigureDirectoryAssetBundle(const std::string& path);
Config config_;
std::unique_ptr<Animator> animator_;
......@@ -125,7 +119,7 @@ class Engine : public UIDelegate,
std::string language_code_;
std::string country_code_;
mojo::Binding<SkyEngine> binding_;
scoped_refptr<mojo::asset_bundle::ZipAssetBundle> zip_asset_bundle_;
ftl::RefPtr<blink::ZipAssetStore> asset_store_;
// TODO(eseidel): This should move into an AnimatorStateMachine.
bool activity_running_;
......
......@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/values.h"
#include "base/json/json_reader.h"
#include "services/asset_bundle/zip_asset_bundle.h"
#include "base/values.h"
#include "flutter/assets/zip_asset_store.h"
#include "sky/engine/core/script/ui_dart_state.h"
#include "sky/engine/platform/fonts/FontData.h"
#include "sky/engine/platform/fonts/FontFaceCreationParams.h"
......@@ -30,7 +30,6 @@ using blink::FontPlatformData;
using blink::FontStyle;
using blink::FontWeight;
using blink::SimpleFontData;
using mojo::asset_bundle::ZipAssetBundle;
// Style attributes of a Flutter font asset.
struct FlutterFontSelector::FlutterFontAttributes {
......@@ -93,17 +92,17 @@ struct FontMatcher {
};
}
void FlutterFontSelector::install(
const scoped_refptr<ZipAssetBundle>& zip_asset_bundle) {
void FlutterFontSelector::Install(
ftl::RefPtr<blink::ZipAssetStore> asset_store) {
RefPtr<FlutterFontSelector> font_selector =
adoptRef(new FlutterFontSelector(zip_asset_bundle));
adoptRef(new FlutterFontSelector(std::move(asset_store)));
font_selector->parseFontManifest();
blink::UIDartState::Current()->set_font_selector(font_selector);
}
FlutterFontSelector::FlutterFontSelector(
const scoped_refptr<ZipAssetBundle>& zip_asset_bundle)
: zip_asset_bundle_(zip_asset_bundle) {}
ftl::RefPtr<blink::ZipAssetStore> asset_store)
: asset_store_(std::move(asset_store)) {}
FlutterFontSelector::~FlutterFontSelector() {}
......@@ -121,8 +120,7 @@ FlutterFontSelector::FlutterFontAttributes::~FlutterFontAttributes() {}
void FlutterFontSelector::parseFontManifest() {
std::vector<uint8_t> font_manifest_data;
if (!zip_asset_bundle_->GetAsBuffer(kFontManifestAssetPath,
&font_manifest_data))
if (!asset_store_->GetAsBuffer(kFontManifestAssetPath, &font_manifest_data))
return;
base::StringPiece font_manifest_str(
......@@ -236,7 +234,7 @@ sk_sp<SkTypeface> FlutterFontSelector::getTypefaceAsset(
}
std::unique_ptr<TypefaceAsset> typeface_asset(new TypefaceAsset);
if (!zip_asset_bundle_->GetAsBuffer(asset_path, &typeface_asset->data)) {
if (!asset_store_->GetAsBuffer(asset_path, &typeface_asset->data)) {
typeface_cache_.insert(std::make_pair(asset_path, nullptr));
return nullptr;
}
......
......@@ -8,16 +8,11 @@
#include <unordered_map>
#include <vector>
#include "flutter/assets/zip_asset_store.h"
#include "sky/engine/platform/fonts/FontCacheKey.h"
#include "sky/engine/platform/fonts/FontSelector.h"
#include "sky/engine/platform/fonts/SimpleFontData.h"
namespace mojo {
namespace asset_bundle {
class ZipAssetBundle;
}
}
namespace sky {
namespace shell {
......@@ -29,8 +24,7 @@ class FlutterFontSelector : public blink::FontSelector {
~FlutterFontSelector() override;
static void install(
const scoped_refptr<mojo::asset_bundle::ZipAssetBundle>& zip_asset_bundle);
static void Install(ftl::RefPtr<blink::ZipAssetStore> asset_store);
PassRefPtr<blink::FontData> getFontData(
const blink::FontDescription& font_description,
......@@ -47,8 +41,7 @@ class FlutterFontSelector : public blink::FontSelector {
private:
struct TypefaceAsset;
FlutterFontSelector(
const scoped_refptr<mojo::asset_bundle::ZipAssetBundle>& zip_asset_bundle);
FlutterFontSelector(ftl::RefPtr<blink::ZipAssetStore> asset_store);
void parseFontManifest();
......@@ -56,15 +49,17 @@ class FlutterFontSelector : public blink::FontSelector {
const blink::FontDescription& font_description,
const AtomicString& family_name);
scoped_refptr<mojo::asset_bundle::ZipAssetBundle> zip_asset_bundle_;
ftl::RefPtr<blink::ZipAssetStore> asset_store_;
HashMap<AtomicString, std::vector<FlutterFontAttributes>> font_family_map_;
std::unordered_map<std::string, std::unique_ptr<TypefaceAsset>>
typeface_cache_;
typedef HashMap<blink::FontCacheKey, RefPtr<blink::SimpleFontData>,
blink::FontCacheKeyHash, blink::FontCacheKeyTraits>
typedef HashMap<blink::FontCacheKey,
RefPtr<blink::SimpleFontData>,
blink::FontCacheKeyHash,
blink::FontCacheKeyTraits>
FontPlatformDataCache;
FontPlatformDataCache font_platform_data_cache_;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册