diff options
Diffstat (limited to 'app')
| -rw-r--r-- | app/build.gradle | 65 | ||||
| -rw-r--r-- | app/lint.xml | 12 | ||||
| -rw-r--r-- | app/src/main/AndroidManifest.xml | 19 | ||||
| -rw-r--r-- | app/src/main/assets/THIRD_PARTY_NOTICES | 16 | ||||
| -rw-r--r-- | app/src/main/assets/scrcpy-server.sha256 | 2 | ||||
| -rw-r--r-- | app/src/main/assets/scrcpy-server.version | 2 |
6 files changed, 72 insertions, 44 deletions
diff --git a/app/build.gradle b/app/build.gradle index 323f340..2c8ec99 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,18 +5,18 @@ plugins { import java.security.MessageDigest android { - namespace 'invalid.lena.scrcpy' - compileSdk 35 + namespace = 'invalid.lena.scrcpy' + compileSdk 36 // Pin build-tools explicitly so the aapt2/zipalign/d8 toolchain is // fixed and builds stay reproducible, not whatever AGP defaults to. - // 35.0.0 is the compileSdk's. + // 35.0.0 is AGP 8.13's supported default. buildToolsVersion '35.0.0' defaultConfig { // The published package id. Immutable across releases. applicationId 'invalid.lena.scrcpy' minSdk 31 - targetSdk 35 + targetSdk 36 versionCode 4 versionName '0.4' } @@ -26,8 +26,8 @@ android { // deterministic. This is the single most common reproducible-build // breaker on AGP. dependenciesInfo { - includeInApk false - includeInBundle false + includeInApk = false + includeInBundle = false } // Release signing pulls credentials from the environment. Set all @@ -49,10 +49,9 @@ android { } } - // Native ABI policy: release ships arm64-v8a only. Every targeted - // source device is 64-bit ARM in practice; 32-bit-only devices are - // not supported. The test rig uses an x86_64 emulator, so debug keeps - // x86_64 (and arm64) so ./test e2e still works. + // Ship one ordinary APK containing both supported 64-bit ABIs. arm64 + // covers physical devices; x86_64 covers emulators and ChromeOS without + // introducing split-APK installation logic. buildTypes { debug { applicationIdSuffix '.debug' @@ -62,15 +61,32 @@ android { } } release { + // x86_64 is here so the emulator can install and RUN the + // minified artifact. Without it no tier ever executed the + // variant that ships, and an R8 misconfiguration - a keep + // rule that is too narrow, a reflective edge R8 could not + // see - would first show up on a user's device. It costs a + // second ABI in the APK and buys coverage of the only build + // that matters. + // + // This is why the APK is ~7.5 MB while the dex shrank: it + // carries two copies of libconscrypt_jni.so and libspake2.so, + // stored uncompressed and 16 KiB aligned for Android 15+ page + // sizes. Uncompressed native libraries inflate the download + // and shrink the installation, because they are mapped from + // the APK instead of being extracted. A single-ABI build is + // about 3.5 MB; splits would give users that without giving + // up the emulator coverage, and are the obvious next step if + // download size starts to matter. ndk { - abiFilters 'arm64-v8a' + abiFilters 'arm64-v8a', 'x86_64' } minifyEnabled true - shrinkResources true + shrinkResources = true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' if (signingReady) { - signingConfig signingConfigs.release + signingConfig = signingConfigs.release } } } @@ -86,20 +102,14 @@ android { // our use case (we only call BC's asn1, crypto, util.encoders): // - picnic post-quantum lookup tables: ~1.2 MB of .properties // - cert-path-reviewer i18n messages: ~92 KB, en+de only - // - kotlin metadata: bleed from spake2-android (Kotlin lib); - // our code is pure Java and doesn't reflect on .kotlin_builtins - // - androidx annotation LICENSE.txt: 10 KB blob, no runtime use // - duplicate META-INF licenses/notices: ordinary AGP cleanup resources.excludes += [ 'META-INF/LICENSE*', 'META-INF/NOTICE*', 'META-INF/versions/9/OSGI-INF/MANIFEST.MF', - 'META-INF/androidx/**', - 'META-INF/kotlin-stdlib*', 'org/bouncycastle/pqc/crypto/picnic/**', 'org/bouncycastle/pqc/legacy/picnic/**', 'org/bouncycastle/x509/CertPathReviewerMessages*.properties', - 'kotlin/**', ] } @@ -122,15 +132,8 @@ dependencies { // we declare it explicitly here rather than patch the vendor tree. implementation 'org.bouncycastle:bcprov-jdk15to18:1.84' - // Bundled Conscrypt. libadb-android's TLS pairing exports keying - // material via Conscrypt. Without a bundled copy it reflects into the - // platform's hidden com.android.org.conscrypt.Conscrypt, which under - // targetSdk 35 is invisible to reflection (getMethod throws - // NoSuchMethodException and pairing fails on real devices). Bundling a - // standalone Conscrypt flips libadb onto the public - // org.conscrypt.Conscrypt API, which is not restricted. Ships a native - // .so (filtered to arm64-v8a in release). - implementation 'org.conscrypt:conscrypt-android:2.5.2' + // Wireless pairing requires the public Conscrypt API and native provider. + implementation 'org.conscrypt:conscrypt-android:2.6.1' testImplementation 'junit:junit:4.13.2' testImplementation 'org.json:json:20240303' @@ -151,14 +154,16 @@ tasks.register('verifyScrcpyServer') { } def expected = expectedServerSum.get() def version = serverVersion.text.trim() - if (!(expected ==~ /[0-9a-f]{64}/) || version.isEmpty()) { + if (!(expected ==~ /[0-9a-f]{64}/) + || !(version ==~ /[0-9]+(\.[0-9]+)*/)) { throw new GradleException('scrcpy server checksum or version is invalid') } def digest = MessageDigest.getInstance('SHA-256') serverJar.withInputStream { input -> byte[] buffer = new byte[64 * 1024] for (int n; (n = input.read(buffer)) >= 0; ) { - if (n > 0) digest.update(buffer, 0, n) + if (n == 0) throw new GradleException('scrcpy server read made no progress') + digest.update(buffer, 0, n) } } def actual = digest.digest().encodeHex().toString() diff --git a/app/lint.xml b/app/lint.xml new file mode 100644 index 0000000..ab9d0e4 --- /dev/null +++ b/app/lint.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<lint> + <!-- AAPT requires adaptive icons to remain version-qualified. --> + <issue id="ObsoleteSdkInt"> + <ignore regexp="mipmap-anydpi-v26"/> + </issue> + <!-- AGP 8.13's tested wrapper is Gradle 8.13. Do not chase an + unvalidated wrapper merely because a newer Gradle exists. --> + <issue id="AndroidGradlePluginVersion"> + <ignore regexp="gradle-wrapper.properties"/> + </issue> +</lint> diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 91e3725..7e8e599 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,11 +1,28 @@ <?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android"> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> + <!-- spake2-android has no targetSdk in its manifest. The merger adds + obsolete implicit permissions after evaluating these removals, so + it misleadingly warns that no declaration is present. The rules are + required: scripts/build-apk fails if any permission gets through. --> + <uses-permission + android:name="android.permission.WRITE_EXTERNAL_STORAGE" + tools:ignore="ScopedStorage" + tools:node="remove"/> + <uses-permission + android:name="android.permission.READ_EXTERNAL_STORAGE" + tools:ignore="ScopedStorage" + tools:node="remove"/> + <uses-permission + android:name="android.permission.READ_PHONE_STATE" + tools:node="remove"/> + <application android:name=".App" android:label="@string/app_name" diff --git a/app/src/main/assets/THIRD_PARTY_NOTICES b/app/src/main/assets/THIRD_PARTY_NOTICES index 36cc025..03a0bd1 100644 --- a/app/src/main/assets/THIRD_PARTY_NOTICES +++ b/app/src/main/assets/THIRD_PARTY_NOTICES @@ -34,25 +34,19 @@ Copyright 2000-2023 The Legion of the Bouncy Castle Inc. Licensed under the MIT license. Source: https://github.com/bcgit/bc-java/tree/r1rv84 -Conscrypt Android 2.5.2 +Conscrypt Android 2.6.1 ----------------------- Copyright 2016 The Android Open Source Project. Licensed under Apache-2.0. Contains modified portions of Netty and Apache Harmony under Apache-2.0. -Source: https://github.com/google/conscrypt/tree/2.5.2 -Notice: https://github.com/google/conscrypt/blob/2.5.2/NOTICE +Source: https://github.com/google/conscrypt/tree/2.6.1 +Notice: https://github.com/google/conscrypt/blob/2.6.1/NOTICE -AndroidX Annotation 1.9.1 -------------------------- -Copyright The Android Open Source Project. -Licensed under Apache-2.0. -Source: https://android.googlesource.com/platform/frameworks/support/ - -scrcpy server 4.0 +scrcpy server 4.1 ----------------- Copyright 2018 Genymobile and 2018-2026 Romain Vimont. Licensed under Apache-2.0. -Source: https://github.com/Genymobile/scrcpy/tree/v4.0 +Source: https://github.com/Genymobile/scrcpy/tree/v4.1 The Apache-2.0 terms used by this application and several components are in the top-level LICENSE file in the source distribution: diff --git a/app/src/main/assets/scrcpy-server.sha256 b/app/src/main/assets/scrcpy-server.sha256 index 376a42f..58a04f6 100644 --- a/app/src/main/assets/scrcpy-server.sha256 +++ b/app/src/main/assets/scrcpy-server.sha256 @@ -1 +1 @@ -84924bd564a1eb6089c872c7521f968058977f91f5ff02514a8c74aff3210f3a +deacb991ed2509715160ffdc7907e47b4160eb30d1566217e9047fd5b8850cae diff --git a/app/src/main/assets/scrcpy-server.version b/app/src/main/assets/scrcpy-server.version index 5186d07..7d5c902 100644 --- a/app/src/main/assets/scrcpy-server.version +++ b/app/src/main/assets/scrcpy-server.version @@ -1 +1 @@ -4.0 +4.1 |