diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 767fde9..c78c419 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -436,6 +436,8 @@ jobs:
run: |
export NDK_HOME="$ANDROID_NDK_LATEST_HOME"
cargo tauri android init --ci
+ # The generated project carries Tauri's launcher icon until `tauri icon` writes the brand's into it.
+ cargo tauri icon ../../assets/brand/tauri-icon.json
cargo tauri android build --apk --debug --target x86_64
# Tauri's own files land in the plugin's copy of the module, never in the crate.
test ! -e ../../android/.tauri
@@ -605,3 +607,21 @@ jobs:
# An unsigned build applies no entitlements, so check the file the signed build applies.
grep -q "com.apple.developer.aps-environment" examples/tauri/entitlements.plist || { echo "no aps-environment in examples/tauri/entitlements.plist"; exit 1; }
fi
+ # The plugin's build script adds the push entitlement and the remote-notification background
+ # mode to the project `tauri ios init` generates, which only an iOS build exercises.
+ - name: Build the Tauri app for iOS, unsigned, and check the handler, the background mode, the entitlement and the icon
+ working-directory: examples/tauri
+ run: |
+ command -v xcodegen > /dev/null || brew install xcodegen
+ cargo tauri ios init --ci
+ cargo tauri icon ../../assets/brand/tauri-icon.json
+ cargo tauri ios build --debug --target aarch64 --no-sign
+ app=$(find gen/apple/build -maxdepth 4 -type d -path "*.xcarchive/Products/Applications/*.app" | head -n1)
+ test -n "$app"
+ binary="$app/$(/usr/libexec/PlistBuddy -c 'Print :CFBundleExecutable' "$app/Info.plist")"
+ nm -gU "$binary" | grep -q ___pushups_background_handler || { echo "no background handler in $binary"; exit 1; }
+ plutil -extract UIBackgroundModes json -o - "$app/Info.plist" | grep -q '"remote-notification"' || { echo "no remote-notification background mode in $app"; exit 1; }
+ plutil -extract CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconName raw -o - "$app/Info.plist" | grep -qx AppIcon || { echo "no app icon in $app"; exit 1; }
+ test -f "$app/Assets.car" || { echo "no compiled asset catalog in $app"; exit 1; }
+ # An unsigned build applies no entitlements, so check the file the signed build applies.
+ grep -A1 aps-environment gen/apple/*_iOS/*_iOS.entitlements | grep -q development || { echo "no aps-environment in the generated entitlements"; exit 1; }
diff --git a/assets/brand/icon-android-foreground.svg b/assets/brand/icon-android-foreground.svg
new file mode 100644
index 0000000..796b38f
--- /dev/null
+++ b/assets/brand/icon-android-foreground.svg
@@ -0,0 +1,13 @@
+
diff --git a/assets/brand/render.sh b/assets/brand/render.sh
index 54ea6a0..76c4c8c 100755
--- a/assets/brand/render.sh
+++ b/assets/brand/render.sh
@@ -29,4 +29,17 @@ done
# iOS reads the home screen icon from this link and rounds its corners itself.
rsvg-convert --width 180 --height 180 "$brand/icon.svg" --output "$public/icons/apple-touch-icon.png"
-oxipng --quiet --opt max --strip safe "$brand"/png/*.png "$public"/icons/*.png
+# The winit example's Android launcher icon, the adaptive foreground at 108dp and the square icon
+# at 48dp that Android 7 shows, per density.
+res=$brand/../../examples/winit/android/app/src/main/res
+for density in mdpi:1 hdpi:1.5 xhdpi:2 xxhdpi:3 xxxhdpi:4; do
+ name=${density%%:*}
+ scale=${density#*:}
+ mkdir -p "$res/mipmap-$name"
+ foreground=$(python3 -c "print(round(108 * $scale))")
+ legacy=$(python3 -c "print(round(48 * $scale))")
+ rsvg-convert --width "$foreground" --height "$foreground" "$brand/icon-android-foreground.svg" --output "$res/mipmap-$name/ic_launcher_foreground.png"
+ rsvg-convert --width "$legacy" --height "$legacy" "$brand/icon.svg" --output "$res/mipmap-$name/ic_launcher.png"
+done
+
+oxipng --quiet --opt max --strip safe "$brand"/png/*.png "$public"/icons/*.png "$res"/mipmap-*/*.png
diff --git a/assets/brand/tauri-icon.json b/assets/brand/tauri-icon.json
new file mode 100644
index 0000000..a956374
--- /dev/null
+++ b/assets/brand/tauri-icon.json
@@ -0,0 +1,5 @@
+{
+ "default": "icon.svg",
+ "bg_color": "#0e1824",
+ "android_fg": "icon-android-foreground.svg"
+}
diff --git a/assets/brand/variants.py b/assets/brand/variants.py
index 6218426..1d432d3 100644
--- a/assets/brand/variants.py
+++ b/assets/brand/variants.py
@@ -39,6 +39,9 @@ def svg(name, width, height, body, view_box=None):
svg("icon-macos.svg", 1024, 1024, f'\n {placed(1024, 0.48)}')
# A maskable web icon, full bleed, with the mark inside the 80% circle Android crops to.
svg("icon-maskable.svg", 1024, 1024, f'\n {placed(1024, 0.56)}')
+# The foreground layer of an Android adaptive icon, transparent on a 108dp canvas, with the mark
+# inside the 66dp circle every launcher mask keeps.
+svg("icon-android-foreground.svg", 1024, 1024, placed(1024, 0.46))
svg("favicon.svg", 64, 64, f'\n {placed(64, 0.78)}')
svg(
"social.svg",
diff --git a/examples/tauri/.gitignore b/examples/tauri/.gitignore
index af8350e..939d8cf 100644
--- a/examples/tauri/.gitignore
+++ b/examples/tauri/.gitignore
@@ -1,4 +1,5 @@
/target
/gen
+/icons
/google-services.json
/embedded.provisionprofile
diff --git a/examples/winit/android/app/src/main/AndroidManifest.xml b/examples/winit/android/app/src/main/AndroidManifest.xml
index 781b4f6..809bc00 100644
--- a/examples/winit/android/app/src/main/AndroidManifest.xml
+++ b/examples/winit/android/app/src/main/AndroidManifest.xml
@@ -1,7 +1,7 @@
-
+
+
+
+
+
diff --git a/examples/winit/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/examples/winit/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..35c2eaf
Binary files /dev/null and b/examples/winit/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/examples/winit/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/examples/winit/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..f924610
Binary files /dev/null and b/examples/winit/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/examples/winit/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/examples/winit/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..cc755a2
Binary files /dev/null and b/examples/winit/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/examples/winit/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/examples/winit/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..1299f9d
Binary files /dev/null and b/examples/winit/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/examples/winit/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/examples/winit/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..26e901e
Binary files /dev/null and b/examples/winit/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/examples/winit/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/examples/winit/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..bf80cf5
Binary files /dev/null and b/examples/winit/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/examples/winit/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/examples/winit/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..906afbe
Binary files /dev/null and b/examples/winit/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/examples/winit/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/examples/winit/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..ec3ebb2
Binary files /dev/null and b/examples/winit/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/examples/winit/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/examples/winit/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..1319106
Binary files /dev/null and b/examples/winit/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/examples/winit/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/examples/winit/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..29e1507
Binary files /dev/null and b/examples/winit/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/examples/winit/android/app/src/main/res/values/ic_launcher_background.xml b/examples/winit/android/app/src/main/res/values/ic_launcher_background.xml
new file mode 100644
index 0000000..963edcd
--- /dev/null
+++ b/examples/winit/android/app/src/main/res/values/ic_launcher_background.xml
@@ -0,0 +1,5 @@
+
+
+
+ #0E1824
+