Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion assets/directory_asset_bundle.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ class DirectoryAssetBundle {

bool GetAsBuffer(const std::string& asset_name, std::vector<uint8_t>* data);

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

private:
const std::string directory_;

FXL_DISALLOW_COPY_AND_ASSIGN(DirectoryAssetBundle);
Expand Down
48 changes: 40 additions & 8 deletions runtime/dart_init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <utility>
#include <vector>

#include "flutter/assets/directory_asset_bundle.h"
#include "flutter/assets/unzipper_provider.h"
#include "flutter/assets/zip_asset_store.h"
#include "flutter/common/settings.h"
Expand All @@ -27,6 +28,7 @@
#include "flutter/runtime/start_up.h"
#include "lib/fxl/arraysize.h"
#include "lib/fxl/build_config.h"
#include "lib/fxl/files/path.h"
#include "lib/fxl/logging.h"
#include "lib/fxl/time/time_delta.h"
#include "lib/tonic/converter/dart_converter.h"
Expand Down Expand Up @@ -265,6 +267,16 @@ Dart_Isolate ServiceIsolateCreateCallback(const char* script_uri,
#endif // FLUTTER_RUNTIME_MODE
}

static bool GetAssetAsBuffer(
const std::string& name,
std::vector<uint8_t>* data,
std::unique_ptr<DirectoryAssetBundle>& directory_asset_bundle,
fxl::RefPtr<ZipAssetStore>& asset_store) {
return (directory_asset_bundle &&
directory_asset_bundle->GetAsBuffer(name, data)) ||
(asset_store && asset_store->GetAsBuffer(name, data));
}

Dart_Isolate IsolateCreateCallback(const char* script_uri,
const char* main,
const char* package_root,
Expand Down Expand Up @@ -296,11 +308,30 @@ Dart_Isolate IsolateCreateCallback(const char* script_uri,
if (!running_from_source) {
// Attempt to copy the snapshot from the asset bundle.
const std::string& bundle_path = entry_path;
fxl::RefPtr<ZipAssetStore> zip_asset_store =
fxl::MakeRefCounted<ZipAssetStore>(
GetUnzipperProviderForPath(std::move(bundle_path)));
zip_asset_store->GetAsBuffer(kKernelAssetKey, &kernel_data);
zip_asset_store->GetAsBuffer(kSnapshotAssetKey, &snapshot_data);

struct stat stat_result = {};
if (::stat(bundle_path.c_str(), &stat_result) == 0) {
std::unique_ptr<DirectoryAssetBundle> directory_asset_bundle;
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be merged with your other change, and become a fxl::RefPtr<>, right?

// TODO(zarah): Remove usage of zip_asset_store once app.flx is removed.
fxl::RefPtr<ZipAssetStore> zip_asset_store;
// bundle_path is either the path to app.flx or the flutter assets
// directory.
std::string flx_path = bundle_path;
if (S_ISDIR(stat_result.st_mode)) {
directory_asset_bundle =
std::make_unique<DirectoryAssetBundle>(bundle_path);
flx_path = files::GetDirectoryName(bundle_path) + "/app.flx";
}

if (access(flx_path.c_str(), R_OK) == 0) {
zip_asset_store = fxl::MakeRefCounted<ZipAssetStore>(
GetUnzipperProviderForPath(flx_path));
}
GetAssetAsBuffer(kKernelAssetKey, &kernel_data, directory_asset_bundle,
zip_asset_store);
GetAssetAsBuffer(kSnapshotAssetKey, &snapshot_data,
directory_asset_bundle, zip_asset_store);
}
}
}

Expand Down Expand Up @@ -561,9 +592,10 @@ void InitDartVM(const uint8_t* vm_snapshot_data,
#endif

if (!bundle_path.empty()) {
auto zip_asset_store = fxl::MakeRefCounted<ZipAssetStore>(
GetUnzipperProviderForPath(std::move(bundle_path)));
zip_asset_store->GetAsBuffer(kPlatformKernelAssetKey, &platform_data);
std::unique_ptr<DirectoryAssetBundle> directory_asset_bundle =
std::make_unique<DirectoryAssetBundle>(bundle_path);
directory_asset_bundle->GetAsBuffer(kPlatformKernelAssetKey,
&platform_data);
if (!platform_data.empty()) {
kernel_platform = Dart_ReadKernelBinary(
platform_data.data(), platform_data.size(), ReleaseFetchedBytes);
Expand Down
6 changes: 3 additions & 3 deletions runtime/dart_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@

namespace blink {

// Name of the kernel blob asset within the FLX bundle.
// Name of the kernel blob asset within the asset directory.
extern const char kKernelAssetKey[];

// Name of the snapshot blob asset within the FLX bundle.
// Name of the snapshot blob asset within the asset directory.
extern const char kSnapshotAssetKey[];

// Name of the platform kernel blob asset within the FLX bundle.
// Name of the platform kernel blob asset within the asset directory.
extern const char kPlatformKernelAssetKey[];

bool IsRunningPrecompiledCode();
Expand Down
31 changes: 18 additions & 13 deletions shell/common/engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,17 @@ void Engine::Init(const std::string& bundle_path) {
#error Unknown OS
#endif

std::string flx_path = bundle_path;
struct stat stat_result = {};
if (::stat(flx_path.c_str(), &stat_result) == 0) {
if (S_ISDIR(stat_result.st_mode)) {
flx_path = files::GetDirectoryName(bundle_path) + "/app.flx";
}
}

blink::InitRuntime(vm_snapshot_data, vm_snapshot_instr,
default_isolate_snapshot_data,
default_isolate_snapshot_instr, bundle_path);
default_isolate_snapshot_instr, flx_path);
}

const std::string Engine::main_entrypoint_ = "main";
Expand Down Expand Up @@ -485,18 +493,18 @@ void Engine::ConfigureAssetBundle(const std::string& path) {
return;
}

std::string flx_path;
if (S_ISDIR(stat_result.st_mode)) {
directory_asset_bundle_ =
std::make_unique<blink::DirectoryAssetBundle>(path);
return;
flx_path = files::GetDirectoryName(path) + "/app.flx";
} else if (S_ISREG(stat_result.st_mode)) {
flx_path = path;
}

if (S_ISREG(stat_result.st_mode)) {
if (PathExists(flx_path)) {
asset_store_ = fxl::MakeRefCounted<blink::ZipAssetStore>(
blink::GetUnzipperProviderForPath(path));
directory_asset_bundle_ = std::make_unique<blink::DirectoryAssetBundle>(
files::GetDirectoryName(path));
return;
blink::GetUnzipperProviderForPath(flx_path));
}
}

Expand Down Expand Up @@ -595,12 +603,9 @@ 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));
} else {
response->CompleteEmpty();
}
std::string asset_path = directory_asset_bundle_->GetPathForAsset(asset_name);
response->Complete(
std::vector<uint8_t>(asset_path.begin(), asset_path.end()));
}

bool Engine::GetAssetAsBuffer(const std::string& name,
Expand Down
2 changes: 1 addition & 1 deletion shell/common/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class Engine : public blink::RuntimeDelegate {
std::string country_code_;
std::string user_settings_data_;
bool semantics_enabled_ = false;
// TODO(abarth): Unify these two behind a common interface.
// TODO(zarah): Remove usage of asset_store_ once app.flx is removed.
fxl::RefPtr<blink::ZipAssetStore> asset_store_;
std::unique_ptr<blink::DirectoryAssetBundle> directory_asset_bundle_;
// TODO(eseidel): This should move into an AnimatorStateMachine.
Expand Down
3 changes: 3 additions & 0 deletions shell/common/switches.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ DEF_SWITCH(EnableTxt,
"enable-txt",
"Enable libtxt as the text shaping library instead of Blink.")
DEF_SWITCH(FLX, "flx", "Specify the FLX path.")
DEF_SWITCH(FlutterAssetsDir,
"flutter-assets-dir",
"Path to the Flutter assets directory.")
DEF_SWITCH(Help, "help", "Display this help text.")
DEF_SWITCH(LogTag, "log-tag", "Tag associated with log messages.")
DEF_SWITCH(MainDartFile, "dart-main", "The path to the main Dart file.")
Expand Down
8 changes: 7 additions & 1 deletion shell/platform/android/io/flutter/view/FlutterMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class FlutterMain {
private static final String AOT_ISOLATE_SNAPSHOT_INSTR_KEY = "isolate-snapshot-instr";
private static final String FLX_KEY = "flx";
private static final String SNAPSHOT_BLOB_KEY = "snapshot-blob";
private static final String FLUTTER_ASSETS_DIR_KEY = "flutter-assets-dir";

// XML Attribute keys supported in AndroidManifest.xml
public static final String PUBLIC_AOT_AOT_SHARED_LIBRARY_PATH =
Expand All @@ -54,6 +55,8 @@ public class FlutterMain {
FlutterMain.class.getName() + '.' + FLX_KEY;
public static final String PUBLIC_SNAPSHOT_BLOB_KEY =
FlutterMain.class.getName() + '.' + SNAPSHOT_BLOB_KEY;
public static final String PUBLIC_FLUTTER_ASSETS_DIR_KEY =
FlutterMain.class.getName() + '.' + FLUTTER_ASSETS_DIR_KEY;

// Resource names used for components of the precompiled snapshot.
private static final String DEFAULT_AOT_SHARED_LIBRARY_PATH= "app.so";
Expand All @@ -63,6 +66,7 @@ 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_FLUTTER_ASSETS_DIR = "flutter_assets";

private static final String MANIFEST = "flutter.yaml";

Expand All @@ -79,6 +83,7 @@ public class FlutterMain {
private static String sAotIsolateSnapshotInstr = DEFAULT_AOT_ISOLATE_SNAPSHOT_INSTR;
private static String sFlx = DEFAULT_FLX;
private static String sSnapshotBlob = DEFAULT_SNAPSHOT_BLOB;
private static String sFlutterAssetsDir = DEFAULT_FLUTTER_ASSETS_DIR;

private static boolean sInitialized = false;
private static ResourceExtractor sResourceExtractor;
Expand Down Expand Up @@ -239,6 +244,7 @@ private static void initResources(Context applicationContext) {
sResourceExtractor = new ResourceExtractor(context)
.addResources(SKY_RESOURCES)
.addResource(sFlx);
.addResource(sFlutterAssetsDir)
if (sIsPrecompiledAsSharedLibrary) {
sResourceExtractor
.addResource(sAotSharedLibraryPath);
Expand Down Expand Up @@ -290,7 +296,7 @@ public static boolean isRunningPrecompiledCode() {

public static String findAppBundlePath(Context applicationContext) {
String dataDirectory = PathUtils.getDataDirectory(applicationContext);
File appBundle = new File(dataDirectory, sFlx);
File appBundle = new File(dataDirectory, sFlutterAssetsDir);
return appBundle.exists() ? appBundle.getPath() : null;
}
}
67 changes: 40 additions & 27 deletions shell/platform/android/io/flutter/view/ResourceExtractor.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;

Expand Down Expand Up @@ -48,37 +50,40 @@ private void extractResources() {
try {
byte[] buffer = null;
final String[] assets = manager.list("");
for (String asset : assets) {
LinkedList<String> 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;
}

final File output = new File(dataDir, asset);
if (output.exists())
continue;
InputStream is = null;
OutputStream os = null;
try {
is = manager.open(asset);
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);
}
os.flush();
} finally {
try {
if (is != null) {
is.close();
}
} finally {
if (os != null) {
os.close();
}
}
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);
}
os.flush();
}
}
}
} catch (IOException e) {
Log.w(TAG, "Exception unpacking resources: " + e.getMessage());
Expand Down Expand Up @@ -179,10 +184,18 @@ public boolean accept(File dir, String name) {

private void deleteFiles() {
final File dataDir = new File(PathUtils.getDataDirectory(mContext));
for (String resource : mResources) {
LinkedList<String> files = new LinkedList<>(mResources);
while (!files.isEmpty()) {
String resource = files.pop();
final File file = new File(dataDir, resource);
if (file.exists()) {
file.delete();
if (file.isFile()) {
file.delete();
} else {
for (String f : file.list()) {
files.add(resource + File.separator + f);
}
}
}
}
for (String timestamp : getExistingTimestamps(dataDir)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ FLUTTER_EXPORT

- (instancetype)initWithFLXArchiveWithScriptSnapshot:(NSURL*)archiveURL NS_DESIGNATED_INITIALIZER;

- (instancetype)initWithFlutterAssets:(NSURL*)archiveURL
dartMain:(NSURL*)dartMainURL
packages:(NSURL*)dartPackages NS_DESIGNATED_INITIALIZER;

- (instancetype)initWithFlutterAssetsWithScriptSnapshot:(NSURL*)archiveURL
NS_DESIGNATED_INITIALIZER;

- (instancetype)initFromDefaultSourceForConfiguration;

@end
Expand Down
Loading