Reputation: 5964
I am including a presigned APK in my AOSP build like so:
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
APK_VERSION := 0.2.0
LOCAL_MODULE := SomeAPK
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := .apk
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_PRIVILEGED_MODULE := true
include $(BUILD_PREBUILT)
However, when the device boots the APK is not installed and I see the following log:
2021-05-25 17:19:02.617 3568-3568/system_process W/PackageManager: Failed to scan /system/priv-app/SomeAPK: Failed to collect certificates from /system/priv-app/SomeAPK/SomeAPK.apk
I have tried setting:
LOCAL_DEX_PREOPT := false
and:
LOCAL_DEX_PREOPT := nostripping
But i'm still seeing the issue.
I can adb install the app fine and I have used all of the tools available to confirm the APK is actually signed.
How can we get AOSP to truly leave the APK signing alone?
Upvotes: 2
Views: 3401
Reputation: 23
I was able to solve this in android.bp file as below.
// Import the APK
android_app_import {
name: "MyApk",
apk: "MyApk.apk",
presigned: true,
dex_preopt: {
enabled: false,
},
}
Upvotes: 2
Reputation: 53
Android team implemented another solution for this issue with the commit b34f64f of platform/build: https://cs.android.com/android/_/android/platform/build/+/b34f64fc7a017ebadd5fb2b1c81341491e4de9a1
In summary, for V2 (or higher) pre-signed APKs, you can define LOCAL_SDK_VERSION to 30 or higher to not alter the APK during its integration. In your case, it would be like (considering your APK was built with SDK version 30):
include $(CLEAR_VARS)
APK_VERSION := 0.2.0
LOCAL_MODULE := SomeAPK
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := .apk
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_PRIVILEGED_MODULE := true
LOCAL_SDK_VERSION := 30
include $(BUILD_PREBUILT)
Upvotes: 3
Reputation: 2008
When prebuilt apk, it will try to uncompress the dex and jni so, if it's stored in apk(zip) with compress. It's checked by zipinfo. Then it will unzip the compress dex/jni so, and zip it again without uncompress. And the v2/v3 signature will be removed by unzip and zip again. v1 signature is stored as zip entry, and it will be keeped.
no compression
-rw-rw-rw- 0.0 unx 3598524 b- stor 81-Jan-01 01:01 classes.dex
You can avoid prebuilt apk to be processed by LOCAL_REPLACE_PREBUILT_APK_INSTALLED
include $(CLEAR_VARS)
APK_VERSION := 0.2.0
LOCAL_MODULE := SomeAPK
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := .apk
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_PRIVILEGED_MODULE := true
LOCAL_REPLACE_PREBUILT_APK_INSTALLED := $(LOCAL_PATH)/$(LOCAL_MODULE).apk
include $(BUILD_PREBUILT)
Upvotes: 5
Reputation: 5964
I eventually found a solution.
Apps that were signed using gradle always seemed to be left with their signature stripped after the AOSP build process.
The solution was to remove the signing config from gradle altogether and sign the app manually instead using apksigner.
E.g:
apksigner sign --ks your-keystore.jks --ks-pass pass:"keystore-password" --ks-key-alias keystore-alias --key-pass pass:"alias-password" --out signed-output.apk input-file.apk
To verify if your APK is signed correctly, it should validate successfully using keytool:
keytool -printcert -jarfile signed-apk.apk
Upvotes: 2