[package]
name    = "solitaire_app"
version.workspace = true
license.workspace = true
edition.workspace = true

[[bin]]
name = "solitaire_app"
path = "src/main.rs"

# `cdylib` is what cargo-apk packages into `libsolitaire_app.so` for
# Android — the activity dlopens the shared object and calls into it.
# `rlib` lets the bin target above link the library normally on
# desktop. Both produce the same code; only the linkage form differs.
[lib]
name = "solitaire_app"
path = "src/lib.rs"
crate-type = ["cdylib", "rlib"]

[dependencies]
bevy             = { workspace = true }
solitaire_engine = { workspace = true }
solitaire_data   = { workspace = true }

# Android-only: the entry point reconstructs the raw `JavaVM` / activity
# handles and registers the safe `solitaire_data::android_jni` bridge. This
# is the one crate in the workspace that performs `unsafe` FFI, so it is also
# the only one that depends on `jni` directly at the app layer.
[target.'cfg(target_os = "android")'.dependencies]
jni = { workspace = true }

# Desktop-only deps. `keyring`'s default-store init only matters on
# platforms with a real keychain backend (Linux Secret Service,
# macOS Keychain, Windows Credential Store), and its transitive
# `rpassword` uses `libc::__errno_location` — a symbol Android's
# bionic doesn't expose. `winit` is promoted from a transitive
# Bevy 0.18 → bevy_winit 0.18 → winit 0.30 dep to a direct dep so
# the `Window::icon` wiring in `set_window_icon` can construct
# `winit::window::Icon` values (bevy_winit 0.18 doesn't re-export
# `Icon`). Android draws its launcher icon from the APK manifest,
# so neither dep matters there. Target-gating keeps `cargo apk
# build` viable; the desktop call sites have their own
# `cfg(not(target_os = "android"))` guards.
[target.'cfg(not(target_os = "android"))'.dependencies]
keyring   = { workspace = true }
winit     = { version = "0.30", default-features = false }
# `tiny-skia` is already in the workspace deps for `solitaire_engine`;
# `solitaire_app` consumes it directly only on the desktop icon path
# (PNG → raw RGBA decode for `set_window_icon`).
tiny-skia = { workspace = true }

# --- Android packaging metadata (read by `cargo-apk`) -------------------
#
# Pinning these values inside the repo means a contributor running
# `cargo apk build -p solitaire_app --target x86_64-linux-android`
# does not need to install whatever SDK version cargo-apk happens to
# default to today. The numbers track the SDK we install in the dev
# setup script: target SDK 34 (Android 14, current Play Store target),
# min SDK 26 (Android 8, the lowest Bevy 0.18 supports cleanly with
# the wgpu / GLES path).
#
# Asset path is `../assets` so the same directory the desktop build
# already uses ships into the APK without copy-tree gymnastics.
# `apk_name` keeps the output filename predictable across machines.
[package.metadata.android]
package = "com.ferrousapp.solitaire"
apk_name = "ferrous-solitaire"
build_targets = ["aarch64-linux-android", "armv7-linux-androideabi", "x86_64-linux-android"]
assets = "../assets"
# Density-bucketed launcher icons. `aapt` processes `res/mipmap-*/` and
# packages them into the APK; the launcher selects the best-fit bucket
# for the device screen density. Sizes used:
#   mdpi  (1×, 48 dp) → 48 px   (exact)
#   hdpi  (1.5×, 72 dp) → 64 px (88 %, aapt scales up slightly)
#   xhdpi (2×, 96 dp) → 128 px  (133 %, aapt scales down)
#   xxhdpi (3×, 144 dp) → 256 px (178 %, aapt scales down)
#   xxxhdpi (4×, 192 dp) → 256 px (133 %, aapt scales down)
resources = "res"
# No `runtime_libs` — we don't ship any precompiled .so files,
# the entire app is pure Rust + Bevy. cargo-apk would try to
# resolve `runtime_libs/<arch>/` if set, and fail on a non-existent
# arch directory under our package.
strip = "strip"

[package.metadata.android.sdk]
target_sdk_version = 34
min_sdk_version = 26

[[package.metadata.android.uses_feature]]
name = "android.hardware.touchscreen"
required = true

[[package.metadata.android.uses_permission]]
name = "android.permission.INTERNET"

[package.metadata.android.application]
label = "Ferrous Solitaire"
# Launcher icon — references the density-bucketed mipmap resource above.
icon = "@mipmap/ic_launcher"
# `debuggable` defaults to false on release builds; cargo-apk flips it
# automatically for debug profiles. Leaving the field unset keeps the
# default behaviour.

[package.metadata.android.application.activity]
# Lock to portrait — the current layout has only been designed and tested
# in portrait orientation. Remove (or add a landscape layout) before
# enabling auto-rotate.
orientation = "portrait"

# `solitaire_app` is the one crate that cannot inherit the workspace
# `forbid(unsafe_code)`: as the Android cdylib it must export the
# `#[unsafe(no_mangle)]` entry point and reconstruct the raw JNI handles
# there (a `no_mangle` symbol cannot live in a dependency rlib). It mirrors
# the workspace lints but at `deny`, so the two `#[allow(unsafe_code)]`
# scopes in the Android entry point are the only unsafe in the whole tree.
[lints.rust]
unsafe_code = "deny"
single_use_lifetimes = "warn"
trivial_casts = "warn"
unused_lifetimes = "warn"
unused_qualifications = "warn"
variant_size_differences = "warn"
unexpected_cfgs = "warn"
