diff --git a/src/lime/tools/ConfigData.hx b/src/lime/tools/ConfigData.hx index 7520169d5..d86981420 100644 --- a/src/lime/tools/ConfigData.hx +++ b/src/lime/tools/ConfigData.hx @@ -9,6 +9,8 @@ import haxe.xml.Fast as Access; abstract ConfigData(Dynamic) to Dynamic from Dynamic { + private static inline var ARRAY:String = "___array"; + public function new() { this = {}; @@ -32,39 +34,12 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic public function exists(id:String):Bool { - var tree = id.split('.'); - - if (tree.length <= 1) - { - return Reflect.hasField(this, id); - } - - var current = this; - - for (leaf in tree) - { - if (Reflect.hasField(current, leaf)) - { - current = Reflect.field(current, leaf); - } - else - { - return false; - } - } - - return true; + return get(id) != null; } public function get(id:String):ConfigData { - var tree = id.split('.'); - - if (tree.length <= 1) - { - return Reflect.field(this, id); - } - + var tree = id.split("."); var current = this; for (leaf in tree) @@ -82,41 +57,29 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic public function getArray(id:String, defaultValue:Array = null):Array { - var tree = id.split('.'); + var tree = id.split("."); var array:Array = null; - if (tree.length <= 1) - { - array = Reflect.field(this, id + "___array"); + var current = this; + var field = tree.pop(); - if (array == null && Reflect.hasField(this, id)) + for (leaf in tree) + { + current = Reflect.field(current, leaf); + + if (current == null) { - array = [Reflect.field(this, id)]; + break; } } - else + + if (current != null) { - var current = this; - var field = tree.pop(); + array = Reflect.field(current, field + ARRAY); - for (leaf in tree) + if (array == null && Reflect.hasField(current, field)) { - current = Reflect.field(current, leaf); - - if (current == null) - { - break; - } - } - - if (current != null) - { - array = Reflect.field(current, field + "___array"); - - if (array == null && Reflect.hasField(current, field)) - { - array = [Reflect.field(current, field)]; - } + array = [Reflect.field(current, field)]; } } @@ -207,6 +170,32 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic return defaultValue; } + public function getKeyValueArray(id:String, defaultValues:Dynamic = null):Array<{ key:Dynamic, value:Dynamic }> + { + var values = {}; + if (defaultValues != null) + { + ObjectTools.copyFields(defaultValues, values); + } + + var data = get(id); + for (key in Reflect.fields(data)) + { + if (!StringTools.endsWith (key, ARRAY)) + { + Reflect.setField(values, key, Reflect.field(data, key)); + } + } + + var pairs = []; + for (key in Reflect.fields(values)) + { + pairs.push({ key: key, value: Reflect.field(values, key) }); + } + + return pairs; + } + private function log(v:Dynamic):Void { if (Log.verbose) @@ -227,7 +216,7 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic { for (field in Reflect.fields(source)) { - if (StringTools.endsWith(field, "___array")) + if (StringTools.endsWith(field, ARRAY)) { continue; } @@ -257,17 +246,17 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic if (doCopy && Reflect.field(source, field) != Reflect.field(destination, field) && typeSource != "TObject") { - if (!Reflect.hasField(destination, field + "___array")) + if (!Reflect.hasField(destination, field + ARRAY)) { - Reflect.setField(destination, field + "___array", [ObjectTools.deepCopy(Reflect.field(destination, field))]); + Reflect.setField(destination, field + ARRAY, [ObjectTools.deepCopy(Reflect.field(destination, field))]); } - var array:Array = Reflect.field(destination, field + "___array"); + var array:Array = Reflect.field(destination, field + ARRAY); - if (Reflect.hasField(source, field + "___array")) + if (Reflect.hasField(source, field + ARRAY)) { - array = array.concat(Reflect.field(source, field + "___array")); - Reflect.setField(destination, field + "___array", array); + array = array.concat(Reflect.field(source, field + ARRAY)); + Reflect.setField(destination, field + ARRAY, array); } else { @@ -289,9 +278,9 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic { Reflect.setField(destination, field, Reflect.field(source, field)); - if (Reflect.hasField(source, field + "___array")) + if (Reflect.hasField(source, field + ARRAY)) { - Reflect.setField(destination, field + "___array", Reflect.field(source, field + "___array")); + Reflect.setField(destination, field + ARRAY, Reflect.field(source, field + ARRAY)); } } } @@ -305,7 +294,7 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic if (StringTools.startsWith(elem.name, "config:")) { - var items = elem.name.split(':'); + var items = elem.name.split(":"); bucketType = items[1]; } @@ -353,12 +342,13 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic if (Reflect.hasField(bucket, child.name)) { - if (!Reflect.hasField(bucket, child.name + "___array")) + var array:Array = Reflect.field(bucket, child.name + ARRAY); + if (array == null) { - Reflect.setField(bucket, child.name + "___array", [ObjectTools.deepCopy(Reflect.field(bucket, child.name))]); + array = [ObjectTools.deepCopy(Reflect.field(bucket, child.name))]; + Reflect.setField(bucket, child.name + ARRAY, array); } - var array:Array = Reflect.field(bucket, child.name + "___array"); var arrayBucket = {}; array.push(arrayBucket); @@ -410,27 +400,9 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic } } - public function push(id:String, value:Dynamic):Void + public function push(id:String, value:Dynamic, ?unique:Bool = false):Void { - var tree = id.split('.'); - - if (tree.length <= 1) - { - if (Reflect.hasField(this, id)) - { - if (!Reflect.hasField(this, id + "___array")) - { - Reflect.setField(this, id + "___array", Reflect.hasField(this, id) ? [ObjectTools.deepCopy(Reflect.field(this, id))] : []); - } - - var array:Array = Reflect.field(this, id + "___array"); - array.push(value); - } - - Reflect.setField(this, id, value); - return; - } - + var tree = id.split("."); var current = this; var field = tree.pop(); @@ -454,13 +426,18 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic if (Reflect.hasField(current, field)) { - if (!Reflect.hasField(current, field + "___array")) + var array:Array = Reflect.field(current, field + ARRAY); + + if (array == null) { - Reflect.setField(current, field + "___array", Reflect.hasField(current, field) ? [ObjectTools.deepCopy(Reflect.field(current, field))] : []); + array = [ObjectTools.deepCopy(Reflect.field(current, field))]; + Reflect.setField(current, field + ARRAY, array); } - var array:Array = Reflect.field(current, field + "___array"); - array.push(value); + if (!unique || array.indexOf(value) == -1) + { + array.push(value); + } } Reflect.setField(current, field, value); @@ -468,14 +445,7 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic public function set(id:String, value:Dynamic):Void { - var tree = id.split('.'); - - if (tree.length <= 1) - { - Reflect.setField(this, id, value); - return; - } - + var tree = id.split("."); var current = this; var field = tree.pop(); @@ -525,12 +495,14 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic { if (typeSource != "TObject") { - if (!Reflect.hasField(bucket, node + "___array")) + var array:Array = Reflect.field(bucket, node + ARRAY); + if (array == null) { - Reflect.setField(bucket, node + "___array", [ObjectTools.deepCopy(Reflect.field(bucket, node))]); + array = [ObjectTools.deepCopy(Reflect.field(bucket, node))]; + Reflect.setField(bucket, node + ARRAY, array); } - cast(Reflect.field(bucket, node + "___array"), Array).push(value); + array.push(value); } Reflect.setField(bucket, node, value); diff --git a/src/lime/tools/ProjectXMLParser.hx b/src/lime/tools/ProjectXMLParser.hx index f573149a4..e5492e478 100644 --- a/src/lime/tools/ProjectXMLParser.hx +++ b/src/lime/tools/ProjectXMLParser.hx @@ -1632,21 +1632,8 @@ class ProjectXMLParser extends HXProject case "install-location": config.set("android.install-location", value); - case "extension": - var extensions = config.getArrayString("android.extension"); - - if (extensions == null || extensions.indexOf(value) == -1) - { - config.push("android.extension", value); - } - - case "permission": - var permissions = config.getArrayString("android.permission"); - - if (permissions == null || permissions.indexOf(value) == -1) - { - config.push("android.permission", value); - } + case "extension", "permission": + config.push("android." + name, value, true); case "gradle-version": config.set("android.gradle-version", value); diff --git a/templates/android/template/app/src/main/AndroidManifest.xml b/templates/android/template/app/src/main/AndroidManifest.xml index af4261bf9..501db19f7 100644 --- a/templates/android/template/app/src/main/AndroidManifest.xml +++ b/templates/android/template/app/src/main/AndroidManifest.xml @@ -4,20 +4,18 @@ - ::if (ANDROID_PERMISSIONS != null)::::foreach ANDROID_PERMISSIONS:: - ::end::::end:: + ::foreach ANDROID_PERMISSIONS:: + ::end:: - =30):: android:allowNativeHeapPointerTagging="false" ::end::> + ::if (WIN_ORIENTATION=="portrait"):: - + + ::elseif (WIN_ORIENTATION=="landscape"):: + ::end:: - ::if (WIN_ORIENTATION=="landscape"):: - - ::end:: - - + diff --git a/tools/platforms/AndroidPlatform.hx b/tools/platforms/AndroidPlatform.hx index d0ea3cb9d..1e864f778 100644 --- a/tools/platforms/AndroidPlatform.hx +++ b/tools/platforms/AndroidPlatform.hx @@ -469,7 +469,21 @@ class AndroidPlatform extends PlatformTarget context.ANDROID_USE_ANDROIDX = project.config.getString("android.useAndroidX", "true"); context.ANDROID_ENABLE_JETIFIER = project.config.getString("android.enableJetifier", "false"); - context.ANDROID_LIBRARY_PROJECTS = []; + context.ANDROID_APPLICATION = project.config.getKeyValueArray("android.application", { + "android:label": project.meta.title, + "android:allowBackup": "true", + "android:theme": "@android:style/Theme.NoTitleBar" + (project.window.fullscreen ? ".Fullscreen" : null), + "android:hardwareAccelerated": "true", + "android:allowNativeHeapPointerTagging": context.ANDROID_TARGET_SDK_VERSION >= 30 ? "false" : null + }); + context.ANDROID_ACTIVITY = project.config.getKeyValueArray("android.activity", { + "android:name": "MainActivity", + "android:exported": "true", + "android:launchMode": "singleTask", + "android:label": project.meta.title, + "android:configChanges": project.config.getArrayString("android.configChanges", ["keyboardHidden", "orientation", "screenSize", "screenLayout", "uiMode"]).join("|"), + "android:screenOrientation": project.window.orientation == PORTRAIT ? "sensorPortrait" : (project.window.orientation == LANDSCAPE ? "sensorLandscape" : null) + }); if (!project.environment.exists("ANDROID_SDK") || !project.environment.exists("ANDROID_NDK_ROOT")) { @@ -505,6 +519,7 @@ class AndroidPlatform extends PlatformTarget "KEY_STORE_ALIAS_PASSWORD")) context.KEY_STORE_ALIAS_PASSWORD = StringTools.replace(context.KEY_STORE_ALIAS_PASSWORD, "\\", "\\\\"); var index = 1; + context.ANDROID_LIBRARY_PROJECTS = []; for (dependency in project.dependencies) { @@ -528,24 +543,38 @@ class AndroidPlatform extends PlatformTarget } } - var iconTypes = ["ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"]; - var iconSizes = [36, 48, 72, 96, 144, 192]; - var icons = project.icons; - - if (icons.length == 0) + for (attribute in context.ANDROID_APPLICATION) { - icons = [new Icon(System.findTemplate(project.templatePaths, "default/icon.svg"))]; - } - - for (i in 0...iconTypes.length) - { - if (IconHelper.createIcon(icons, iconSizes[i], iconSizes[i], sourceSet + "/res/drawable-" + iconTypes[i] + "/icon.png")) + if (attribute.key == "android:icon") { context.HAS_ICON = true; + break; } } - IconHelper.createIcon(icons, 732, 412, sourceSet + "/res/drawable-xhdpi/ouya_icon.png"); + if (context.HAS_ICON == null) + { + var iconTypes = ["ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"]; + var iconSizes = [36, 48, 72, 96, 144, 192]; + var icons = project.icons; + + if (icons.length == 0) + { + icons = [new Icon(System.findTemplate(project.templatePaths, "default/icon.svg"))]; + } + for (i in 0...iconTypes.length) + { + // create multiple icons, only set "android:icon" once + if (IconHelper.createIcon(icons, iconSizes[i], iconSizes[i], sourceSet + "/res/drawable-" + iconTypes[i] + "/icon.png") + && !context.HAS_ICON) + { + context.HAS_ICON = true; + context.ANDROID_APPLICATION.push({ key: "android:icon", value: "@drawable/icon" }); + } + } + + IconHelper.createIcon(icons, 732, 412, sourceSet + "/res/drawable-xhdpi/ouya_icon.png"); + } var packageDirectory = project.meta.packageName; packageDirectory = sourceSet + "/java/" + packageDirectory.split(".").join("/");