Skip to content

Commit da5a36e

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 d7a22f1 commit da5a36e

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

xbuild/src/gradle/mod.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ pub fn build(env: &BuildEnv, libraries: Vec<(Target, PathBuf)>, out: &Path) -> R
6666
dependencies.push_str(&format!("implementation '{dep}'\n"));
6767
}
6868

69+
let asset_packs = if config.assets.is_empty() {
70+
""
71+
} else {
72+
r#"assetPacks = [":baseAssets"]"#
73+
};
74+
6975
let app_build_gradle = format!(
7076
r#"
7177
plugins {{
@@ -82,13 +88,59 @@ pub fn build(env: &BuildEnv, libraries: Vec<(Target, PathBuf)>, out: &Path) -> R
8288
versionCode {version_code}
8389
versionName '{version_name}'
8490
}}
91+
{asset_packs}
8592
}}
8693
dependencies {{
8794
{dependencies}
8895
}}
8996
"#,
9097
);
9198

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