parse error bei Aktualisierung von Android-Paketen

Bei mir ist das Update auf CyanogenMod 13 recht holprig verlaufen, wie ich im Datenkanal 44 berichtet habe. Dabei ist zum Beispiel die Aktualisierung der Sqlite-Datenbank für die Startbildschirme nicht vollständig vollzogen wurden und die Spalten für die neue Version waren in den Tabellen hinzugefügt, aber die Versionskennung der Datenbank war noch die alte, so dass das Update immer wieder angestoßen wurde, aber fehlschlug. Daher wurden all meine Änderungen, die ich an der Hauptübersicht vorgenommen habe, nicht gespeichert – aber ich konnte damit leben. Im Februar hatte ich mir dann endlich die Mühe gemacht, das Problem zu untersuchen, und konnte die Ursache auch identifizieren und durch das Löschen der »halben« Datenbank beheben.

Ein weiteres, kleines Problem, dass mich seither plagte, war das Aktualisieren von Paketen. Mit dem YalpStore und Whatsapp Beta Updater konnte ich zwar die apk-Dateien laden, aber wenn die Aktualisierung oder Installation der Pakete vom Programm angestoßen wurde, kam immer ein weißes Fenster mit der Meldung parsing error und nichts passierte. Heute habe ich mich dem Problem mal angenommen, da ich schon durch die Fehlersuche nach der unveränderlichen Hauptübersicht die passenden Werkzeuge gefunden hatte.

Der erste Schritt, den ich bei der Fehlersuche bei Android immer gehe, ist vom Laptop aus adb logcat aufzurufen. Im jetzigen Fall lies sich auch der Fehler sehr gut nachstellen und ich bekam folgende Ausgabe (ich habe irrelevante Meldungen per Hand entfernt):

% adb logcat
04-15 10:35:11.002  2293  3273 I ActivityManager: START u0 {act=android.intent.action.VIEW dat=file:///storage/40EE-07D4/Download/tunein.player.130507.apk typ=application/vnd.android.package-archive flg=0x10000000 cmp=com.android.packageinstaller/.PackageInstallerActivity} from uid 10074 on display 0
04-15 10:35:11.093 23101 23101 W         : Unable to open '/storage/40EE-07D4/Download/tunein.player.130507.apk': Permission denied
04-15 10:35:11.093 23101 23101 W zipro   : Error opening archive /storage/40EE-07D4/Download/tunein.player.130507.apk: I/O Error
04-15 10:35:11.093 23101 23101 D asset   : failed to open Zip archive '/storage/40EE-07D4/Download/tunein.player.130507.apk'
04-15 10:35:11.094 23101 23101 W PackageInstaller: Parse error when parsing manifest. Discontinuing installation
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics: Failed to hash APK contents
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics: java.io.FileNotFoundException: /storage/40EE-07D4/Download/tunein.player.130507.apk: open failed: EACCES (Permission denied)
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics:  at libcore.io.IoBridge.open(IoBridge.java:452)
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics:  at java.io.FileInputStream.<init>(FileInputStream.java:76)
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics:  at com.android.packageinstaller.InstallFlowAnalytics.getSha256ContentsDigest(InstallFlowAnalytics.java:598)
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics:  at com.android.packageinstaller.InstallFlowAnalytics.getPackageContentsDigest(InstallFlowAnalytics.java:581)
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics:  at com.android.packageinstaller.InstallFlowAnalytics.-wrap0(InstallFlowAnalytics.java)
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics:  at com.android.packageinstaller.InstallFlowAnalytics$2.run(InstallFlowAnalytics.java:467)
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics:  at java.lang.Thread.run(Thread.java:818)
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics: Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics:  at libcore.io.Posix.open(Native Method)
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics:  at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics:  at libcore.io.IoBridge.open(IoBridge.java:438)
04-15 10:35:11.122 23101 23340 W InstallFlowAnalytics:  ... 8 more
04-15 10:35:11.263  2293  2314 I ActivityManager: Displayed com.android.packageinstaller/.PackageInstallerActivity: +203ms

In den Logmeldungen sind die wichtigsten Informationen alle enthalten: Das Problem ist, dass der Paket-Installer nicht auf die Datei im Download-Verzeichnis zugreifen darf, sprich das übliche Unix-Problem mit Rechten. Die Rechte für den Zugriff auf den externen Speicher werden für Android über die Rechteverwaltung von Adroid bestimmt.

Daher war als erstes zu klären, welches Paket es genau betraf, denn die Installationen werden von YalpStore und WhatsApp Beta Updater an ein anderes Programm übergeben. Die Kennung dieses Paketes ist direkt in der ersten Zeile in der Info-Meldung vom ActivityManager zu sehen: com.android.packageinstaller. Also habe ich mir für dieses Paket die entsprechende Rechtevergabe angesehen:

% adb shell dumpsys package com.android.packageinstaller
…
    requested permissions:
      android.permission.INSTALL_PACKAGES
      android.permission.DELETE_PACKAGES
      android.permission.CLEAR_APP_CACHE
      android.permission.CLEAR_APP_USER_DATA
      android.permission.READ_EXTERNAL_STORAGE
      android.permission.MANAGE_USERS
      android.permission.GRANT_RUNTIME_PERMISSIONS
      android.permission.REVOKE_RUNTIME_PERMISSIONS
      android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS
      android.permission.INTERACT_ACROSS_USERS_FULL
      android.permission.READ_INSTALL_SESSIONS
      android.permission.UPDATE_APP_OPS_STATS
      android.permission.WAKE_LOCK
      android.permission.KILL_UID
      com.google.android.permission.INSTALL_WEARABLE_PACKAGES
    install permissions:
      android.permission.KILL_UID: granted=true
      android.permission.CLEAR_APP_USER_DATA: granted=true
      android.permission.INSTALL_PACKAGES: granted=true
      android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS: granted=true
      android.permission.INTERACT_ACROSS_USERS_FULL: granted=true
      android.permission.READ_INSTALL_SESSIONS: granted=true
      android.permission.REVOKE_RUNTIME_PERMISSIONS: granted=true
      android.permission.MANAGE_USERS: granted=true
      android.permission.CLEAR_APP_CACHE: granted=true
      android.permission.GRANT_RUNTIME_PERMISSIONS: granted=true
      android.permission.WAKE_LOCK: granted=true
      android.permission.UPDATE_APP_OPS_STATS: granted=true
      android.permission.DELETE_PACKAGES: granted=true

Das Paket com.android.packageinstaller wünscht sich zwar das Recht android.permission.READ_EXTERNAL_STORAGE zum Zugriff auf den externen Speicher, also unter anderem das Download-Verzeichnis, aber dieses Recht wurde nicht gewährt. Also habe ich das Recht durch adb shell pm grant com.android.packageinstaller android.permission.READ_EXTERNAL_STORAGE von Hand vergeben und nachdem ich über OS Monitor den laufenden Installer-Prozess beendet hatte, damit der Prozess beim Neustart auch das neu vergebene Recht bekommt, lief es, wie gewünscht.