diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c5734f480..6f5d2d622 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -402,7 +402,7 @@
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 dac7c5bc3..d31d2641b 100644
--- a/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstaller.java
+++ b/app/src/main/java/org/fdroid/fdroid/installer/DefaultInstaller.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2016 Dominik Schürmann
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
package org.fdroid.fdroid.installer;
import android.app.PendingIntent;
@@ -49,9 +68,9 @@ public class DefaultInstaller extends Installer {
installIntent.setAction(InstallExtensionDialogActivity.ACTION_INSTALL);
installIntent.setData(sanitizedUri);
} else {
- installIntent = new Intent(mContext, AndroidInstallerActivity.class);
- installIntent.setAction(AndroidInstallerActivity.ACTION_INSTALL_PACKAGE);
- installIntent.putExtra(AndroidInstallerActivity.EXTRA_ORIGINATING_URI, originatingUri);
+ installIntent = new Intent(mContext, DefaultInstallerActivity.class);
+ installIntent.setAction(DefaultInstallerActivity.ACTION_INSTALL_PACKAGE);
+ installIntent.putExtra(DefaultInstallerActivity.EXTRA_ORIGINATING_URI, originatingUri);
installIntent.setData(sanitizedUri);
}
@@ -63,7 +82,6 @@ public class DefaultInstaller extends Installer {
sendBroadcastInstall(uri, originatingUri,
Installer.ACTION_INSTALL_USER_INTERACTION, installPendingIntent);
-
}
@Override
@@ -76,10 +94,10 @@ public class DefaultInstaller extends Installer {
uninstallIntent = new Intent(mContext, InstallExtensionDialogActivity.class);
uninstallIntent.setAction(InstallExtensionDialogActivity.ACTION_UNINSTALL);
} else {
- uninstallIntent = new Intent(mContext, AndroidInstallerActivity.class);
- uninstallIntent.setAction(AndroidInstallerActivity.ACTION_UNINSTALL_PACKAGE);
+ uninstallIntent = new Intent(mContext, DefaultInstallerActivity.class);
+ uninstallIntent.setAction(DefaultInstallerActivity.ACTION_UNINSTALL_PACKAGE);
uninstallIntent.putExtra(
- AndroidInstallerActivity.EXTRA_UNINSTALL_PACKAGE_NAME, packageName);
+ DefaultInstallerActivity.EXTRA_UNINSTALL_PACKAGE_NAME, packageName);
}
PendingIntent uninstallPendingIntent = PendingIntent.getActivity(
mContext.getApplicationContext(),
diff --git a/app/src/main/java/org/fdroid/fdroid/installer/ExtensionInstaller.java b/app/src/main/java/org/fdroid/fdroid/installer/ExtensionInstaller.java
new file mode 100644
index 000000000..887d18290
--- /dev/null
+++ b/app/src/main/java/org/fdroid/fdroid/installer/ExtensionInstaller.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2016 Dominik Schürmann
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.fdroid.fdroid.installer;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.util.Log;
+
+import org.fdroid.fdroid.BuildConfig;
+import org.fdroid.fdroid.privileged.install.InstallExtensionDialogActivity;
+
+import java.io.File;
+
+/**
+ * Special Installer that is only useful to install the Privileged Extension apk
+ */
+public class ExtensionInstaller extends Installer {
+
+ private static final String TAG = "ExtensionInstaller";
+
+ ExtensionInstaller(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void installPackage(Uri uri, Uri originatingUri, String packageName) {
+ sendBroadcastInstall(uri, originatingUri, Installer.ACTION_INSTALL_STARTED);
+
+ Uri sanitizedUri;
+ try {
+ sanitizedUri = Installer.prepareApkFile(mContext, uri, packageName);
+ } catch (InstallFailedException e) {
+ Log.e(TAG, "prepareApkFile failed", e);
+ return;
+ }
+
+ // extension must be signed with the same public key as main F-Droid
+ // NOTE: Disabled for debug builds to be able to use official extension from repo
+ ApkSignatureVerifier signatureVerifier = new ApkSignatureVerifier(mContext);
+ if (!BuildConfig.DEBUG && !signatureVerifier.hasFDroidSignature(new File(sanitizedUri.getPath()))) {
+ throw new RuntimeException("APK signature of extension not correct!");
+ }
+ Intent installIntent;
+ installIntent = new Intent(mContext, InstallExtensionDialogActivity.class);
+ installIntent.setAction(InstallExtensionDialogActivity.ACTION_INSTALL);
+ installIntent.setData(sanitizedUri);
+
+ PendingIntent installPendingIntent = PendingIntent.getActivity(
+ mContext.getApplicationContext(),
+ uri.hashCode(),
+ installIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+
+ sendBroadcastInstall(uri, originatingUri,
+ Installer.ACTION_INSTALL_USER_INTERACTION, installPendingIntent);
+ }
+
+ @Override
+ protected void uninstallPackage(String packageName) {
+ sendBroadcastUninstall(packageName, Installer.ACTION_UNINSTALL_STARTED);
+
+ Intent uninstallIntent;
+ uninstallIntent = new Intent(mContext, InstallExtensionDialogActivity.class);
+ uninstallIntent.setAction(InstallExtensionDialogActivity.ACTION_UNINSTALL);
+
+ PendingIntent uninstallPendingIntent = PendingIntent.getActivity(
+ mContext.getApplicationContext(),
+ packageName.hashCode(),
+ uninstallIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+
+ sendBroadcastUninstall(packageName,
+ Installer.ACTION_UNINSTALL_USER_INTERACTION, uninstallPendingIntent);
+ }
+}
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 1d6f6fc6e..3f57b26e4 100644
--- a/app/src/main/java/org/fdroid/fdroid/installer/InstallerFactory.java
+++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallerFactory.java
@@ -30,9 +30,16 @@ public class InstallerFactory {
private static final String TAG = "InstallerFactory";
public static Installer create(Context context) {
+ return create(context, null);
+ }
+
+ public static Installer create(Context context, String packageName) {
Installer installer;
- if (isPrivilegedInstallerEnabled()) {
+ if (packageName != null && packageName.equals(PrivilegedInstaller.PRIVILEGED_EXTENSION_PACKAGE_NAME)) {
+ // special case: F-Droid Privileged Extension
+ installer = new ExtensionInstaller(context);
+ } else if (isPrivilegedInstallerEnabled()) {
if (PrivilegedInstaller.isExtensionInstalledCorrectly(context)
== PrivilegedInstaller.IS_EXTENSION_INSTALLED_YES) {
Utils.debugLog(TAG, "privileged extension correctly installed -> PrivilegedInstaller");
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 323356284..5e8fa5652 100644
--- a/app/src/main/java/org/fdroid/fdroid/installer/InstallerService.java
+++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallerService.java
@@ -71,7 +71,6 @@ public class InstallerService extends Service {
serviceLooper = thread.getLooper();
serviceHandler = new ServiceHandler(serviceLooper);
localBroadcastManager = LocalBroadcastManager.getInstance(this);
- installer = InstallerFactory.create(this);
}
@Override
@@ -118,20 +117,19 @@ public class InstallerService extends Service {
}
protected void handleIntent(Intent intent) {
+ String packageName = intent.getStringExtra(Installer.EXTRA_PACKAGE_NAME);
+ installer = InstallerFactory.create(this, packageName);
+
switch (intent.getAction()) {
case ACTION_INSTALL: {
Uri uri = intent.getData();
Uri originatingUri = intent.getParcelableExtra(Installer.EXTRA_ORIGINATING_URI);
- String packageName = intent.getStringExtra(Installer.EXTRA_PACKAGE_NAME);
installer.installPackage(uri, originatingUri, packageName);
break;
}
case ACTION_UNINSTALL: {
- String packageName =
- intent.getStringExtra(Installer.EXTRA_PACKAGE_NAME);
-
installer.uninstallPackage(packageName);
break;
}