Skip to content

Commit e7edc95

Browse files
committed
gradle: Embed assets in baseAssets "Play Asset Delivery" pack
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
1 parent ffe3e34 commit e7edc95

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

xbuild/src/gradle/mod.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::cargo::CrateType;
22
use crate::{task, BuildEnv, Format, Opt};
3-
use anyhow::Result;
3+
use anyhow::{Context, Result};
44
use std::path::Path;
55
use std::process::Command;
66

@@ -67,6 +67,12 @@ pub fn build(env: &BuildEnv, out: &Path) -> Result<()> {
6767
dependencies.push_str(&format!("implementation '{}'\n", dep));
6868
}
6969

70+
let asset_packs = if config.assets.is_empty() {
71+
""
72+
} else {
73+
r#"assetPacks = [":baseAssets"]"#
74+
};
75+
7076
let app_build_gradle = format!(
7177
r#"
7278
plugins {{
@@ -83,6 +89,7 @@ pub fn build(env: &BuildEnv, out: &Path) -> Result<()> {
8389
versionCode {version_code}
8490
versionName '{version_name}'
8591
}}
92+
{asset_packs}
8693
}}
8794
dependencies {{
8895
{dependencies}
@@ -96,6 +103,51 @@ pub fn build(env: &BuildEnv, out: &Path) -> Result<()> {
96103
dependencies = dependencies,
97104
);
98105

106+
let pack_name = "baseAssets";
107+
let base_assets = gradle.join(pack_name);
108+
// Make sure that any possibly-obsolete asset pack does not clobber the build
109+
let _ = std::fs::remove_dir_all(&base_assets);
110+
111+
if !config.assets.is_empty() {
112+
std::fs::create_dir_all(&base_assets)?;
113+
let assets = format!(
114+
r#"
115+
plugins {{
116+
id 'com.android.asset-pack'
117+
}}
118+
assetPack {{
119+
packName = "{pack_name}" // Directory name for the asset pack
120+
dynamicDelivery {{
121+
// Use install-time to make assets available to AAssetManager
122+
// https://developer.android.com/guide/playcore/asset-delivery/integrate-native
123+
deliveryType = "install-time"
124+
}}
125+
}}
126+
"#,
127+
);
128+
129+
std::fs::write(base_assets.join("build.gradle"), assets)?;
130+
131+
let target_dir = base_assets.join("src/main/assets");
132+
let _ = std::fs::remove_dir_all(&target_dir);
133+
std::fs::create_dir_all(&target_dir)?;
134+
for asset in &config.assets {
135+
let path = env.cargo().package_root().join(asset.path());
136+
let target = target_dir.join(asset.path().file_name().unwrap());
137+
138+
if !asset.optional() || path.exists() {
139+
// Make this file or directory available to the `gradle` build system
140+
xcommon::symlink(&path, &target).with_context(|| {
141+
format!(
142+
"Failed to make asset file/folder `{}` available to gradle at `{}`",
143+
path.display(),
144+
target.display()
145+
)
146+
})?;
147+
}
148+
}
149+
}
150+
99151
if let Some(icon_path) = env.icon.as_ref() {
100152
let mut scaler = xcommon::Scaler::open(icon_path)?;
101153
scaler.optimize();

xbuild/src/gradle/settings.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ dependencyResolutionManagement {
1414
}
1515

1616
include ':app'
17+
include ':baseAssets'

0 commit comments

Comments
 (0)