From ca995093b6078a5d87f233602cfcd1eb7b0f664e Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sun, 12 Jan 2025 16:50:16 -0600 Subject: [PATCH 1/6] Add .aab bundling for Android. --- .../Platform/Android/AndroidPlatformTools.cpp | 55 ++++++++++++++----- Source/Editor/Windows/GameCookerWindow.cs | 38 +++++++++++++ 2 files changed, 79 insertions(+), 14 deletions(-) diff --git a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp index eb5469b47..b81166346 100644 --- a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp +++ b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp @@ -364,27 +364,54 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data) } #endif const bool distributionPackage = buildSettings->ForDistribution || data.Configuration == BuildConfiguration::Release; + if (data.CustomDefines.Contains(String(TEXT("BuildAAB")))) { - CreateProcessSettings procSettings; - procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug")); - procSettings.WorkingDirectory = data.OriginalOutputPath; - const int32 result = Platform::CreateProcess(procSettings); - if (result != 0) + // .aab { - data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); + CreateProcessSettings procSettings; + procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT(":app:bundle") : TEXT(":app:bundleDebug")); + procSettings.WorkingDirectory = data.OriginalOutputPath; + const int32 result = Platform::CreateProcess(procSettings); + if (result != 0) + { + data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); + return true; + } + } + // Copy result package + const String aab = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release.aab") : TEXT("app/build/outputs/bundle/debug/app-debug.aab")); + const String outputAab = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".aab"); + if (FileSystem::CopyFile(outputAab, aab)) + { + LOG(Error, "Failed to copy package from {0} to {1}", aab, outputAab); return true; } + LOG(Info, "Output Android application package: {0} (size: {1} MB)", outputAab, FileSystem::GetFileSize(outputAab) / 1024 / 1024); } - - // Copy result package - const String apk = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release-unsigned.apk") : TEXT("app/build/outputs/apk/debug/app-debug.apk")); - const String outputApk = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".apk"); - if (FileSystem::CopyFile(outputApk, apk)) + else { - LOG(Error, "Failed to copy package from {0} to {1}", apk, outputApk); - return true; + // .apk + { + CreateProcessSettings procSettings; + procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug")); + procSettings.WorkingDirectory = data.OriginalOutputPath; + const int32 result = Platform::CreateProcess(procSettings); + if (result != 0) + { + data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); + return true; + } + } + // Copy result package + const String apk = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release-unsigned.apk") : TEXT("app/build/outputs/apk/debug/app-debug.apk")); + const String outputApk = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".apk"); + if (FileSystem::CopyFile(outputApk, apk)) + { + LOG(Error, "Failed to copy package from {0} to {1}", apk, outputApk); + return true; + } + LOG(Info, "Output Android application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024); } - LOG(Info, "Output Android application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024); return false; } diff --git a/Source/Editor/Windows/GameCookerWindow.cs b/Source/Editor/Windows/GameCookerWindow.cs index cbe211eca..e4a3a47e8 100644 --- a/Source/Editor/Windows/GameCookerWindow.cs +++ b/Source/Editor/Windows/GameCookerWindow.cs @@ -233,6 +233,44 @@ namespace FlaxEditor.Windows class Android : Platform { protected override BuildPlatform BuildPlatform => BuildPlatform.AndroidARM64; + private bool _buildAAB = false; + + [EditorOrder(21), Tooltip("Build an android app bundle instead of an APK"), EditorDisplay(null, "Build .aab")] + public bool BuildAAB + { + get => _buildAAB; + set + { + _buildAAB = value; + if (value) + { + + var newDefines = new List(); + if (CustomDefines != null) + newDefines.AddRange(CustomDefines); + newDefines.Add("BuildAAB"); + CustomDefines = newDefines.ToArray(); + } + else + { + if (CustomDefines != null) + { + if (CustomDefines.Contains("BuildAAB")) + { + var newDefines = new List(); + foreach (var define in CustomDefines) + { + if (!define.Equals("BuildAAB", StringComparison.Ordinal)) + { + newDefines.Add(define); + } + } + CustomDefines = newDefines.ToArray(); + } + } + } + } + } } class Switch : Platform From 01d1dbba6cc5dbe3ee0df110e085c14f72b32604 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sun, 12 Jan 2025 16:57:19 -0600 Subject: [PATCH 2/6] Add aditional check for if custom define of BuildAAB already exists. --- Source/Editor/Windows/GameCookerWindow.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Windows/GameCookerWindow.cs b/Source/Editor/Windows/GameCookerWindow.cs index e4a3a47e8..89b56f05d 100644 --- a/Source/Editor/Windows/GameCookerWindow.cs +++ b/Source/Editor/Windows/GameCookerWindow.cs @@ -244,7 +244,8 @@ namespace FlaxEditor.Windows _buildAAB = value; if (value) { - + if (CustomDefines != null && CustomDefines.Contains("BuildAAB")) + return; var newDefines = new List(); if (CustomDefines != null) newDefines.AddRange(CustomDefines); From f274639e940ec68258ec6bd250c9c06c0bc6e6cd Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sun, 12 Jan 2025 17:17:59 -0600 Subject: [PATCH 3/6] Fix path bug. --- Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp index b81166346..69e1a591b 100644 --- a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp +++ b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp @@ -379,7 +379,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data) } } // Copy result package - const String aab = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release.aab") : TEXT("app/build/outputs/bundle/debug/app-debug.aab")); + const String aab = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/bundle/release/app-release.aab") : TEXT("app/build/outputs/bundle/debug/app-debug.aab")); const String outputAab = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".aab"); if (FileSystem::CopyFile(outputAab, aab)) { From 563f0b9ab45b34ec817c34e1358345a042cecc56 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 13 Jan 2025 07:24:50 -0600 Subject: [PATCH 4/6] Move Build .aab to Android platform settings and make it side-by-side --- .../Platform/Android/AndroidPlatformTools.cpp | 47 +++++++++---------- Source/Editor/Windows/GameCookerWindow.cs | 39 --------------- .../Android/AndroidPlatformSettings.h | 6 +++ 3 files changed, 28 insertions(+), 64 deletions(-) diff --git a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp index 69e1a591b..0e46be17b 100644 --- a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp +++ b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp @@ -364,7 +364,8 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data) } #endif const bool distributionPackage = buildSettings->ForDistribution || data.Configuration == BuildConfiguration::Release; - if (data.CustomDefines.Contains(String(TEXT("BuildAAB")))) + + if (platformSettings->BuildAAB) { // .aab { @@ -375,43 +376,39 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data) if (result != 0) { data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); - return true; } } // Copy result package const String aab = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/bundle/release/app-release.aab") : TEXT("app/build/outputs/bundle/debug/app-debug.aab")); const String outputAab = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".aab"); if (FileSystem::CopyFile(outputAab, aab)) - { LOG(Error, "Failed to copy package from {0} to {1}", aab, outputAab); - return true; - } - LOG(Info, "Output Android application package: {0} (size: {1} MB)", outputAab, FileSystem::GetFileSize(outputAab) / 1024 / 1024); + else + LOG(Info, "Output AAB Android application package: {0} (size: {1} MB)", outputAab, FileSystem::GetFileSize(outputAab) / 1024 / 1024); } - else + + // .apk { - // .apk + CreateProcessSettings procSettings; + procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug")); + procSettings.WorkingDirectory = data.OriginalOutputPath; + const int32 result = Platform::CreateProcess(procSettings); + if (result != 0) { - CreateProcessSettings procSettings; - procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug")); - procSettings.WorkingDirectory = data.OriginalOutputPath; - const int32 result = Platform::CreateProcess(procSettings); - if (result != 0) - { - data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); - return true; - } - } - // Copy result package - const String apk = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release-unsigned.apk") : TEXT("app/build/outputs/apk/debug/app-debug.apk")); - const String outputApk = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".apk"); - if (FileSystem::CopyFile(outputApk, apk)) - { - LOG(Error, "Failed to copy package from {0} to {1}", apk, outputApk); + data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); return true; } - LOG(Info, "Output Android application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024); } + // Copy result package + const String apk = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release-unsigned.apk") : TEXT("app/build/outputs/apk/debug/app-debug.apk")); + const String outputApk = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".apk"); + if (FileSystem::CopyFile(outputApk, apk)) + { + LOG(Error, "Failed to copy package from {0} to {1}", apk, outputApk); + return true; + } + LOG(Info, "Output Android APK application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024); + return false; } diff --git a/Source/Editor/Windows/GameCookerWindow.cs b/Source/Editor/Windows/GameCookerWindow.cs index 89b56f05d..cbe211eca 100644 --- a/Source/Editor/Windows/GameCookerWindow.cs +++ b/Source/Editor/Windows/GameCookerWindow.cs @@ -233,45 +233,6 @@ namespace FlaxEditor.Windows class Android : Platform { protected override BuildPlatform BuildPlatform => BuildPlatform.AndroidARM64; - private bool _buildAAB = false; - - [EditorOrder(21), Tooltip("Build an android app bundle instead of an APK"), EditorDisplay(null, "Build .aab")] - public bool BuildAAB - { - get => _buildAAB; - set - { - _buildAAB = value; - if (value) - { - if (CustomDefines != null && CustomDefines.Contains("BuildAAB")) - return; - var newDefines = new List(); - if (CustomDefines != null) - newDefines.AddRange(CustomDefines); - newDefines.Add("BuildAAB"); - CustomDefines = newDefines.ToArray(); - } - else - { - if (CustomDefines != null) - { - if (CustomDefines.Contains("BuildAAB")) - { - var newDefines = new List(); - foreach (var define in CustomDefines) - { - if (!define.Equals("BuildAAB", StringComparison.Ordinal)) - { - newDefines.Add(define); - } - } - CustomDefines = newDefines.ToArray(); - } - } - } - } - } } class Switch : Platform diff --git a/Source/Engine/Platform/Android/AndroidPlatformSettings.h b/Source/Engine/Platform/Android/AndroidPlatformSettings.h index c42270a05..e66f1bda1 100644 --- a/Source/Engine/Platform/Android/AndroidPlatformSettings.h +++ b/Source/Engine/Platform/Android/AndroidPlatformSettings.h @@ -108,6 +108,12 @@ API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API API_FIELD(Attributes="EditorOrder(500), EditorDisplay(\"General\")") TextureQuality TexturesQuality = TextureQuality::ASTC_Medium; + /// + /// Whether to build android app bundle (aab) side by side with apk. + /// + API_FIELD(Attributes="EditorOrder(500), EditorDisplay(\"General\", \"Build .aab\")") + bool BuildAAB; + /// /// Custom icon texture to use for the application (overrides the default one). /// From 55fa372197445bb761d5a68ed6be16d4aacf2303 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 13 Jan 2025 07:30:01 -0600 Subject: [PATCH 5/6] re-add returns to aab --- .../Platform/Android/AndroidPlatformTools.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp index 0e46be17b..9e4f18b2c 100644 --- a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp +++ b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp @@ -375,16 +375,19 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data) const int32 result = Platform::CreateProcess(procSettings); if (result != 0) { - data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); + data.Error(String::Format(TEXT("Failed to build Gradle project into .aab package (result code: {0}). See log for more info."), result)); + return true; } } // Copy result package const String aab = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/bundle/release/app-release.aab") : TEXT("app/build/outputs/bundle/debug/app-debug.aab")); const String outputAab = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".aab"); if (FileSystem::CopyFile(outputAab, aab)) - LOG(Error, "Failed to copy package from {0} to {1}", aab, outputAab); - else - LOG(Info, "Output AAB Android application package: {0} (size: {1} MB)", outputAab, FileSystem::GetFileSize(outputAab) / 1024 / 1024); + { + LOG(Error, "Failed to copy .aab package from {0} to {1}", aab, outputAab); + return true; + } + LOG(Info, "Output Android AAB application package: {0} (size: {1} MB)", outputAab, FileSystem::GetFileSize(outputAab) / 1024 / 1024); } // .apk @@ -395,7 +398,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data) const int32 result = Platform::CreateProcess(procSettings); if (result != 0) { - data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); + data.Error(String::Format(TEXT("Failed to build Gradle project into .apk package (result code: {0}). See log for more info."), result)); return true; } } @@ -404,7 +407,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data) const String outputApk = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".apk"); if (FileSystem::CopyFile(outputApk, apk)) { - LOG(Error, "Failed to copy package from {0} to {1}", apk, outputApk); + LOG(Error, "Failed to copy .apk package from {0} to {1}", apk, outputApk); return true; } LOG(Info, "Output Android APK application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024); From 4add5dcf494b8eac139c221ed776e995d84e6b8d Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 13 Jan 2025 17:31:34 +0100 Subject: [PATCH 6/6] Add missing default value and fix doc comment #3150 --- Source/Engine/Platform/Android/AndroidPlatformSettings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Platform/Android/AndroidPlatformSettings.h b/Source/Engine/Platform/Android/AndroidPlatformSettings.h index e66f1bda1..9a035f1ea 100644 --- a/Source/Engine/Platform/Android/AndroidPlatformSettings.h +++ b/Source/Engine/Platform/Android/AndroidPlatformSettings.h @@ -109,10 +109,10 @@ API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API TextureQuality TexturesQuality = TextureQuality::ASTC_Medium; /// - /// Whether to build android app bundle (aab) side by side with apk. + /// Whether to build Android App Bundle (aab) side by side with apk. /// API_FIELD(Attributes="EditorOrder(500), EditorDisplay(\"General\", \"Build .aab\")") - bool BuildAAB; + bool BuildAAB = true; /// /// Custom icon texture to use for the application (overrides the default one).