From 204ac3cca9095daffac945ea8d72f8bddc2313bc Mon Sep 17 00:00:00 2001 From: Chirayu Desai Date: Thu, 20 Apr 2017 21:56:59 +0530 Subject: [PATCH 1/2] PackageManagerCompat: Handle exceptions better * Don't catch all exceptions, only what we expect. * Also re-format comments as javadoc --- .../fdroid/compat/PackageManagerCompat.java | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/compat/PackageManagerCompat.java b/app/src/main/java/org/fdroid/fdroid/compat/PackageManagerCompat.java index 7c02411cc..05a6c51c7 100644 --- a/app/src/main/java/org/fdroid/fdroid/compat/PackageManagerCompat.java +++ b/app/src/main/java/org/fdroid/fdroid/compat/PackageManagerCompat.java @@ -5,9 +5,24 @@ import android.content.Context; import android.content.pm.PackageManager; import android.os.Build; import android.util.Log; + import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.installer.PrivilegedInstaller; +/** + * Starting with 7.0 (API 24), we're using PackageInstaller APIs + * to install and uninstall apps via the privileged extension. + * That enforces the uninstaller being the same as the installer, + * so set the package name to privileged extension if it is being used. + *

+ * While setting the installer package name, many problems can occur, + * such as: + *

  • App wasn't installed due to incompatibility + *
  • User canceled install + *
  • Another app interfered in the process + *
  • Another app already set the target's installer package, + * which happens in the case where we fell back to {@link org.fdroid.fdroid.installer.DefaultInstaller} + */ public class PackageManagerCompat { private static final String TAG = "PackageManagerCompat"; @@ -16,25 +31,13 @@ public class PackageManagerCompat { public static void setInstaller(Context context, PackageManager mPm, String packageName) { if (Build.VERSION.SDK_INT < 11) return; try { - /* - * Starting with 7.0 (API 24), we're using PackageInstaller APIs - * to install and uninstall apps via the privileged extension. - * That enforces the uninstaller being the same as the installer, - * so set the package name to that. - */ if (Build.VERSION.SDK_INT >= 24 && PrivilegedInstaller.isDefault(context)) { mPm.setInstallerPackageName(packageName, "org.fdroid.fdroid.privileged"); } else { mPm.setInstallerPackageName(packageName, "org.fdroid.fdroid"); } Utils.debugLog(TAG, "Installer package name for " + packageName + " set successfully"); - } catch (Exception e) { - // Many problems can occur: - // * App wasn't installed due to incompatibility - // * User canceled install - // * Another app interfered in the process - // * Another app already set the target's installer package - // * ... + } catch (SecurityException | IllegalArgumentException e) { Log.e(TAG, "Could not set installer package name for " + packageName, e); } From c095a85c3dd3c505951bebb52e4ae010c69cc9f9 Mon Sep 17 00:00:00 2001 From: Chirayu Desai Date: Wed, 3 May 2017 00:28:47 +0530 Subject: [PATCH 2/2] Installer: Fallback to DefaultInstaller on API >= 24 for uninstall, ... when PackageInstaller is the installer (privext). * In the case where the Privileged Extension is installed, but the installation happens through DefaultInstaller still due to something like a permission mismatch, that is set as the installer package name. * We cannot install packages installed by that via the system methods, so fallback to DefualtInstaller for uninstalling as well when the app is installed by PackageInstaller --- .../main/java/org/fdroid/fdroid/installer/Installer.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/installer/Installer.java b/app/src/main/java/org/fdroid/fdroid/installer/Installer.java index 45f63ce11..e9299c49a 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/Installer.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/Installer.java @@ -24,6 +24,7 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.PatternMatcher; @@ -32,7 +33,6 @@ import android.text.TextUtils; import android.util.Log; import org.fdroid.fdroid.Utils; -import org.fdroid.fdroid.compat.PackageManagerCompat; import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.ApkProvider; import org.fdroid.fdroid.privileged.views.AppDiff; @@ -141,9 +141,10 @@ public abstract class Installer { return null; } - try { - PackageManagerCompat.setInstaller(context, context.getPackageManager(), apk.packageName); - } catch (SecurityException e) { + PackageManager pm = context.getPackageManager(); + if (Build.VERSION.SDK_INT >= 24 && ( + pm.getInstallerPackageName(apk.packageName).equals("com.android.packageinstaller") + || pm.getInstallerPackageName(apk.packageName).equals("com.google.android.packageinstaller"))) { Utils.debugLog(TAG, "Falling back to default installer for uninstall"); Intent intent = new Intent(context, DefaultInstallerActivity.class); intent.setAction(DefaultInstallerActivity.ACTION_UNINSTALL_PACKAGE);