From e69a6d5a8f24e7745516001f58bee49e05f2ea9e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 1 Sep 2016 14:59:26 +0200 Subject: [PATCH] store Apk instance in Installer instance for fetching state If F-Droid or InstallManagerService get killed while an install is in progress, that install will ultimately broadcast back to InstallManagerService to manage the notifications. The state is gone since things have been killed, so include the Apk instance in the Intent that is included in the broadcasts so that InstallManagerService can fetch all required info from the database. closes #698 --- .../java/org/fdroid/fdroid/AppDetails.java | 22 ++++---- .../java/org/fdroid/fdroid/RepoUpdater.java | 4 +- .../fdroid/installer/DefaultInstaller.java | 17 +++---- .../installer/DefaultInstallerActivity.java | 28 ++++------ .../fdroid/installer/ExtensionInstaller.java | 16 +++--- .../installer/InstallManagerService.java | 8 +-- .../fdroid/fdroid/installer/Installer.java | 51 ++++++++++--------- .../fdroid/installer/InstallerFactory.java | 19 ++++--- .../fdroid/installer/InstallerService.java | 12 ++--- .../fdroid/installer/PrivilegedInstaller.java | 19 +++---- .../views/UninstallDialogActivity.java | 8 +-- 11 files changed, 105 insertions(+), 99 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/AppDetails.java b/app/src/main/java/org/fdroid/fdroid/AppDetails.java index f433ae184..a4fbbcd24 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppDetails.java +++ b/app/src/main/java/org/fdroid/fdroid/AppDetails.java @@ -862,7 +862,7 @@ public class AppDetails extends AppCompatActivity { return true; case UNINSTALL: - uninstallApk(app.packageName); + uninstallApk(); return true; case IGNOREALL: @@ -959,9 +959,13 @@ public class AppDetails extends AppCompatActivity { InstallManagerService.queue(this, app, apk); } - private void uninstallApk(String packageName) { - Installer installer = InstallerFactory.create(this, null); - Intent intent = installer.getUninstallScreen(packageName); + /** + * Queue for uninstall based on the instance variable {@link #app} + */ + private void uninstallApk() { + Apk apk = app.installedApk; + Installer installer = InstallerFactory.create(this, apk); + Intent intent = installer.getUninstallScreen(apk); if (intent != null) { // uninstall screen required Utils.debugLog(TAG, "screen screen required"); @@ -975,7 +979,7 @@ public class AppDetails extends AppCompatActivity { private void startUninstall() { localBroadcastManager.registerReceiver(uninstallReceiver, Installer.getUninstallIntentFilter(app.packageName)); - InstallerService.uninstall(context, app.packageName); + InstallerService.uninstall(context, app.installedApk); } private void launchApk(String packageName) { @@ -1630,7 +1634,7 @@ public class AppDetails extends AppCompatActivity { // If "launchable", launch activity.launchApk(app.packageName); } else { - activity.uninstallApk(app.packageName); + activity.uninstallApk(); } } else if (app.suggestedVersionCode > 0) { // If not installed, install @@ -1658,10 +1662,6 @@ public class AppDetails extends AppCompatActivity { appDetails = (AppDetails) activity; } - void remove() { - appDetails.uninstallApk(appDetails.getApp().packageName); - } - @Override public void onViewCreated(View view, Bundle savedInstanceState) { // A bit of a hack, but we can't add the header view in setupSummaryHeader(), @@ -1689,7 +1689,7 @@ public class AppDetails extends AppCompatActivity { App app = appDetails.getApp(); final Apk apk = appDetails.getApks().getItem(position - l.getHeaderViewsCount()); if (app.installedVersionCode == apk.versionCode) { - remove(); + appDetails.uninstallApk(); } else if (app.installedVersionCode > apk.versionCode) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setMessage(R.string.installDowngrade); diff --git a/app/src/main/java/org/fdroid/fdroid/RepoUpdater.java b/app/src/main/java/org/fdroid/fdroid/RepoUpdater.java index 9d30651e1..c4acc9a76 100644 --- a/app/src/main/java/org/fdroid/fdroid/RepoUpdater.java +++ b/app/src/main/java/org/fdroid/fdroid/RepoUpdater.java @@ -483,7 +483,9 @@ public class RepoUpdater { } if (repoPushRequest.versionCode == null || repoPushRequest.versionCode == packageInfo.versionCode) { - InstallerService.uninstall(context, packageName); + Apk apk = ApkProvider.Helper.find(context, repoPushRequest.packageName, + packageInfo.versionCode); + InstallerService.uninstall(context, apk); } else { Utils.debugLog(TAG, "ignoring request based on versionCode:" + repoPushRequest); } diff --git a/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstaller.java b/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstaller.java index cf440ae96..fa202dda5 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstaller.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstaller.java @@ -41,8 +41,8 @@ public class DefaultInstaller extends Installer { private static final String TAG = "DefaultInstaller"; - DefaultInstaller(Context context) { - super(context); + DefaultInstaller(Context context, Apk apk) { + super(context, apk); } @Override @@ -54,6 +54,7 @@ public class DefaultInstaller extends Installer { Intent installIntent = new Intent(context, DefaultInstallerActivity.class); installIntent.setAction(DefaultInstallerActivity.ACTION_INSTALL_PACKAGE); installIntent.putExtra(Installer.EXTRA_DOWNLOAD_URI, downloadUri); + installIntent.putExtra(Installer.EXTRA_APK, apk); installIntent.setData(localApkUri); PendingIntent installPendingIntent = PendingIntent.getActivity( @@ -67,21 +68,19 @@ public class DefaultInstaller extends Installer { } @Override - protected void uninstallPackage(String packageName) { - sendBroadcastUninstall(packageName, Installer.ACTION_UNINSTALL_STARTED); + protected void uninstallPackage() { + sendBroadcastUninstall(Installer.ACTION_UNINSTALL_STARTED); Intent uninstallIntent = new Intent(context, DefaultInstallerActivity.class); uninstallIntent.setAction(DefaultInstallerActivity.ACTION_UNINSTALL_PACKAGE); - uninstallIntent.putExtra( - DefaultInstallerActivity.EXTRA_UNINSTALL_PACKAGE_NAME, packageName); + uninstallIntent.putExtra(Installer.EXTRA_APK, apk); PendingIntent uninstallPendingIntent = PendingIntent.getActivity( context.getApplicationContext(), - packageName.hashCode(), + apk.packageName.hashCode(), uninstallIntent, PendingIntent.FLAG_UPDATE_CURRENT); - sendBroadcastUninstall(packageName, - Installer.ACTION_UNINSTALL_USER_INTERACTION, uninstallPendingIntent); + sendBroadcastUninstall(Installer.ACTION_UNINSTALL_USER_INTERACTION, uninstallPendingIntent); } @Override diff --git a/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstallerActivity.java b/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstallerActivity.java index 8c7769f41..04efb2087 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstallerActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstallerActivity.java @@ -31,6 +31,7 @@ import android.support.v4.app.FragmentActivity; import android.util.Log; import org.fdroid.fdroid.R; +import org.fdroid.fdroid.data.Apk; /** * A transparent activity as a wrapper around Android's PackageInstaller Intents @@ -41,13 +42,10 @@ public class DefaultInstallerActivity extends FragmentActivity { static final String ACTION_INSTALL_PACKAGE = "org.fdroid.fdroid.installer.DefaultInstaller.action.INSTALL_PACKAGE"; static final String ACTION_UNINSTALL_PACKAGE = "org.fdroid.fdroid.installer.DefaultInstaller.action.UNINSTALL_PACKAGE"; - static final String EXTRA_UNINSTALL_PACKAGE_NAME = "org.fdroid.fdroid.installer.DefaultInstaller.extra.UNINSTALL_PACKAGE_NAME"; - private static final int REQUEST_CODE_INSTALL = 0; private static final int REQUEST_CODE_UNINSTALL = 1; private Uri downloadUri; - private String uninstallPackageName; // for the broadcasts private DefaultInstaller installer; @@ -56,18 +54,16 @@ public class DefaultInstallerActivity extends FragmentActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - installer = new DefaultInstaller(this); - Intent intent = getIntent(); String action = intent.getAction(); + Apk apk = intent.getParcelableExtra(Installer.EXTRA_APK); + installer = new DefaultInstaller(this, apk); if (ACTION_INSTALL_PACKAGE.equals(action)) { Uri localApkUri = intent.getData(); downloadUri = intent.getParcelableExtra(Installer.EXTRA_DOWNLOAD_URI); installPackage(localApkUri); } else if (ACTION_UNINSTALL_PACKAGE.equals(action)) { - uninstallPackageName = intent.getStringExtra(EXTRA_UNINSTALL_PACKAGE_NAME); - - uninstallPackage(uninstallPackageName); + uninstallPackage(apk.packageName); } else { throw new IllegalStateException("Intent action not specified!"); } @@ -134,7 +130,7 @@ public class DefaultInstallerActivity extends FragmentActivity { getPackageManager().getPackageInfo(packageName, 0); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "NameNotFoundException", e); - installer.sendBroadcastUninstall(packageName, Installer.ACTION_UNINSTALL_INTERRUPTED, + installer.sendBroadcastUninstall(Installer.ACTION_UNINSTALL_INTERRUPTED, "Package that is scheduled for uninstall is not installed!"); finish(); return; @@ -155,7 +151,7 @@ public class DefaultInstallerActivity extends FragmentActivity { startActivityForResult(intent, REQUEST_CODE_UNINSTALL); } catch (ActivityNotFoundException e) { Log.e(TAG, "ActivityNotFoundException", e); - installer.sendBroadcastUninstall(packageName, Installer.ACTION_UNINSTALL_INTERRUPTED, + installer.sendBroadcastUninstall(Installer.ACTION_UNINSTALL_INTERRUPTED, "This Android rom does not support ACTION_UNINSTALL_PACKAGE!"); finish(); } @@ -197,25 +193,21 @@ public class DefaultInstallerActivity extends FragmentActivity { case REQUEST_CODE_UNINSTALL: // resultCode is always 0 on Android < 4.0. if (Build.VERSION.SDK_INT < 14) { - installer.sendBroadcastUninstall(uninstallPackageName, - Installer.ACTION_UNINSTALL_COMPLETE); + installer.sendBroadcastUninstall(Installer.ACTION_UNINSTALL_COMPLETE); break; } switch (resultCode) { case Activity.RESULT_OK: - installer.sendBroadcastUninstall(uninstallPackageName, - Installer.ACTION_UNINSTALL_COMPLETE); + installer.sendBroadcastUninstall(Installer.ACTION_UNINSTALL_COMPLETE); break; case Activity.RESULT_CANCELED: - installer.sendBroadcastUninstall(uninstallPackageName, - Installer.ACTION_UNINSTALL_INTERRUPTED); + installer.sendBroadcastUninstall(Installer.ACTION_UNINSTALL_INTERRUPTED); break; case Activity.RESULT_FIRST_USER: default: // AOSP UninstallAppProgress returns RESULT_FIRST_USER on error - installer.sendBroadcastUninstall(uninstallPackageName, - Installer.ACTION_UNINSTALL_INTERRUPTED, + installer.sendBroadcastUninstall(Installer.ACTION_UNINSTALL_INTERRUPTED, getString(R.string.uninstall_error_unknown)); break; } diff --git a/app/src/main/java/org/fdroid/fdroid/installer/ExtensionInstaller.java b/app/src/main/java/org/fdroid/fdroid/installer/ExtensionInstaller.java index d40137c2d..ed3f00f66 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/ExtensionInstaller.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/ExtensionInstaller.java @@ -1,4 +1,5 @@ /* + * Copyright (C) 2016 Blue Jay Wireless * Copyright (C) 2016 Dominik Schürmann * * This program is free software; you can redistribute it and/or @@ -39,8 +40,8 @@ import java.io.File; */ public class ExtensionInstaller extends Installer { - ExtensionInstaller(Context context) { - super(context); + ExtensionInstaller(Context context, Apk apk) { + super(context, apk); } @Override @@ -71,23 +72,22 @@ public class ExtensionInstaller extends Installer { } @Override - protected void uninstallPackage(String packageName) { - sendBroadcastUninstall(packageName, Installer.ACTION_UNINSTALL_STARTED); + protected void uninstallPackage() { + sendBroadcastUninstall(Installer.ACTION_UNINSTALL_STARTED); Intent uninstallIntent = new Intent(context, InstallExtensionDialogActivity.class); uninstallIntent.setAction(InstallExtensionDialogActivity.ACTION_UNINSTALL); PendingIntent uninstallPendingIntent = PendingIntent.getActivity( context.getApplicationContext(), - packageName.hashCode(), + apk.packageName.hashCode(), uninstallIntent, PendingIntent.FLAG_UPDATE_CURRENT); - sendBroadcastUninstall(packageName, - Installer.ACTION_UNINSTALL_USER_INTERACTION, uninstallPendingIntent); + sendBroadcastUninstall(Installer.ACTION_UNINSTALL_USER_INTERACTION, uninstallPendingIntent); // don't use broadcasts for the rest of this special installer - sendBroadcastUninstall(packageName, Installer.ACTION_UNINSTALL_COMPLETE); + sendBroadcastUninstall(Installer.ACTION_UNINSTALL_COMPLETE); } @Override diff --git a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java index 1a21bd9db..7fedf8256 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java @@ -235,6 +235,7 @@ public class InstallManagerService extends Service { @Override public void onReceive(Context context, Intent intent) { String downloadUrl = intent.getDataString(); + Apk apk; switch (intent.getAction()) { case Installer.ACTION_INSTALL_STARTED: // nothing to do @@ -247,6 +248,7 @@ public class InstallManagerService extends Service { localBroadcastManager.unregisterReceiver(this); break; case Installer.ACTION_INSTALL_INTERRUPTED: + apk = intent.getParcelableExtra(Installer.EXTRA_APK); String errorMessage = intent.getStringExtra(Installer.EXTRA_ERROR_MESSAGE); @@ -264,15 +266,15 @@ public class InstallManagerService extends Service { localBroadcastManager.unregisterReceiver(this); break; case Installer.ACTION_INSTALL_USER_INTERACTION: + apk = intent.getParcelableExtra(Installer.EXTRA_APK); PendingIntent installPendingIntent = intent.getParcelableExtra(Installer.EXTRA_USER_INTERACTION_PI); - Apk apkUserInteraction = getApkFromActive(downloadUrl); // show notification if app details is not visible - if (AppDetails.isAppVisible(apkUserInteraction.packageName)) { + if (AppDetails.isAppVisible(apk.packageName)) { cancelNotification(downloadUrl); } else { - notifyDownloadComplete(apkUserInteraction, downloadUrl, installPendingIntent); + notifyDownloadComplete(apk, downloadUrl, installPendingIntent); } break; 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 8df65cd4c..bdcf2a271 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/Installer.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/Installer.java @@ -1,4 +1,5 @@ /* + * Copyright (C) 2016 Blue Jay Wireless * Copyright (C) 2016 Dominik Schürmann * * This program is free software; you can redistribute it and/or @@ -42,11 +43,12 @@ import java.io.IOException; * Handles the actual install process. Subclasses implement the details. */ public abstract class Installer { - final Context context; - private final LocalBroadcastManager localBroadcastManager; - private static final String TAG = "Installer"; + final Context context; + final Apk apk; + private final LocalBroadcastManager localBroadcastManager; + public static final String ACTION_INSTALL_STARTED = "org.fdroid.fdroid.installer.Installer.action.INSTALL_STARTED"; public static final String ACTION_INSTALL_COMPLETE = "org.fdroid.fdroid.installer.Installer.action.INSTALL_COMPLETE"; public static final String ACTION_INSTALL_INTERRUPTED = "org.fdroid.fdroid.installer.Installer.action.INSTALL_INTERRUPTED"; @@ -67,12 +69,16 @@ public abstract class Installer { */ static final String EXTRA_DOWNLOAD_URI = "org.fdroid.fdroid.installer.Installer.extra.DOWNLOAD_URI"; public static final String EXTRA_APK = "org.fdroid.fdroid.installer.Installer.extra.APK"; - public static final String EXTRA_PACKAGE_NAME = "org.fdroid.fdroid.installer.Installer.extra.PACKAGE_NAME"; public static final String EXTRA_USER_INTERACTION_PI = "org.fdroid.fdroid.installer.Installer.extra.USER_INTERACTION_PI"; public static final String EXTRA_ERROR_MESSAGE = "org.fdroid.fdroid.net.installer.Installer.extra.ERROR_MESSAGE"; - Installer(Context context) { + /** + * @param apk must be included so that all the phases of the install process + * can get all the data about the app, even after F-Droid was killed + */ + Installer(Context context, Apk apk) { this.context = context; + this.apk = apk; localBroadcastManager = LocalBroadcastManager.getInstance(context); } @@ -125,18 +131,18 @@ public abstract class Installer { * Returns an Intent to start a dialog wrapped in an activity * for uninstall confirmation. * - * @param packageName packageName of app to uninstall + * @param apk {@link Apk} instance of app to uninstall * @return Intent with activity for uninstall confirmation * Returns null if Installer handles that on itself, e.g., * with DefaultInstaller. */ - public Intent getUninstallScreen(String packageName) { + public Intent getUninstallScreen(Apk apk) { if (!isUnattended()) { return null; } Intent intent = new Intent(context, UninstallDialogActivity.class); - intent.putExtra(Installer.EXTRA_PACKAGE_NAME, packageName); + intent.putExtra(Installer.EXTRA_APK, apk); return intent; } @@ -158,31 +164,31 @@ public abstract class Installer { Intent intent = new Intent(action); intent.setData(downloadUri); intent.putExtra(Installer.EXTRA_USER_INTERACTION_PI, pendingIntent); + intent.putExtra(Installer.EXTRA_APK, apk); if (!TextUtils.isEmpty(errorMessage)) { intent.putExtra(Installer.EXTRA_ERROR_MESSAGE, errorMessage); } localBroadcastManager.sendBroadcast(intent); } - void sendBroadcastUninstall(String packageName, String action, String errorMessage) { - sendBroadcastUninstall(packageName, action, null, errorMessage); + void sendBroadcastUninstall(String action, String errorMessage) { + sendBroadcastUninstall(action, null, errorMessage); } - void sendBroadcastUninstall(String packageName, String action) { - sendBroadcastUninstall(packageName, action, null, null); + void sendBroadcastUninstall(String action) { + sendBroadcastUninstall(action, null, null); } - void sendBroadcastUninstall(String packageName, String action, PendingIntent pendingIntent) { - sendBroadcastUninstall(packageName, action, pendingIntent, null); + void sendBroadcastUninstall(String action, PendingIntent pendingIntent) { + sendBroadcastUninstall(action, pendingIntent, null); } - void sendBroadcastUninstall(String packageName, String action, - PendingIntent pendingIntent, String errorMessage) { - Uri uri = Uri.fromParts("package", packageName, null); + void sendBroadcastUninstall(String action, PendingIntent pendingIntent, String errorMessage) { + Uri uri = Uri.fromParts("package", apk.packageName, null); Intent intent = new Intent(action); intent.setData(uri); // for broadcast filtering - intent.putExtra(Installer.EXTRA_PACKAGE_NAME, packageName); + intent.putExtra(Installer.EXTRA_APK, apk); intent.putExtra(Installer.EXTRA_USER_INTERACTION_PI, pendingIntent); if (!TextUtils.isEmpty(errorMessage)) { intent.putExtra(Installer.EXTRA_ERROR_MESSAGE, errorMessage); @@ -242,7 +248,7 @@ public abstract class Installer { if (isUnattended()) { Log.e(TAG, e.getMessage(), e); Log.e(TAG, "Falling back to AOSP DefaultInstaller!"); - DefaultInstaller defaultInstaller = new DefaultInstaller(context); + DefaultInstaller defaultInstaller = new DefaultInstaller(context, apk); defaultInstaller.installPackageInternal(localApkUri, downloadUri, apk); return; } @@ -266,11 +272,10 @@ public abstract class Installer { protected abstract void installPackageInternal(Uri localApkUri, Uri downloadUri, Apk apk); /** - * Uninstall app - * - * @param packageName package name of the app that should be uninstalled + * Uninstall app as defined by {@link Installer#apk} in + * {@link Installer#Installer(Context, Apk)} */ - protected abstract void uninstallPackage(String packageName); + protected abstract void uninstallPackage(); /** * This {@link Installer} instance is capable of "unattended" install and diff --git a/app/src/main/java/org/fdroid/fdroid/installer/InstallerFactory.java b/app/src/main/java/org/fdroid/fdroid/installer/InstallerFactory.java index 3c19ae42c..47c9bc74c 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallerFactory.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallerFactory.java @@ -1,4 +1,5 @@ /* + * Copyright (C) 2016 Blue Jay Wireless * Copyright (C) 2016 Dominik Schürmann * * This program is free software; you can redistribute it and/or @@ -20,6 +21,7 @@ package org.fdroid.fdroid.installer; import android.content.Context; +import android.text.TextUtils; import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.Apk; @@ -34,22 +36,23 @@ public class InstallerFactory { * case to install the "F-Droid Privileged Extension" ExtensionInstaller. * * @param context current {@link Context} - * @param apk apk to be installed. Required to select the ExtensionInstaller. - * If this is null, the ExtensionInstaller will never be returned. + * @param apk to be installed, always required. * @return instance of an Installer */ public static Installer create(Context context, Apk apk) { - Installer installer; + if (apk == null || TextUtils.isEmpty(apk.packageName)) { + throw new IllegalArgumentException("packageName must not be empty!"); + } - if (apk != null - && apk.packageName.equals(PrivilegedInstaller.PRIVILEGED_EXTENSION_PACKAGE_NAME)) { + Installer installer; + if (apk.packageName.equals(PrivilegedInstaller.PRIVILEGED_EXTENSION_PACKAGE_NAME)) { // special case for "F-Droid Privileged Extension" - installer = new ExtensionInstaller(context); + installer = new ExtensionInstaller(context, apk); } else if (PrivilegedInstaller.isDefault(context)) { Utils.debugLog(TAG, "privileged extension correctly installed -> PrivilegedInstaller"); - installer = new PrivilegedInstaller(context); + installer = new PrivilegedInstaller(context, apk); } else { - installer = new DefaultInstaller(context); + installer = new DefaultInstaller(context, apk); } return installer; diff --git a/app/src/main/java/org/fdroid/fdroid/installer/InstallerService.java b/app/src/main/java/org/fdroid/fdroid/installer/InstallerService.java index 4e3b3ad9f..e911ebf2e 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallerService.java @@ -1,4 +1,5 @@ /* + * Copyright (C) 2016 Blue Jay Wireless * Copyright (C) 2016 Dominik Schürmann * * This program is free software; you can redistribute it and/or @@ -65,8 +66,7 @@ public class InstallerService extends IntentService { Uri downloadUri = intent.getParcelableExtra(Installer.EXTRA_DOWNLOAD_URI); installer.installPackage(uri, downloadUri, apk); } else if (ACTION_UNINSTALL.equals(intent.getAction())) { - String packageName = intent.getStringExtra(Installer.EXTRA_PACKAGE_NAME); - installer.uninstallPackage(packageName); + installer.uninstallPackage(); } } @@ -90,13 +90,13 @@ public class InstallerService extends IntentService { /** * Uninstall an app * - * @param context this app's {@link Context} - * @param packageName package name of the app that will be uninstalled + * @param context this app's {@link Context} + * @param apk {@link Apk} instance of the app that will be uninstalled */ - public static void uninstall(Context context, String packageName) { + public static void uninstall(Context context, Apk apk) { Intent intent = new Intent(context, InstallerService.class); intent.setAction(ACTION_UNINSTALL); - intent.putExtra(Installer.EXTRA_PACKAGE_NAME, packageName); + intent.putExtra(Installer.EXTRA_APK, apk); context.startService(intent); } diff --git a/app/src/main/java/org/fdroid/fdroid/installer/PrivilegedInstaller.java b/app/src/main/java/org/fdroid/fdroid/installer/PrivilegedInstaller.java index 8649f729b..c1f7ac64a 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/PrivilegedInstaller.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/PrivilegedInstaller.java @@ -1,4 +1,5 @@ /* + * Copyright (C) 2016 Blue Jay Wireless * Copyright (C) 2014-2016 Dominik Schürmann * Copyright (C) 2015 Daniel Martí * @@ -255,8 +256,8 @@ public class PrivilegedInstaller extends Installer { "device owner has marked the package as uninstallable."); } - public PrivilegedInstaller(Context context) { - super(context); + public PrivilegedInstaller(Context context, Apk apk) { + super(context, apk); } public static boolean isExtensionInstalled(Context context) { @@ -354,8 +355,8 @@ public class PrivilegedInstaller extends Installer { } @Override - protected void uninstallPackage(final String packageName) { - sendBroadcastUninstall(packageName, Installer.ACTION_UNINSTALL_STARTED); + protected void uninstallPackage() { + sendBroadcastUninstall(Installer.ACTION_UNINSTALL_STARTED); ServiceConnection mServiceConnection = new ServiceConnection() { public void onServiceConnected(ComponentName name, IBinder service) { @@ -365,9 +366,9 @@ public class PrivilegedInstaller extends Installer { @Override public void handleResult(String packageName, int returnCode) throws RemoteException { if (returnCode == DELETE_SUCCEEDED) { - sendBroadcastUninstall(packageName, ACTION_UNINSTALL_COMPLETE); + sendBroadcastUninstall(ACTION_UNINSTALL_COMPLETE); } else { - sendBroadcastUninstall(packageName, ACTION_UNINSTALL_INTERRUPTED, + sendBroadcastUninstall(ACTION_UNINSTALL_INTERRUPTED, "Error " + returnCode + ": " + UNINSTALL_RETURN_CODES.get(returnCode)); } @@ -377,15 +378,15 @@ public class PrivilegedInstaller extends Installer { try { boolean hasPermissions = privService.hasPrivilegedPermissions(); if (!hasPermissions) { - sendBroadcastUninstall(packageName, ACTION_UNINSTALL_INTERRUPTED, + sendBroadcastUninstall(ACTION_UNINSTALL_INTERRUPTED, context.getString(R.string.system_install_denied_permissions)); return; } - privService.deletePackage(packageName, 0, callback); + privService.deletePackage(apk.packageName, 0, callback); } catch (RemoteException e) { Log.e(TAG, "RemoteException", e); - sendBroadcastUninstall(packageName, ACTION_UNINSTALL_INTERRUPTED, + sendBroadcastUninstall(ACTION_UNINSTALL_INTERRUPTED, "connecting to privileged service failed"); } } diff --git a/app/src/main/java/org/fdroid/fdroid/privileged/views/UninstallDialogActivity.java b/app/src/main/java/org/fdroid/fdroid/privileged/views/UninstallDialogActivity.java index fa2380719..2538cefb8 100644 --- a/app/src/main/java/org/fdroid/fdroid/privileged/views/UninstallDialogActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/privileged/views/UninstallDialogActivity.java @@ -32,6 +32,7 @@ import android.view.ContextThemeWrapper; import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.R; +import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.installer.Installer; /** @@ -48,14 +49,15 @@ public class UninstallDialogActivity extends FragmentActivity { super.onCreate(savedInstanceState); final Intent intent = getIntent(); - final String packageName = intent.getStringExtra(Installer.EXTRA_PACKAGE_NAME); + final Apk apk = intent.getParcelableExtra(Installer.EXTRA_APK); PackageManager pm = getPackageManager(); ApplicationInfo appInfo; try { //noinspection WrongConstant (lint is actually wrong here!) - appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES); + appInfo = pm.getApplicationInfo(apk.packageName, + PackageManager.GET_UNINSTALLED_PACKAGES); } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException("Failed to get ApplicationInfo for uninstalling"); } @@ -86,7 +88,7 @@ public class UninstallDialogActivity extends FragmentActivity { @Override public void onClick(DialogInterface dialog, int which) { Intent data = new Intent(); - data.putExtra(Installer.EXTRA_PACKAGE_NAME, packageName); + data.putExtra(Installer.EXTRA_APK, apk); setResult(Activity.RESULT_OK, intent); finish(); }