Add icon and meaningful versioning to Android APK

Also plumbs through the "branding", giving a different package name and
display name to (for example) preview builds.

Change-Id: I2bd40dbc560de55c2ef9b16efc5dd4a28a769c36
This commit is contained in:
hikari_no_yume
2025-06-29 18:34:30 +02:00
parent 592057f608
commit d671600d78
12 changed files with 57 additions and 29 deletions

View File

@@ -63,6 +63,7 @@ Usability:
- App icons in the app picker are now sorted by the display name of the app, case-insensitively. (@hikari-no-yume)
- The accelerometer (tilt controls) can now be simulated using a mouse, instead of a game controller or real accelerometer. Simply hold down the right mouse button and move the mouse cursor. (@alborrajo)
- The new `--disable-analog-stick-tilt-controls` option can be used to disable the use of the game controller's analog sticks for accelerometer simulation. This is useful on devices with both an integrated game controller and an integrated accelerometer, as touchHLE by default will only use the real accelerometer if no game controller is detected. (@hikari-no-yume)
- Android builds and releases of touchHLE now have an icon and meaningful version metadata. They also now use a different package name for preview builds versus releases, which means you can install them side-by-side. (@hikari-no-yume)
- macOS builds and releases of touchHLE now come as an application bundle (`.app` directory) rather than as a bare “Unix executable” file. This should fix problems some users encountered with running touchHLE outside of a terminal, and allows putting touchHLE in the Applications folder like a normal graphical app. To support this, user data (apps, options, etc) is now stored in “Application Support” rather than the current directory, and the bundled files (fonts, dylibs, etc) are now part of the app bundle. If you prefer the old layout, you can still get it if you move all the files out of the bundle. (@hikari-no-yume)
- The new `--force-composition=` option has been added, which is a workaround that may solve rendering issues in some games, at the cost of performance. For some games it is applied by the default options. (@ciciplusplus)
- touchHLE now writes log messages to a file on all platforms, not just on Android. The file has been renamed from `log.txt` to `touchHLE_log.txt`. (@hikari-no-yume)

View File

@@ -12,11 +12,41 @@ apply plugin: 'com.android.application'
apply plugin: "com.github.willir.rust.cargo-ndk-android"
apply plugin: 'org.jetbrains.kotlin.android'
static def runTouchHLEVersionTool(boolean wantBranding) {
return ('cargo run --package touchHLE_version' + (wantBranding ? ' -- --branding' : '')).execute().text.trim()
}
static def getTouchHLEBranding() {
return runTouchHLEVersionTool(/* wantBranding: */ true)
}
static def getTouchHLEVersionName() {
return runTouchHLEVersionTool(/* wantBranding: */ false)
}
static def join(String prefix, String separator, String branding) {
if (branding.isEmpty()) {
return prefix
} else {
return prefix + separator + branding
}
}
android {
ndkVersion "25.2.9519653"
compileSdkVersion 31
defaultConfig {
applicationId "org.touchhle.android"
def branding = getTouchHLEBranding()
applicationId 'org.touchhle.android'
applicationIdSuffix(branding.isEmpty() ? null : branding.toLowerCase())
resValue 'string', 'app_name', join('touchHLE', ' ', branding)
buildConfigField 'String', 'APP_NAME', ('"' + join('touchHLE', ' ', branding) + '"')
manifestPlaceholders = [
icon: join('@drawable/icon', '_', branding.toLowerCase())
]
buildConfigField 'int', 'APP_ICON', join('R.drawable.icon', '_', branding.toLowerCase())
versionName join(getTouchHLEVersionName(), ' ', branding)
minSdkVersion 21 // first version with AArch64
targetSdkVersion 31
externalNativeBuild {

View File

@@ -11,8 +11,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="auto"
android:versionCode="1"
android:versionName="android">
android:versionCode="1">
<!-- Touchscreen support -->
<uses-feature
@@ -61,6 +60,7 @@
android:name="org.touchhle.android.touchHLEApplication"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="${icon}"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
@@ -95,9 +95,10 @@
<provider
android:name="org.touchhle.android.DocumentsProvider"
android:authorities="org.touchhle.android.provider"
android:authorities="${applicationId}.provider"
android:exported="true"
android:grantUriPermissions="true"
android:icon="${icon}"
android:permission="android.permission.MANAGE_DOCUMENTS">
<intent-filter>
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />

View File

@@ -32,7 +32,7 @@ class DocumentsProvider : DocumentsProvider() {
//private val baseDirectory = Environment.getExternalStorageDirectory()
// private val baseDirectory = touchHLEApplication.getContext().getExternalFilesDir(null)!!
//private val applicationName = SkylineApplication.instance.applicationInfo.loadLabel(SkylineApplication.instance.packageManager).toString()
private val applicationName = "touchHLE"
private val applicationName = BuildConfig.APP_NAME
companion object {
private val DEFAULT_ROOT_PROJECTION : Array<String> = arrayOf(
@@ -55,9 +55,6 @@ class DocumentsProvider : DocumentsProvider() {
DocumentsContract.Document.COLUMN_SIZE
)
//const val AUTHORITY : String = BuildConfig.APPLICATION_ID + ".provider"
const val AUTHORITY : String = "org.touchhle.android.provider"
const val ROOT_ID : String = "root"
}
@@ -96,7 +93,7 @@ class DocumentsProvider : DocumentsProvider() {
add(DocumentsContract.Root.COLUMN_DOCUMENT_ID, getDocumentId(getBaseDirectory()))
add(DocumentsContract.Root.COLUMN_MIME_TYPES, "*/*")
add(DocumentsContract.Root.COLUMN_AVAILABLE_BYTES, getBaseDirectory().freeSpace)
//add(DocumentsContract.Root.COLUMN_ICON, R.drawable.logo_skyline)
add(DocumentsContract.Root.COLUMN_ICON, BuildConfig.APP_ICON)
}
return cursor

View File

@@ -0,0 +1 @@
../../../../../../res/icon.png

View File

@@ -0,0 +1 @@
../../../../../../res/icon_preview.png

View File

@@ -0,0 +1 @@
../../../../../../res/icon_unofficial.png

View File

@@ -1,9 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
- Parts of this file are derived from SDL 2's Android project template, which
- has a different license. Please see vendor/SDL/LICENSE.txt for details. -->
<resources>
<string name="app_name">touchHLE</string>
</resources>

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 126 B

After

Width:  |  Height:  |  Size: 126 B

View File

@@ -270,10 +270,10 @@ fn show_app_picker_gui(
"" => include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/res/icon.png")),
"UNOFFICIAL" => include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/res/icon-unofficial.png"
"/res/icon_unofficial.png"
)),
"PREVIEW" => {
include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/res/icon-preview.png"))
include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/res/icon_preview.png"))
}
_ => panic!(),
};

View File

@@ -152,8 +152,13 @@ pub fn user_data_base_path() -> Cow<'static, Path> {
/// that [user_data_base_path] represents.
pub fn url_for_opening_user_data_dir() -> Result<String, String> {
if std::env::consts::OS == "android" {
// See DocumentsProvider.kt and AndroidManifest.xml
Ok("content://org.touchhle.android.provider/root/root".to_string())
// See DocumentsProvider.kt, app/build.gradle and AndroidManifest.xml
let brand = crate::branding();
Ok(format!(
"content://org.touchhle.android{}{}.provider/root/root",
if brand.is_empty() { "" } else { "." },
brand.to_lowercase()
))
} else {
let path = user_data_base_path()
.join(".")