Move installation of extension into own Installer

This commit is contained in:
Dominik Schürmann 2016-05-28 21:23:48 +03:00
parent c5f9070370
commit de1d310499
5 changed files with 131 additions and 14 deletions

View File

@ -402,7 +402,7 @@
</intent-filter>
</receiver>
<activity
android:name=".installer.AndroidInstallerActivity"
android:name=".installer.DefaultInstallerActivity"
android:theme="@style/AppThemeTransparent" />
<receiver android:name=".receiver.StartupReceiver" >

View File

@ -1,3 +1,22 @@
/*
* Copyright (C) 2016 Dominik Schürmann <dominik@dominikschuermann.de>
*
* 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(),

View File

@ -0,0 +1,94 @@
/*
* Copyright (C) 2016 Dominik Schürmann <dominik@dominikschuermann.de>
*
* 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);
}
}

View File

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

View File

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