Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/overlays.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Overlay APKs

on:
push:
paths:
- "overlays/**"
- ".github/workflows/overlays.yml"
pull_request:
paths:
- "overlays/**"
- ".github/workflows/overlays.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"

- name: Build overlays
run: ./overlays/build.sh

- uses: actions/upload-artifact@v4
with:
name: overlay-apks
path: overlays/dist/*.apk
if-no-files-found: error

# Pushes (not PRs) refresh a prerelease so the APKs can be downloaded on a
# phone without signing in to GitHub.
publish:
if: github.event_name != 'pull_request'
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
with:
name: overlay-apks
path: dist
- uses: softprops/action-gh-release@v2
with:
tag_name: overlay-test
target_commitish: ${{ github.sha }}
name: Overlay test builds
prerelease: true
body: |
Test overlay APKs for One UI 9, built from ${{ github.sha }}.
Install and verify steps: overlays/README.md.
files: dist/*.apk
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ daemon.log
# Native Android app: keep the Gradle wrapper and the shared debug signing key.
!android/gradle/wrapper/gradle-wrapper.jar
!android/app/debug.keystore
overlays/dist/
60 changes: 60 additions & 0 deletions overlays/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Overlay APKs

Prebuilt Runtime Resource Overlays for phones without root. Each folder here
(`test-accent/`, ...) is one overlay; `build.sh` turns every folder into a
signed APK in `overlays/dist/`, and the **Overlay APKs** workflow publishes them
to the [`overlay-test`](https://github.com/Bingblop/oneui-theme-engine/releases/tag/overlay-test)
prerelease.

## test-accent

Targets the framework (`android`) and paints the primary Monet ramp
(`system_accent1_0` ... `system_accent1_1000`) plus the Android 14 primary role
colors bright magenta. It answers one question: can a user-installed overlay
change framework colors on One UI 9, or does the overlayable policy skip them?

### Run it

Every command below works from a PC as `adb shell <command>`, or on the phone
inside a Shizuku shell (`rish`). Download `oneuitheme-test-accent.apk` from the
prerelease to `Download/` first.

1. Record the current value:

cmd overlay lookup --user current android android:color/system_accent1_600

2. Install:

pm install -r /sdcard/Download/oneuitheme-test-accent.apk

(From a PC, `adb install -r oneuitheme-test-accent.apk` does the same.)

3. See whether Android accepted it for the framework:

cmd overlay list android | grep oneuitheme

`[ ]` means installed and allowed but not enabled yet. `---` means Android
refused it (the overlayable policy check failed); stop and report that.

4. Enable it and put it above Samsung's own palette overlays:

cmd overlay enable --user current com.oneuitheme.test.accent
cmd overlay set-priority com.oneuitheme.test.accent highest

5. Check the value again; a working overlay returns `#ffb800ad`:

cmd overlay lookup --user current android android:color/system_accent1_600
cmd overlay dump com.oneuitheme.test.accent | head -20

6. Look at the screen: force-stop Settings (`am force-stop com.android.settings`)
and reopen it. Switches and highlights turning magenta means it works.

### Undo

cmd overlay disable --user current com.oneuitheme.test.accent
pm uninstall com.oneuitheme.test.accent

### What to report

The line from step 3, both lookups (steps 1 and 5), the `dump` output, and
whether anything on screen turned magenta.
40 changes: 40 additions & 0 deletions overlays/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
# Builds every overlay under overlays/<name>/ into a signed APK in overlays/dist/.
# Needs an Android SDK (ANDROID_HOME) with build-tools and a platform installed.
set -euo pipefail

root="$(cd "$(dirname "$0")" && pwd)"
sdk="${ANDROID_HOME:-${ANDROID_SDK_ROOT:-}}"
[ -n "$sdk" ] || { echo "ANDROID_HOME is not set" >&2; exit 1; }

bt="$sdk/build-tools/$(ls "$sdk/build-tools" | sort -V | tail -1)"
platform="$(ls -d "$sdk"/platforms/android-* | sort -V | tail -1)"
android_jar="$platform/android.jar"
keystore="$root/../android/app/debug.keystore"
echo "build-tools: $bt"
echo "platform: $platform"

dist="$root/dist"
rm -rf "$dist" && mkdir -p "$dist"

for dir in "$root"/*/; do
name="$(basename "$dir")"
[ -f "$dir/AndroidManifest.xml" ] || continue
work="$(mktemp -d)"
echo "== $name"

"$bt/aapt2" compile --dir "$dir/res" -o "$work/res.zip"
"$bt/aapt2" link -I "$android_jar" \
--manifest "$dir/AndroidManifest.xml" \
-o "$work/unsigned.apk" "$work/res.zip"
"$bt/zipalign" -p -f 4 "$work/unsigned.apk" "$work/aligned.apk"
"$bt/apksigner" sign --ks "$keystore" --ks-pass pass:android \
--ks-key-alias androiddebugkey --key-pass pass:android \
--out "$dist/oneuitheme-$name.apk" "$work/aligned.apk"
"$bt/apksigner" verify "$dist/oneuitheme-$name.apk"

"$bt/aapt2" dump badging "$dist/oneuitheme-$name.apk" | head -3
"$bt/aapt2" dump resources "$dist/oneuitheme-$name.apk" | grep -c "color/" \
| xargs echo "colors:"
rm -rf "$work"
done
21 changes: 21 additions & 0 deletions overlays/test-accent/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Test overlay: paints the framework's primary Monet ramp (system_accent1_*)
bright magenta so it is obvious on screen whether a non-root overlay
APK can reach framework colors on One UI 9.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.oneuitheme.test.accent"
android:versionCode="1"
android:versionName="0.1-test">

<uses-sdk android:minSdkVersion="31" android:targetSdkVersion="35" />

<overlay
android:targetPackage="android"
android:isStatic="false" />

<application
android:hasCode="false"
android:label="One UI Theme test: accent" />
</manifest>
23 changes: 23 additions & 0 deletions overlays/test-accent/res/values/colors.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Monet primary ramp (public since Android 12), replaced with magenta. -->
<color name="system_accent1_0">#FFFFFFFF</color>
<color name="system_accent1_10">#FFFFFBFF</color>
<color name="system_accent1_50">#FFFFEBF8</color>
<color name="system_accent1_100">#FFFFD7F3</color>
<color name="system_accent1_200">#FFFFAAEE</color>
<color name="system_accent1_300">#FFFF77E8</color>
<color name="system_accent1_400">#FFFF3DE3</color>
<color name="system_accent1_500">#FFE600D8</color>
<color name="system_accent1_600">#FFB800AD</color>
<color name="system_accent1_700">#FF8C0084</color>
<color name="system_accent1_800">#FF62005C</color>
<color name="system_accent1_900">#FF3B0037</color>
<color name="system_accent1_1000">#FF000000</color>

<!-- Material 3 role colors (public since Android 14). -->
<color name="system_primary_light">#FFB800AD</color>
<color name="system_primary_dark">#FFFFAAEE</color>
<color name="system_primary_container_light">#FFFFD7F3</color>
<color name="system_primary_container_dark">#FF8C0084</color>
</resources>
Loading