PackageManager.deletePackageAsUser () не работает для приложений, установленных PlayStore - PullRequest
0 голосов
/ 19 октября 2018

Я создал приложение, которое должно иметь возможность удалять приложения на устройстве.Приложение подписано соответствующим сертификатом платформы и имеет следующие разрешения:

android.permission.DELETE_PACKAGES
android.permission.INTERACT_ACROSS_USERS_FULL
android.permission.INSTALL_PACKAGES
android.permission.MANAGE_USERS

Чтобы удалить пакет, приложение вызывает следующую функцию

 PackageManager.deletePackageAsUser(packageName,observer,flags,userHandle);

или если не задан дескриптор пользователя

 PackageManager.deletePackage(packageName,observer,flags);

Обе функции работают для приложений, которые были установлены вручную или с помощью следующей команды

Runtime.getRuntime().exec("pm install -r -i my.package.name --user 0 pathTo.apk");

Если я пытаюсь удалить приложение, установленное через PlayStore, происходит сбой.Это не дает ошибки.Также я не вижу подсказок в logcat.

Я определил наблюдателя

IPackageDeleteObserver ob = new IPackageDeleteObserver() {
    public void packageDeleted(String s, int i) throws RemoteException {
        Log.e("dbg","s: " + s + " i:"+i);
    }

    public IBinder asBinder() {
        Log.e("dbg","binder called");
        return null;
    }
};

При удалении установленного вручную apk, обе функции вызываются.При удалении приложения, которое было установлено в PlayStore, вызывается только функция asBinder.

Я использовал Pixel с AOSP 8.1 и два пользовательских устройства.Мое приложение всегда подписывалось соответствующим сертификатом платформы.

РЕШЕНИЕ:

Мне пришлось добавить android: sharedUserId = "android.uid.system" в мой манифест Android.Я немного покопался в источнике android и нашел функцию

PackageManagerService.isCallerAllowedToSilentlyUninstall

Эта проверка вызывается при вызове PackageManager.deletePackage.Из исходного кода я понял, что наличие разрешения android.permission.DELETE_PACKAGES недостаточно для удаления приложений, которые были установлены другим приложением (playstore).Это разрешено только PlayStore и PackageInstaller.

   private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
    if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
          || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
        return true;
    }
    ....

Наличие System UID - единственная возможность получить предоставленную операцию (за исключением пакетов, которые были установлены моим собственным приложением.)

...