diff --git a/app/src/main/java/org/fdroid/fdroid/FDroidApp.java b/app/src/main/java/org/fdroid/fdroid/FDroidApp.java index 51bcc1201..2ea3acd60 100644 --- a/app/src/main/java/org/fdroid/fdroid/FDroidApp.java +++ b/app/src/main/java/org/fdroid/fdroid/FDroidApp.java @@ -27,7 +27,7 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothManager; import android.content.Context; import android.content.Intent; -import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Configuration; @@ -377,12 +377,12 @@ public class FDroidApp extends Application { try { PackageManager pm = getPackageManager(); - ApplicationInfo appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA); + PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_META_DATA); sendBt = new Intent(Intent.ACTION_SEND); // The APK type ("application/vnd.android.package-archive") is blocked by stock Android, so use zip sendBt.setType("application/zip"); - sendBt.putExtra(Intent.EXTRA_STREAM, ApkFileProvider.getSafeUri(this, appInfo)); + sendBt.putExtra(Intent.EXTRA_STREAM, ApkFileProvider.getSafeUri(this, packageInfo)); // not all devices have the same Bluetooth Activities, so // let's find it diff --git a/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java b/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java index c7cf1fd04..5fcc0aa7c 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java @@ -79,9 +79,13 @@ public class AppProvider extends FDroidProvider { return apps; } - public static App findHighestPriorityMetadata(ContentResolver resolver, String packageName) { + public static App findHighestPriorityMetadata(ContentResolver resolver, String packageName, String[] cols) { final Uri uri = getHighestPriorityMetadataUri(packageName); - return cursorToApp(resolver.query(uri, Cols.ALL, null, null, null)); + return cursorToApp(resolver.query(uri, cols, null, null, null)); + } + + public static App findHighestPriorityMetadata(ContentResolver resolver, String packageName) { + return findHighestPriorityMetadata(resolver, packageName, Cols.ALL); } /** diff --git a/app/src/main/java/org/fdroid/fdroid/installer/ApkCache.java b/app/src/main/java/org/fdroid/fdroid/installer/ApkCache.java index 96bbc341a..edf36a078 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/ApkCache.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/ApkCache.java @@ -21,6 +21,7 @@ package org.fdroid.fdroid.installer; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; import android.net.Uri; import com.nostra13.universalimageloader.utils.StorageUtils; @@ -28,6 +29,8 @@ import com.nostra13.universalimageloader.utils.StorageUtils; import org.apache.commons.io.FileUtils; import org.fdroid.fdroid.Hasher; import org.fdroid.fdroid.data.Apk; +import org.fdroid.fdroid.data.App; +import org.fdroid.fdroid.data.AppProvider; import org.fdroid.fdroid.data.SanitizedFile; import java.io.File; @@ -42,8 +45,11 @@ public class ApkCache { * verify the hash after copying. This is because we are copying from an installed apk, which * other apps do not have permission to modify. */ - public static SanitizedFile copyInstalledApkToFiles(Context context, ApplicationInfo appInfo) throws IOException { - return copyApkToFiles(context, new File(appInfo.publicSourceDir), false, null, null); + public static SanitizedFile copyInstalledApkToFiles(Context context, PackageInfo packageInfo) throws IOException { + ApplicationInfo appInfo = packageInfo.applicationInfo; + CharSequence name = context.getPackageManager().getApplicationLabel(appInfo); + String apkFileName = name + "-" + packageInfo.versionName + ".apk"; + return copyApkToFiles(context, new File(appInfo.publicSourceDir), apkFileName, false, null, null); } /** @@ -54,7 +60,10 @@ public class ApkCache { */ public static SanitizedFile copyApkFromCacheToFiles(Context context, File apkFile, Apk expectedApk) throws IOException { - return copyApkToFiles(context, apkFile, true, expectedApk.hash, expectedApk.hashType); + App app = AppProvider.Helper.findHighestPriorityMetadata(context.getContentResolver(), expectedApk.packageName); + String name = app == null ? expectedApk.packageName : app.name; + String apkFileName = name + "-" + expectedApk.versionName + ".apk"; + return copyApkToFiles(context, apkFile, apkFileName, true, expectedApk.hash, expectedApk.hashType); } /** @@ -64,10 +73,17 @@ public class ApkCache { * if the app was installed from part of the system where it can't be tampered * with (e.g. installed apks on disk) then */ - private static SanitizedFile copyApkToFiles(Context context, File apkFile, boolean verifyHash, String hash, String hashType) + private static SanitizedFile copyApkToFiles(Context context, File apkFile, String destinationName, boolean verifyHash, String hash, String hashType) throws IOException { - SanitizedFile sanitizedApkFile = SanitizedFile.knownSanitized( - File.createTempFile("install-", ".apk", context.getFilesDir())); + SanitizedFile sanitizedApkFile = new SanitizedFile(context.getFilesDir(), destinationName); + + // Don't think this is necessary, but the docs for FileUtils#copyFile() are not clear + // on whether it overwrites destination files (pretty confident it does, as per the docs + // in FileUtils#copyFileToDirectory() - which delegates to copyFile()). + if (sanitizedApkFile.exists()) { + sanitizedApkFile.delete(); + } + FileUtils.copyFile(apkFile, sanitizedApkFile); // verify copied file's hash with expected hash from Apk class diff --git a/app/src/main/java/org/fdroid/fdroid/installer/ApkFileProvider.java b/app/src/main/java/org/fdroid/fdroid/installer/ApkFileProvider.java index 1ccda4656..23ca8f46b 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/ApkFileProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/ApkFileProvider.java @@ -21,7 +21,7 @@ package org.fdroid.fdroid.installer; import android.content.Context; import android.content.Intent; -import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; import android.net.Uri; import android.os.Build; import android.support.v4.content.FileProvider; @@ -49,8 +49,8 @@ public class ApkFileProvider extends FileProvider { private static final String AUTHORITY = "org.fdroid.fdroid.installer.ApkFileProvider"; - public static Uri getSafeUri(Context context, ApplicationInfo appInfo) throws IOException { - SanitizedFile tempApkFile = ApkCache.copyInstalledApkToFiles(context, appInfo); + public static Uri getSafeUri(Context context, PackageInfo packageInfo) throws IOException { + SanitizedFile tempApkFile = ApkCache.copyInstalledApkToFiles(context, packageInfo); return getSafeUri(context, tempApkFile, Build.VERSION.SDK_INT >= 24); }