Skip to content

Commit 4adef85

Browse files
committed
Merge pull request #106447 from kojurohan42/instant-build
Add support for exporting to Google Play Instant via Google Play Instant Export Option
2 parents 7842a04 + 12ad9ed commit 4adef85

File tree

5 files changed

+50
-3
lines changed

5 files changed

+50
-3
lines changed

platform/android/doc_classes/EditorExportPlatformAndroid.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@
6161
<member name="gradle_build/export_format" type="int" setter="" getter="">
6262
Application export format (*.apk or *.aab).
6363
</member>
64+
<member name="gradle_build/google_play_instant" type="bool" setter="" getter="">
65+
If [code]true[/code], configures the exported project for Play Instant Build.
66+
Use this option when targeting Play Instant to allow users to launch the app without installation. See [url=https://developer.android.com/topic/google-play-instant/overview]Google Play Instant[/url].
67+
[b]Note:[/b] Instant play games also need to be optimized for size. See [url=https://docs.godotengine.org/en/stable/contributing/development/compiling/optimizing_for_size.html]Optimizing a build for size[/url].
68+
</member>
6469
<member name="gradle_build/gradle_build_directory" type="String" setter="" getter="">
6570
Path to the Gradle build directory. If left empty, then [code]res://android[/code] will be used.
6671
</member>

platform/android/export/export_plugin.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ static const int EXPORT_FORMAT_AAB = 1;
280280

281281
static const char *APK_ASSETS_DIRECTORY = "assets";
282282
static const char *AAB_ASSETS_DIRECTORY = "assetPackInstallTime/src/main/assets";
283+
static const char *INSTANT_APP_ASSETS_DIRECTORY = "assets"; // instant build doesn't support installTime assetspacks, so using the same directory as APK
283284

284285
static const int DEFAULT_MIN_SDK_VERSION = 24; // Should match the value in 'platform/android/java/app/config.gradle#minSdk'
285286
static const int DEFAULT_TARGET_SDK_VERSION = 35; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk'
@@ -524,6 +525,12 @@ String EditorExportPlatformAndroid::get_valid_basename(const Ref<EditorExportPre
524525

525526
String EditorExportPlatformAndroid::get_assets_directory(const Ref<EditorExportPreset> &p_preset, int p_export_format) const {
526527
String gradle_build_directory = ExportTemplateManager::get_android_build_directory(p_preset);
528+
529+
bool google_play_instant_build = p_preset->get("gradle_build/google_play_instant");
530+
if (google_play_instant_build) {
531+
return gradle_build_directory.path_join(INSTANT_APP_ASSETS_DIRECTORY); // Always use base APK asset format
532+
}
533+
527534
return gradle_build_directory.path_join(p_export_format == EXPORT_FORMAT_AAB ? AAB_ASSETS_DIRECTORY : APK_ASSETS_DIRECTORY);
528535
}
529536

@@ -994,10 +1001,19 @@ void EditorExportPlatformAndroid::_get_manifest_info(const Ref<EditorExportPrese
9941001

9951002
void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, bool p_debug) {
9961003
print_verbose("Building temporary manifest...");
1004+
1005+
bool google_play_instant_build = (bool)p_preset->get("gradle_build/google_play_instant");
1006+
9971007
String manifest_text =
9981008
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
9991009
"<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
1000-
" xmlns:tools=\"http://schemas.android.com/tools\">\n";
1010+
" xmlns:tools=\"http://schemas.android.com/tools\"";
1011+
1012+
if (google_play_instant_build) {
1013+
manifest_text += " android:targetSandboxVersion=\"2\" \n xmlns:dist=\"http://schemas.android.com/apk/distribution\"";
1014+
}
1015+
1016+
manifest_text += ">\n";
10011017

10021018
manifest_text += _get_screen_sizes_tag(p_preset);
10031019
manifest_text += _get_gles_tag();
@@ -1031,6 +1047,7 @@ void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref<EditorExportPres
10311047
}
10321048

10331049
manifest_text += _get_application_tag(Ref<EditorExportPlatform>(this), p_preset, _has_read_write_storage_permission(perms), p_debug, manifest_metadata);
1050+
10341051
manifest_text += "</manifest>\n";
10351052
String manifest_path = ExportTemplateManager::get_android_build_directory(p_preset).path_join(vformat("src/%s/AndroidManifest.xml", (p_debug ? "debug" : "release")));
10361053

@@ -2008,6 +2025,12 @@ String EditorExportPlatformAndroid::get_export_option_warning(const EditorExport
20082025
if (int(p_preset->get("gradle_build/export_format")) == EXPORT_FORMAT_AAB && !gradle_build_enabled) {
20092026
return TTR("\"Export AAB\" is only valid when \"Use Gradle Build\" is enabled.");
20102027
}
2028+
} else if (p_name == "gradle_build/google_play_instant") {
2029+
bool instant_enabled = p_preset->get("gradle_build/google_play_instant");
2030+
bool gradle_build_enabled = p_preset->get("gradle_build/use_gradle_build");
2031+
if (instant_enabled && !gradle_build_enabled) {
2032+
return TTR("\"Instant Build\" is only valid when \"Use Gradle Build\" is enabled.");
2033+
}
20112034
} else if (p_name == "gradle_build/min_sdk") {
20122035
String min_sdk_str = p_preset->get("gradle_build/min_sdk");
20132036
bool gradle_build_enabled = p_preset->get("gradle_build/use_gradle_build");
@@ -2087,6 +2110,7 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
20872110
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "gradle_build/gradle_build_directory", PROPERTY_HINT_PLACEHOLDER_TEXT, "res://android"), "", false, false));
20882111
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "gradle_build/android_source_template", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
20892112
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "gradle_build/export_format", PROPERTY_HINT_ENUM, "Export APK,Export AAB"), EXPORT_FORMAT_APK, false, true));
2113+
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "gradle_build/google_play_instant"), false, true, true));
20902114
// Using String instead of int to default to an empty string (no override) with placeholder for instructions (see GH-62465).
20912115
// This implies doing validation that the string is a proper int.
20922116
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "gradle_build/min_sdk", PROPERTY_HINT_PLACEHOLDER_TEXT, vformat("%d (default)", DEFAULT_MIN_SDK_VERSION)), "", false, true));
@@ -3564,6 +3588,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
35643588
String enabled_abi_string = join_abis(enabled_abis, "|", false);
35653589
String sign_flag = should_sign ? "true" : "false";
35663590
String zipalign_flag = "true";
3591+
String play_instant_flag = bool_to_string(p_preset->get("gradle_build/google_play_instant"));
35673592

35683593
Vector<String> android_libraries;
35693594
Vector<String> android_dependencies;
@@ -3638,6 +3663,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
36383663
cmdline.push_back("-Pplugins_maven_repos=" + combined_android_dependencies_maven_repos); // argument to specify the list of maven repos for android dependencies provided by plugins.
36393664
cmdline.push_back("-Pperform_zipalign=" + zipalign_flag); // argument to specify whether the build should be zipaligned.
36403665
cmdline.push_back("-Pperform_signing=" + sign_flag); // argument to specify whether the build should be signed.
3666+
cmdline.push_back("-Pplay_instant_app=" + play_instant_flag); // argument to specify whether the build is for Google Play Instant.
36413667

36423668
// NOTE: The release keystore is not included in the verbose logging
36433669
// to avoid accidentally leaking sensitive information when sharing verbose logs for troubleshooting.

platform/android/export/gradle_export_util.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,8 @@ String _get_application_tag(const Ref<EditorExportPlatform> &p_export_platform,
315315
int app_category_index = (int)(p_preset->get("package/app_category"));
316316
bool is_game = app_category_index == APP_CATEGORY_GAME;
317317

318+
bool google_play_instant_build = (bool)p_preset->get("gradle_build/google_play_instant");
319+
318320
String manifest_application_text = vformat(
319321
" <application android:label=\"@string/godot_project_name_string\"\n"
320322
" android:allowBackup=\"%s\"\n"
@@ -335,6 +337,10 @@ String _get_application_tag(const Ref<EditorExportPlatform> &p_export_platform,
335337
}
336338
manifest_application_text += " tools:ignore=\"GoogleAppIndexingWarning\">\n\n";
337339

340+
if (google_play_instant_build) {
341+
manifest_application_text += " <dist:module dist:instant=\"true\" />\n";
342+
}
343+
338344
for (int i = 0; i < p_metadata.size(); i++) {
339345
manifest_application_text += vformat(" <meta-data tools:node=\"replace\" android:name=\"%s\" android:value=\"%s\" />\n", p_metadata[i].name, p_metadata[i].value);
340346
}

platform/android/java/app/build.gradle

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ dependencies {
3737
implementation "androidx.fragment:fragment:$versions.fragmentVersion"
3838
implementation "androidx.core:core-splashscreen:$versions.splashscreenVersion"
3939

40+
if (isInstantApp()) {
41+
implementation "com.google.android.gms:play-services-instantapps:$versions.instantAppsVersion"
42+
}
43+
4044
if (rootProject.findProject(":lib")) {
4145
implementation project(":lib")
4246
} else if (rootProject.findProject(":godot:lib")) {
@@ -90,7 +94,7 @@ android {
9094
jvmTarget = versions.javaVersion
9195
}
9296

93-
assetPacks = [":assetPackInstallTime"]
97+
assetPacks = isInstantApp() ? [] : [":assetPackInstallTime"]
9498

9599
namespace = 'com.godot.game'
96100

platform/android/java/app/config.gradle

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ ext.versions = [
1515
// Also update 'platform/android/detect.py#get_ndk_version()' when this is updated.
1616
ndkVersion : '28.1.13356709',
1717
splashscreenVersion: '1.0.1',
18-
openxrVendorsVersion: '4.0.0-stable'
18+
openxrVendorsVersion: '4.0.0-stable',
19+
instantAppsVersion: '17.0.0'
1920

2021
]
2122

@@ -379,3 +380,8 @@ ext.getAddonsDirectory = { ->
379380
String addonsDirectory = project.hasProperty("addons_directory") ? project.property("addons_directory") : ""
380381
return addonsDirectory
381382
}
383+
384+
ext.isInstantApp = { ->
385+
String instantApp = project.hasProperty("play_instant_app") ? project.property("play_instant_app") : ""
386+
return Boolean.parseBoolean(instantApp)
387+
}

0 commit comments

Comments
 (0)