Skip to content

Commit

Permalink
gradle: Embed assets in baseAssets "Play Asset Delivery" pack
Browse files Browse the repository at this point in the history
Assets for AABs could be embedded in the application pack but have
significant limitations and size constraints.  Implement the most
simple form of an asset pack that comprises all assets listed in
`manifest.yaml` in an `install-time` pack that is a fixed dependency of
the app.  This makes the files available to `AAssetManager` as soon as
the app is started while being exempt of the 150MB limit.

This matches the existing "asset embedding" functionality provided by
our native APK build.

https://developer.android.com/guide/playcore/asset-delivery/integrate-native
  • Loading branch information
MarijnS95 committed Oct 10, 2023
1 parent f58cf19 commit d5ebb6e
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
56 changes: 56 additions & 0 deletions xbuild/src/gradle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ pub fn build(env: &BuildEnv, out: &Path) -> Result<()> {
dependencies.push_str(&format!("implementation '{}'\n", dep));
}

let asset_packs = if config.assets.is_empty() {
""
} else {
r#"assetPacks = [":baseAssets"]"#
};

let app_build_gradle = format!(
r#"
plugins {{
Expand All @@ -83,6 +89,7 @@ pub fn build(env: &BuildEnv, out: &Path) -> Result<()> {
versionCode {version_code}
versionName '{version_name}'
}}
{asset_packs}
}}
dependencies {{
{dependencies}
Expand All @@ -96,6 +103,55 @@ pub fn build(env: &BuildEnv, out: &Path) -> Result<()> {
dependencies = dependencies,
);

let pack_name = "baseAssets";
let base_assets = gradle.join(pack_name);
// Make sure that any possibly-obsolete asset pack does not clobber the build
let _ = std::fs::remove_dir_all(&base_assets);

if !config.assets.is_empty() {
std::fs::create_dir_all(&base_assets)?;
let assets = format!(
r#"
plugins {{
id 'com.android.asset-pack'
}}
assetPack {{
packName = "{pack_name}" // Directory name for the asset pack
dynamicDelivery {{
// Use install-time to make assets available to AAssetManager
// https://developer.android.com/guide/playcore/asset-delivery/integrate-native
deliveryType = "install-time"
}}
}}
"#,
);

std::fs::write(base_assets.join("build.gradle"), assets)?;

let target_dir = base_assets.join("src/main/assets");
let _ = std::fs::remove_dir_all(&target_dir);
std::fs::create_dir_all(&target_dir)?;
for asset in &config.assets {
let path = env.cargo().package_root().join(asset.path());
let target = target_dir.join(asset.path().file_name().unwrap());

if !asset.optional() || path.exists() {
// Make this file or directory available to the `gradle` build system

// Windows has special functions for files and directories:
// https://doc.rust-lang.org/std/fs/fn.soft_link.html
#[cfg(windows)]
if path.is_dir() {
std::os::windows::fs::symlink_dir(path, target)?;
} else {
std::os::windows::fs::symlink_file(path, target)?;
}
#[cfg(unix)]
std::os::unix::fs::symlink(path, target)?;
}
}
}

if let Some(icon_path) = env.icon.as_ref() {
let mut scaler = xcommon::Scaler::open(icon_path)?;
scaler.optimize();
Expand Down
1 change: 1 addition & 0 deletions xbuild/src/gradle/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ dependencyResolutionManagement {
}

include ':app'
include ':baseAssets'

0 comments on commit d5ebb6e

Please sign in to comment.