From b0748fc11fee348628916faf407a60d66edeffdb Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Thu, 10 Nov 2022 11:19:42 -0300 Subject: [PATCH] [app] pass App object into installers, so it is available everywhere where needed --- .../fdroid/panic/PanicResponderActivity.java | 6 ++-- .../fdroid/fdroid/AppUpdateStatusManager.java | 11 +++++++ .../fdroid/installer/DefaultInstaller.java | 7 +++-- .../installer/DefaultInstallerActivity.java | 4 ++- .../fdroid/installer/FileInstaller.java | 7 +++-- .../installer/FileInstallerActivity.java | 7 +++-- .../installer/InstallManagerService.java | 10 +++++-- .../fdroid/fdroid/installer/Installer.java | 29 ++++++++++++------- .../fdroid/installer/InstallerFactory.java | 10 ++++--- .../fdroid/installer/InstallerService.java | 15 ++++++---- .../fdroid/installer/ObfInstallerService.java | 25 +++++++++------- .../fdroid/installer/PrivilegedInstaller.java | 5 ++-- .../views/UninstallDialogActivity.java | 3 ++ .../fdroid/views/AppDetailsActivity.java | 6 ++-- .../views/apps/AppListItemController.java | 2 +- .../items/KnownVulnAppListItemController.java | 2 +- .../fdroid/installer/FileInstallerTest.java | 5 +++- .../installer/InstallerFactoryTest.java | 9 ++++-- 18 files changed, 110 insertions(+), 53 deletions(-) diff --git a/app/src/full/java/org/fdroid/fdroid/panic/PanicResponderActivity.java b/app/src/full/java/org/fdroid/fdroid/panic/PanicResponderActivity.java index e5accc7ff..b2d1c1df9 100644 --- a/app/src/full/java/org/fdroid/fdroid/panic/PanicResponderActivity.java +++ b/app/src/full/java/org/fdroid/fdroid/panic/PanicResponderActivity.java @@ -3,12 +3,12 @@ package org.fdroid.fdroid.panic; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.os.Build; import android.os.Bundle; import android.util.Log; import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.DBHelper; import org.fdroid.fdroid.installer.Installer; import org.fdroid.fdroid.installer.InstallerService; @@ -87,9 +87,11 @@ public class PanicResponderActivity extends AppCompatActivity { lbm.registerReceiver(receiver, Installer.getUninstallIntentFilter(lastToUninstall)); for (String packageName : wipeList) { + App app = new App(); Apk apk = new Apk(); + app.packageName = packageName; apk.packageName = packageName; - InstallerService.uninstall(context, apk); + InstallerService.uninstall(context, app, apk); } // wait for apps to uninstall before triggering final responses diff --git a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java index ccc89d7c5..da0013e42 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java +++ b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java @@ -443,6 +443,17 @@ public final class AppUpdateStatusManager { } } + @Nullable + public App getApp(String canonicalUrl) { + synchronized (appMapping) { + AppUpdateStatus entry = appMapping.get(canonicalUrl); + if (entry != null) { + return entry.app; + } + return null; + } + } + @Nullable public Apk getApk(String canonicalUrl) { synchronized (appMapping) { 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 5081b587a..d8b011b5f 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstaller.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstaller.java @@ -26,6 +26,7 @@ import android.content.Intent; import android.net.Uri; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.net.DownloaderService; import androidx.annotation.NonNull; @@ -41,8 +42,8 @@ public class DefaultInstaller extends Installer { public static final String TAG = "DefaultInstaller"; - DefaultInstaller(Context context, @NonNull Apk apk) { - super(context, apk); + DefaultInstaller(Context context, @NonNull App app, @NonNull Apk apk) { + super(context, app, apk); } @Override @@ -51,6 +52,7 @@ public class DefaultInstaller extends Installer { Intent installIntent = new Intent(context, DefaultInstallerActivity.class); installIntent.setAction(DefaultInstallerActivity.ACTION_INSTALL_PACKAGE); installIntent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, canonicalUri.toString()); + installIntent.putExtra(Installer.EXTRA_APP, app); installIntent.putExtra(Installer.EXTRA_APK, apk); installIntent.setData(localApkUri); @@ -68,6 +70,7 @@ public class DefaultInstaller extends Installer { protected void uninstallPackage() { Intent uninstallIntent = new Intent(context, DefaultInstallerActivity.class); uninstallIntent.setAction(DefaultInstallerActivity.ACTION_UNINSTALL_PACKAGE); + uninstallIntent.putExtra(Installer.EXTRA_APP, app); uninstallIntent.putExtra(Installer.EXTRA_APK, apk); PendingIntent uninstallPendingIntent = PendingIntent.getActivity( context.getApplicationContext(), 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 89721b223..0bb6d982a 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstallerActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstallerActivity.java @@ -32,6 +32,7 @@ import android.util.Log; import org.fdroid.fdroid.R; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.net.DownloaderService; import androidx.appcompat.app.AppCompatActivity; @@ -65,8 +66,9 @@ public class DefaultInstallerActivity extends FragmentActivity { Intent intent = getIntent(); String action = intent.getAction(); + App app = intent.getParcelableExtra(Installer.EXTRA_APP); Apk apk = intent.getParcelableExtra(Installer.EXTRA_APK); - installer = new DefaultInstaller(this, apk); + installer = new DefaultInstaller(this, app, apk); if (ACTION_INSTALL_PACKAGE.equals(action)) { Uri localApkUri = intent.getData(); canonicalUri = Uri.parse(intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL)); diff --git a/app/src/main/java/org/fdroid/fdroid/installer/FileInstaller.java b/app/src/main/java/org/fdroid/fdroid/installer/FileInstaller.java index 1509bf2da..a285ae6c9 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/FileInstaller.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/FileInstaller.java @@ -25,14 +25,15 @@ import android.content.Intent; import android.net.Uri; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.net.DownloaderService; import androidx.annotation.NonNull; public class FileInstaller extends Installer { - public FileInstaller(Context context, @NonNull Apk apk) { - super(context, apk); + public FileInstaller(Context context, @NonNull App app, @NonNull Apk apk) { + super(context, app, apk); } @Override @@ -55,6 +56,7 @@ public class FileInstaller extends Installer { Intent installIntent = new Intent(context, FileInstallerActivity.class); installIntent.setAction(FileInstallerActivity.ACTION_INSTALL_FILE); installIntent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, canonicalUri.toString()); + installIntent.putExtra(Installer.EXTRA_APP, app); installIntent.putExtra(Installer.EXTRA_APK, apk); installIntent.setData(localApkUri); @@ -72,6 +74,7 @@ public class FileInstaller extends Installer { protected void uninstallPackage() { Intent uninstallIntent = new Intent(context, FileInstallerActivity.class); uninstallIntent.setAction(FileInstallerActivity.ACTION_UNINSTALL_FILE); + uninstallIntent.putExtra(Installer.EXTRA_APP, app); uninstallIntent.putExtra(Installer.EXTRA_APK, apk); PendingIntent uninstallPendingIntent = PendingIntent.getActivity( context.getApplicationContext(), diff --git a/app/src/main/java/org/fdroid/fdroid/installer/FileInstallerActivity.java b/app/src/main/java/org/fdroid/fdroid/installer/FileInstallerActivity.java index ec3f50ee6..6569be121 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/FileInstallerActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/FileInstallerActivity.java @@ -14,6 +14,7 @@ import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.R; import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.net.DownloaderService; import java.io.File; @@ -40,6 +41,7 @@ public class FileInstallerActivity extends FragmentActivity { // for the broadcasts private FileInstaller installer; + private App app; private Apk apk; private Uri localApkUri; /** @@ -56,8 +58,9 @@ public class FileInstallerActivity extends FragmentActivity { Intent intent = getIntent(); String action = intent.getAction(); localApkUri = intent.getData(); + app = intent.getParcelableExtra(Installer.EXTRA_APP); apk = intent.getParcelableExtra(Installer.EXTRA_APK); - installer = new FileInstaller(this, apk); + installer = new FileInstaller(this, app, apk); if (ACTION_INSTALL_FILE.equals(action)) { canonicalUri = Uri.parse(intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL)); if (hasStoragePermission()) { @@ -182,7 +185,7 @@ public class FileInstallerActivity extends FragmentActivity { */ private boolean postInstall(Uri canonicalUri, Apk apk, File path) { if (path.getName().endsWith(".obf") || path.getName().endsWith(".obf.zip")) { - ObfInstallerService.install(this, canonicalUri, apk, path); + ObfInstallerService.install(this, canonicalUri, app, apk, path); return true; } return false; 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 36d58c9f9..6282f2341 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java @@ -354,9 +354,10 @@ public class InstallManagerService extends Service { localBroadcastManager.unregisterReceiver(this); registerInstallReceiver(canonicalUrl); + App app = appUpdateStatusManager.getApp(canonicalUrl); Apk apk = appUpdateStatusManager.getApk(canonicalUrl); if (apk != null) { - InstallerService.install(context, localApkUri, canonicalUri, apk); + InstallerService.install(context, localApkUri, canonicalUri, app, apk); } break; case DownloaderService.ACTION_INTERRUPTED: @@ -389,6 +390,7 @@ public class InstallManagerService extends Service { return; } String canonicalUrl = intent.getDataString(); + App app; Apk apk; switch (intent.getAction()) { case Installer.ACTION_INSTALL_STARTED: @@ -410,20 +412,22 @@ public class InstallManagerService extends Service { localBroadcastManager.unregisterReceiver(this); break; case Installer.ACTION_INSTALL_INTERRUPTED: + app = intent.getParcelableExtra(Installer.EXTRA_APP); apk = intent.getParcelableExtra(Installer.EXTRA_APK); String errorMessage = intent.getStringExtra(Installer.EXTRA_ERROR_MESSAGE); if (!TextUtils.isEmpty(errorMessage)) { - appUpdateStatusManager.setApkError(null, apk, errorMessage); + appUpdateStatusManager.setApkError(app, apk, errorMessage); } else { appUpdateStatusManager.removeApk(canonicalUrl); } localBroadcastManager.unregisterReceiver(this); break; case Installer.ACTION_INSTALL_USER_INTERACTION: + app = intent.getParcelableExtra(Installer.EXTRA_APP); apk = intent.getParcelableExtra(Installer.EXTRA_APK); PendingIntent installPendingIntent = intent.getParcelableExtra(Installer.EXTRA_USER_INTERACTION_PI); - appUpdateStatusManager.addApk(null, apk, AppUpdateStatusManager.Status.ReadyToInstall, installPendingIntent); + appUpdateStatusManager.addApk(app, apk, AppUpdateStatusManager.Status.ReadyToInstall, installPendingIntent); break; default: throw new RuntimeException("intent action not handled!"); 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 c48df9ed1..995b9754c 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/Installer.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/Installer.java @@ -34,6 +34,7 @@ import android.util.Log; import org.fdroid.fdroid.BuildConfig; import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.privileged.views.AppDiff; import org.fdroid.fdroid.privileged.views.AppSecurityPermissions; import org.fdroid.fdroid.privileged.views.InstallConfirmActivity; @@ -52,6 +53,7 @@ public abstract class Installer { private static final String TAG = "Installer"; final Context context; + final App app; final Apk apk; public static final String AUTHORITY = BuildConfig.APPLICATION_ID + ".installer"; @@ -66,6 +68,7 @@ public abstract class Installer { public static final String ACTION_UNINSTALL_INTERRUPTED = "org.fdroid.fdroid.installer.Installer.action.UNINSTALL_INTERRUPTED"; public static final String ACTION_UNINSTALL_USER_INTERACTION = "org.fdroid.fdroid.installer.Installer.action.UNINSTALL_USER_INTERACTION"; + public static final String EXTRA_APP = "org.fdroid.fdroid.installer.Installer.extra.APP"; public static final String EXTRA_APK = "org.fdroid.fdroid.installer.Installer.extra.APK"; 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"; @@ -74,8 +77,9 @@ public abstract class Installer { * @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, @NonNull Apk apk) { + Installer(Context context, @NonNull App app, @NonNull Apk apk) { this.context = context; + this.app = app; this.apk = apk; } @@ -97,6 +101,7 @@ public abstract class Installer { return null; } Intent intent = new Intent(context, InstallConfirmActivity.class); + intent.putExtra(Installer.EXTRA_APP, app); intent.putExtra(Installer.EXTRA_APK, apk); return intent; @@ -147,34 +152,37 @@ public abstract class Installer { Utils.debugLog(TAG, "Falling back to default installer for uninstall"); Intent intent = new Intent(context, DefaultInstallerActivity.class); intent.setAction(DefaultInstallerActivity.ACTION_UNINSTALL_PACKAGE); + intent.putExtra(Installer.EXTRA_APP, app); intent.putExtra(Installer.EXTRA_APK, apk); return intent; } Intent intent = new Intent(context, UninstallDialogActivity.class); + intent.putExtra(Installer.EXTRA_APP, app); intent.putExtra(Installer.EXTRA_APK, apk); return intent; } void sendBroadcastInstall(Uri canonicalUri, String action, PendingIntent pendingIntent) { - sendBroadcastInstall(context, canonicalUri, action, apk, pendingIntent, null); + sendBroadcastInstall(context, canonicalUri, action, app, apk, pendingIntent, null); } void sendBroadcastInstall(Uri canonicalUri, String action) { - sendBroadcastInstall(context, canonicalUri, action, apk, null, null); + sendBroadcastInstall(context, canonicalUri, action, app, apk, null, null); } void sendBroadcastInstall(Uri canonicalUri, String action, String errorMessage) { - sendBroadcastInstall(context, canonicalUri, action, apk, null, errorMessage); + sendBroadcastInstall(context, canonicalUri, action, app, apk, null, errorMessage); } static void sendBroadcastInstall(Context context, - Uri canonicalUri, String action, Apk apk, + Uri canonicalUri, String action, App app, Apk apk, PendingIntent pendingIntent, String errorMessage) { Intent intent = new Intent(action); intent.setData(canonicalUri); intent.putExtra(Installer.EXTRA_USER_INTERACTION_PI, pendingIntent); + intent.putExtra(Installer.EXTRA_APP, app); intent.putExtra(Installer.EXTRA_APK, apk); if (!TextUtils.isEmpty(errorMessage)) { intent.putExtra(Installer.EXTRA_ERROR_MESSAGE, errorMessage); @@ -195,19 +203,20 @@ public abstract class Installer { } private void sendBroadcastUninstall(String action, PendingIntent pendingIntent, String errorMessage) { - sendBroadcastUninstall(context, apk, action, pendingIntent, errorMessage); + sendBroadcastUninstall(context, app, apk, action, pendingIntent, errorMessage); } - static void sendBroadcastUninstall(Context context, Apk apk, String action) { - sendBroadcastUninstall(context, apk, action, null, null); + static void sendBroadcastUninstall(Context context, App app, Apk apk, String action) { + sendBroadcastUninstall(context, app, apk, action, null, null); } - private static void sendBroadcastUninstall(Context context, Apk apk, String action, + private static void sendBroadcastUninstall(Context context, App app, Apk apk, 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_APP, app); intent.putExtra(Installer.EXTRA_APK, apk); intent.putExtra(Installer.EXTRA_USER_INTERACTION_PI, pendingIntent); if (!TextUtils.isEmpty(errorMessage)) { @@ -300,7 +309,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, apk); + DefaultInstaller defaultInstaller = new DefaultInstaller(context, app, apk); defaultInstaller.installPackageInternal(sanitizedUri, canonicalUri); return; } 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 478d1d1e8..340519865 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallerFactory.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallerFactory.java @@ -24,6 +24,7 @@ import android.content.Context; import android.text.TextUtils; import org.fdroid.fdroid.Utils; +import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.Apk; import androidx.annotation.NonNull; @@ -38,10 +39,11 @@ public class InstallerFactory { * case to install the "F-Droid Privileged Extension" ExtensionInstaller. * * @param context current {@link Context} + * @param app to be installed, always required. * @param apk to be installed, always required. * @return instance of an Installer */ - public static Installer create(Context context, @NonNull Apk apk) { + public static Installer create(Context context, @NonNull App app, @NonNull Apk apk) { if (TextUtils.isEmpty(apk.packageName)) { throw new IllegalArgumentException("Apk.packageName must not be empty: " + apk); } @@ -49,12 +51,12 @@ public class InstallerFactory { Installer installer; if (!apk.isApk()) { Utils.debugLog(TAG, "Using FileInstaller for non-apk file"); - installer = new FileInstaller(context, apk); + installer = new FileInstaller(context, app, apk); } else if (PrivilegedInstaller.isDefault(context)) { Utils.debugLog(TAG, "privileged extension correctly installed -> PrivilegedInstaller"); - installer = new PrivilegedInstaller(context, apk); + installer = new PrivilegedInstaller(context, app, apk); } else { - installer = new DefaultInstaller(context, apk); + installer = new DefaultInstaller(context, app, 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 9dd6ea136..1aa41449a 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallerService.java @@ -68,11 +68,12 @@ public class InstallerService extends JobIntentService { @Override protected void onHandleWork(@NonNull Intent intent) { + final App app = intent.getParcelableExtra(Installer.EXTRA_APP); final Apk apk = intent.getParcelableExtra(Installer.EXTRA_APK); if (apk == null) { return; } - Installer installer = InstallerFactory.create(this, apk); + Installer installer = InstallerFactory.create(this, app, apk); if (ACTION_INSTALL.equals(intent.getAction())) { Uri uri = intent.getData(); @@ -120,13 +121,14 @@ public class InstallerService extends JobIntentService { * @see #uninstall(Context, Apk) * @see InstallManagerService */ - public static void install(Context context, Uri localApkUri, Uri canonicalUri, Apk apk) { - Installer.sendBroadcastInstall(context, canonicalUri, Installer.ACTION_INSTALL_STARTED, apk, - null, null); + public static void install(Context context, Uri localApkUri, Uri canonicalUri, App app, Apk apk) { + Installer.sendBroadcastInstall(context, canonicalUri, Installer.ACTION_INSTALL_STARTED, app, + apk, null, null); Intent intent = new Intent(context, InstallerService.class); intent.setAction(ACTION_INSTALL); intent.setData(localApkUri); intent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, canonicalUri.toString()); + intent.putExtra(Installer.EXTRA_APP, app); intent.putExtra(Installer.EXTRA_APK, apk); enqueueWork(context, intent); } @@ -148,13 +150,14 @@ public class InstallerService extends JobIntentService { * @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, @NonNull Apk apk) { + public static void uninstall(Context context, @NonNull App app, @NonNull Apk apk) { Objects.requireNonNull(apk); - Installer.sendBroadcastUninstall(context, apk, Installer.ACTION_UNINSTALL_STARTED); + Installer.sendBroadcastUninstall(context, app, apk, Installer.ACTION_UNINSTALL_STARTED); Intent intent = new Intent(context, InstallerService.class); intent.setAction(ACTION_UNINSTALL); + intent.putExtra(Installer.EXTRA_APP, app); intent.putExtra(Installer.EXTRA_APK, apk); enqueueWork(context, intent); } diff --git a/app/src/main/java/org/fdroid/fdroid/installer/ObfInstallerService.java b/app/src/main/java/org/fdroid/fdroid/installer/ObfInstallerService.java index 43aac0893..36f150b0b 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/ObfInstallerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/ObfInstallerService.java @@ -13,6 +13,7 @@ import android.webkit.MimeTypeMap; import org.apache.commons.io.FileUtils; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.net.DownloaderService; import java.io.File; @@ -38,10 +39,11 @@ public class ObfInstallerService extends IntentService { super("ObfInstallerService"); } - public static void install(Context context, Uri canonicalUri, Apk apk, File path) { + public static void install(Context context, Uri canonicalUri, App app, Apk apk, File path) { Intent intent = new Intent(context, ObfInstallerService.class); intent.setAction(ACTION_INSTALL_OBF); intent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, canonicalUri.toString()); + intent.putExtra(Installer.EXTRA_APP, app); intent.putExtra(Installer.EXTRA_APK, apk); intent.putExtra(EXTRA_OBF_PATH, path.getAbsolutePath()); context.startService(intent); @@ -54,15 +56,16 @@ public class ObfInstallerService extends IntentService { return; } Uri canonicalUri = Uri.parse(intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL)); + final App app = intent.getParcelableExtra(Installer.EXTRA_APP); final Apk apk = intent.getParcelableExtra(Installer.EXTRA_APK); final String path = intent.getStringExtra(EXTRA_OBF_PATH); final String extension = MimeTypeMap.getFileExtensionFromUrl(path); if ("obf".equals(extension)) { - sendPostInstallAndCompleteIntents(canonicalUri, apk, new File(path)); + sendPostInstallAndCompleteIntents(canonicalUri, app, apk, new File(path)); return; } if (!"zip".equals(extension)) { - sendBroadcastInstall(Installer.ACTION_INSTALL_INTERRUPTED, canonicalUri, apk, + sendBroadcastInstall(Installer.ACTION_INSTALL_INTERRUPTED, canonicalUri, app, apk, "Only .obf and .zip files are supported: " + path); return; } @@ -70,7 +73,7 @@ public class ObfInstallerService extends IntentService { File zip = new File(path); ZipFile zipFile = new ZipFile(zip); if (zipFile.size() < 1) { - sendBroadcastInstall(Installer.ACTION_INSTALL_INTERRUPTED, canonicalUri, apk, + sendBroadcastInstall(Installer.ACTION_INSTALL_INTERRUPTED, canonicalUri, app, apk, "Corrupt or empty ZIP file!"); } ZipEntry zipEntry = zipFile.entries().nextElement(); @@ -79,15 +82,15 @@ public class ObfInstallerService extends IntentService { FileUtils.copyInputStreamToFile(zipFile.getInputStream(zipEntry), extracted); // Since we delete the file here, it won't show as installed anymore zip.delete(); - sendPostInstallAndCompleteIntents(canonicalUri, apk, extracted); + sendPostInstallAndCompleteIntents(canonicalUri, app, apk, extracted); } catch (IOException e) { e.printStackTrace(); - sendBroadcastInstall(Installer.ACTION_INSTALL_INTERRUPTED, canonicalUri, apk, e.getMessage()); + sendBroadcastInstall(Installer.ACTION_INSTALL_INTERRUPTED, canonicalUri, app, apk, e.getMessage()); } } - private void sendBroadcastInstall(String action, Uri canonicalUri, Apk apk, String msg) { - Installer.sendBroadcastInstall(this, canonicalUri, action, apk, null, msg); + private void sendBroadcastInstall(String action, Uri canonicalUri, App app, Apk apk, String msg) { + Installer.sendBroadcastInstall(this, canonicalUri, action, app, apk, null, msg); } /** @@ -97,7 +100,7 @@ public class ObfInstallerService extends IntentService { * When this was written, OsmAnd only supported importing OBF files via a * {@code file:///} URL, so this disables {@link android.os.FileUriExposedException}. */ - void sendPostInstallAndCompleteIntents(Uri canonicalUri, Apk apk, File file) { + void sendPostInstallAndCompleteIntents(Uri canonicalUri, App app, Apk apk, File file) { if (Build.VERSION.SDK_INT >= 24) { try { Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure"); @@ -122,10 +125,10 @@ public class ObfInstallerService extends IntentService { | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); - sendBroadcastInstall(Installer.ACTION_INSTALL_COMPLETE, canonicalUri, apk, null); + sendBroadcastInstall(Installer.ACTION_INSTALL_COMPLETE, canonicalUri, app, apk, null); } else { Log.i(TAG, "No AppCompatActivity available to handle " + intent); - sendBroadcastInstall(Installer.ACTION_INSTALL_INTERRUPTED, canonicalUri, apk, null); + sendBroadcastInstall(Installer.ACTION_INSTALL_INTERRUPTED, canonicalUri, app, apk, null); } } } \ No newline at end of file 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 9465f1651..14eb5b9ea 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/PrivilegedInstaller.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/PrivilegedInstaller.java @@ -35,6 +35,7 @@ import org.fdroid.fdroid.BuildConfig; import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.R; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.privileged.IPrivilegedCallback; import org.fdroid.fdroid.privileged.IPrivilegedService; @@ -251,8 +252,8 @@ public class PrivilegedInstaller extends Installer { "device owner has marked the package as uninstallable."); } - PrivilegedInstaller(Context context, @NonNull Apk apk) { - super(context, apk); + PrivilegedInstaller(Context context, App app, @NonNull Apk apk) { + super(context, app, apk); } private static boolean isExtensionInstalled(Context context) { 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 e3f9b587a..d66fc1c77 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 @@ -29,6 +29,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.data.App; import org.fdroid.fdroid.installer.Installer; import androidx.annotation.Nullable; @@ -50,6 +51,7 @@ public class UninstallDialogActivity extends FragmentActivity { super.onCreate(savedInstanceState); final Intent intent = getIntent(); + final App app = intent.getParcelableExtra(Installer.EXTRA_APP); final Apk apk = intent.getParcelableExtra(Installer.EXTRA_APK); PackageManager pm = getPackageManager(); @@ -89,6 +91,7 @@ public class UninstallDialogActivity extends FragmentActivity { @Override public void onClick(DialogInterface dialog, int which) { Intent data = new Intent(); + data.putExtra(Installer.EXTRA_APP, app); data.putExtra(Installer.EXTRA_APK, apk); setResult(AppCompatActivity.RESULT_OK, intent); finish(); diff --git a/app/src/main/java/org/fdroid/fdroid/views/AppDetailsActivity.java b/app/src/main/java/org/fdroid/fdroid/views/AppDetailsActivity.java index 4833f43ed..e274efbf6 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/AppDetailsActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/views/AppDetailsActivity.java @@ -426,7 +426,7 @@ public class AppDetailsActivity extends AppCompatActivity } private void initiateInstall(Apk apk) { - Installer installer = InstallerFactory.create(this, apk); + Installer installer = InstallerFactory.create(this, app, apk); Intent intent = installer.getPermissionScreen(); if (intent != null) { // permission screen required @@ -440,7 +440,7 @@ public class AppDetailsActivity extends AppCompatActivity private void startUninstall() { registerUninstallReceiver(); - InstallerService.uninstall(this, app.installedApk); + InstallerService.uninstall(this, app, app.installedApk); } private void registerUninstallReceiver() { @@ -837,7 +837,7 @@ public class AppDetailsActivity extends AppCompatActivity } app.installedApk = apk; } - Installer installer = InstallerFactory.create(this, apk); + Installer installer = InstallerFactory.create(this, app, apk); Intent intent = installer.getUninstallScreen(); if (intent != null) { // uninstall screen required diff --git a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java index cb3fabac5..89dce45c8 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java +++ b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java @@ -537,7 +537,7 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder { Uri canonicalUri = Uri.parse(canonicalUrl); broadcastManager.registerReceiver(receiver, Installer.getInstallIntentFilter(canonicalUri)); - Installer installer = InstallerFactory.create(activity, currentStatus.apk); + Installer installer = InstallerFactory.create(activity, currentStatus.app, currentStatus.apk); installer.installPackage(Uri.parse(apkFilePath.toURI().toString()), canonicalUri); } else { FDroidDatabase db = DBHelper.getDb(activity); diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java index b302402b0..92fbacd35 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java +++ b/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java @@ -73,7 +73,7 @@ public class KnownVulnAppListItemController extends AppListItemController { InstallManagerService.queue(activity, app, currentApk); } else { manager.registerReceiver(installReceiver, Installer.getUninstallIntentFilter(app.packageName)); - InstallerService.uninstall(activity, installedApk); + InstallerService.uninstall(activity, app, installedApk); } } diff --git a/app/src/test/java/org/fdroid/fdroid/installer/FileInstallerTest.java b/app/src/test/java/org/fdroid/fdroid/installer/FileInstallerTest.java index fb6d6f720..4e2a1b9c9 100644 --- a/app/src/test/java/org/fdroid/fdroid/installer/FileInstallerTest.java +++ b/app/src/test/java/org/fdroid/fdroid/installer/FileInstallerTest.java @@ -4,6 +4,7 @@ import android.content.ContextWrapper; import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.data.App; import org.fdroid.index.v2.FileV1; import org.junit.Before; import org.junit.Test; @@ -30,12 +31,14 @@ public class FileInstallerTest { @Test public void testInstallOtaZip() { + App app = new App(); + app.packageName = "org.fdroid.fdroid.privileged.ota"; Apk apk = new Apk(); apk.apkFile = new FileV1("org.fdroid.fdroid.privileged.ota_2010.zip", "hash", null, null); apk.packageName = "org.fdroid.fdroid.privileged.ota"; apk.versionCode = 2010; assertFalse(apk.isApk()); - Installer installer = InstallerFactory.create(context, apk); + Installer installer = InstallerFactory.create(context, app, apk); assertEquals("should be a FileInstaller", FileInstaller.class, installer.getClass()); diff --git a/app/src/test/java/org/fdroid/fdroid/installer/InstallerFactoryTest.java b/app/src/test/java/org/fdroid/fdroid/installer/InstallerFactoryTest.java index 8265bfd80..9d0c6549d 100644 --- a/app/src/test/java/org/fdroid/fdroid/installer/InstallerFactoryTest.java +++ b/app/src/test/java/org/fdroid/fdroid/installer/InstallerFactoryTest.java @@ -4,6 +4,7 @@ import android.content.ContextWrapper; import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.data.App; import org.fdroid.index.v2.FileV1; import org.junit.Before; import org.junit.Test; @@ -28,10 +29,12 @@ public class InstallerFactoryTest { @Test public void testApkInstallerInstance() { for (String filename : new String[]{"test.apk", "A.APK", "b.ApK"}) { + App app = new App(); + app.packageName = "test"; Apk apk = new Apk(); apk.apkFile = new FileV1(filename, "hash", null, null); apk.packageName = "test"; - Installer installer = InstallerFactory.create(context, apk); + Installer installer = InstallerFactory.create(context, app, apk); assertEquals(filename + " should use a DefaultInstaller", DefaultInstaller.class, installer.getClass()); @@ -41,10 +44,12 @@ public class InstallerFactoryTest { @Test public void testFileInstallerInstance() { for (String filename : new String[]{"org.fdroid.fdroid.privileged.ota_2110.zip", "test.ZIP"}) { + App app = new App(); + app.packageName = "cafe0088"; Apk apk = new Apk(); apk.apkFile = new FileV1(filename, "hash", null, null); apk.packageName = "cafe0088"; - Installer installer = InstallerFactory.create(context, apk); + Installer installer = InstallerFactory.create(context, app, apk); assertEquals("should be a FileInstaller", FileInstaller.class, installer.getClass());