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 Aug 9, 2024
1 parent ffe3e34 commit e7edc95
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
54 changes: 53 additions & 1 deletion xbuild/src/gradle/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::cargo::CrateType;
use crate::{task, BuildEnv, Format, Opt};
use anyhow::Result;
use anyhow::{Context, Result};
use std::path::Path;
use std::process::Command;

Expand Down 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,51 @@ 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
xcommon::symlink(&path, &target).with_context(|| {
format!(
"Failed to make asset file/folder `{}` available to gradle at `{}`",
path.display(),
target.display()
)
})?;
}
}
}

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 e7edc95

Please sign in to comment.