[app] Remove code for SDK versions that we don't support anymore

This commit is contained in:
Torsten Grote
2022-06-16 12:25:08 -03:00
committed by Hans-Christoph Steiner
parent 6c007e92b3
commit d000f3fade
35 changed files with 122 additions and 668 deletions

View File

@@ -141,10 +141,6 @@ final public class WifiApControl {
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
private static String getDeviceName(WifiManager wifiManager) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
Log.w(TAG, "Older device - falling back to the default device name: " + FALLBACK_DEVICE);
return FALLBACK_DEVICE;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Log.w(TAG, "6.0 or later, unaccessible MAC - falling back to the default device name: " + FALLBACK_DEVICE);
return FALLBACK_DEVICE;

View File

@@ -88,29 +88,21 @@ public class SDCardScannerService extends IntentService {
Process.setThreadPriority(Process.THREAD_PRIORITY_LOWEST);
HashSet<File> files = new HashSet<>();
if (Build.VERSION.SDK_INT < 21) {
if (Environment.isExternalStorageRemovable()) {
File sdcard = Environment.getExternalStorageDirectory();
String state = Environment.getExternalStorageState();
Collections.addAll(files, checkExternalStorage(sdcard, state));
for (File f : getExternalFilesDirs(null)) {
Log.i(TAG, "getExternalFilesDirs " + f);
if (f == null || !f.isDirectory()) {
continue;
}
} else {
for (File f : getExternalFilesDirs(null)) {
Log.i(TAG, "getExternalFilesDirs " + f);
if (f == null || !f.isDirectory()) {
continue;
}
Log.i(TAG, "getExternalFilesDirs " + f);
if (Environment.isExternalStorageRemovable(f)) {
String state = Environment.getExternalStorageState(f);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
// remove Android/data/org.fdroid.fdroid/files to get root
File sdcard = f.getParentFile().getParentFile().getParentFile().getParentFile();
Collections.addAll(files, checkExternalStorage(sdcard, state));
} else {
Collections.addAll(files, checkExternalStorage(f, state));
}
Log.i(TAG, "getExternalFilesDirs " + f);
if (Environment.isExternalStorageRemovable(f)) {
String state = Environment.getExternalStorageState(f);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
// remove Android/data/org.fdroid.fdroid/files to get root
File sdcard = f.getParentFile().getParentFile().getParentFile().getParentFile();
Collections.addAll(files, checkExternalStorage(sdcard, state));
} else {
Collections.addAll(files, checkExternalStorage(f, state));
}
}
}

View File

@@ -106,11 +106,9 @@ public class TreeUriScannerIntentService extends IntentService {
}
Uri uri = intent.getData();
if (uri != null) {
if (Build.VERSION.SDK_INT >= 19) {
ContentResolver contentResolver = context.getContentResolver();
int perms = Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
contentResolver.takePersistableUriPermission(uri, perms);
}
ContentResolver contentResolver = context.getContentResolver();
int perms = Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
contentResolver.takePersistableUriPermission(uri, perms);
String msg = String.format(context.getString(R.string.swap_toast_using_path), uri.toString());
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
scan(context, uri);

View File

@@ -48,9 +48,6 @@ public class UsbDeviceAttachedReceiver extends BroadcastReceiver {
@RequiresApi(api = 19)
@Override
public void onReceive(final Context context, Intent intent) {
if (Build.VERSION.SDK_INT < 19) {
return;
}
if (intent == null || TextUtils.isEmpty(intent.getAction())
|| !UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {

View File

@@ -48,10 +48,6 @@ public class UsbDeviceDetachedReceiver extends BroadcastReceiver {
@RequiresApi(api = 19)
@Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT < 19) {
return;
}
if (intent == null || TextUtils.isEmpty(intent.getAction())
|| !UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getAction())) {
Log.i(TAG, "ignoring irrelevant intent: " + intent);

View File

@@ -12,11 +12,7 @@ public class ExitActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= 21) {
finishAndRemoveTask();
} else {
finish();
}
finishAndRemoveTask();
System.exit(0);
}

View File

@@ -137,8 +137,6 @@ public class PanicResponderActivity extends AppCompatActivity {
private void exitAndClear() {
ExitActivity.exitAndRemoveFromRecentApps(this);
if (Build.VERSION.SDK_INT >= 21) {
finishAndRemoveTask();
}
finishAndRemoveTask();
}
}

View File

@@ -96,26 +96,19 @@ public class NearbyViewBinder {
}
});
if (Build.VERSION.SDK_INT >= 21) {
File[] dirs = activity.getExternalFilesDirs("");
if (dirs != null) {
for (File dir : dirs) {
if (dir != null && Environment.isExternalStorageRemovable(dir)) {
String state = Environment.getExternalStorageState(dir);
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)
|| Environment.MEDIA_MOUNTED.equals(state)) {
// remove Android/data/org.fdroid.fdroid/files to get root
externalStorage = dir.getParentFile().getParentFile().getParentFile().getParentFile();
break;
}
File[] dirs = activity.getExternalFilesDirs("");
if (dirs != null) {
for (File dir : dirs) {
if (dir != null && Environment.isExternalStorageRemovable(dir)) {
String state = Environment.getExternalStorageState(dir);
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)
|| Environment.MEDIA_MOUNTED.equals(state)) {
// remove Android/data/org.fdroid.fdroid/files to get root
externalStorage = dir.getParentFile().getParentFile().getParentFile().getParentFile();
break;
}
}
}
} else if (Environment.isExternalStorageRemovable() &&
(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY)
|| Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))) {
Log.i(TAG, "<21 isExternalStorageRemovable MEDIA_MOUNTED");
externalStorage = Environment.getExternalStorageDirectory();
}
final String writeExternalStorage = Manifest.permission.WRITE_EXTERNAL_STORAGE;

View File

@@ -5,7 +5,6 @@ import android.content.pm.FeatureInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import org.fdroid.fdroid.compat.SupportedArchitectures;
import org.fdroid.fdroid.data.Apk;
import java.util.ArrayList;
@@ -45,7 +44,7 @@ public class CompatibilityChecker {
}
}
cpuAbis = SupportedArchitectures.getAbis();
cpuAbis = Build.SUPPORTED_ABIS;
}
private boolean compatibleApi(@Nullable String[] nativecode) {

View File

@@ -56,7 +56,6 @@ import org.fdroid.database.FDroidDatabase;
import org.fdroid.database.Repository;
import org.fdroid.fdroid.Preferences.ChangeListener;
import org.fdroid.fdroid.Preferences.Theme;
import org.fdroid.fdroid.compat.PRNGFixes;
import org.fdroid.fdroid.data.App;
import org.fdroid.fdroid.data.DBHelper;
import org.fdroid.fdroid.installer.ApkFileProvider;
@@ -327,24 +326,10 @@ public class FDroidApp extends Application implements androidx.work.Configuratio
FDroidDatabase db = DBHelper.getDb(this);
db.getRepositoryDao().getLiveRepositories().observeForever(repositories -> repos = repositories);
PRNGFixes.apply();
applyTheme();
configureProxy(preferences);
// bug specific to exactly 5.0 makes it only work with the old index
// which includes an ugly, hacky workaround
// https://gitlab.com/fdroid/fdroidclient/issues/1014
if (Build.VERSION.SDK_INT == 21) {
preferences.setExpertMode(true);
preferences.setForceOldIndex(true);
}
// TODO should not be needed anymore
//InstalledAppProviderService.compareToPackageManager(this);
// If the user changes the preference to do with filtering anti-feature apps,
// it is easier to just notify a change in the app provider,
// so that the newly updated list will correctly filter relevant apps.
@@ -393,9 +378,7 @@ public class FDroidApp extends Application implements androidx.work.Configuratio
if (!TextUtils.equals(packageName, unset)) {
int modeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
if (Build.VERSION.SDK_INT >= 19) {
modeFlags |= Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION;
}
modeFlags |= Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION;
grantUriPermission(packageName, InstallHistoryService.LOG_URI, modeFlags);
}

View File

@@ -108,11 +108,7 @@ public final class Languages {
final Resources resources = contextWrapper.getBaseContext().getResources();
Configuration config = resources.getConfiguration();
if (Build.VERSION.SDK_INT >= 17) {
config.setLocale(locale);
} else {
config.locale = locale;
}
config.setLocale(locale);
resources.updateConfiguration(config, resources.getDisplayMetrics());
}

View File

@@ -8,7 +8,6 @@ import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.os.Build;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
@@ -34,9 +33,6 @@ public class NfcHelper {
@TargetApi(16)
public static void setAndroidBeam(AppCompatActivity activity, String packageName) {
if (Build.VERSION.SDK_INT < 16) {
return;
}
PackageManager pm = activity.getPackageManager();
NfcAdapter nfcAdapter = getAdapter(activity);
if (nfcAdapter != null) {
@@ -55,9 +51,6 @@ public class NfcHelper {
@TargetApi(16)
public static void disableAndroidBeam(AppCompatActivity activity) {
if (Build.VERSION.SDK_INT < 16) {
return;
}
NfcAdapter nfcAdapter = getAdapter(activity);
if (nfcAdapter != null) {
nfcAdapter.setBeamPushUris(null, activity);

View File

@@ -3,7 +3,6 @@ package org.fdroid.fdroid;
import android.annotation.TargetApi;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
@@ -32,12 +31,6 @@ public class NfcNotEnabledActivity extends AppCompatActivity {
}
}
// this API was added in 4.0 aka Ice Cream Sandwich
@TargetApi(14)
private void doOnIceCreamSandwich(Intent intent) {
intent.setAction(Settings.ACTION_NFCSHARING_SETTINGS);
}
@Override
public void onCreate(Bundle savedInstanceState) {
FDroidApp fdroidApp = (FDroidApp) getApplication();
@@ -46,11 +39,7 @@ public class NfcNotEnabledActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
final Intent intent = new Intent();
if (Build.VERSION.SDK_INT >= 16) {
doOnJellybean(intent);
} else {
doOnIceCreamSandwich(intent);
}
doOnJellybean(intent);
startActivity(intent);
finish();
}

View File

@@ -18,9 +18,7 @@
package org.fdroid.fdroid;
import android.app.AlarmManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.BroadcastReceiver;
@@ -32,7 +30,6 @@ import android.content.IntentFilter;
import android.net.Uri;
import android.os.Build;
import android.os.Process;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
@@ -173,43 +170,28 @@ public class UpdateService extends JobIntentService {
interval != Preferences.UPDATE_INTERVAL_DISABLED
&& !(data == Preferences.OVER_NETWORK_NEVER && wifi == Preferences.OVER_NETWORK_NEVER);
if (Build.VERSION.SDK_INT < 21) {
Intent intent = new Intent(context, UpdateService.class);
PendingIntent pending = PendingIntent.getService(context, 0, intent, 0);
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pending);
if (scheduleNewJob) {
alarm.setInexactRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 5000, interval, pending);
Utils.debugLog(TAG, "Update scheduler alarm set");
} else {
Utils.debugLog(TAG, "Update scheduler alarm not set");
}
Utils.debugLog(TAG, "Using android-21 JobScheduler for updates");
JobScheduler jobScheduler = ContextCompat.getSystemService(context, JobScheduler.class);
ComponentName componentName = new ComponentName(context, UpdateJobService.class);
JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, componentName)
.setRequiresDeviceIdle(true)
.setPeriodic(interval);
if (Build.VERSION.SDK_INT >= 26) {
builder.setRequiresBatteryNotLow(true)
.setRequiresStorageNotLow(true);
}
if (data == Preferences.OVER_NETWORK_ALWAYS && wifi == Preferences.OVER_NETWORK_ALWAYS) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
} else {
Utils.debugLog(TAG, "Using android-21 JobScheduler for updates");
JobScheduler jobScheduler = ContextCompat.getSystemService(context, JobScheduler.class);
ComponentName componentName = new ComponentName(context, UpdateJobService.class);
JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, componentName)
.setRequiresDeviceIdle(true)
.setPeriodic(interval);
if (Build.VERSION.SDK_INT >= 26) {
builder.setRequiresBatteryNotLow(true)
.setRequiresStorageNotLow(true);
}
if (data == Preferences.OVER_NETWORK_ALWAYS && wifi == Preferences.OVER_NETWORK_ALWAYS) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
} else {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
}
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
}
jobScheduler.cancel(JOB_ID);
if (scheduleNewJob) {
jobScheduler.schedule(builder.build());
Utils.debugLog(TAG, "Update scheduler alarm set");
} else {
Utils.debugLog(TAG, "Update scheduler alarm not set");
}
jobScheduler.cancel(JOB_ID);
if (scheduleNewJob) {
jobScheduler.schedule(builder.build());
Utils.debugLog(TAG, "Update scheduler alarm set");
} else {
Utils.debugLog(TAG, "Update scheduler alarm not set");
}
}

View File

@@ -27,7 +27,6 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.StatFs;
@@ -181,11 +180,7 @@ public final class Utils {
return 50 * 1024 * 1024; // just return a minimal amount
}
StatFs stat = new StatFs(statDir.getPath());
if (Build.VERSION.SDK_INT < 18) {
return (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
} else {
return stat.getAvailableBlocksLong() * stat.getBlockSizeLong();
}
return stat.getAvailableBlocksLong() * stat.getBlockSizeLong();
}
public static long getImageCacheDirTotalMemory(Context context) {
@@ -197,11 +192,7 @@ public final class Utils {
return 100 * 1024 * 1024; // just return a minimal amount
}
StatFs stat = new StatFs(statDir.getPath());
if (Build.VERSION.SDK_INT < 18) {
return (long) stat.getBlockCount() * (long) stat.getBlockSize();
} else {
return stat.getBlockCountLong() * stat.getBlockSizeLong();
}
return stat.getBlockCountLong() * stat.getBlockSizeLong();
}
public static void copy(InputStream input, OutputStream output) throws IOException {

View File

@@ -25,15 +25,7 @@ public class FileCompat {
private static final String TAG = "FileCompat";
public static boolean symlink(SanitizedFile source, SanitizedFile dest) {
if (Build.VERSION.SDK_INT >= 21) {
symlinkOs(source, dest);
} else if (Build.VERSION.SDK_INT >= 15) {
symlinkLibcore(source, dest);
} else {
symlinkRuntime(source, dest);
}
symlinkOs(source, dest);
return dest.exists();
}

View File

@@ -1,326 +0,0 @@
package org.fdroid.fdroid.compat;
/*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will Google be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, as long as the origin is not misrepresented.
*/
import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Process;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.SecureRandomSpi;
import java.security.Security;
/**
* Fixes for the output of the default PRNG having low entropy.
* <p>
* The fixes need to be applied via {@link #apply()} before any use of Java
* Cryptography Architecture primitives. A good place to invoke them is in the
* application's {@code onCreate}.
*
* @see <a href="http://android-developers.blogspot.jp/2013/08/some-securerandom-thoughts.html">Some SecureRandom Thoughts</a>
*/
public final class PRNGFixes {
private static final byte[] BUILD_FINGERPRINT_AND_DEVICE_SERIAL =
getBuildFingerprintAndDeviceSerial();
/**
* Hidden constructor to prevent instantiation.
*/
private PRNGFixes() {
}
/**
* Applies all fixes.
*
* @throws SecurityException if a fix is needed but could not be applied.
*/
public static void apply() {
applyOpenSSLFix();
installLinuxPRNGSecureRandom();
}
/**
* Applies the fix for OpenSSL PRNG having low entropy. Does nothing if the
* fix is not needed.
*
* @throws SecurityException if the fix is needed but could not be applied.
*/
private static void applyOpenSSLFix() throws SecurityException {
if (Build.VERSION.SDK_INT < 16 || Build.VERSION.SDK_INT > 18) {
// No need to apply the fix
return;
}
try {
// Mix in the device- and invocation-specific seed.
Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto")
.getMethod("RAND_seed", byte[].class)
.invoke(null, generateSeed());
// Mix output of Linux PRNG into OpenSSL's PRNG
int bytesRead = (Integer) Class.forName(
"org.apache.harmony.xnet.provider.jsse.NativeCrypto")
.getMethod("RAND_load_file", String.class, long.class)
.invoke(null, "/dev/urandom", 1024);
if (bytesRead != 1024) {
throw new IOException(
"Unexpected number of bytes read from Linux PRNG: "
+ bytesRead);
}
} catch (Exception e) {
throw new SecurityException("Failed to seed OpenSSL PRNG", e);
}
}
/**
* Installs a Linux PRNG-backed {@code SecureRandom} implementation as the
* default. Does nothing if the implementation is already the default or if
* there is not need to install the implementation.
*
* @throws SecurityException if the fix is needed but could not be applied.
*/
private static void installLinuxPRNGSecureRandom()
throws SecurityException {
if (Build.VERSION.SDK_INT > 18) {
// No need to apply the fix
return;
}
// Install a Linux PRNG-based SecureRandom implementation as the
// default, if not yet installed.
Provider[] secureRandomProviders = Security.getProviders("SecureRandom.SHA1PRNG");
if (secureRandomProviders == null
|| secureRandomProviders.length < 1
|| !LinuxPRNGSecureRandomProvider.class.equals(secureRandomProviders[0].getClass())) {
Security.insertProviderAt(new LinuxPRNGSecureRandomProvider(), 1);
}
// Assert that new SecureRandom() and
// SecureRandom.getInstance("SHA1PRNG") return a SecureRandom backed
// by the Linux PRNG-based SecureRandom implementation.
SecureRandom rng1 = new SecureRandom();
if (!LinuxPRNGSecureRandomProvider.class.equals(
rng1.getProvider().getClass())) {
throw new SecurityException(
"new SecureRandom() backed by wrong Provider: "
+ rng1.getProvider().getClass());
}
SecureRandom rng2;
try {
rng2 = SecureRandom.getInstance("SHA1PRNG");
} catch (NoSuchAlgorithmException e) {
throw new SecurityException("SHA1PRNG not available", e);
}
if (!LinuxPRNGSecureRandomProvider.class.equals(
rng2.getProvider().getClass())) {
throw new SecurityException(
"SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong"
+ " Provider: " + rng2.getProvider().getClass());
}
}
/**
* {@code Provider} of {@code SecureRandom} engines which pass through
* all requests to the Linux PRNG.
*/
@SuppressWarnings("serial")
private static class LinuxPRNGSecureRandomProvider extends Provider {
LinuxPRNGSecureRandomProvider() {
super("LinuxPRNG",
1.0,
"A Linux-specific random number provider that uses"
+ " /dev/urandom");
// Although /dev/urandom is not a SHA-1 PRNG, some apps
// explicitly request a SHA1PRNG SecureRandom and we thus need to
// prevent them from getting the default implementation whose output
// may have low entropy.
put("SecureRandom.SHA1PRNG", LinuxPRNGSecureRandom.class.getName());
put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
}
}
/**
* {@link SecureRandomSpi} which passes all requests to the Linux PRNG
* ({@code /dev/urandom}).
*/
@SuppressWarnings("serial")
public static class LinuxPRNGSecureRandom extends SecureRandomSpi {
private static final String TAG = "PRNGFixes";
/*
* IMPLEMENTATION NOTE: Requests to generate bytes and to mix in a seed
* are passed through to the Linux PRNG (/dev/urandom). Instances of
* this class seed themselves by mixing in the current time, PID, UID,
* build fingerprint, and hardware serial number (where available) into
* Linux PRNG.
*
* Concurrency: Read requests to the underlying Linux PRNG are
* serialized (on S_LOCK) to ensure that multiple threads do not get
* duplicated PRNG output.
*/
private static final File URANDOM_FILE = new File("/dev/urandom");
private static final Object S_LOCK = new Object();
/**
* Input stream for reading from Linux PRNG or {@code null} if not yet
* opened.
*
* @GuardedBy("S_LOCK")
*/
private static DataInputStream sUrandomIn;
/**
* Output stream for writing to Linux PRNG or {@code null} if not yet
* opened.
*
* @GuardedBy("S_LOCK")
*/
private static OutputStream sUrandomOut;
/**
* Whether this engine instance has been seeded. This is needed because
* each instance needs to seed itself if the client does not explicitly
* seed it.
*/
private boolean seeded;
@Override
protected void engineSetSeed(byte[] bytes) {
try {
OutputStream out;
synchronized (S_LOCK) {
out = getUrandomOutputStream();
}
out.write(bytes);
out.flush();
} catch (IOException e) {
// On a small fraction of devices /dev/urandom is not writable.
// Log and ignore.
Log.w(TAG, "Failed to mix seed into " + URANDOM_FILE);
} finally {
seeded = true;
}
}
@Override
protected void engineNextBytes(byte[] bytes) {
if (!seeded) {
// Mix in the device- and invocation-specific seed.
engineSetSeed(generateSeed());
}
try {
DataInputStream in;
synchronized (S_LOCK) {
in = getUrandomInputStream();
}
synchronized (in) {
in.readFully(bytes);
}
} catch (IOException e) {
throw new SecurityException(
"Failed to read from " + URANDOM_FILE, e);
}
}
@Override
protected byte[] engineGenerateSeed(int size) {
byte[] seed = new byte[size];
engineNextBytes(seed);
return seed;
}
private DataInputStream getUrandomInputStream() {
synchronized (S_LOCK) {
if (sUrandomIn == null) {
// NOTE: Consider inserting a BufferedInputStream between
// DataInputStream and FileInputStream if you need higher
// PRNG output performance and can live with future PRNG
// output being pulled into this process prematurely.
try {
sUrandomIn = new DataInputStream(
new FileInputStream(URANDOM_FILE));
} catch (IOException e) {
throw new SecurityException("Failed to open "
+ URANDOM_FILE + " for reading", e);
}
}
return sUrandomIn;
}
}
private OutputStream getUrandomOutputStream() throws IOException {
synchronized (S_LOCK) {
if (sUrandomOut == null) {
sUrandomOut = new FileOutputStream(URANDOM_FILE);
}
return sUrandomOut;
}
}
}
/**
* Generates a device- and invocation-specific seed to be mixed into the
* Linux PRNG.
*/
private static byte[] generateSeed() {
try {
ByteArrayOutputStream seedBuffer = new ByteArrayOutputStream();
DataOutputStream seedBufferOut =
new DataOutputStream(seedBuffer);
seedBufferOut.writeLong(System.currentTimeMillis());
seedBufferOut.writeLong(System.nanoTime());
seedBufferOut.writeInt(Process.myPid());
seedBufferOut.writeInt(Process.myUid());
seedBufferOut.write(BUILD_FINGERPRINT_AND_DEVICE_SERIAL);
seedBufferOut.close();
return seedBuffer.toByteArray();
} catch (IOException e) {
throw new SecurityException("Failed to generate seed", e);
}
}
@SuppressLint("HardwareIds")
private static byte[] getBuildFingerprintAndDeviceSerial() {
StringBuilder result = new StringBuilder();
String fingerprint = Build.FINGERPRINT;
if (fingerprint != null) {
result.append(fingerprint);
}
String serial = Build.SERIAL;
if (serial != null) {
result.append(serial);
}
try {
return result.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("UTF-8 encoding not supported");
}
}
}

View File

@@ -1,20 +0,0 @@
package org.fdroid.fdroid.compat;
import android.annotation.TargetApi;
import android.os.Build;
public class SupportedArchitectures {
/**
* The most preferred ABI is the first element in the list.
*/
@TargetApi(21)
@SuppressWarnings("deprecation")
public static String[] getAbis() {
if (Build.VERSION.SDK_INT >= 21) {
return Build.SUPPORTED_ABIS;
}
return new String[]{Build.CPU_ABI, Build.CPU_ABI2};
}
}

View File

@@ -441,49 +441,42 @@ public class Apk implements Comparable<Apk>, Parcelable {
set.add(versions.getName());
}
}
if (Build.VERSION.SDK_INT >= 16 && set.contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
if (set.contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
set.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
if (Build.VERSION.SDK_INT >= 29) {
if (set.contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
set.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (targetSdkVersion >= 29) {
// Do nothing. The targetSdk for the below split-permissions is set to 29,
// so we don't make any changes for apps targetting 29 or above
} else {
// TODO: Change the strings below to Manifest.permission once we target SDK 29.
if (targetSdkVersion < 29) {
if (set.contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
set.add("android.permission.ACCESS_BACKGROUND_LOCATION");
set.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION);
}
if (set.contains(Manifest.permission.ACCESS_COARSE_LOCATION)) {
set.add("android.permission.ACCESS_BACKGROUND_LOCATION");
set.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION);
}
if (set.contains(Manifest.permission.READ_EXTERNAL_STORAGE)) {
set.add("android.permission.ACCESS_MEDIA_LOCATION");
set.add(Manifest.permission.ACCESS_MEDIA_LOCATION);
}
}
// Else do nothing. The targetSdk for the below split-permissions is set to 29,
// so we don't make any changes for apps targetting 29 or above
}
if (Build.VERSION.SDK_INT >= 31) {
if (targetSdkVersion >= 31) {
// Do nothing. The targetSdk for the below split-permissions is set to 31,
// so we don't make any changes for apps targetting 31 or above
} else {
// TODO: Change the strings below to Manifest.permission once we target SDK 31.
if (targetSdkVersion < 31) {
if (set.contains(Manifest.permission.BLUETOOTH) ||
set.contains(Manifest.permission.BLUETOOTH_ADMIN)) {
set.add("android.permission.BLUETOOTH_SCAN");
set.add("android.permission.BLUETOOTH_CONNECT");
set.add("android.permission.BLUETOOTH_ADVERTISE");
set.add(Manifest.permission.BLUETOOTH_SCAN);
set.add(Manifest.permission.BLUETOOTH_CONNECT);
set.add(Manifest.permission.BLUETOOTH_ADVERTISE);
}
}
// Else do nothing. The targetSdk for the above split-permissions is set to 31,
// so we don't make any changes for apps targetting 31 or above
}
if (Build.VERSION.SDK_INT >= 33) {
if (targetSdkVersion >= 33) {
// Do nothing. The targetSdk for the below split-permissions is set to 33,
// so we don't make any changes for apps targetting 33 or above
} else {
// TODO: Change the strings below to Manifest.permission once we target SDK 31.
if (targetSdkVersion < 33) {
// TODO: Change the strings below to Manifest.permission once we compile with SDK 33
if (set.contains(Manifest.permission.BODY_SENSORS)) {
set.add("android.permission.BODY_SENSORS_BACKGROUND");
}
@@ -494,6 +487,8 @@ public class Apk implements Comparable<Apk>, Parcelable {
set.add("android.permission.READ_MEDIA_IMAGES");
}
}
// Else do nothing. The targetSdk for the above split-permissions is set to 33,
// so we don't make any changes for apps targetting 33 or above
}
requestedPermissions = set.toArray(new String[set.size()]);

View File

@@ -99,13 +99,7 @@ public class DefaultInstallerActivity extends FragmentActivity {
// works only when being installed as system-app
// https://code.google.com/p/android/issues/detail?id=42253
if (Build.VERSION.SDK_INT < 16) {
intent.setAction(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(uri);
intent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
intent.putExtra(Intent.EXTRA_ALLOW_REPLACE, true);
} else if (Build.VERSION.SDK_INT < 24) {
if (Build.VERSION.SDK_INT < 24) {
intent.setAction(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(uri);
intent.putExtra(Intent.EXTRA_RETURN_RESULT, true);

View File

@@ -23,7 +23,6 @@ package org.fdroid.fdroid.installer;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.WildcardFileFilter;
@@ -150,9 +149,7 @@ public class InstallerService extends JobIntentService {
* @param apk {@link Apk} instance of the app that will be uninstalled
*/
public static void uninstall(Context context, @NonNull Apk apk) {
if (Build.VERSION.SDK_INT >= 19) {
Objects.requireNonNull(apk);
}
Objects.requireNonNull(apk);
Installer.sendBroadcastUninstall(context, apk, Installer.ACTION_UNINSTALL_STARTED);

View File

@@ -6,7 +6,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.util.Log;
import androidx.annotation.NonNull;
@@ -27,8 +26,7 @@ import java.util.Enumeration;
* unmetered internet available, based on
* {@link android.net.ConnectivityManager#CONNECTIVITY_ACTION}
* <p>
* {@link Build.VERSION_CODES#N Android 7.0} removed
* {@link android.net.ConnectivityManager#CONNECTIVITY_ACTION} so this will
* Android 7.0 removed {@link android.net.ConnectivityManager#CONNECTIVITY_ACTION} so this will
* need to be totally changed to support that.
*
* @see <a href="https://developer.android.com/topic/performance/background-optimization">Background Optimizations</a>
@@ -53,8 +51,7 @@ public class ConnectivityMonitorService extends JobIntentService {
/**
* Register the {@link BroadcastReceiver} which also starts this
* {@code Service} since it is a sticky broadcast. This cannot be
* registered in the manifest, since {@link Build.VERSION_CODES#N Android 7.0}
* makes that not work.
* registered in the manifest, since Android 7.0 makes that not work.
*/
public static void registerAndStart(Context context) {
context.registerReceiver(CONNECTIVITY_RECEIVER, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
@@ -85,7 +82,7 @@ public class ConnectivityMonitorService extends JobIntentService {
}
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork == null && Build.VERSION.SDK_INT >= 21 && cm.getAllNetworks().length == 0) {
if (activeNetwork == null && cm.getAllNetworks().length == 0) {
try {
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {

View File

@@ -29,7 +29,6 @@ import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Parcel;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
@@ -120,7 +119,7 @@ public class AppSecurityPermissions {
public Drawable loadGroupIcon(Context context, PackageManager pm) {
Drawable iconDrawable;
if (icon != 0) {
iconDrawable = (Build.VERSION.SDK_INT < 22) ? loadIcon(pm) : loadUnbadgedIcon(pm);
iconDrawable = loadUnbadgedIcon(pm);
} else {
iconDrawable = ContextCompat.getDrawable(context, R.drawable.ic_perm_device_info);
}
@@ -264,9 +263,6 @@ public class AppSecurityPermissions {
}
private int[] getRequestedPermissionFlags(PackageInfo info) {
if (Build.VERSION.SDK_INT < 16) {
return new int[info.requestedPermissions.length];
}
return info.requestedPermissionsFlags;
}
@@ -347,7 +343,7 @@ public class AppSecurityPermissions {
*/
@TargetApi(16)
private static boolean isNewPermission(PackageInfo installedPkgInfo, int existingFlags) {
if (installedPkgInfo == null || Build.VERSION.SDK_INT < 16) {
if (installedPkgInfo == null) {
return false;
}
@@ -420,8 +416,7 @@ public class AppSecurityPermissions {
private PermissionItemView getPermissionItemView(MyPermissionGroupInfo grp, MyPermissionInfo perm,
boolean first, CharSequence newPermPrefix) {
PermissionItemView permView = (PermissionItemView) inflater.inflate(
Build.VERSION.SDK_INT >= 17 &&
(perm.flags & PermissionInfo.FLAG_COSTS_MONEY) != 0
(perm.flags & PermissionInfo.FLAG_COSTS_MONEY) != 0
? R.layout.app_permission_item_money : R.layout.app_permission_item,
null);
permView.setPermission(grp, perm, first, newPermPrefix);

View File

@@ -4,11 +4,7 @@ import android.content.Context;
public abstract class CameraCharacteristicsChecker {
public static CameraCharacteristicsChecker getInstance(final Context context) {
if (android.os.Build.VERSION.SDK_INT >= 21) {
return new CameraCharacteristicsMinApiLevel21(context);
} else {
return new CameraCharacteristicsMaxApiLevel20();
}
return new CameraCharacteristicsMinApiLevel21(context);
}
public abstract boolean hasAutofocus();

View File

@@ -34,7 +34,6 @@ import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
@@ -782,9 +781,6 @@ public class AppDetailsActivity extends AppCompatActivity
private BluetoothAdapter getBluetoothAdapter() {
// to use the new, recommended way of getting the adapter
// http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html
if (Build.VERSION.SDK_INT < 18) {
return BluetoothAdapter.getDefaultAdapter();
}
return ContextCompat.getSystemService(this, BluetoothManager.class).getAdapter();
}

View File

@@ -10,7 +10,6 @@ import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.text.Spannable;
import android.text.Spanned;
import android.text.TextUtils;
@@ -615,22 +614,15 @@ public class AppDetailsRecyclerViewAdapter
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
FilenameUtils.getExtension(installedFile.getName()));
viewIntent.setDataAndType(uri, mimeType);
if (Build.VERSION.SDK_INT < 19) {
viewIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
viewIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
}
viewIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
if (context.getPackageManager().queryIntentActivities(viewIntent, 0).size() > 0) {
buttonPrimaryView.setText(R.string.menu_open);
buttonPrimaryView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
context.startActivity(viewIntent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
buttonPrimaryView.setOnClickListener(v -> {
try {
context.startActivity(viewIntent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
});
} else {

View File

@@ -470,14 +470,12 @@ public class PreferencesFragment extends PreferenceFragmentCompat
// by the time the user boots, opens F-Droid, and views this settings page, then there
// is no benefit showing it to them (it will only be disabled and we can't offer any
// way to easily install from here.
if (Build.VERSION.SDK_INT > 19 && !installed) {
if (pref != null) {
otherPrefGroup.removePreference(pref);
}
if (!installed) {
otherPrefGroup.removePreference(pref);
} else {
pref.setEnabled(installed);
pref.setDefaultValue(installed);
pref.setChecked(enabled && installed);
pref.setEnabled(true);
pref.setDefaultValue(true);
pref.setChecked(enabled);
pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
@@ -581,8 +579,7 @@ public class PreferencesFragment extends PreferenceFragmentCompat
if (updateIntervalPrevious != updateIntervalSeekBar.getValue()) {
UpdateService.schedule(getActivity());
} else if (Build.VERSION.SDK_INT >= 21 &&
(overWifiPrevious != overWifiSeekBar.getValue() || overDataPrevious != overDataSeekBar.getValue())) {
} else if (overWifiPrevious != overWifiSeekBar.getValue() || overDataPrevious != overDataSeekBar.getValue()) {
UpdateService.schedule(getActivity());
}
}

View File

@@ -9,7 +9,6 @@ import android.content.IntentFilter;
import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -296,11 +295,7 @@ public class RepoDetailsActivity extends AppCompatActivity {
}
boolean needsEnableNfcMenuItem;
if (Build.VERSION.SDK_INT < 16) {
needsEnableNfcMenuItem = !nfcAdapter.isEnabled();
} else {
needsEnableNfcMenuItem = !nfcAdapter.isNdefPushEnabled();
}
needsEnableNfcMenuItem = !nfcAdapter.isNdefPushEnabled();
menuItem.setVisible(needsEnableNfcMenuItem);
}

View File

@@ -3,7 +3,6 @@ package org.fdroid.fdroid.views;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import org.fdroid.fdroid.R;
@@ -17,7 +16,6 @@ import androidx.core.content.ContextCompat;
*/
public class SeekBarForegroundThumb extends AppCompatSeekBar {
private Drawable tickMark;
private Context context;
public SeekBarForegroundThumb(Context context) {
super(context);
@@ -35,18 +33,9 @@ public class SeekBarForegroundThumb extends AppCompatSeekBar {
}
private void init(Context context) {
this.context = context;
tickMark = ContextCompat.getDrawable(context, R.drawable.seekbar_tickmark);
}
private Drawable getThumbCompat() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
return getThumb();
} else {
return context.getResources().getDrawable(R.drawable.seekbar_thumb);
}
}
@Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas);
@@ -59,7 +48,7 @@ public class SeekBarForegroundThumb extends AppCompatSeekBar {
if (count > 1) {
final int w = tickMark.getIntrinsicWidth();
final int h = tickMark.getIntrinsicHeight();
final int halfThumbW = getThumbCompat().getIntrinsicWidth() / 2;
final int halfThumbW = getThumb().getIntrinsicWidth() / 2;
final int halfW = w >= 0 ? w / 2 : 1;
final int halfH = h >= 0 ? h / 2 : 1;
tickMark.setBounds(-halfW, -halfH, halfW, halfH);

View File

@@ -21,7 +21,6 @@ package org.fdroid.fdroid.views.appdetails;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -79,11 +78,7 @@ public class AntiFeaturesListingView extends RecyclerView {
@Override
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= 21) {
i.setFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
} else {
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
}
i.setFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
i.setData(Uri.parse("https://f-droid.org/docs/Anti-Features#" + antiFeatureName));
getContext().startActivity(i);
}

View File

@@ -8,7 +8,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Outline;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
@@ -137,24 +136,22 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder {
}
});
if (Build.VERSION.SDK_INT >= 21) {
installButton.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
float density = activity.getResources().getDisplayMetrics().density;
installButton.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
float density = activity.getResources().getDisplayMetrics().density;
// This is a bit hacky/hardcoded/too-specific to the particular icons we're using.
// This is because the default "download & install" and "downloaded & ready to install"
// icons are smaller than the "downloading progress" button. Hence, we can't just use
// the width/height of the view to calculate the outline size.
int xPadding = (int) (8 * density);
int yPadding = (int) (9 * density);
int right = installButton.getWidth() - xPadding;
int bottom = installButton.getHeight() - yPadding;
outline.setOval(xPadding, yPadding, right, bottom);
}
});
}
// This is a bit hacky/hardcoded/too-specific to the particular icons we're using.
// This is because the default "download & install" and "downloaded & ready to install"
// icons are smaller than the "downloading progress" button. Hence, we can't just use
// the width/height of the view to calculate the outline size.
int xPadding = (int) (8 * density);
int yPadding = (int) (9 * density);
int right = installButton.getWidth() - xPadding;
int bottom = installButton.getHeight() - yPadding;
outline.setOval(xPadding, yPadding, right, bottom);
}
});
}
icon = (ImageView) itemView.findViewById(R.id.icon);

View File

@@ -2,7 +2,6 @@ package org.fdroid.fdroid.views.apps;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.text.Editable;
import android.text.Spanned;
import android.text.TextWatcher;
@@ -132,23 +131,19 @@ public class CategoryTextWatcher implements TextWatcher {
}
removeSpans(textToSpannify, CategorySpan.class);
if (Build.VERSION.SDK_INT >= 21) {
removeSpans(textToSpannify, TtsSpan.class);
}
removeSpans(textToSpannify, TtsSpan.class);
int colonIndex = textToSpannify.toString().indexOf(':');
if (colonIndex > 0) {
CategorySpan span = new CategorySpan(context);
textToSpannify.setSpan(span, 0, colonIndex + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (Build.VERSION.SDK_INT >= 21) {
// For accessibility reasons, make this more clear to screen readers that the
// span we just added semantically represents a category.
CharSequence categoryName = textToSpannify.subSequence(0, colonIndex);
TtsSpan ttsSpan = new TtsSpan.TextBuilder(context.getString(R.string.tts_category_name,
categoryName)).build();
textToSpannify.setSpan(ttsSpan, 0, 0, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
// For accessibility reasons, make this more clear to screen readers that the
// span we just added semantically represents a category.
CharSequence categoryName = textToSpannify.subSequence(0, colonIndex);
TtsSpan ttsSpan = new TtsSpan.TextBuilder(context.getString(R.string.tts_category_name,
categoryName)).build();
textToSpannify.setSpan(ttsSpan, 0, 0, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}

View File

@@ -26,10 +26,8 @@ import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -111,13 +109,6 @@ public class MainActivity extends AppCompatActivity {
pager.setLayoutManager(new NonScrollingHorizontalLayoutManager(this));
pager.setAdapter(adapter);
// Without this, the focus is completely busted on pre 15 devices. Trying to use them
// without this ends up with each child view showing for a fraction of a second, then
// reverting back to the "Latest" screen again, in completely non-deterministic ways.
if (Build.VERSION.SDK_INT <= 15) {
pager.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
}
bottomNavigation = (BottomNavigationView) findViewById(R.id.bottom_navigation);
bottomNavigation.setOnNavigationItemSelectedListener(item -> {
pager.scrollToPosition(item.getOrder());

View File

@@ -7,7 +7,6 @@ import android.system.ErrnoException;
import android.system.Os;
import android.system.StructStat;
import org.apache.commons.io.FileUtils;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.installer.ApkCache;
@@ -208,10 +207,6 @@ public class CleanCacheWorker extends Worker {
clearOldFiles(file, millisAgo);
}
deleteFileAndLog(f);
} else if (Build.VERSION.SDK_INT <= 21) {
if (FileUtils.isFileOlder(f, olderThan)) {
deleteFileAndLog(f);
}
} else {
Impl21.deleteIfOld(f, olderThan);
}

View File

@@ -50,7 +50,6 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import androidx.annotation.NonNull;
@@ -251,9 +250,7 @@ public class FDroidMetricsWorker extends Worker {
EVENTS.add(getDeviceEvent(weekStart, "isPrivilegedInstallerEnabled",
Preferences.get().isPrivilegedInstallerEnabled()));
EVENTS.add(getDeviceEvent(weekStart, "Build.VERSION.SDK_INT", Build.VERSION.SDK_INT));
if (Build.VERSION.SDK_INT >= 21) {
EVENTS.add(getDeviceEvent(weekStart, "Build.SUPPORTED_ABIS", Arrays.toString(Build.SUPPORTED_ABIS)));
}
EVENTS.add(getDeviceEvent(weekStart, "Build.SUPPORTED_ABIS", Arrays.toString(Build.SUPPORTED_ABIS)));
for (PackageInfo packageInfo : packageInfoList) {
if (isTimestampInReportingWeek(weekStart, packageInfo.firstInstallTime)) {
@@ -425,11 +422,7 @@ public class FDroidMetricsWorker extends Worker {
@Override
public int hashCode() {
if (Build.VERSION.SDK_INT >= 19) {
return Objects.hash(applicationId, versionCode, action);
} else {
return new Random().nextInt(); // quick kludge
}
return Objects.hash(applicationId, versionCode, action);
}
@Override