Rename the app SteamDeck → DroidDeck

App name, app ID and code package: DroidDeck, com.droiddeck.launcher
(sources moved to com/droiddeck/launcher, the 68 JNI functions renamed
with them). The new app ID installs beside SteamDeck rather than over it.

Everywhere the name was the app's own: the sidebar title, the session
report, share zips, the shell title, wake-lock and log tags, User-Agents,
the Compose theme, the Download folder and switch files (droiddeck-env,
-osc, -driver, -tu-debug, -no-pad, -pad-log, -no-hud, -wlr-renderer; the
old names are not read), and inside the runtime (droiddeck-desktop,
Firefox's droiddeck.js, the shortcuts tag, the rumble socket, debug and
cache paths). Build scripts, CI artifact (droiddeck-apk), CMake project,
README and the progress log follow.

Kept on purpose: Valve's Steam Deck (the -steamdeck flag,
steamdeck_publicbeta/stable, 'Steam Deck mode', the steamos.cloud
package URLs) and names inside the hosted desktop package (steamdeck.png,
steamdeck-steam, steamdeck-bigpicture). 'Desktop installed' now tests for
labwc instead of the launcher the app stages itself. A committed
__pycache__ .pyc is removed.
This commit is contained in:
The412Banner committed 2026-09-23 18:28:04 -04:00
1 parent bd51571530
commit ae6dcc9798
118 files changed
+498 -487

No files matched your search

+5 -5
View File
@@ -211,11 +211,11 @@ jobs:
rm -rf mango-pkgs
ls -l "$M"
# And the desktop's launcher and labwc defaults, staged over the desktop package's copies.
install -Dm644 tools/linuxfs/desktop/steamdeck-desktop "$D/usr/local/bin/steamdeck-desktop"
install -Dm644 tools/linuxfs/desktop/droiddeck-desktop "$D/usr/local/bin/droiddeck-desktop"
install -Dm644 tools/linuxfs/desktop/autostart "$D/etc/xdg/labwc/autostart"
install -Dm644 tools/linuxfs/desktop/rc.xml "$D/etc/xdg/labwc/rc.xml"
install -Dm644 tools/linuxfs/desktop/panel.conf "$D/etc/xdg/lxqt/panel.conf"
install -Dm644 tools/linuxfs/desktop/firefox-steamdeck.js "$D/usr/lib/firefox/defaults/pref/steamdeck.js"
install -Dm644 tools/linuxfs/desktop/firefox-droiddeck.js "$D/usr/lib/firefox/defaults/pref/droiddeck.js"
ls -lR "$D"
# The daemon's AAudio sink (tools/aaudio-sink), compiled here against upstream PulseAudio 13
@@ -388,7 +388,7 @@ jobs:
BUILD_OUTCOME: ${{ steps.build.outcome }}
run: |
set -uo pipefail
MARK="<!-- steamdeck-pr-build -->"
MARK="<!-- droiddeck-pr-build -->"
{
echo "$MARK"
echo "## Build of this pull request"
@@ -399,7 +399,7 @@ jobs:
success)
echo "### Build passed"
echo
echo "The apk is the \`steamdeck-apk\` artifact on [this run]($RUN_URL) (signed with the same test key as every build, so it installs over any other)."
echo "The apk is the \`droiddeck-apk\` artifact on [this run]($RUN_URL) (signed with the same test key as every build, so it installs over any other)."
;;
failure)
echo "### ERROR: Build failed"
@@ -438,7 +438,7 @@ jobs:
- uses: actions/upload-artifact@v4
with:
name: steamdeck-apk
name: droiddeck-apk
path: app/build/outputs/apk/release/*.apk
if-no-files-found: error
retention-days: 30
+4 -4
View File
@@ -1,20 +1,20 @@
# SteamDeck
# DroidDeck
Run Valve's native ARM64 Steam client on an Adreno Android device. Steam runs in a Linux runtime under proot, with gamescope and an in-app Vulkan compositor. Windows games use Valve's ARM64 Proton and FEX. A desktop with LXQt, Firefox, and emulators is also available.
## Requirements and install
Use Android 9 or newer on a supported Adreno device (730 or newer, or 8xx). Mali, Xclipse, PowerVR, and Adreno 710 are unsupported. No root is required. Allow about 3 GB for the runtime and 1.1 GB more for the desktop and emulators. Install the APK from [Releases](https://github.com/The412Banner/SteamDeck/releases), install the Linux runtime, then press **Play** and sign in. Steam downloads on first launch. Install **Desktop & apps** to use the desktop and emulators.
Use Android 9 or newer on a supported Adreno device (730 or newer, or 8xx). Mali, Xclipse, PowerVR, and Adreno 710 are unsupported. No root is required. Allow about 3 GB for the runtime and 1.1 GB more for the desktop and emulators. Install the APK from [Releases](https://github.com/The412Banner/DroidDeck/releases), install the Linux runtime, then press **Play** and sign in. Steam downloads on first launch. Install **Desktop & apps** to use the desktop and emulators.
On Android 12+, if Steam exits without a log, turn off **Restrict child processes** in Developer options.
## Build
Run `tools/build_local.sh` with Docker, Java 17, the Android SDK/NDK, and `zstd` installed. It builds the ARM64 audio sinks from PulseAudio 13.0 and packages them into the APK at `app/build/outputs/apk/release/app-release.apk`. Set `STEAMDECK_PA13_SOURCE_DIR` to an existing PulseAudio 13.0 source directory to skip downloading it. To install the APK on an attached device, run `tools/deploy_local.sh`.
Run `tools/build_local.sh` with Docker, Java 17, the Android SDK/NDK, and `zstd` installed. It builds the ARM64 audio sinks from PulseAudio 13.0 and packages them into the APK at `app/build/outputs/apk/release/app-release.apk`. Set `DROIDDECK_PA13_SOURCE_DIR` to an existing PulseAudio 13.0 source directory to skip downloading it. To install the APK on an attached device, run `tools/deploy_local.sh`.
## Limits
Compatibility and performance vary by device; hardware validation is limited. Desktop compositing uses software rendering. Firefox sandboxing is reduced under proot. See the session logs in `Download/SteamDeck/` when diagnosing problems.
Compatibility and performance vary by device; hardware validation is limited. Desktop compositing uses software rendering. Firefox sandboxing is reduced under proot. See the session logs in `Download/DroidDeck/` when diagnosing problems.
## Credits and licence
+2 -2
View File
@@ -5,14 +5,14 @@ apply plugin: 'kotlin-android'
apply plugin: 'org.jetbrains.kotlin.plugin.compose'
android {
namespace 'com.steamdeck.launcher'
namespace 'com.droiddeck.launcher'
compileSdk 34
// The NDK is pinned by property so CI can hand in whatever the runner already has rather than
// downloading a second copy; see gradle.properties.
ndkVersion project.findProperty('ndkVersion') ?: '27.3.13750724'
defaultConfig {
applicationId "com.steamdeck.launcher"
applicationId "com.droiddeck.launcher"
minSdkVersion 26
// 28 is not a leftover. An app on targetSdk 29+ runs in a domain that may not execute a
// file out of its own data directory, and this app's entire job is to exec a rootfs:
+1 -1
View File
@@ -1,7 +1,7 @@
# The app's native side: the Wayland compositor the session presents into, the adrenotools loader
# it opens Turnip with, and one small library for the fake-input ring's memory fence.
cmake_minimum_required(VERSION 3.22.1)
project(steamdeck C CXX)
project(droiddeck C CXX)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -Wno-unused-function -Wimplicit-function-declaration")
+1 -1
View File
@@ -304,7 +304,7 @@ send_vibration(int strong, int weak, uint16_t duration_ms, uint16_t slot) {
struct sockaddr_un addr = {};
addr.sun_family = AF_UNIX;
const char *name = "steamdeck-rumble";
const char *name = "droiddeck-rumble";
memcpy(addr.sun_path + 1, name, strlen(name));
socklen_t addrlen = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(name);
@@ -108,10 +108,10 @@ struct VkTable {
#include <android/log.h>
#include <string>
#define WLOG_TAG "SteamDeck_Renderer"
#define WLOG_TAG "DroidDeck_Renderer"
#define RLOG(...) if(verboseLog) __android_log_print(ANDROID_LOG_DEBUG,WLOG_TAG,__VA_ARGS__)
#define RLOG_E(...) __android_log_print(ANDROID_LOG_ERROR,WLOG_TAG,__VA_ARGS__)
#define SCANOUT_LOG(...) __android_log_print(ANDROID_LOG_DEBUG,"SteamDeck_Scanout",__VA_ARGS__)
#define SCANOUT_LOG(...) __android_log_print(ANDROID_LOG_DEBUG,"DroidDeck_Scanout",__VA_ARGS__)
#include <vulkan/vulkan_android.h>
#include <android/hardware_buffer.h>
+7 -7
View File
@@ -23,25 +23,25 @@ std::string toStdString(JNIEnv* env, jstring s) {
} // namespace
extern "C" JNIEXPORT jint JNICALL
Java_com_steamdeck_launcher_gpu_LsfgNative_nativeValidateDll(JNIEnv* env, jclass, jstring dllPath) {
Java_com_droiddeck_launcher_gpu_LsfgNative_nativeValidateDll(JNIEnv* env, jclass, jstring dllPath) {
return (jint)lsfg::validateDll(toStdString(env, dllPath));
}
extern "C" JNIEXPORT jint JNICALL
Java_com_steamdeck_launcher_gpu_LsfgNative_nativeDllVariant(JNIEnv* env, jclass, jstring dllPath,
Java_com_droiddeck_launcher_gpu_LsfgNative_nativeDllVariant(JNIEnv* env, jclass, jstring dllPath,
jboolean preferFp16) {
return (jint)lsfg::dllVariant(toStdString(env, dllPath), preferFp16 == JNI_TRUE);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_steamdeck_launcher_gpu_LsfgNative_nativeBuildCache(JNIEnv* env, jclass, jstring dllPath,
Java_com_droiddeck_launcher_gpu_LsfgNative_nativeBuildCache(JNIEnv* env, jclass, jstring dllPath,
jstring cachePath, jboolean preferFp16) {
return (jint)lsfg::buildCache(toStdString(env, dllPath), toStdString(env, cachePath),
preferFp16 == JNI_TRUE);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_steamdeck_launcher_gpu_LsfgNative_nativeCacheMatchesSource(JNIEnv* env, jclass,
Java_com_droiddeck_launcher_gpu_LsfgNative_nativeCacheMatchesSource(JNIEnv* env, jclass,
jstring cachePath,
jstring dllPath) {
bool matches = false;
@@ -51,7 +51,7 @@ Java_com_steamdeck_launcher_gpu_LsfgNative_nativeCacheMatchesSource(JNIEnv* env,
}
extern "C" JNIEXPORT jint JNICALL
Java_com_steamdeck_launcher_gpu_LsfgNative_nativeCacheVariant(JNIEnv* env, jclass, jstring cachePath) {
Java_com_droiddeck_launcher_gpu_LsfgNative_nativeCacheVariant(JNIEnv* env, jclass, jstring cachePath) {
lsfg::Variant variant = lsfg::Variant::None;
if (lsfg::cacheVariant(toStdString(env, cachePath), variant) != lsfg::DllStatus::Ok)
return (jint)lsfg::Variant::None;
@@ -59,11 +59,11 @@ Java_com_steamdeck_launcher_gpu_LsfgNative_nativeCacheVariant(JNIEnv* env, jclas
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_steamdeck_launcher_gpu_LsfgNative_nativeStatusName(JNIEnv* env, jclass, jint status) {
Java_com_droiddeck_launcher_gpu_LsfgNative_nativeStatusName(JNIEnv* env, jclass, jint status) {
return env->NewStringUTF(lsfg::statusName((lsfg::DllStatus)status));
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_steamdeck_launcher_gpu_LsfgNative_nativeVariantName(JNIEnv* env, jclass, jint variant) {
Java_com_droiddeck_launcher_gpu_LsfgNative_nativeVariantName(JNIEnv* env, jclass, jint variant) {
return env->NewStringUTF(lsfg::variantName((lsfg::Variant)variant));
}
+1 -1
View File
@@ -22,7 +22,7 @@
#include <cstdint>
#ifndef SCANOUT_LOG
#define SCANOUT_LOG(...) __android_log_print(ANDROID_LOG_DEBUG,"SteamDeck_Scanout",__VA_ARGS__)
#define SCANOUT_LOG(...) __android_log_print(ANDROID_LOG_DEBUG,"DroidDeck_Scanout",__VA_ARGS__)
#endif
class ScanoutContext {
+1 -1
View File
@@ -10,7 +10,7 @@
#include <stdatomic.h>
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_input_FakeInputWriter_nativeStoreFence(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_input_FakeInputWriter_nativeStoreFence(JNIEnv *env, jclass clazz) {
(void)env;
(void)clazz;
atomic_thread_fence(memory_order_release);
@@ -7,20 +7,20 @@
#include "framegen_bridge.h"
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetFrameGenEngine(JNIEnv *env, jclass clazz, jint kind) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetFrameGenEngine(JNIEnv *env, jclass clazz, jint kind) {
(void)env; (void)clazz;
vkp_framegen_set_engine((int)kind);
}
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetFrameGenArmed(JNIEnv *env, jclass clazz,
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetFrameGenArmed(JNIEnv *env, jclass clazz,
jboolean armed, jint multiplier) {
(void)env; (void)clazz;
vkp_framegen_set_armed(armed ? 1 : 0, (int)multiplier);
}
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetLsfgCachePath(JNIEnv *env, jclass clazz, jstring path) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetLsfgCachePath(JNIEnv *env, jclass clazz, jstring path) {
(void)clazz;
if (!path) { vkp_framegen_set_lsfg_cache_path(NULL); return; }
const char *c = (*env)->GetStringUTFChars(env, path, NULL);
@@ -29,34 +29,34 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetLsfgCachePath(JNI
}
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetFrameGenTuning(JNIEnv *env, jclass clazz,
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetFrameGenTuning(JNIEnv *env, jclass clazz,
jfloat flowScale, jfloat refreshHz) {
(void)env; (void)clazz;
vkp_framegen_set_tuning((float)flowScale, (float)refreshHz);
}
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetWinFgTuning(JNIEnv *env, jclass clazz,
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetWinFgTuning(JNIEnv *env, jclass clazz,
jint model, jint perfPreset) {
(void)env; (void)clazz;
vkp_framegen_set_winfg_tuning((int)model, (int)perfPreset);
}
JNIEXPORT jint JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeFrameGenProblem(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeFrameGenProblem(JNIEnv *env, jclass clazz) {
(void)env; (void)clazz;
return (jint)vkp_framegen_problem();
}
JNIEXPORT jstring JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeFrameGenCapsReason(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeFrameGenCapsReason(JNIEnv *env, jclass clazz) {
(void)clazz;
const char *r = vkp_framegen_caps_reason();
return (*env)->NewStringUTF(env, r ? r : "");
}
JNIEXPORT jfloatArray JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeFrameGenStats(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeFrameGenStats(JNIEnv *env, jclass clazz) {
(void)clazz;
float st[6] = {0.f, 0.f, 0.f, 0.f, -1.f, -1.f};
vkp_framegen_stats(st);
@@ -53,7 +53,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
g_jvm = vm;
JNIEnv *env;
if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6) == JNI_OK) {
jclass c = (*env)->FindClass(env, "com/steamdeck/launcher/wayland/WaylandCompositor");
jclass c = (*env)->FindClass(env, "com/droiddeck/launcher/wayland/WaylandCompositor");
if (c) {
g_compositor_cls = (*env)->NewGlobalRef(env, c);
g_on_first_frame = (*env)->GetStaticMethodID(env, g_compositor_cls,
@@ -222,14 +222,14 @@ static void start_thread(void) {
/* The compositor thread's tid, or 0 before it starts. The app opens a PerformanceHintManager session
* on it and reports each presented frame's interval, so the governor sees a frame that ran long. */
JNIEXPORT jint JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeCompositorTid(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeCompositorTid(JNIEnv *env, jclass clazz) {
(void)env; (void)clazz;
return (jint)g_comp_tid;
}
/* Headless start (no output window) - used for bring-up tests. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeStart(JNIEnv *env, jclass clazz,
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeStart(JNIEnv *env, jclass clazz,
jstring xdgRuntimeDir) {
set_runtime_dir(env, xdgRuntimeDir);
start_thread();
@@ -246,7 +246,7 @@ static char *dup_jstr(JNIEnv *env, jstring s) {
/* Start with a real output Surface + the container's Turnip driver (adrenotools).
* Frames committed by clients are composited to this Surface via Turnip. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeStartWithSurface(
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeStartWithSurface(
JNIEnv *env, jclass clazz, jobject surface, jstring xdgRuntimeDir,
jstring driverPath, jstring libraryName, jstring nativeLibDir) {
set_runtime_dir(env, xdgRuntimeDir);
@@ -266,34 +266,34 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeStartWithSurface(
/* Inject a pointer event from the Android SurfaceView touch listener (UI thread).
* action: 0=down 1=move 2=up; x/y in output space (0..1919, 0..1079). */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSendPointer(
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSendPointer(
JNIEnv *env, jclass clazz, jint action, jint x, jint y) {
banner_wayland_send_pointer(action, x, y);
}
/* Inject a key event. evdev = Linux input keycode (KEY_A=30…); state 1=down 0=up. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSendKey(
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSendKey(
JNIEnv *env, jclass clazz, jint evdev, jint state) {
banner_wayland_send_key(evdev, state);
}
/* App X-server input in scene (virtual desktop) coordinates; see banner_wayland_send_scene_input. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSendSceneInput(
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSendSceneInput(
JNIEnv *env, jclass clazz, jint type, jint a, jint b) {
banner_wayland_send_scene_input(type, a, b);
}
/* One screen refresh (Choreographer frame callback, UI thread): the compositor draws once. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeVsync(JNIEnv *env, jclass clazz, jlong frameTimeNanos) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeVsync(JNIEnv *env, jclass clazz, jlong frameTimeNanos) {
banner_wayland_vsync((int64_t)frameTimeNanos);
}
/* Shortcut launches: don't draw explorer's windows (desktop, taskbar), like X11's unviewable classes. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetHideShell(JNIEnv *env, jclass clazz, jboolean hide) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetHideShell(JNIEnv *env, jclass clazz, jboolean hide) {
g_hide_shell = hide ? 1 : 0;
}
@@ -302,7 +302,7 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetHideShell(JNIEnv
* thread, any time: before the compositor starts it is the launch default; afterwards the compositor
* thread flips the state, tells the bound games to rebuild their swapchains for it and redraws. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetZeroCopy(JNIEnv *env, jclass clazz, jboolean on) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetZeroCopy(JNIEnv *env, jclass clazz, jboolean on) {
int live = banner_get_display() != NULL;
if (!live) g_zero_copy = on ? 1 : 0; /* read by ahb_swapchain_init before the queue drains */
banner_host_zero_copy(on ? 1 : 0, live);
@@ -312,13 +312,13 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetZeroCopy(JNIEnv *
/* Milliseconds since the compositor last put a game frame on the layer without a copy; -1 = never
* this session. The drawer's status line ("switching..." until the frames arrive / stop). */
JNIEXPORT jint JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeZeroCopyLastFrameAgeMs(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeZeroCopyLastFrameAgeMs(JNIEnv *env, jclass clazz) {
return (jint)ahb_swapchain_last_frame_age_ms();
}
/* Zero-copy frames in the last completed 10 s stats window (on_stats_timer), for the drawer's live line. */
JNIEXPORT jint JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeZeroCopyFrames(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeZeroCopyFrames(JNIEnv *env, jclass clazz) {
return (jint)g_zero_copy_last;
}
@@ -326,7 +326,7 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeZeroCopyFrames(JNIEn
* the renderer's driver imports it (default on; BANNER_WAYLAND_UBWC=0 = off). Set before the compositor
* starts. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetUbwc(JNIEnv *env, jclass clazz, jboolean on) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetUbwc(JNIEnv *env, jclass clazz, jboolean on) {
g_ubwc = on ? 1 : 0;
__android_log_print(ANDROID_LOG_INFO, TAG, "compressed (UBWC) game buffers %s", on ? "on" : "off");
}
@@ -334,7 +334,7 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetUbwc(JNIEnv *env,
/* Debug: name no DRM device in the dma-buf feedback (BANNER_WAYLAND_NO_RENDER_NODE=1), the way a
* phone that exposes no /dev/dri node to apps does. Set before the compositor starts. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetNoRenderNode(JNIEnv *env, jclass clazz, jboolean on) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetNoRenderNode(JNIEnv *env, jclass clazz, jboolean on) {
g_no_render_node = on ? 1 : 0;
if (on) __android_log_print(ANDROID_LOG_INFO, TAG, "debug: advertising no DRM device (main device 0:0)");
}
@@ -344,27 +344,27 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetNoRenderNode(JNIE
* without this SurfaceFlinger never sees the game's cadence. 0 = clear the vote. Any thread, any
* time; the compositor applies it with its next layer transaction and logs the change. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetLayerFrameRate(JNIEnv *env, jclass clazz, jfloat hz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetLayerFrameRate(JNIEnv *env, jclass clazz, jfloat hz) {
(void)env; (void)clazz;
sc_layer_set_frame_rate((float)hz);
}
/* The panel's refresh rate (Hz) for the advertised wl_output mode. Set before the compositor starts. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetOutputRefreshRate(JNIEnv *env, jclass clazz, jfloat hz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetOutputRefreshRate(JNIEnv *env, jclass clazz, jfloat hz) {
g_output_refresh_mhz = hz > 1.0f ? (int)(hz * 1000.0f + 0.5f) : 0;
}
/* The container's screen size for the advertised wl_output mode. Set before the compositor starts. */
extern void vkp_reset_first_frame(void);
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeResetFirstFrame(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeResetFirstFrame(JNIEnv *env, jclass clazz) {
(void)env; (void)clazz;
vkp_reset_first_frame();
}
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetOutputSize(JNIEnv *env, jclass clazz, jint w, jint h) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetOutputSize(JNIEnv *env, jclass clazz, jint w, jint h) {
g_output_w = w > 0 ? w : 0;
g_output_h = h > 0 ? h : 0;
}
@@ -372,7 +372,7 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetOutputSize(JNIEnv
/* Fullscreen mode + screen alignment (Container.FULLSCREEN_* / ALIGN_* values): how the scene is
* fitted onto the output. Any thread, any time; the next frame uses it. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetScaleMode(JNIEnv *env, jclass clazz, jint mode, jint alignment) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetScaleMode(JNIEnv *env, jclass clazz, jint mode, jint alignment) {
vk_present_set_scale_mode(mode, alignment);
__android_log_print(ANDROID_LOG_INFO, TAG, "scale mode %d alignment %d", mode, alignment);
}
@@ -383,38 +383,38 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetScaleMode(JNIEnv
/* Scaling mode: 0=None 1=Linear 2=Nearest 3=SGSR 4=FSR 5=FSR Fit 6=Sharpen 7=NIS 8=SGSR HQ. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetUpscaler(JNIEnv *env, jclass clazz, jint mode) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetUpscaler(JNIEnv *env, jclass clazz, jint mode) {
vkp_effects_set_scaling(mode);
}
/* The upscaler's sharpness slider 0..100 (RCAS lobe / SGSR edge / NIS sharpness). */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetUpscaleSharpness(JNIEnv *env, jclass clazz, jint sharpness) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetUpscaleSharpness(JNIEnv *env, jclass clazz, jint sharpness) {
vkp_effects_set_upscale_sharpness(sharpness);
}
/* AMD CAS sharpen toggle + level 0..100 (0 = pass off). */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetCas(JNIEnv *env, jclass clazz, jboolean enabled, jint sharpness) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetCas(JNIEnv *env, jclass clazz, jboolean enabled, jint sharpness) {
vkp_effects_set_cas(enabled ? 1 : 0, sharpness);
}
/* Fake-HDR toggle. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetHdr(JNIEnv *env, jclass clazz, jboolean enabled) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetHdr(JNIEnv *env, jclass clazz, jboolean enabled) {
vkp_effects_set_hdr(enabled ? 1 : 0);
}
/* Terminal debanding toggle + strength 0..200 (100 = 1 LSB). */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetDeband(JNIEnv *env, jclass clazz, jboolean enabled, jint strength) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetDeband(JNIEnv *env, jclass clazz, jboolean enabled, jint strength) {
vkp_effects_set_deband(enabled ? 1 : 0, strength);
}
/* Colour grade (slider units: brightness/contrast -100..100, gamma 0.5..3, saturation 0..200 %) and the
* FXAA / Toon / CRT / NTSC toggles - VulkanRenderer.setScreenEffects. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetScreenEffects(JNIEnv *env, jclass clazz, jfloat brightness,
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetScreenEffects(JNIEnv *env, jclass clazz, jfloat brightness,
jfloat contrast, jfloat gamma, jfloat saturation, jboolean fxaa, jboolean toon, jboolean crt, jboolean ntsc) {
vkp_effects_set_screen(brightness, contrast, gamma, saturation, fxaa ? 1 : 0, toon ? 1 : 0, crt ? 1 : 0, ntsc ? 1 : 0);
}
@@ -423,7 +423,7 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetScreenEffects(JNI
* framework (the panel's HDR capability) rather than in the compositor. banner_log() mirrors to
* logcat and appends to the session file when one is open, so this is safe at any point. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeLogDisplay(JNIEnv *env, jclass clazz, jstring message) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeLogDisplay(JNIEnv *env, jclass clazz, jstring message) {
char *s = dup_jstr(env, message);
if (s) banner_log("display", "%s", s);
free(s);
@@ -432,7 +432,7 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeLogDisplay(JNIEnv *e
/* The same under the "perf" area: facts the app knows about the session's performance setup (the CPU
* cores the game is pinned to, say). Same safety as nativeLogDisplay. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeLogPerf(JNIEnv *env, jclass clazz, jstring message) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeLogPerf(JNIEnv *env, jclass clazz, jstring message) {
char *s = dup_jstr(env, message);
if (s) banner_log("perf", "%s", s);
free(s);
@@ -442,7 +442,7 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeLogPerf(JNIEnv *env,
/* The opt-in: mode 0 off, 1 BANNER_WAYLAND_HDR=1, 2 =force (testing). Before the compositor starts. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetHdrRequest(JNIEnv *env, jclass clazz, jint mode,
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetHdrRequest(JNIEnv *env, jclass clazz, jint mode,
jstring source, jboolean dxvkHdr, jboolean zeroCopyForced) {
char *s = dup_jstr(env, source);
banner_color_set_request((int)mode, s, dxvkHdr ? 1 : 0, zeroCopyForced ? 1 : 0);
@@ -451,7 +451,7 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetHdrRequest(JNIEnv
/* The game's display as android.view.Display reports it (before the start; again on every change). */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetHdrDisplay(JNIEnv *env, jclass clazz, jint id, jstring name,
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetHdrDisplay(JNIEnv *env, jclass clazz, jint id, jstring name,
jstring formats, jboolean hdr10, jfloat maxLum, jfloat maxAvg, jfloat minLum, jboolean ratioAvailable,
jfloat ratio, jint api) {
char *n = dup_jstr(env, name), *f = dup_jstr(env, formats);
@@ -462,38 +462,38 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetHdrDisplay(JNIEnv
/* One Display.getHdrSdrRatio() reading (listener = from the display's ratio listener). Any thread. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeHdrSdrRatioSample(JNIEnv *env, jclass clazz, jfloat ratio,
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeHdrSdrRatioSample(JNIEnv *env, jclass clazz, jfloat ratio,
jboolean listener) {
banner_color_ratio_sample((float)ratio, listener ? 1 : 0);
}
/* ms since an HDR frame last reached a display layer, -1 = never this session. Any thread. */
JNIEXPORT jint JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeHdrLastFrameAgeMs(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeHdrLastFrameAgeMs(JNIEnv *env, jclass clazz) {
return (jint)banner_color_last_frame_age_ms();
}
/* -1 = not decided yet, 0 = closed, 1 = open. Any thread. */
JNIEXPORT jint JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeHdrGateState(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeHdrGateState(JNIEnv *env, jclass clazz) {
return (jint)banner_color_gate_state();
}
/* The session is ending: the "HDR on screen: ..." summary line. Any thread, once. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeHdrSessionEnd(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeHdrSessionEnd(JNIEnv *env, jclass clazz) {
banner_color_session_end();
}
/* HDR frames really on screen right now (the HUD badge). Any thread. */
JNIEXPORT jboolean JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeHdrOnScreen(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeHdrOnScreen(JNIEnv *env, jclass clazz) {
return banner_color_hdr_on_screen() ? JNI_TRUE : JNI_FALSE;
}
/* One "color" line in the session log from Java. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeLogColor(JNIEnv *env, jclass clazz, jstring message) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeLogColor(JNIEnv *env, jclass clazz, jstring message) {
char *s = dup_jstr(env, message);
if (s) banner_log("color", "%s", s);
free(s);
@@ -502,7 +502,7 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeLogColor(JNIEnv *env
/* One line in the session log under an area Java names ("gpu", "nvapi"): launch facts the app decides.
* The area is the log's 9-character column; an empty one reads "app". */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeLog(JNIEnv *env, jclass clazz, jstring area, jstring message) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeLog(JNIEnv *env, jclass clazz, jstring area, jstring message) {
char *a = dup_jstr(env, area), *s = dup_jstr(env, message);
if (s) banner_log(a && a[0] ? a : "app", "%s", s);
free(a);
@@ -511,26 +511,26 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeLog(JNIEnv *env, jcl
/* SDR content's level inside an HDR picture, in nits (default 203). */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetHdrSdrWhite(JNIEnv *env, jclass clazz, jfloat nits) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetHdrSdrWhite(JNIEnv *env, jclass clazz, jfloat nits) {
banner_color_set_sdr_white((float)nits);
}
/* The drawer's live HDR output switch: on = HDR frames as HDR, off = the same frames tone-mapped to SDR.
* Applied on the compositor thread (logged there, with a redraw). */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetHdrOutput(JNIEnv *env, jclass clazz, jboolean on) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetHdrOutput(JNIEnv *env, jclass clazz, jboolean on) {
if (banner_get_display()) banner_host_hdr_output(on ? 1 : 0);
else banner_color_set_output(on ? 1 : 0); /* no compositor thread yet: nothing is drawing either */
}
JNIEXPORT jboolean JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeHdrOutput(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeHdrOutput(JNIEnv *env, jclass clazz) {
return banner_color_output() ? JNI_TRUE : JNI_FALSE;
}
/* Device evidence for the HDR lines: thermal status + headroom, brightness + mode. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeHdrEnvSample(JNIEnv *env, jclass clazz, jint thermal,
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeHdrEnvSample(JNIEnv *env, jclass clazz, jint thermal,
jfloat headroom, jint brightness, jint mode) {
banner_color_env_sample((int)thermal, (float)headroom != (float)headroom ? -1.0f : (float)headroom,
(int)brightness, (int)mode);
@@ -538,18 +538,18 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeHdrEnvSample(JNIEnv
/* Display.getHighestHdrSdrRatio() (Android 16+), <= 0 = not reported. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetHdrHighestRatio(JNIEnv *env, jclass clazz, jfloat ratio) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetHdrHighestRatio(JNIEnv *env, jclass clazz, jfloat ratio) {
banner_color_set_highest_ratio((float)ratio == (float)ratio ? (float)ratio : -1.0f);
}
/* The HDR headroom the screen surface should ask for (HDR10 swapchain frames in the last 1.5 s), 0 = none. */
JNIEXPORT jfloat JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeHdrScreenHeadroom(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeHdrScreenHeadroom(JNIEnv *env, jclass clazz) {
return (jfloat)banner_color_screen_headroom(NULL, 0);
}
JNIEXPORT jstring JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeHdrScreenHeadroomWhy(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeHdrScreenHeadroomWhy(JNIEnv *env, jclass clazz) {
char why[200];
banner_color_screen_headroom(why, sizeof(why));
return (*env)->NewStringUTF(env, why);
@@ -557,25 +557,25 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeHdrScreenHeadroomWhy
/* The app's screen-surface request, for the no-headroom lines: > 0 asked, 0 cleared, -1 not possible. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeHdrNoteHeadroomRequest(JNIEnv *env, jclass clazz, jfloat ratio) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeHdrNoteHeadroomRequest(JNIEnv *env, jclass clazz, jfloat ratio) {
banner_color_note_headroom_request((float)ratio);
}
/* 0 none, 1 HDR frames on screen with headroom, 2 HDR frames on screen without headroom for 5 s+. */
JNIEXPORT jint JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeHdrState(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeHdrState(JNIEnv *env, jclass clazz) {
return (jint)banner_color_hdr_state();
}
/* An HDR game's frames were shown tone-mapped to SDR in the last 1.5 s (the drawer's status line). */
JNIEXPORT jboolean JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeHdrToneMappedOnScreen(JNIEnv *env, jclass clazz) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeHdrToneMappedOnScreen(JNIEnv *env, jclass clazz) {
return banner_color_tonemapped_on_screen() ? JNI_TRUE : JNI_FALSE;
}
/* The Look the controls currently match (null = Custom) - only named in the session log. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetLookName(JNIEnv *env, jclass clazz, jstring name) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetLookName(JNIEnv *env, jclass clazz, jstring name) {
char *s = dup_jstr(env, name);
vkp_effects_set_look(s);
free(s);
@@ -583,14 +583,14 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetLookName(JNIEnv *
/* The in-game FPS limiter: frames per second, 0 = unlimited. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetFpsLimit(JNIEnv *env, jclass clazz, jint fps) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetFpsLimit(JNIEnv *env, jclass clazz, jint fps) {
g_fps_limit = fps > 0 ? fps : 0;
__android_log_print(ANDROID_LOG_INFO, TAG, "fps limit %d", fps);
}
/* Swap/clear the output window (e.g. SurfaceView recreated/destroyed). */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetSurface(
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetSurface(
JNIEnv *env, jclass clazz, jobject surface) {
if (surface) {
vk_present_set_window(ANativeWindow_fromSurface(env, surface));
@@ -616,7 +616,7 @@ static char *dup_bytes(JNIEnv *env, jbyteArray arr, int *len) {
/* Android's clipboard text becomes the guest's selection (empty/null = clear). */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetClipboardText(JNIEnv *env, jclass clazz, jbyteArray utf8) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeSetClipboardText(JNIEnv *env, jclass clazz, jbyteArray utf8) {
int len;
char *buf = dup_bytes(env, utf8, &len);
banner_host_clipboard_text(buf ? buf : "", len);
@@ -625,7 +625,7 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeSetClipboardText(JNI
/* Soft-keyboard text committed to the program accepting text input. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeTextInputCommit(JNIEnv *env, jclass clazz, jbyteArray utf8) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeTextInputCommit(JNIEnv *env, jclass clazz, jbyteArray utf8) {
int len;
char *buf = dup_bytes(env, utf8, &len);
if (buf && len) banner_host_text_commit(buf, len);
@@ -634,7 +634,7 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeTextInputCommit(JNIE
/* Composing (pre-edit) text; cursorBegin/cursorEnd are character indexes into it, -1 = end. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeTextInputPreedit(JNIEnv *env, jclass clazz, jbyteArray utf8,
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeTextInputPreedit(JNIEnv *env, jclass clazz, jbyteArray utf8,
jint cursorBegin, jint cursorEnd) {
int len;
char *buf = dup_bytes(env, utf8, &len);
@@ -644,6 +644,6 @@ Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeTextInputPreedit(JNI
/* The IME deleted characters around the caret. */
JNIEXPORT void JNICALL
Java_com_steamdeck_launcher_wayland_WaylandCompositor_nativeTextInputDelete(JNIEnv *env, jclass clazz, jint before, jint after) {
Java_com_droiddeck_launcher_wayland_WaylandCompositor_nativeTextInputDelete(JNIEnv *env, jclass clazz, jint before, jint after) {
banner_host_text_delete(before, after);
}
@@ -1,7 +1,7 @@
package com.steamdeck.launcher
package com.droiddeck.launcher
import android.app.Application
import com.steamdeck.launcher.session.CrashHandler
import com.droiddeck.launcher.session.CrashHandler
/** Process-wide setup: the crash handler, so a session's folder is finished even when we die. */
class App : Application() {
@@ -1,9 +1,9 @@
package com.steamdeck.launcher
package com.droiddeck.launcher
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import com.steamdeck.launcher.session.SessionService
import com.droiddeck.launcher.session.SessionService
/** Receives the system Home launch and routes it without consuming KEYCODE_HOME. */
class HomeActivity : Activity() {
@@ -1,4 +1,4 @@
package com.steamdeck.launcher
package com.droiddeck.launcher
import android.app.role.RoleManager
import android.graphics.Bitmap
@@ -9,8 +9,8 @@ import android.content.pm.PackageManager
import android.os.Build
import android.provider.Settings
import androidx.core.graphics.drawable.toBitmap
import com.steamdeck.launcher.session.SessionService
import com.steamdeck.launcher.session.SessionState
import com.droiddeck.launcher.session.SessionService
import com.droiddeck.launcher.session.SessionState
/** Android Home role and the launchable Android apps shown by the in-session app drawer. */
object HomeApp {
@@ -1,4 +1,4 @@
package com.steamdeck.launcher
package com.droiddeck.launcher
import android.Manifest
import android.content.Intent
@@ -18,42 +18,42 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import com.steamdeck.launcher.gpu.FrameGen
import com.steamdeck.launcher.gpu.LinuxVulkanDriver
import com.steamdeck.launcher.gpu.LinuxVulkanDriverManager
import com.steamdeck.launcher.gpu.TurnipDriver
import com.steamdeck.launcher.gpu.TurnipReleases
import com.steamdeck.launcher.gpu.LsfgNative
import com.steamdeck.launcher.runtime.LinuxRuntime
import com.steamdeck.launcher.runtime.DesktopCatalog
import com.steamdeck.launcher.runtime.LinuxRuntimeInstaller
import com.steamdeck.launcher.session.SessionService
import com.steamdeck.launcher.ui.PackageRow
import com.steamdeck.launcher.session.OfflineMode
import com.steamdeck.launcher.session.ProtonExtras
import com.steamdeck.launcher.session.SessionLogShare
import com.steamdeck.launcher.session.SessionPrefs
import com.steamdeck.launcher.ui.ProtonPage
import com.steamdeck.launcher.ui.ProtonRow
import com.steamdeck.launcher.core.CpuCores
import com.steamdeck.launcher.ui.CoreRow
import com.steamdeck.launcher.ui.PerformancePage
import com.steamdeck.launcher.ui.ModeSettingsPage
import com.steamdeck.launcher.ui.ModeSettings
import com.steamdeck.launcher.ui.ModeSettingsActions
import com.steamdeck.launcher.ui.DriverRow
import com.steamdeck.launcher.ui.ConfirmDialog
import com.steamdeck.launcher.ui.CreditsDialog
import com.steamdeck.launcher.ui.FrontEndScreen
import com.steamdeck.launcher.ui.FrontEndState
import com.steamdeck.launcher.ui.FrontEndActions
import com.steamdeck.launcher.frontend.Library
import com.steamdeck.launcher.ui.SteamDeckTheme
import com.steamdeck.launcher.ui.RomsDialog
import com.steamdeck.launcher.files.InAppFilePicker
import com.steamdeck.launcher.session.SessionArtifacts
import com.steamdeck.launcher.session.SessionState
import com.steamdeck.launcher.session.GameStorage
import com.droiddeck.launcher.gpu.FrameGen
import com.droiddeck.launcher.gpu.LinuxVulkanDriver
import com.droiddeck.launcher.gpu.LinuxVulkanDriverManager
import com.droiddeck.launcher.gpu.TurnipDriver
import com.droiddeck.launcher.gpu.TurnipReleases
import com.droiddeck.launcher.gpu.LsfgNative
import com.droiddeck.launcher.runtime.LinuxRuntime
import com.droiddeck.launcher.runtime.DesktopCatalog
import com.droiddeck.launcher.runtime.LinuxRuntimeInstaller
import com.droiddeck.launcher.session.SessionService
import com.droiddeck.launcher.ui.PackageRow
import com.droiddeck.launcher.session.OfflineMode
import com.droiddeck.launcher.session.ProtonExtras
import com.droiddeck.launcher.session.SessionLogShare
import com.droiddeck.launcher.session.SessionPrefs
import com.droiddeck.launcher.ui.ProtonPage
import com.droiddeck.launcher.ui.ProtonRow
import com.droiddeck.launcher.core.CpuCores
import com.droiddeck.launcher.ui.CoreRow
import com.droiddeck.launcher.ui.PerformancePage
import com.droiddeck.launcher.ui.ModeSettingsPage
import com.droiddeck.launcher.ui.ModeSettings
import com.droiddeck.launcher.ui.ModeSettingsActions
import com.droiddeck.launcher.ui.DriverRow
import com.droiddeck.launcher.ui.ConfirmDialog
import com.droiddeck.launcher.ui.CreditsDialog
import com.droiddeck.launcher.ui.FrontEndScreen
import com.droiddeck.launcher.ui.FrontEndState
import com.droiddeck.launcher.ui.FrontEndActions
import com.droiddeck.launcher.frontend.Library
import com.droiddeck.launcher.ui.DroidDeckTheme
import com.droiddeck.launcher.ui.RomsDialog
import com.droiddeck.launcher.files.InAppFilePicker
import com.droiddeck.launcher.session.SessionArtifacts
import com.droiddeck.launcher.session.SessionState
import com.droiddeck.launcher.session.GameStorage
/**
* The whole app outside a session: is the runtime installed, is there a newer one, frame
@@ -107,8 +107,8 @@ class MainActivity : ComponentActivity() {
private var mic by mutableStateOf(false)
private var linuxRows by mutableStateOf<List<DriverRow>>(emptyList())
/** The latest Banners-Turnip release as each driver menu offers it (see [refreshReleaseRows]). */
private var linuxDownloads by mutableStateOf<List<com.steamdeck.launcher.ui.DownloadRow>>(emptyList())
private var androidDownloads by mutableStateOf<List<com.steamdeck.launcher.ui.DownloadRow>>(emptyList())
private var linuxDownloads by mutableStateOf<List<com.droiddeck.launcher.ui.DownloadRow>>(emptyList())
private var androidDownloads by mutableStateOf<List<com.droiddeck.launcher.ui.DownloadRow>>(emptyList())
private var releaseStatus by mutableStateOf("Not checked yet - tap refresh to look for new drivers")
private var releaseChecking by mutableStateOf(false)
private var canRestoreBundled by mutableStateOf(false)
@@ -149,7 +149,7 @@ class MainActivity : ComponentActivity() {
private var addedGamesDirs by mutableStateOf<List<String>>(emptyList())
private var addedGamesArt by mutableStateOf(true)
@Volatile private var artFetchRunning = false
private var addedGames by mutableStateOf<List<com.steamdeck.launcher.ui.AddedGameRow>>(emptyList())
private var addedGames by mutableStateOf<List<com.droiddeck.launcher.ui.AddedGameRow>>(emptyList())
private val pickRomsDir = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { r ->
if (r.resultCode == RESULT_OK) InAppFilePicker.pickedPath(r.data)?.let { path ->
SessionPrefs.setRomsDir(this, path)
@@ -211,7 +211,7 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
theme = SessionPrefs.theme(this)
setContent {
SteamDeckTheme(theme) {
DroidDeckTheme(theme) {
val sm = settingsMode
val page: (@Composable () -> Unit)? = when {
sm != null -> { { ModeSettingsHost(sm) } }
@@ -277,7 +277,7 @@ class MainActivity : ComponentActivity() {
onProtons = { openProtons() },
onPerformance = { refreshCores(); showProtons = false; showPerformance = true },
onRoms = { showRoms = true },
onFiles = { startActivity(Intent(this, com.steamdeck.launcher.files.FileManagerActivity::class.java)) },
onFiles = { startActivity(Intent(this, com.droiddeck.launcher.files.FileManagerActivity::class.java)) },
onLogs = {
SessionPrefs.setLogsEnabled(this, !SessionPrefs.logsEnabled(this))
logsEnabled = SessionPrefs.logsEnabled(this)
@@ -315,7 +315,7 @@ class MainActivity : ComponentActivity() {
showNonAdreno?.let { release ->
ConfirmDialog(
title = "Not an Adreno GPU",
text = "Turnip supports Adreno GPUs. On ${com.steamdeck.launcher.core.DeviceSupport.gpuName()}, Steam may show a black screen. Download: ${"%.0f".format(release.size / 1e6)} MB.",
text = "Turnip supports Adreno GPUs. On ${com.droiddeck.launcher.core.DeviceSupport.gpuName()}, Steam may show a black screen. Download: ${"%.0f".format(release.size / 1e6)} MB.",
confirm = "Install anyway",
onConfirm = { showNonAdreno = null; install(release) },
onDismiss = { showNonAdreno = null },
@@ -607,8 +607,8 @@ class MainActivity : ComponentActivity() {
/** The added games as the settings page lists them; a scan of the folder, on this thread (one level, small). */
private fun refreshAddedGames() {
addedGames = com.steamdeck.launcher.frontend.AddedGames.scan(this).map { g ->
com.steamdeck.launcher.ui.AddedGameRow(g.folder.path, g.folderName(), g.exe.path, g.exe.name, g.candidates.map { c -> c.path to c.name }.distinctBy { it.first })
addedGames = com.droiddeck.launcher.frontend.AddedGames.scan(this).map { g ->
com.droiddeck.launcher.ui.AddedGameRow(g.folder.path, g.folderName(), g.exe.path, g.exe.name, g.candidates.map { c -> c.path to c.name }.distinctBy { it.first })
}
// Art the games do not have yet, from Steam's store, off the main thread; the rail
// redraws when something arrives.
@@ -616,8 +616,8 @@ class MainActivity : ComponentActivity() {
artFetchRunning = true
Thread({
try {
val games = com.steamdeck.launcher.frontend.AddedGames.scan(this)
if (com.steamdeck.launcher.frontend.AddedGameArt.fetchMissing(this, games)) ui.post { refresh() }
val games = com.droiddeck.launcher.frontend.AddedGames.scan(this)
if (com.droiddeck.launcher.frontend.AddedGameArt.fetchMissing(this, games)) ui.post { refresh() }
} finally {
artFetchRunning = false
}
@@ -637,7 +637,7 @@ class MainActivity : ComponentActivity() {
refreshAddedGames()
shapeMode = SessionPrefs.shapeMode(this)
hdrOn = SessionPrefs.hdr(this, mode)
hdrReason = com.steamdeck.launcher.wayland.HdrSupport.probe(this).reason
hdrReason = com.droiddeck.launcher.wayland.HdrSupport.probe(this).reason
touchMode = SessionPrefs.touchMode(this)
suspendPolicy = SessionPrefs.suspendPolicy(this, mode)
oscMode = SessionPrefs.oscMode(this)
@@ -753,7 +753,7 @@ class MainActivity : ComponentActivity() {
.filter { a -> TurnipReleases.installedId(this, a) { id -> if (linux) lm.isInstalled(id) else td.isInstalled(id) } == null }
.map { a ->
val mb = "%.1f MB".format(a.size / 1_048_576.0)
com.steamdeck.launcher.ui.DownloadRow(a.name, "${a.source} ${a.tag}", "${a.label} · $mb", releaseProgress[a.name])
com.droiddeck.launcher.ui.DownloadRow(a.name, "${a.source} ${a.tag}", "${a.label} · $mb", releaseProgress[a.name])
}
linuxDownloads = rows(linux = true)
androidDownloads = rows(linux = false)
@@ -815,7 +815,7 @@ class MainActivity : ComponentActivity() {
Log.w(TAG, "release driver download", e)
"Download failed: ${e.message}"
} finally {
file?.let { com.steamdeck.launcher.core.FileUtils.delete(it) }
file?.let { com.droiddeck.launcher.core.FileUtils.delete(it) }
}
ui.post {
releaseProgress.remove(assetName)
@@ -880,8 +880,8 @@ class MainActivity : ComponentActivity() {
} else null
// The libraries, off the main thread: manifests and a folder scan.
Thread({
val games = if (ready) Library.steamGames(this) + com.steamdeck.launcher.frontend.AddedGames.scan(this).map { g ->
com.steamdeck.launcher.frontend.AddedGameArt.resolve(this, g).let { art -> Library.SteamGame(g.appId.toInt(), g.name, art.portrait ?: art.header, "added", g.gameId) }
val games = if (ready) Library.steamGames(this) + com.droiddeck.launcher.frontend.AddedGames.scan(this).map { g ->
com.droiddeck.launcher.frontend.AddedGameArt.resolve(this, g).let { art -> Library.SteamGame(g.appId.toInt(), g.name, art.portrait ?: art.header, "added", g.gameId) }
} else emptyList()
val emus = Library.emulators(this) { id -> DesktopCatalog.installed(this, id) != null }
ui.post { steamGames = games; emulatorList = emus }
@@ -903,13 +903,13 @@ class MainActivity : ComponentActivity() {
// The runtime draws with Turnip, an Adreno driver: on Mali, Xclipse or PowerVR the
// compositor gets no usable Vulkan device and a session is sound over a black screen.
// Said before the download, not after it; the user may still go ahead.
if (installed == null && !com.steamdeck.launcher.core.DeviceSupport.adreno()) { showNonAdreno = release; return }
if (installed == null && !com.droiddeck.launcher.core.DeviceSupport.adreno()) { showNonAdreno = release; return }
install(release)
}
/** Starts a session; with no runtime on a non-Adreno, the same warning Setup gives comes first, before any download. */
private fun startSession(intent: Intent) {
val warn = installed == null && !com.steamdeck.launcher.core.DeviceSupport.adreno()
val warn = installed == null && !com.droiddeck.launcher.core.DeviceSupport.adreno()
if (warn && available != null) showNonAdreno = available
else startActivity(intent)
}
@@ -1,4 +1,4 @@
package com.steamdeck.launcher
package com.droiddeck.launcher
import android.hardware.input.InputManager
import android.hardware.display.DisplayManager
@@ -25,38 +25,38 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import com.steamdeck.launcher.core.FileUtils
import com.steamdeck.launcher.gpu.FrameGen
import com.steamdeck.launcher.gpu.LsfgNative
import com.steamdeck.launcher.gpu.TurnipDriver
import com.steamdeck.launcher.input.EvdevKeys
import com.steamdeck.launcher.input.KeyboardHost
import com.steamdeck.launcher.input.OnScreenControls
import com.steamdeck.launcher.input.PadBridge
import com.steamdeck.launcher.input.PointerGestures
import com.steamdeck.launcher.input.SecondScreenDisplay
import com.steamdeck.launcher.input.SecondScreenMode
import com.steamdeck.launcher.input.TouchpadGestures
import com.steamdeck.launcher.runtime.LinuxRuntime
import com.steamdeck.launcher.session.LoadingState
import com.steamdeck.launcher.session.PerfHints
import com.steamdeck.launcher.session.PerfHud
import com.steamdeck.launcher.session.PerfMode
import com.steamdeck.launcher.session.SessionPrefs
import com.steamdeck.launcher.session.SessionPaths
import com.steamdeck.launcher.wayland.HdrSupport
import com.steamdeck.launcher.session.SessionService
import com.steamdeck.launcher.session.SessionState
import com.steamdeck.launcher.ui.CursorOverlay
import com.steamdeck.launcher.ui.DrawerActions
import com.steamdeck.launcher.ui.HudText
import com.steamdeck.launcher.ui.LoadingOverlay
import com.steamdeck.launcher.ui.SessionDrawer
import com.steamdeck.launcher.ui.SessionPausedOverlay
import com.steamdeck.launcher.ui.SecondScreenPresentation
import com.steamdeck.launcher.ui.SteamDeckTheme
import com.steamdeck.launcher.wayland.CompositorHost
import com.steamdeck.launcher.wayland.WaylandCompositor
import com.droiddeck.launcher.core.FileUtils
import com.droiddeck.launcher.gpu.FrameGen
import com.droiddeck.launcher.gpu.LsfgNative
import com.droiddeck.launcher.gpu.TurnipDriver
import com.droiddeck.launcher.input.EvdevKeys
import com.droiddeck.launcher.input.KeyboardHost
import com.droiddeck.launcher.input.OnScreenControls
import com.droiddeck.launcher.input.PadBridge
import com.droiddeck.launcher.input.PointerGestures
import com.droiddeck.launcher.input.SecondScreenDisplay
import com.droiddeck.launcher.input.SecondScreenMode
import com.droiddeck.launcher.input.TouchpadGestures
import com.droiddeck.launcher.runtime.LinuxRuntime
import com.droiddeck.launcher.session.LoadingState
import com.droiddeck.launcher.session.PerfHints
import com.droiddeck.launcher.session.PerfHud
import com.droiddeck.launcher.session.PerfMode
import com.droiddeck.launcher.session.SessionPrefs
import com.droiddeck.launcher.session.SessionPaths
import com.droiddeck.launcher.wayland.HdrSupport
import com.droiddeck.launcher.session.SessionService
import com.droiddeck.launcher.session.SessionState
import com.droiddeck.launcher.ui.CursorOverlay
import com.droiddeck.launcher.ui.DrawerActions
import com.droiddeck.launcher.ui.HudText
import com.droiddeck.launcher.ui.LoadingOverlay
import com.droiddeck.launcher.ui.SessionDrawer
import com.droiddeck.launcher.ui.SessionPausedOverlay
import com.droiddeck.launcher.ui.SecondScreenPresentation
import com.droiddeck.launcher.ui.DroidDeckTheme
import com.droiddeck.launcher.wayland.CompositorHost
import com.droiddeck.launcher.wayland.WaylandCompositor
import java.io.File
/**
@@ -155,9 +155,9 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
loading = LoadingState(this)
if (!SessionState.running) {
val needRuntime = com.steamdeck.launcher.runtime.LinuxRuntimeInstaller.installedVersion(this) == null
val needRuntime = com.droiddeck.launcher.runtime.LinuxRuntimeInstaller.installedVersion(this) == null
val needDesktop = intent.getStringExtra(SessionService.EXTRA_MODE) == SessionService.MODE_DESKTOP &&
!com.steamdeck.launcher.runtime.DesktopCatalog.desktopInstalled(this)
!com.droiddeck.launcher.runtime.DesktopCatalog.desktopInstalled(this)
if (needRuntime || needDesktop) installThenStart(needRuntime, needDesktop)
}
hud = PerfHud(this)
@@ -175,7 +175,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
// through to the pad and the game underneath.
root.addView(ComposeView(this).apply {
setContent {
SteamDeckTheme {
DroidDeckTheme {
CursorOverlay(cursorPos, cursorVisible, resources.displayMetrics.density)
if (hud.text.isNotEmpty()) HudText(hud.text)
if (loading.visible) LoadingOverlay(loading.step, loading.percent, loading.elapsed, loading.hint, loading.ended)
@@ -258,9 +258,9 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
private fun sendSteamGuide() {
drawerOpen = false
padBridge?.applyTouch { state -> state.press(com.steamdeck.launcher.input.PadState.GUIDE, true) }
padBridge?.applyTouch { state -> state.press(com.droiddeck.launcher.input.PadState.GUIDE, true) }
uiHandler.postDelayed({
padBridge?.applyTouch { state -> state.press(com.steamdeck.launcher.input.PadState.GUIDE, false) }
padBridge?.applyTouch { state -> state.press(com.droiddeck.launcher.input.PadState.GUIDE, false) }
}, 90)
}
@@ -310,7 +310,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
}
/** Reports one package's download on the loading screen: "<what> · 332 of 791 MB", checking, unpacking. */
private fun progressFor(what: String, mb: Long) = com.steamdeck.launcher.runtime.LinuxRuntimeInstaller.ProgressListener { stage, p ->
private fun progressFor(what: String, mb: Long) = com.droiddeck.launcher.runtime.LinuxRuntimeInstaller.ProgressListener { stage, p ->
uiHandler.post {
loading.percent = p
loading.step = when {
@@ -323,9 +323,9 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
/** Null when the runtime is in, else the loading screen's closing line. */
private fun installRuntime(): String? {
val release = com.steamdeck.launcher.runtime.LinuxRuntimeInstaller.fetchRelease()
val release = com.droiddeck.launcher.runtime.LinuxRuntimeInstaller.fetchRelease()
?: return "Could not reach the runtime catalog. Check the connection and press Play again."
val ok = com.steamdeck.launcher.runtime.LinuxRuntimeInstaller.install(this, release,
val ok = com.droiddeck.launcher.runtime.LinuxRuntimeInstaller.install(this, release,
progressFor("the Linux runtime", release.size / 1_000_000))
return if (ok) null else "The Linux runtime did not install. Check the connection and press Play again."
}
@@ -333,9 +333,9 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
/** Null when the desktop package is in, else the loading screen's closing line. */
private fun installDesktop(): String? {
uiHandler.post { loading.percent = -1; loading.step = "downloading the desktop" }
val entry = com.steamdeck.launcher.runtime.DesktopCatalog.fetch()?.firstOrNull { it.id == "desktop" }
val entry = com.droiddeck.launcher.runtime.DesktopCatalog.fetch()?.firstOrNull { it.id == "desktop" }
?: return "Could not reach the desktop catalog. Check the connection and press Desktop again."
val problem = com.steamdeck.launcher.runtime.DesktopCatalog.install(this, entry,
val problem = com.droiddeck.launcher.runtime.DesktopCatalog.install(this, entry,
progressFor("the desktop", entry.size / 1_000_000))
return problem?.let { "The desktop did not install ($it). Check the connection and press Desktop again." }
}
@@ -757,9 +757,9 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
sendWheel = { steps -> WaylandCompositor.nativeSendSceneInput(4, steps, 0) },
onSteamMenu = {
if (SessionState.mode == SessionService.MODE_STEAM) {
padBridge?.applyTouch { st -> st.press(com.steamdeck.launcher.input.PadState.GUIDE, true) }
padBridge?.applyTouch { st -> st.press(com.droiddeck.launcher.input.PadState.GUIDE, true) }
Handler(Looper.getMainLooper()).postDelayed({
padBridge?.applyTouch { st -> st.press(com.steamdeck.launcher.input.PadState.GUIDE, false) }
padBridge?.applyTouch { st -> st.press(com.droiddeck.launcher.input.PadState.GUIDE, false) }
}, 90)
}
},
@@ -854,9 +854,9 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
return true
}
/** The mode decides which controls appear; `steamdeck-osc` in Downloads still overrides. */
/** The mode decides which controls appear; `droiddeck-osc` in Downloads still overrides. */
private fun updateOnScreenControls() {
val forced = File(Environment.getExternalStorageDirectory(), "Download/steamdeck-osc")
val forced = File(Environment.getExternalStorageDirectory(), "Download/droiddeck-osc")
.takeIf { it.isFile }
?.let { FileUtils.readString(it)?.trim()?.lowercase() }
?: SessionPrefs.oscMode(this)
@@ -1,10 +1,10 @@
package com.steamdeck.launcher.audio;
package com.droiddeck.launcher.audio;
import android.os.Process;
import android.util.Log;
import com.steamdeck.launcher.core.SessionPart;
import com.steamdeck.launcher.core.HostProcess;
import com.droiddeck.launcher.core.SessionPart;
import com.droiddeck.launcher.core.HostProcess;
import java.io.File;
import java.util.ArrayList;
@@ -1,13 +1,13 @@
package com.steamdeck.launcher.audio;
package com.droiddeck.launcher.audio;
import android.content.Context;
import android.os.Process;
import android.util.Log;
import com.steamdeck.launcher.core.FileUtils;
import com.steamdeck.launcher.core.SessionPart;
import com.steamdeck.launcher.core.HostProcess;
import com.steamdeck.launcher.core.TarZst;
import com.droiddeck.launcher.core.FileUtils;
import com.droiddeck.launcher.core.SessionPart;
import com.droiddeck.launcher.core.HostProcess;
import com.droiddeck.launcher.core.TarZst;
import java.io.File;
import java.io.InputStream;
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.core
package com.droiddeck.launcher.core
import java.io.File
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.core
package com.droiddeck.launcher.core
import android.app.ActivityManager
import android.content.Context
@@ -7,15 +7,15 @@ import android.os.Environment
import android.os.StatFs
import android.provider.Settings
import android.util.Log
import com.steamdeck.launcher.gpu.LinuxVulkanDriver
import com.steamdeck.launcher.gpu.LinuxVulkanDriverManager
import com.steamdeck.launcher.gpu.TurnipDriver
import com.steamdeck.launcher.runtime.DesktopCatalog
import com.steamdeck.launcher.runtime.LinuxRuntime
import com.steamdeck.launcher.runtime.LinuxRuntimeInstaller
import com.steamdeck.launcher.session.SessionPrefs
import com.steamdeck.launcher.session.SessionService
import com.steamdeck.launcher.session.SessionState
import com.droiddeck.launcher.gpu.LinuxVulkanDriver
import com.droiddeck.launcher.gpu.LinuxVulkanDriverManager
import com.droiddeck.launcher.gpu.TurnipDriver
import com.droiddeck.launcher.runtime.DesktopCatalog
import com.droiddeck.launcher.runtime.LinuxRuntime
import com.droiddeck.launcher.runtime.LinuxRuntimeInstaller
import com.droiddeck.launcher.session.SessionPrefs
import com.droiddeck.launcher.session.SessionService
import com.droiddeck.launcher.session.SessionState
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
@@ -50,7 +50,7 @@ object DeviceReport {
b.append(key.padEnd(24)).append(value ?: "unknown").append('\n')
}
b.append("SteamDeck session report\n")
b.append("DroidDeck session report\n")
b.append("========================\n")
k("Written", SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz", Locale.US).format(Date()))
k("Session mode", when (mode) { SessionService.MODE_DESKTOP -> "desktop (labwc/LXQt)"; SessionService.MODE_RUN -> "a program under gamescope"; else -> "Steam client (gamescope)" })
@@ -155,7 +155,7 @@ object DeviceReport {
k("Touch mode", SessionPrefs.touchMode(context))
k("Performance HUD", SessionPrefs.hudEnabled(context))
k("Game storage", when (val g = SessionPrefs.gameStorage(context)) {
"" -> "automatic (" + (com.steamdeck.launcher.session.GameStorage.effective(context)?.path ?: "no card present") + ")"
"" -> "automatic (" + (com.droiddeck.launcher.session.GameStorage.effective(context)?.path ?: "no card present") + ")"
SessionPrefs.GAME_STORAGE_OFF -> "internal only"
else -> g
})
@@ -178,9 +178,9 @@ object DeviceReport {
})
h("Device switch files in Download")
for (name in listOf("steamdeck-env", "steamdeck-tu-debug", "steamdeck-driver",
"steamdeck-osc", "steamdeck-no-pad", "steamdeck-pad-log",
"steamdeck-no-hud", "steamdeck-wlr-renderer")) {
for (name in listOf("droiddeck-env", "droiddeck-tu-debug", "droiddeck-driver",
"droiddeck-osc", "droiddeck-no-pad", "droiddeck-pad-log",
"droiddeck-no-hud", "droiddeck-wlr-renderer")) {
val f = File(Environment.getExternalStorageDirectory(), "Download/$name")
if (f.isFile) k(name, FileUtils.readString(f)?.trim()?.replace('\n', ' ')?.ifEmpty { "(present, empty)" } ?: "(present)")
}
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.core
package com.droiddeck.launcher.core
import android.os.Build
import java.io.File
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.core;
package com.droiddeck.launcher.core;
import android.util.Log;
@@ -106,7 +106,7 @@ public final class Downloader {
connection.setConnectTimeout(TIMEOUT_MS);
connection.setReadTimeout(TIMEOUT_MS);
connection.setInstanceFollowRedirects(true);
connection.setRequestProperty("User-Agent", "SteamDeck-Android");
connection.setRequestProperty("User-Agent", "DroidDeck-Android");
return connection;
}
}
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.core
package com.droiddeck.launcher.core
/**
* FEXCore presets for the x86 games the Steam client launches, Bannerlator's table carried over
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.core;
package com.droiddeck.launcher.core;
import android.content.Context;
import android.system.ErrnoException;
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.core
package com.droiddeck.launcher.core
/** The variables a host process is started with, in the order they were set. */
class HostEnvironment {
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.core
package com.droiddeck.launcher.core
import android.util.Log
import java.io.File
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.core
package com.droiddeck.launcher.core
/**
* Scrubs credentials out of a log line before it is written somewhere a user will share.
@@ -1,11 +1,11 @@
package com.steamdeck.launcher.core
package com.droiddeck.launcher.core
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
import android.util.Log
import com.steamdeck.launcher.runtime.LinuxRuntime
import com.droiddeck.launcher.runtime.LinuxRuntime
import java.io.File
import java.net.Inet4Address
import java.net.Inet6Address
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.core
package com.droiddeck.launcher.core
import android.os.Process
import android.util.Log
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.core;
package com.droiddeck.launcher.core;
import android.content.Context;
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.core;
package com.droiddeck.launcher.core;
import android.content.Context;
import android.util.Log;
@@ -16,7 +16,7 @@ import java.io.OutputStream;
/**
* The small zstd tarballs that ship inside the apk (the Turnip driver, the PulseAudio modules).
* The runtime rootfs is not one of these - it needs hard links and symlinks preserved, which
* {@link com.steamdeck.launcher.runtime.LinuxRuntimeInstaller} handles itself.
* {@link com.droiddeck.launcher.runtime.LinuxRuntimeInstaller} handles itself.
*/
public final class TarZst {
private static final String TAG = "TarZst";
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.files
package com.droiddeck.launcher.files
import android.content.res.Configuration
import androidx.compose.animation.core.animateDpAsState
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.files
package com.droiddeck.launcher.files
import android.content.Context
import org.json.JSONArray
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.files
package com.droiddeck.launcher.files
import android.Manifest
import android.content.pm.PackageManager
@@ -10,7 +10,7 @@ import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier
import com.steamdeck.launcher.ui.SteamDeckTheme
import com.droiddeck.launcher.ui.DroidDeckTheme
/** The File Manager as a screen of its own, from the Files tile on the main screen. */
class FileManagerActivity : ComponentActivity() {
@@ -20,7 +20,7 @@ class FileManagerActivity : ComponentActivity() {
requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1)
}
setContent {
SteamDeckTheme {
DroidDeckTheme {
Surface(modifier = Modifier.fillMaxSize().systemBarsPadding(), color = MaterialTheme.colorScheme.background) {
FileManagerScreen()
}
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.files
package com.droiddeck.launcher.files
import android.widget.Toast
import androidx.activity.compose.BackHandler
@@ -114,8 +114,8 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.steamdeck.launcher.R
import com.steamdeck.launcher.session.SessionPrefs
import com.droiddeck.launcher.R
import com.droiddeck.launcher.session.SessionPrefs
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -1217,7 +1217,7 @@ fun FileManagerScreen(
// The ROMs folder chosen on the main screen: what the session shows as /root/ROMs.
SessionPrefs.romsDir(context).takeIf { it.isNotEmpty() }?.let(::File)?.takeIf { it.isDirectory }
?.let { add(locItem("ROMs", Icons.Filled.SportsEsports, it)) }
File("/storage/emulated/0/Download/SteamDeck").takeIf { it.isDirectory }?.let { add(locItem("Session logs", Icons.Filled.Description, it)) }
File("/storage/emulated/0/Download/DroidDeck").takeIf { it.isDirectory }?.let { add(locItem("Session logs", Icons.Filled.Description, it)) }
File("/storage/emulated/0/Pictures").takeIf { it.isDirectory }?.let { add(locItem("Pictures", Icons.Filled.Image, it)) }
}
val favItems = remember(favTick) { FavoritesStore.list(context).map(::File).filter { it.exists() } }
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.files
package com.droiddeck.launcher.files
import android.util.Log
import java.io.File
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.files
package com.droiddeck.launcher.files
import android.Manifest
import android.app.Activity
@@ -12,7 +12,7 @@ import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier
import com.steamdeck.launcher.ui.SteamDeckTheme
import com.droiddeck.launcher.ui.DroidDeckTheme
import java.io.File
/**
@@ -43,7 +43,7 @@ class FilePickerActivity : ComponentActivity() {
?.let { File(it) }?.takeIf { it.isDirectory }
setContent {
SteamDeckTheme {
DroidDeckTheme {
Surface(modifier = Modifier.fillMaxSize().systemBarsPadding(), color = MaterialTheme.colorScheme.background) {
FileManagerScreen(
pickMode = true,
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.files
package com.droiddeck.launcher.files
import android.content.Context
import android.content.Intent
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.files
package com.droiddeck.launcher.files
import androidx.compose.foundation.background
import androidx.compose.foundation.border
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.files
package com.droiddeck.launcher.files
import androidx.compose.foundation.border
import androidx.compose.material3.AlertDialog
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.files
package com.droiddeck.launcher.files
import android.graphics.Bitmap
import android.graphics.BitmapFactory
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.files
package com.droiddeck.launcher.files
import android.content.Context
import android.os.Build
@@ -1,10 +1,10 @@
package com.steamdeck.launcher.frontend
package com.droiddeck.launcher.frontend
import android.content.Context
import android.graphics.Bitmap
import android.util.Log
import com.steamdeck.launcher.files.PeIconExtractor
import com.steamdeck.launcher.session.SessionPrefs
import com.droiddeck.launcher.files.PeIconExtractor
import com.droiddeck.launcher.session.SessionPrefs
import org.json.JSONObject
import java.io.File
import java.net.HttpURLConnection
@@ -161,7 +161,7 @@ object AddedGameArt {
val c = URL(url).openConnection() as HttpURLConnection
c.connectTimeout = 10_000
c.readTimeout = 15_000
c.setRequestProperty("User-Agent", "SteamDeck-launcher")
c.setRequestProperty("User-Agent", "DroidDeck-launcher")
return try {
if (c.responseCode != 200) null else c.inputStream.use { it.readBytes() }
} catch (e: Exception) {
@@ -1,10 +1,10 @@
package com.steamdeck.launcher.frontend
package com.droiddeck.launcher.frontend
import android.content.Context
import android.os.Environment
import android.util.Log
import com.steamdeck.launcher.session.GameStorage
import com.steamdeck.launcher.session.SessionPrefs
import com.droiddeck.launcher.session.GameStorage
import com.droiddeck.launcher.session.SessionPrefs
import java.io.File
import java.util.zip.CRC32
@@ -1,10 +1,10 @@
package com.steamdeck.launcher.frontend
package com.droiddeck.launcher.frontend
import android.content.Context
import com.steamdeck.launcher.R
import com.steamdeck.launcher.runtime.LinuxRuntime
import com.steamdeck.launcher.session.GameStorage
import com.steamdeck.launcher.session.SessionPrefs
import com.droiddeck.launcher.R
import com.droiddeck.launcher.runtime.LinuxRuntime
import com.droiddeck.launcher.session.GameStorage
import com.droiddeck.launcher.session.SessionPrefs
import java.io.File
/**
@@ -1,8 +1,8 @@
package com.steamdeck.launcher.gpu
package com.droiddeck.launcher.gpu
import android.content.Context
import android.util.Log
import com.steamdeck.launcher.wayland.WaylandCompositor
import com.droiddeck.launcher.wayland.WaylandCompositor
/**
* The frame-generation setting and how it reaches the compositor.
@@ -110,7 +110,7 @@ object FrameGen {
}
}
android.app.AlertDialog.Builder(activity)
.setTitle(com.steamdeck.launcher.R.string.frame_gen_title)
.setTitle(com.droiddeck.launcher.R.string.frame_gen_title)
.setSingleChoiceItems(adapter, current) { dialog, which ->
when (which) {
0 -> set(activity, ENGINE_OFF, 2)
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.gpu;
package com.droiddeck.launcher.gpu;
import android.content.Context;
import android.util.Log;
@@ -1,10 +1,10 @@
package com.steamdeck.launcher.gpu;
package com.droiddeck.launcher.gpu;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import com.steamdeck.launcher.core.FileUtils;
import com.droiddeck.launcher.core.FileUtils;
import org.json.JSONObject;
@@ -1,9 +1,9 @@
package com.steamdeck.launcher.gpu;
package com.droiddeck.launcher.gpu;
import android.content.Context;
import android.util.Log;
import com.steamdeck.launcher.runtime.LinuxRuntime;
import com.droiddeck.launcher.runtime.LinuxRuntime;
import java.io.File;
@@ -1,13 +1,13 @@
package com.steamdeck.launcher.gpu;
package com.droiddeck.launcher.gpu;
import android.content.Context;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import com.steamdeck.launcher.core.FileUtils;
import com.steamdeck.launcher.core.TarZst;
import com.steamdeck.launcher.session.SessionPrefs;
import com.droiddeck.launcher.core.FileUtils;
import com.droiddeck.launcher.core.TarZst;
import com.droiddeck.launcher.session.SessionPrefs;
import org.json.JSONObject;
@@ -51,7 +51,7 @@ public final class TurnipDriver {
/** The two the apk carries; never removable, unpacked on demand. */
public static final List<String> BUNDLED = Collections.unmodifiableList(Arrays.asList(DRIVER_A7XX, DRIVER_A8XX));
/** Overrides the pick, for a device we cannot reach: a7xx, a8xx or system. */
private static final String OVERRIDE_FILE = "Download/steamdeck-driver";
private static final String OVERRIDE_FILE = "Download/droiddeck-driver";
/** Bundled drivers the user deleted: hidden from the list, their unpacked copy removed. */
private static final String PREFS = "graphics_driver";
private static final String KEY_HIDDEN = "hiddenBundled";
@@ -1,7 +1,7 @@
package com.steamdeck.launcher.gpu
package com.droiddeck.launcher.gpu
import android.content.Context
import com.steamdeck.launcher.core.FileUtils
import com.droiddeck.launcher.core.FileUtils
import org.json.JSONArray
import org.json.JSONObject
import java.io.File
@@ -114,7 +114,7 @@ object TurnipReleases {
c.connectTimeout = 15_000
c.readTimeout = 20_000
c.setRequestProperty("Accept", "application/vnd.github+json")
c.setRequestProperty("User-Agent", "SteamDeck-app")
c.setRequestProperty("User-Agent", "DroidDeck-app")
try {
val code = c.responseCode
if (code == 403 || code == 429) throw IOException("GitHub's rate limit was hit - try again later")
@@ -171,7 +171,7 @@ object TurnipReleases {
val c = URL(asset.url).openConnection() as HttpURLConnection
c.connectTimeout = 15_000
c.readTimeout = 60_000
c.setRequestProperty("User-Agent", "SteamDeck-app")
c.setRequestProperty("User-Agent", "DroidDeck-app")
c.instanceFollowRedirects = true
try {
if (c.responseCode != 200) throw IOException("download answered HTTP ${c.responseCode}")
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.input;
package com.droiddeck.launcher.input;
import android.view.KeyEvent;
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.input;
package com.droiddeck.launcher.input;
import android.util.Log;
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.input
package com.droiddeck.launcher.input
import android.app.Activity
import android.content.Context
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.input
package com.droiddeck.launcher.input
import android.annotation.SuppressLint
import android.content.Context
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.input;
package com.droiddeck.launcher.input;
import android.os.Handler;
import android.os.Looper;
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.input
package com.droiddeck.launcher.input
/**
* What one Xbox-shaped pad is doing right now: two sticks and two triggers as -1..1 / 0..1, the
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.input
package com.droiddeck.launcher.input
import android.os.Handler
import android.os.Looper
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.input
package com.droiddeck.launcher.input
/** The control surface shown on a secondary Android display during a Linux session. */
enum class SecondScreenMode(val id: String, val label: String) {
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.input
package com.droiddeck.launcher.input
import android.os.Handler
import android.os.Looper
@@ -1,9 +1,9 @@
package com.steamdeck.launcher.runtime
package com.droiddeck.launcher.runtime
import android.content.Context
import android.util.Log
import com.steamdeck.launcher.core.Downloader
import com.steamdeck.launcher.core.FileUtils
import com.droiddeck.launcher.core.Downloader
import com.droiddeck.launcher.core.FileUtils
import org.json.JSONObject
import java.io.File
@@ -45,14 +45,16 @@ object DesktopCatalog {
}
}
private fun marker(context: Context, id: String) = File(LinuxRuntime.rootDir(context), ".steamdeck-pkg-$id")
private fun marker(context: Context, id: String) = File(LinuxRuntime.rootDir(context), ".droiddeck-pkg-$id")
/** The installed version of a package, or null. */
fun installed(context: Context, id: String): String? =
FileUtils.readString(marker(context, id))?.trim()?.takeIf { it.isNotEmpty() }
// labwc comes with the hosted desktop package itself (its launcher is staged by the app at
// every session, so it cannot tell whether the package is there); SessionFiles uses the same test.
fun desktopInstalled(context: Context): Boolean =
File(LinuxRuntime.rootDir(context), "usr/local/bin/steamdeck-desktop").isFile
File(LinuxRuntime.rootDir(context), "usr/bin/labwc").isFile
/** Downloads, verifies and installs one package. Returns null on success, else a message. */
fun install(context: Context, entry: Entry, listener: LinuxRuntimeInstaller.ProgressListener?): String? {
@@ -80,7 +82,7 @@ object DesktopCatalog {
else download.renameTo(target)
if (!placed) return "Could not place the AppImage"
target.setExecutable(true, false)
FileUtils.writeString(File(root, "usr/share/applications/steamdeck-${entry.id}.desktop"),
FileUtils.writeString(File(root, "usr/share/applications/droiddeck-${entry.id}.desktop"),
"[Desktop Entry]\nType=Application\nName=${entry.name}\n" +
"Exec=env APPIMAGE_EXTRACT_AND_RUN=1 /opt/appimages/${entry.id}.AppImage\n" +
"Icon=${entry.icon}\nTerminal=false\nCategories=${entry.category};\n")
@@ -123,7 +125,7 @@ object DesktopCatalog {
val root = LinuxRuntime.rootDir(context)
if (entry.kind == "appimage") {
File(root, "opt/appimages/${entry.id}.AppImage").delete()
File(root, "usr/share/applications/steamdeck-${entry.id}.desktop").delete()
File(root, "usr/share/applications/droiddeck-${entry.id}.desktop").delete()
}
marker(context, entry.id).delete()
}
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.runtime
package com.droiddeck.launcher.runtime
import android.content.Context
import android.net.ConnectivityManager
@@ -7,7 +7,7 @@ import android.net.Network
import android.os.Build
import android.provider.Settings
import android.util.Log
import com.steamdeck.launcher.core.SessionPart
import com.droiddeck.launcher.core.SessionPart
import java.io.File
import java.io.IOException
import java.net.Inet4Address
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.runtime;
package com.droiddeck.launcher.runtime;
import android.content.Context;
import android.os.Process;
@@ -33,7 +33,7 @@ public final class LinuxRuntime {
public static final String EXTRA_LINUX_MODE = "linux_mode";
private static final String KGSL_DEVICE = "/dev/kgsl-3d0";
/** Where every Linux session's debug log lands: public, so a user can just hand the folder over. */
public static final String DEBUG_LOG_DIR = "SteamDeck";
public static final String DEBUG_LOG_DIR = "DroidDeck";
public static File debugLogDir() {
return new File(android.os.Environment.getExternalStoragePublicDirectory(
@@ -1,11 +1,11 @@
package com.steamdeck.launcher.runtime;
package com.droiddeck.launcher.runtime;
import android.content.Context;
import android.util.Log;
import com.steamdeck.launcher.core.Downloader;
import com.steamdeck.launcher.core.FileUtils;
import com.droiddeck.launcher.core.Downloader;
import com.droiddeck.launcher.core.FileUtils;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
@@ -1,10 +1,10 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.util.Log
import com.steamdeck.launcher.core.SessionPart
import com.droiddeck.launcher.core.SessionPart
import java.io.File
import kotlin.math.abs
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.content.Context
import android.util.Log
@@ -1,10 +1,10 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.content.Context
import android.os.Environment
import android.os.StatFs
import android.os.storage.StorageManager
import com.steamdeck.launcher.core.FileUtils
import com.droiddeck.launcher.core.FileUtils
import java.io.File
/**
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.content.Context
import android.os.SystemClock
@@ -25,7 +25,7 @@ class LoadingState(context: Context) {
var hint by mutableStateOf("")
var ended by mutableStateOf(false)
private val hints = context.resources.getStringArray(com.steamdeck.launcher.R.array.loading_hints)
private val hints = context.resources.getStringArray(com.droiddeck.launcher.R.array.loading_hints)
private val startedAt = SystemClock.elapsedRealtime()
/** Once a second: the clock and the hint. */
@@ -1,8 +1,8 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.content.Context
import android.util.Log
import com.steamdeck.launcher.runtime.LinuxRuntime
import com.droiddeck.launcher.runtime.LinuxRuntime
import java.io.File
/**
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.util.Log
import java.io.File
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.content.Context
import android.os.Build
@@ -7,7 +7,7 @@ import android.os.Looper
import android.os.PerformanceHintManager
import android.util.Log
import androidx.annotation.RequiresApi
import com.steamdeck.launcher.wayland.WaylandCompositor
import com.droiddeck.launcher.wayland.WaylandCompositor
import java.util.concurrent.Executors
/**
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.content.Context
import android.os.Environment
@@ -8,8 +8,8 @@ import android.os.SystemClock
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import com.steamdeck.launcher.gpu.FrameGen
import com.steamdeck.launcher.wayland.WaylandCompositor
import com.droiddeck.launcher.gpu.FrameGen
import com.droiddeck.launcher.wayland.WaylandCompositor
import java.io.File
import java.util.Locale
import java.util.concurrent.atomic.AtomicInteger
@@ -36,7 +36,7 @@ class PerfHud(context: Context) {
/** The session's own switch (drawer), with the Downloads file as a device-side override. */
private val enabled: Boolean
get() = SessionPrefs.hudEnabled(context)
&& !File(Environment.getExternalStorageDirectory(), "Download/steamdeck-no-hud").exists()
&& !File(Environment.getExternalStorageDirectory(), "Download/droiddeck-no-hud").exists()
/** Told, on the main thread, when the window presenting frames changes. */
var onPresentingWindowChanged: (() -> Unit)? = null
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.app.Activity
import android.app.GameManager
@@ -1,11 +1,11 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.content.Context
import android.os.StatFs
import android.util.Log
import com.steamdeck.launcher.core.Downloader
import com.steamdeck.launcher.core.FileUtils
import com.steamdeck.launcher.runtime.LinuxRuntime
import com.droiddeck.launcher.core.Downloader
import com.droiddeck.launcher.core.FileUtils
import com.droiddeck.launcher.runtime.LinuxRuntime
import java.io.File
import java.security.MessageDigest
import org.json.JSONArray
@@ -114,7 +114,7 @@ object ProtonExtras {
return try {
val root = LinuxRuntime.rootDir(context)
LinuxRuntime.writeAccounts(context)
com.steamdeck.launcher.session.SessionFiles.stage(context, root)
com.droiddeck.launcher.session.SessionFiles.stage(context, root)
val runtimeDir = File(context.filesDir, ".proton-install-rt").apply { mkdirs() }
val guest = listOf(
"/usr/bin/env", "-i", "HOME=/root", "USER=root", "PATH=/usr/local/bin:/usr/bin:/bin",
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.app.ActivityManager
import android.content.Context
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.net.LocalServerSocket
import android.os.Build
@@ -6,7 +6,7 @@ import android.os.VibrationEffect
import android.os.Vibrator
import android.os.VibratorManager
import android.util.Log
import com.steamdeck.launcher.core.SessionPart
import com.droiddeck.launcher.core.SessionPart
import java.io.DataInputStream
import kotlin.math.max
@@ -70,6 +70,6 @@ class RumbleComponent : SessionPart() {
companion object {
private const val TAG = "SessionService"
/** Must match the fake evdev layer (fakeinput_steam.cpp). */
const val NAME = "steamdeck-rumble"
const val NAME = "droiddeck-rumble"
}
}
@@ -1,11 +1,11 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.content.Context
import android.util.Log
import com.steamdeck.launcher.core.LogRedactor
import com.steamdeck.launcher.core.SessionLogCapture
import com.steamdeck.launcher.runtime.LinuxRuntime
import com.steamdeck.launcher.wayland.WaylandCompositor
import com.droiddeck.launcher.core.LogRedactor
import com.droiddeck.launcher.core.SessionLogCapture
import com.droiddeck.launcher.runtime.LinuxRuntime
import com.droiddeck.launcher.wayland.WaylandCompositor
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
@@ -1,16 +1,16 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.content.Context
import android.os.Environment
import android.util.Log
import com.steamdeck.launcher.core.FileUtils
import com.steamdeck.launcher.runtime.LinuxRuntime
import com.droiddeck.launcher.core.FileUtils
import com.droiddeck.launcher.runtime.LinuxRuntime
import java.io.File
/** Everything the session needs written into the runtime before it starts. */
object SessionFiles {
private const val TAG = "SessionFiles"
private const val NO_PAD_SWITCH = "Download/steamdeck-no-pad"
private const val NO_PAD_SWITCH = "Download/droiddeck-no-pad"
/** Where the DirectAudio driver lives inside the runtime; the wrappers get it as BL_DIRECTAUDIO. */
const val DIRECTAUDIO_DIR = "usr/local/lib/directaudio"
@@ -55,11 +55,11 @@ object SessionFiles {
// The desktop's launcher and labwc defaults, only where the desktop package is installed:
// staging them into a runtime without it would make the desktop look present when it is not.
val desktop = arrayOf(
"usr/local/bin/steamdeck-desktop" to "usr/local/bin/steamdeck-desktop",
"usr/local/bin/droiddeck-desktop" to "usr/local/bin/droiddeck-desktop",
"etc/xdg/labwc/autostart" to "etc/xdg/labwc/autostart",
"etc/xdg/labwc/rc.xml" to "etc/xdg/labwc/rc.xml",
"etc/xdg/lxqt/panel.conf" to "etc/xdg/lxqt/panel.conf",
"usr/lib/firefox/defaults/pref/steamdeck.js" to "usr/lib/firefox/defaults/pref/steamdeck.js",
"usr/lib/firefox/defaults/pref/droiddeck.js" to "usr/lib/firefox/defaults/pref/droiddeck.js",
)
// The patched gamescope (tools/gamescope): the runtime's own version rebuilt with the ARM64
// client fixes, over /usr/local/bin so it comes first in the session's PATH. Only when the
@@ -1,10 +1,10 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.content.ClipData
import android.content.Context
import android.content.Intent
import androidx.core.content.FileProvider
import com.steamdeck.launcher.runtime.LinuxRuntime
import com.droiddeck.launcher.runtime.LinuxRuntime
import java.io.File
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
@@ -25,7 +25,7 @@ object SessionLogShare {
fun zipLatest(context: Context): File? {
val folder = latest(context) ?: return null
val out = File(context.cacheDir, "shared-logs").apply { deleteRecursively(); mkdirs() }
val zip = File(out, "SteamDeck-${folder.name}.zip")
val zip = File(out, "DroidDeck-${folder.name}.zip")
ZipOutputStream(zip.outputStream().buffered()).use { z ->
folder.walkTopDown().filter { it.isFile }.forEach { f ->
z.putNextEntry(ZipEntry(folder.name + "/" + f.relativeTo(folder).path))
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.content.Context
import android.util.Log
@@ -8,10 +8,10 @@ import java.util.Date
import java.util.Locale
/**
* One folder per session under `Download/SteamDeck/`, holding everything that session recorded:
* One folder per session under `Download/DroidDeck/`, holding everything that session recorded:
*
* ```
* Download/SteamDeck/session-20260921-161256/
* Download/DroidDeck/session-20260921-161256/
* device.txt what this device is, and every setting the session ran with
* session.log the guest session: proot, gamescope, the client's stdout
* wayland.log the app's compositor
@@ -74,7 +74,7 @@ object SessionPaths {
if (dir == ended) dir = null
// A folder kept in the cache was never meant to outlive its session.
if (ended != null && ended.path.startsWith(context.cacheDir.path)) {
com.steamdeck.launcher.core.FileUtils.delete(ended)
com.droiddeck.launcher.core.FileUtils.delete(ended)
}
}
}
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.content.Context
@@ -220,7 +220,7 @@ object SessionPrefs {
}
/**
* Whether a session writes its folder under Download/SteamDeck. Off, the same logs are kept in
* Whether a session writes its folder under Download/DroidDeck. Off, the same logs are kept in
* the app's cache for the session's lifetime (the scripts need somewhere to write) and thrown
* away at the end, so nothing accumulates in Downloads.
*/
@@ -332,7 +332,7 @@ object SessionPrefs {
/**
* What the desktop shell composites with: pixman (software, the default - the Adreno stand-in
* is not a DRM render node, so labwc's gbm allocator cannot use it), or gles2 / vulkan for a
* device that has a real node. `Download/steamdeck-wlr-renderer` still overrides it.
* device that has a real node. `Download/droiddeck-wlr-renderer` still overrides it.
*/
fun desktopRenderer(context: Context): String = prefs(context).getString("desktopRenderer", "pixman") ?: "pixman"
@@ -1,7 +1,7 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import com.steamdeck.launcher.gpu.LinuxVulkanDriver
import com.steamdeck.launcher.gpu.LinuxVulkanDriverManager
import com.droiddeck.launcher.gpu.LinuxVulkanDriver
import com.droiddeck.launcher.gpu.LinuxVulkanDriverManager
import android.app.Notification
import android.app.NotificationChannel
@@ -21,21 +21,21 @@ import android.os.Handler
import android.os.Looper
import android.os.PowerManager
import android.util.Log
import com.steamdeck.launcher.R
import com.steamdeck.launcher.SessionActivity
import com.steamdeck.launcher.audio.DirectAudioRelayComponent
import com.steamdeck.launcher.audio.PulseAudioComponent
import com.steamdeck.launcher.core.CpuCores
import com.steamdeck.launcher.core.DeviceReport
import com.steamdeck.launcher.core.HostEnvironment
import com.steamdeck.launcher.core.SessionLogCapture
import com.steamdeck.launcher.core.NetworkReport
import com.steamdeck.launcher.core.SessionPart
import com.steamdeck.launcher.core.FileUtils
import com.steamdeck.launcher.core.HostProcess
import com.steamdeck.launcher.input.FakeInputWriter
import com.steamdeck.launcher.runtime.LinuxNetworkLinkComponent
import com.steamdeck.launcher.runtime.LinuxRuntime
import com.droiddeck.launcher.R
import com.droiddeck.launcher.SessionActivity
import com.droiddeck.launcher.audio.DirectAudioRelayComponent
import com.droiddeck.launcher.audio.PulseAudioComponent
import com.droiddeck.launcher.core.CpuCores
import com.droiddeck.launcher.core.DeviceReport
import com.droiddeck.launcher.core.HostEnvironment
import com.droiddeck.launcher.core.SessionLogCapture
import com.droiddeck.launcher.core.NetworkReport
import com.droiddeck.launcher.core.SessionPart
import com.droiddeck.launcher.core.FileUtils
import com.droiddeck.launcher.core.HostProcess
import com.droiddeck.launcher.input.FakeInputWriter
import com.droiddeck.launcher.runtime.LinuxNetworkLinkComponent
import com.droiddeck.launcher.runtime.LinuxRuntime
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
@@ -53,7 +53,7 @@ import java.util.Locale
* backgrounded download does not throttle to nothing. All three are Bannerlator's recipe, where
* each was added to fix a failure seen on a device.
*
* The activity comes and goes on top of this; see [com.steamdeck.launcher.wayland.CompositorHost].
* The activity comes and goes on top of this; see [com.droiddeck.launcher.wayland.CompositorHost].
*/
class SessionService : Service() {
private val components = java.util.concurrent.CopyOnWriteArrayList<SessionPart>()
@@ -308,11 +308,11 @@ class SessionService : Service() {
// default preset sets nothing, which is what every session ran on before.
if (SessionState.mode == MODE_STEAM) {
val preset = SessionPrefs.fexPreset(this)
val vars = com.steamdeck.launcher.core.FexPreset.env(preset)
val vars = com.droiddeck.launcher.core.FexPreset.env(preset)
vars.forEach { guest.add(it) }
if (vars.isNotEmpty()) Log.i(TAG, "fex preset $preset: ${vars.joinToString(" ")}")
}
// Anything else, for a device that cannot be reached with a debugger: Downloads/steamdeck-env
// Anything else, for a device that cannot be reached with a debugger: Downloads/droiddeck-env
// holds KEY=VALUE lines that go into the session's environment as written, after ours, so a
// line here wins. Zink and Turnip tunables (ZINK_DESCRIPTORS=lazy, MESA_*), gamescope's,
// the client's - whatever the experiment needs, without a build per attempt.
@@ -411,18 +411,18 @@ class SessionService : Service() {
// DRM render node. Ours is a KGSL stand-in that gbm cannot use - labwc dies at "unable to
// create allocator" - so the desktop shell is composited by pixman (software, a shm
// allocator, no DRM). Accelerated clients on it pay a CPU copy; a 2D emulator does not
// notice, a demanding one does. steamdeck-wlr-renderer in Downloads (pixman/vulkan/gles2)
// notice, a demanding one does. droiddeck-wlr-renderer in Downloads (pixman/vulkan/gles2)
// overrides it, for trying acceleration on a device that has a real node.
if (SessionState.mode == MODE_DESKTOP) {
val override = File(Environment.getExternalStorageDirectory(), "Download/steamdeck-wlr-renderer")
val override = File(Environment.getExternalStorageDirectory(), "Download/droiddeck-wlr-renderer")
.takeIf { it.isFile }?.let { FileUtils.readString(it)?.trim() }
guest.add("BL_WLR_RENDERER=" + (override?.takeIf { it.isNotEmpty() } ?: SessionPrefs.desktopRenderer(this)))
}
// The user's own games, for the runtime's shortcuts writer to put in the client's library
// before the client starts (see frontend/AddedGames and bannerlator-steam-shortcuts).
if (SessionState.mode == MODE_STEAM) {
val added = com.steamdeck.launcher.frontend.AddedGames.scan(this)
val listing = com.steamdeck.launcher.frontend.AddedGames.writeListing(this, added)
val added = com.droiddeck.launcher.frontend.AddedGames.scan(this)
val listing = com.droiddeck.launcher.frontend.AddedGames.writeListing(this, added)
guest.add("BL_ADDED_GAMES=" + listing.path)
if (added.isNotEmpty()) Log.i(TAG, "added games: " + added.joinToString { "${it.name} (${it.exe.name})" })
}
@@ -505,7 +505,7 @@ class SessionService : Service() {
}
// The user's own games folder (the Steam cog's "Added games"), bound at a fixed place so
// the shortcuts the app writes point somewhere whatever storage the folder is on.
for (root in com.steamdeck.launcher.frontend.AddedGames.roots(this)) {
for (root in com.droiddeck.launcher.frontend.AddedGames.roots(this)) {
if (root.host.isDirectory && root.host.canRead()) {
File(LinuxRuntime.rootDir(this), root.guest.removePrefix("/")).mkdirs()
binds.add(root.host.path + ":" + root.guest)
@@ -707,7 +707,7 @@ class SessionService : Service() {
}
}
Log.i(TAG, "launch request from the session: Steam $ui" + (if (url.isNotEmpty()) " $url" else ""))
val next = Intent(this@SessionService, com.steamdeck.launcher.SessionActivity::class.java)
val next = Intent(this@SessionService, com.droiddeck.launcher.SessionActivity::class.java)
.putExtra(EXTRA_MODE, MODE_STEAM)
.putExtra(EXTRA_STEAM_UI, ui)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
@@ -857,7 +857,7 @@ class SessionService : Service() {
try {
if (wakeLock?.isHeld != true) {
val power = getSystemService(Context.POWER_SERVICE) as? PowerManager
wakeLock = power?.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SteamDeck:session")?.apply {
wakeLock = power?.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DroidDeck:session")?.apply {
setReferenceCounted(false)
acquire(12L * 60L * 60L * 1000L)
}
@@ -870,7 +870,7 @@ class SessionService : Service() {
val wifi = applicationContext.getSystemService(Context.WIFI_SERVICE) as? WifiManager
@Suppress("DEPRECATION") // deprecated from API 29, still honoured; targetSdk is 28
if (wifiLock?.isHeld != true) {
wifiLock = wifi?.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "SteamDeck:session-wifi")
wifiLock = wifi?.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "DroidDeck:session-wifi")
?.apply {
setReferenceCounted(false)
acquire()
@@ -954,27 +954,27 @@ class SessionService : Service() {
companion object {
private const val TAG = "SessionService"
/** Downloads file whose contents become TU_DEBUG inside the session, e.g. "sysmem". */
private const val TU_DEBUG_SWITCH = "Download/steamdeck-tu-debug"
private const val TU_DEBUG_SWITCH = "Download/droiddeck-tu-debug"
/** Downloads file of KEY=VALUE lines added to the session environment verbatim. */
private const val ENV_SWITCH = "Download/steamdeck-env"
private const val ENV_SWITCH = "Download/droiddeck-env"
private const val CHANNEL_ID = "session"
private const val NOTIFICATION_ID = 1001
const val ACTION_STOP = "com.steamdeck.launcher.STOP_SESSION"
const val ACTION_RESUME = "com.steamdeck.launcher.RESUME_SESSION"
const val ACTION_HOME_GUIDE = "com.steamdeck.launcher.HOME_GUIDE"
private const val ACTION_ACTIVITY_VISIBLE = "com.steamdeck.launcher.ACTIVITY_VISIBLE"
private const val ACTION_ACTIVITY_HIDDEN = "com.steamdeck.launcher.ACTIVITY_HIDDEN"
private const val ACTION_TRACK_AUXILIARY = "com.steamdeck.launcher.TRACK_AUXILIARY"
private const val ACTION_STOP_AUXILIARY = "com.steamdeck.launcher.STOP_AUXILIARY"
private const val ACTION_AUXILIARY_EXITED = "com.steamdeck.launcher.AUXILIARY_EXITED"
const val ACTION_STOP = "com.droiddeck.launcher.STOP_SESSION"
const val ACTION_RESUME = "com.droiddeck.launcher.RESUME_SESSION"
const val ACTION_HOME_GUIDE = "com.droiddeck.launcher.HOME_GUIDE"
private const val ACTION_ACTIVITY_VISIBLE = "com.droiddeck.launcher.ACTIVITY_VISIBLE"
private const val ACTION_ACTIVITY_HIDDEN = "com.droiddeck.launcher.ACTIVITY_HIDDEN"
private const val ACTION_TRACK_AUXILIARY = "com.droiddeck.launcher.TRACK_AUXILIARY"
private const val ACTION_STOP_AUXILIARY = "com.droiddeck.launcher.STOP_AUXILIARY"
private const val ACTION_AUXILIARY_EXITED = "com.droiddeck.launcher.AUXILIARY_EXITED"
private const val EXTRA_AUXILIARY_PID = "auxiliaryPid"
/** Command lines that can only belong to a session of ours. */
private val STRAGGLERS = listOf("bannerlator-session", "gamescope", "Xwayland", "steamrtarm64",
"steamwebhelper", "linuxfs/opt/android-host/proot", "pulseaudio/libpulseaudio.so")
/** How long proot gets to run its own cleanup before it is killed outright. */
private const val GRACE_MS = 1200L
private const val NO_PAD_SWITCH = "Download/steamdeck-no-pad"
private const val PAD_LOG_SWITCH = "Download/steamdeck-pad-log"
private const val NO_PAD_SWITCH = "Download/droiddeck-no-pad"
private const val PAD_LOG_SWITCH = "Download/droiddeck-pad-log"
const val EXTRA_MODE = "mode"
const val MODE_STEAM = "steam"
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import java.io.File
import androidx.compose.runtime.getValue
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import android.os.Process
import java.io.File
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.session
package com.droiddeck.launcher.session
import com.termux.terminal.TerminalSession
import com.termux.terminal.TerminalSessionClient
@@ -30,7 +30,7 @@ object SessionTerminal {
return TerminalSession(
current.command.first(), current.workingDirectory, current.command,
current.hostEnvironment, 3000, client,
).also { it.mSessionName = "SteamDeck Linux shell" }
).also { it.mSessionName = "DroidDeck Linux shell" }
}
fun clear(generation: Int? = null) {
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.ui
package com.droiddeck.launcher.ui
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.fillMaxSize
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.ui
package com.droiddeck.launcher.ui
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.ui
package com.droiddeck.launcher.ui
import android.graphics.Bitmap
import android.os.Build
@@ -105,9 +105,9 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.zIndex
import coil.compose.AsyncImage
import com.steamdeck.launcher.R
import com.steamdeck.launcher.frontend.Library
import com.steamdeck.launcher.gpu.FrameGen
import com.droiddeck.launcher.R
import com.droiddeck.launcher.frontend.Library
import com.droiddeck.launcher.gpu.FrameGen
import java.io.File
import kotlin.math.roundToInt
@@ -134,7 +134,7 @@ class FrontEndState(
val theme: String = Themes.PAPER,
val isHomeApp: Boolean = false,
val defaultHomeLabel: String? = null,
val androidApps: List<com.steamdeck.launcher.HomeApp.LaunchableApp> = emptyList(),
val androidApps: List<com.droiddeck.launcher.HomeApp.LaunchableApp> = emptyList(),
val packages: List<PackageRow>? = null,
val packageCatalogLoading: Boolean = false,
val packageBusyId: String? = null,
@@ -168,7 +168,7 @@ class FrontEndActions(
val onPageBack: () -> Unit = {},
val onTheme: (String) -> Unit = {},
val onHomeApp: () -> Unit = {},
val onAndroidApp: (com.steamdeck.launcher.HomeApp.LaunchableApp) -> Unit = {},
val onAndroidApp: (com.droiddeck.launcher.HomeApp.LaunchableApp) -> Unit = {},
)
@@ -278,7 +278,7 @@ private fun Rail(
Image(painterResource(R.drawable.logo), null, modifier = Modifier.size(30.dp))
Spacer(Modifier.width(10.dp))
Column {
Text("SteamDeck", fontSize = 18.sp, fontWeight = FontWeight.Bold, color = colors.onBackground)
Text("DroidDeck", fontSize = 18.sp, fontWeight = FontWeight.Bold, color = colors.onBackground)
val status = when {
s.busy -> if (s.percent >= 0) "${s.stage} ${s.percent}%" else s.stage
!s.ready -> "runtime not installed"
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.ui
package com.droiddeck.launcher.ui
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.ui
package com.droiddeck.launcher.ui
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.padding
@@ -14,9 +14,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.steamdeck.launcher.core.FexPreset
import com.steamdeck.launcher.session.SessionPrefs
import com.steamdeck.launcher.session.SessionService
import com.droiddeck.launcher.core.FexPreset
import com.droiddeck.launcher.session.SessionPrefs
import com.droiddeck.launcher.session.SessionService
/** [tag] is shown beside the name: [BUNDLED], [DOWNLOADED], [IMPORTED], or "" for Auto / Runtime default. */
class DriverRow(val id: String, val name: String, val detail: String, val removable: Boolean, val tag: String = "") {
@@ -179,7 +179,7 @@ fun ModeSettingsPage(s: ModeSettings, a: ModeSettingsActions) {
ChoiceRow(
host, "shape", "Shape",
if (custom != null) "Set by the custom resolution." else "The panel's shape stays at 16:9 or wider; pick Exactly this panel for a 4:3 or 3:2 screen.",
com.steamdeck.launcher.session.SessionPrefs.shapeChoices, s.shapeMode, enabled = custom == null, onPick = a.onShape,
com.droiddeck.launcher.session.SessionPrefs.shapeChoices, s.shapeMode, enabled = custom == null, onPick = a.onShape,
)
if (editCustom) CustomResolutionDialog(
initial = custom,
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.ui
package com.droiddeck.launcher.ui
/** Package metadata shown on an emulator's own detail page. */
class PackageRow(
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.ui
package com.droiddeck.launcher.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.border
@@ -89,7 +89,7 @@ fun PerformancePage(
)
ToggleRow(
host, "deck", "Steam Deck mode",
"Runs the client with -steamdeck. SteamOS helpers and battery info are provided.",
"Runs the client with -droiddeck. SteamOS helpers and battery info are provided.",
steamDeckMode, onChange = onSteamDeckMode,
)
}
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.ui
package com.droiddeck.launcher.ui
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.ui
package com.droiddeck.launcher.ui
import androidx.compose.foundation.layout.Column
import androidx.compose.ui.Modifier
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.ui
package com.droiddeck.launcher.ui
import android.app.Presentation
import android.content.ClipboardManager
@@ -21,14 +21,14 @@ import android.widget.FrameLayout
import android.widget.HorizontalScrollView
import android.widget.LinearLayout
import android.widget.TextView
import com.steamdeck.launcher.input.KeyboardHost
import com.steamdeck.launcher.input.PointerGestures
import com.steamdeck.launcher.input.SecondScreenMode
import com.steamdeck.launcher.input.TouchpadGestures
import com.steamdeck.launcher.SessionActivity
import com.steamdeck.launcher.session.SessionService
import com.steamdeck.launcher.session.SessionState
import com.steamdeck.launcher.session.SessionTerminal
import com.droiddeck.launcher.input.KeyboardHost
import com.droiddeck.launcher.input.PointerGestures
import com.droiddeck.launcher.input.SecondScreenMode
import com.droiddeck.launcher.input.TouchpadGestures
import com.droiddeck.launcher.SessionActivity
import com.droiddeck.launcher.session.SessionService
import com.droiddeck.launcher.session.SessionState
import com.droiddeck.launcher.session.SessionTerminal
import com.termux.terminal.TerminalEmulator
import com.termux.terminal.TerminalSession
import com.termux.terminal.TerminalSessionClient
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.ui
package com.droiddeck.launcher.ui
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -35,8 +35,8 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.steamdeck.launcher.R
import com.steamdeck.launcher.HomeApp
import com.droiddeck.launcher.R
import com.droiddeck.launcher.HomeApp
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.Spring
@@ -64,11 +64,11 @@ import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
import com.steamdeck.launcher.core.FexPreset
import com.steamdeck.launcher.gpu.FrameGen
import com.steamdeck.launcher.session.SessionPrefs
import com.steamdeck.launcher.input.SecondScreenDisplay
import com.steamdeck.launcher.input.SecondScreenMode
import com.droiddeck.launcher.core.FexPreset
import com.droiddeck.launcher.gpu.FrameGen
import com.droiddeck.launcher.session.SessionPrefs
import com.droiddeck.launcher.input.SecondScreenDisplay
import com.droiddeck.launcher.input.SecondScreenMode
import kotlinx.coroutines.flow.collect
@Composable
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.ui
package com.droiddeck.launcher.ui
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.ui
package com.droiddeck.launcher.ui
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
@@ -7,7 +7,7 @@ import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import com.steamdeck.launcher.session.SessionPrefs
import com.droiddeck.launcher.session.SessionPrefs
class Palette(
val id: String, val label: String, val detail: String,
@@ -52,7 +52,7 @@ object Themes {
val LocalPalette = staticCompositionLocalOf { Themes.byId(Themes.PAPER) }
@Composable
fun SteamDeckTheme(theme: String? = null, content: @Composable () -> Unit) {
fun DroidDeckTheme(theme: String? = null, content: @Composable () -> Unit) {
val id = theme ?: SessionPrefs.theme(LocalContext.current)
val p = Themes.byId(id)
val scheme = darkColorScheme(
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.wayland
package com.droiddeck.launcher.wayland
import android.view.Choreographer
import android.view.Surface
@@ -1,4 +1,4 @@
package com.steamdeck.launcher.wayland
package com.droiddeck.launcher.wayland
import android.content.Context
import android.os.Build
Loaded 100 of 118 files, more files were not shown because too many files have changed in this diff. Show more