Merge branch 'installer-fallback-N' into 'master'

Installer (and uninstall) fallback fixes for API >= 24

See merge request !482
This commit is contained in:
Hans-Christoph Steiner 2017-04-18 21:23:02 +02:00
commit 148d69d9b4
4 changed files with 40 additions and 22 deletions

View File

@ -5,9 +5,8 @@ import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Build; import android.os.Build;
import android.util.Log; import android.util.Log;
import org.fdroid.fdroid.installer.PrivilegedInstaller;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.installer.PrivilegedInstaller;
public class PackageManagerCompat { public class PackageManagerCompat {

View File

@ -338,7 +338,11 @@ public class InstallManagerService extends Service {
Apk apkComplete = appUpdateStatusManager.getApk(downloadUrl); Apk apkComplete = appUpdateStatusManager.getApk(downloadUrl);
if (apkComplete != null) { if (apkComplete != null) {
PackageManagerCompat.setInstaller(context, getPackageManager(), apkComplete.packageName); try {
PackageManagerCompat.setInstaller(context, getPackageManager(), apkComplete.packageName);
} catch (SecurityException e) {
// Will happen if we fell back to DefaultInstaller for some reason.
}
} }
localBroadcastManager.unregisterReceiver(this); localBroadcastManager.unregisterReceiver(this);
break; break;

View File

@ -25,11 +25,14 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.os.PatternMatcher; import android.os.PatternMatcher;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.compat.PackageManagerCompat;
import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.ApkProvider; import org.fdroid.fdroid.data.ApkProvider;
import org.fdroid.fdroid.privileged.views.AppDiff; import org.fdroid.fdroid.privileged.views.AppDiff;
@ -137,6 +140,16 @@ public abstract class Installer {
return null; return null;
} }
try {
PackageManagerCompat.setInstaller(context, context.getPackageManager(), apk.packageName);
} catch (SecurityException e) {
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_APK, apk);
return intent;
}
Intent intent = new Intent(context, UninstallDialogActivity.class); Intent intent = new Intent(context, UninstallDialogActivity.class);
intent.putExtra(Installer.EXTRA_APK, apk); intent.putExtra(Installer.EXTRA_APK, apk);
@ -228,6 +241,19 @@ public abstract class Installer {
* installation of that specific APK * installation of that specific APK
*/ */
public void installPackage(Uri localApkUri, Uri downloadUri) { public void installPackage(Uri localApkUri, Uri downloadUri) {
Uri sanitizedUri;
try {
// move apk file to private directory for installation and check hash
sanitizedUri = ApkFileProvider.getSafeUri(
context, localApkUri, apk, supportsContentUri());
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
sendBroadcastInstall(downloadUri, Installer.ACTION_INSTALL_INTERRUPTED,
e.getMessage());
return;
}
try { try {
// verify that permissions of the apk file match the ones from the apk object // verify that permissions of the apk file match the ones from the apk object
ApkVerifier apkVerifier = new ApkVerifier(context, localApkUri, apk); ApkVerifier apkVerifier = new ApkVerifier(context, localApkUri, apk);
@ -245,23 +271,18 @@ public abstract class Installer {
Log.e(TAG, e.getMessage(), e); Log.e(TAG, e.getMessage(), e);
Log.e(TAG, "Falling back to AOSP DefaultInstaller!"); Log.e(TAG, "Falling back to AOSP DefaultInstaller!");
DefaultInstaller defaultInstaller = new DefaultInstaller(context, apk); DefaultInstaller defaultInstaller = new DefaultInstaller(context, apk);
defaultInstaller.installPackageInternal(localApkUri, downloadUri); // https://code.google.com/p/android/issues/detail?id=205827
if (Build.VERSION.SDK_INT >= 24) {
// content scheme for N and above
defaultInstaller.installPackageInternal(sanitizedUri, downloadUri);
} else {
// file scheme for below N
defaultInstaller.installPackageInternal(localApkUri, downloadUri);
}
return; return;
} }
} }
Uri sanitizedUri;
try {
// move apk file to private directory for installation and check hash
sanitizedUri = ApkFileProvider.getSafeUri(
context, localApkUri, apk, supportsContentUri());
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
sendBroadcastInstall(downloadUri, Installer.ACTION_INSTALL_INTERRUPTED,
e.getMessage());
return;
}
installPackageInternal(sanitizedUri, downloadUri); installPackageInternal(sanitizedUri, downloadUri);
} }

View File

@ -31,10 +31,8 @@ import android.os.Build;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import org.fdroid.fdroid.compat.PackageManagerCompat;
import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.privileged.IPrivilegedCallback; import org.fdroid.fdroid.privileged.IPrivilegedCallback;
import org.fdroid.fdroid.privileged.IPrivilegedService; import org.fdroid.fdroid.privileged.IPrivilegedService;
@ -395,10 +393,6 @@ public class PrivilegedInstaller extends Installer {
} }
}; };
/*
* Set installer to the privileged extension
*/
PackageManagerCompat.setInstaller(context, context.getPackageManager(), apk.packageName);
Intent serviceIntent = new Intent(PRIVILEGED_EXTENSION_SERVICE_INTENT); Intent serviceIntent = new Intent(PRIVILEGED_EXTENSION_SERVICE_INTENT);
serviceIntent.setPackage(PRIVILEGED_EXTENSION_PACKAGE_NAME); serviceIntent.setPackage(PRIVILEGED_EXTENSION_PACKAGE_NAME);
context.getApplicationContext().bindService(serviceIntent, mServiceConnection, context.getApplicationContext().bindService(serviceIntent, mServiceConnection,