[app] pass App object into installers, so it is available everywhere where needed

This commit is contained in:
Torsten Grote
2022-11-10 11:19:42 -03:00
committed by Hans-Christoph Steiner
parent d3b5620035
commit b0748fc11f
18 changed files with 110 additions and 53 deletions

View File

@@ -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

View File

@@ -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) {

View File

@@ -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(),

View File

@@ -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));

View File

@@ -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(),

View File

@@ -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;

View File

@@ -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!");

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);
}
}
}

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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());

View File

@@ -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());