TL;DR
This issue occurs when an app is trying to re-declare an existing permission, with error message INSTALL_FAILED_DUPLICATE_PERMISSION
. It mainly affected apps that are based on Adobe AIR (package prefix with com.air
). The main cause is the different code implementation in Lollipop 5.0 when verifying a certificate's signature used to sign an app. For the solution, just skip over to the "Solution" part.
Update: Google has fixed this issue on Lollipop 5.0.1.
Technical Details
Excerpts from Android L Developer Preview issue tracker which are linked from an entry on AOSP issue tracker,
Post #4:
logcat tells me there's a conflict with redeclaring permissions during installation (in my case, Amazon is trying to redeclare getui.permission.GetuiService, which is already owned by Camera 360)
Post #12's LogCat:
10-25 08:06:37.805 749 824 W PackageManager: Package com.tencent.mm attempting to redeclare permission com.google.android.c2dm.permission.SEND already owned by com.google.android.gsf
10-25 08:06:37.926 4812 4812 D Finsky : [1] PackageInstallerImpl.cancelSession: Canceling session 121130466 for com.tencent.mm
10-25 08:06:37.926 4812 4812 E Finsky : [1] PackageInstallerImpl.handleCommitCallback: Error -505 while installing com.tencent.mm: INSTALL_FAILED_DUPLICATE_PERMISSION: Package com.tencent.mm attempting to redeclare permission com.google.android.c2dm.permission.SEND already owned by com.google.android.gsf
10-25 08:06:37.926 4812 4812 W Finsky : [1] 4.installFailed: Install failure of com.tencent.mm: -505 null
10-25 08:06:37.933 749 749 D ZenLog : intercepted: 0|com.android.vending|-973170826|null|10017,!priority
10-25 08:06:37.933 749 749 V NotificationService: pkg=com.android.vending canInterrupt=false intercept=true
10-25 08:06:37.964 4812 4812 D Finsky : [1] InstallerTask.cancelCleanup: Cancel running installation of com.tencent.mm
Excerpts from AOSP issue tracker,
Post #4
In API19 the new X509CertImpl(encCert) wraps the certificate (which is already parsed and ready for SHA1 computation), while in API 21, the certificate is forwarded as byte stream, parsed again and processed by a certificate factory. Which factory that is, depends on the context. In case of the L devices I tested on, the factory will create an OpenSSLX509Certificate. Unfortunately, there is something in our certificate which openssl has trouble with and the fingerprint changes during openssl processing. I can reproduce this also with the openssl tool, when I convert our certificate into some other format (e.g., PEM).
If the SHA1 would be computed directly on 'encCert.getEncoded()' it would be correct in both cases.
Solution
Update: As of 2014-12-04, Google has fixed this issue on Lollipop 5.0.1. For those who didn't do any workaround trying to reinstall the app, you can flash Lollipop 5.0.1 image when it's ready/wait for the OTA.
Post #20, #21
Looks like this has been fixed in 5.0.1:
https://android.googlesource.com/platform/libcore/+/6632d8c9d8d1a3ac338d541676148677641bafe3
https://android.googlesource.com/platform/frameworks/base/+/32a22c44b8351c1cccd3a1f9c47a33469d9378e0
Status: Released
Committer's note
Recover apps with malformed certificates.
There was a window of time in Lollipop where we persisted certificates
after they had passed through a decode/encode cycle. The well-written
OpenSSL library was liberal when decoding (allowing slightly malformed
certs to be parsed), but then strict when encoding, giving us
different bytes for effectively the same certificate.
A related libcore change (0c990ab4a90b8a5492a67b2b728ac9a4a1ccfa1b)
now returns the original bytes verbatim, fixing both pre-Lollipop
installs and installs after that change.
This change recovers any apps that had been installed during the
window of time described above by doing a one-time check to see if
the certs are effectively equal.
Please refer to older revision for other suggested solutions.