mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-11 18:29:05 +01:00
Drop support for Android 4
new minSdk is 21
This commit is contained in:
@@ -11,7 +11,7 @@ android {
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 31
|
||||
versionCode 10500
|
||||
versionName "1.5.0"
|
||||
|
||||
@@ -20,7 +20,6 @@ import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static org.briarproject.bramble.util.IoUtils.deleteFileOrDir;
|
||||
@@ -105,15 +104,11 @@ class AndroidAccountManager extends AccountManagerImpl
|
||||
}
|
||||
files.add(appContext.getFilesDir());
|
||||
addIfNotNull(files, appContext.getExternalCacheDir());
|
||||
if (SDK_INT >= 19) {
|
||||
for (File file : appContext.getExternalCacheDirs()) {
|
||||
addIfNotNull(files, file);
|
||||
}
|
||||
for (File file : appContext.getExternalCacheDirs()) {
|
||||
addIfNotNull(files, file);
|
||||
}
|
||||
if (SDK_INT >= 21) {
|
||||
for (File file : appContext.getExternalMediaDirs()) {
|
||||
addIfNotNull(files, file);
|
||||
}
|
||||
for (File file : appContext.getExternalMediaDirs()) {
|
||||
addIfNotNull(files, file);
|
||||
}
|
||||
// Clear the cache directory but don't delete it
|
||||
File cacheDir = appContext.getCacheDir();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject.bramble.plugin.bluetooth;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Application;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
@@ -49,7 +50,6 @@ import static android.bluetooth.BluetoothAdapter.STATE_ON;
|
||||
import static android.bluetooth.BluetoothDevice.ACTION_FOUND;
|
||||
import static android.bluetooth.BluetoothDevice.DEVICE_TYPE_LE;
|
||||
import static android.bluetooth.BluetoothDevice.EXTRA_DEVICE;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static java.util.Collections.shuffle;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static java.util.logging.Level.INFO;
|
||||
@@ -60,6 +60,7 @@ import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
@SuppressLint("MissingPermission")
|
||||
class AndroidBluetoothPlugin extends
|
||||
AbstractBluetoothPlugin<BluetoothSocket, BluetoothServerSocket> {
|
||||
|
||||
@@ -253,7 +254,7 @@ class AndroidBluetoothPlugin extends
|
||||
} else if (ACTION_FOUND.equals(action)) {
|
||||
BluetoothDevice d = i.getParcelableExtra(EXTRA_DEVICE);
|
||||
// Ignore Bluetooth LE devices
|
||||
if (SDK_INT < 18 || d.getType() != DEVICE_TYPE_LE) {
|
||||
if (d.getType() != DEVICE_TYPE_LE) {
|
||||
String address = d.getAddress();
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Discovered " +
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.briarproject.bramble.plugin.tcp;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Application;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.LinkAddress;
|
||||
@@ -37,7 +36,6 @@ import javax.net.SocketFactory;
|
||||
import static android.content.Context.CONNECTIVITY_SERVICE;
|
||||
import static android.content.Context.WIFI_SERVICE;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.list;
|
||||
import static java.util.Collections.singletonList;
|
||||
@@ -118,7 +116,7 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
||||
// If there's no wifi IPv4 address, we might be a client on an
|
||||
// IPv6-only wifi network. We can only detect this on API 21+
|
||||
if (wifi == null) {
|
||||
return SDK_INT >= 21 ? getWifiClientIpv6Address() : null;
|
||||
return getWifiClientIpv6Address();
|
||||
}
|
||||
// Use the wifi IPv4 address to determine which interface's IPv6
|
||||
// address we should return (if the interface has a suitable address)
|
||||
@@ -172,7 +170,6 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
||||
* Returns a link-local IPv6 address for the wifi client interface, or null
|
||||
* if there's no such interface or it doesn't have a suitable address.
|
||||
*/
|
||||
@TargetApi(21)
|
||||
@Nullable
|
||||
private InetAddress getWifiClientIpv6Address() {
|
||||
// https://issuetracker.google.com/issues/175055271
|
||||
@@ -234,7 +231,6 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
||||
// On API 21 and later, a socket that is not created with the wifi
|
||||
// network's socket factory may try to connect via another network
|
||||
private SocketFactory getSocketFactory() {
|
||||
if (SDK_INT < 21) return SocketFactory.getDefault();
|
||||
// https://issuetracker.google.com/issues/175055271
|
||||
try {
|
||||
for (Network net : connectivityManager.getAllNetworks()) {
|
||||
@@ -302,7 +298,7 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
||||
Pair<InetAddress, Boolean> wifi = getWifiIpv4Address();
|
||||
// If there's no wifi IPv4 address, we might be a client on an
|
||||
// IPv6-only wifi network. We can only detect this on API 21+
|
||||
if (wifi == null && SDK_INT >= 21) {
|
||||
if (wifi == null) {
|
||||
InetAddress ipv6 = getWifiClientIpv6Address();
|
||||
if (ipv6 != null) return new Pair<>(ipv6, false);
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@ import static android.provider.Settings.Secure.ANDROID_ID;
|
||||
@NotNullByDefault
|
||||
class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
|
||||
|
||||
private static final int SEED_LENGTH = 32;
|
||||
|
||||
private final Context appContext;
|
||||
|
||||
@Inject
|
||||
@@ -72,27 +70,6 @@ class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
|
||||
// Silence strict mode
|
||||
StrictMode.ThreadPolicy tp = StrictMode.allowThreadDiskWrites();
|
||||
super.writeSeed();
|
||||
if (SDK_INT <= 18) applyOpenSslFix();
|
||||
StrictMode.setThreadPolicy(tp);
|
||||
}
|
||||
|
||||
// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
|
||||
private void applyOpenSslFix() {
|
||||
byte[] seed = new UnixSecureRandomSpi().engineGenerateSeed(
|
||||
SEED_LENGTH);
|
||||
try {
|
||||
// Seed the OpenSSL PRNG
|
||||
Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto")
|
||||
.getMethod("RAND_seed", byte[].class)
|
||||
.invoke(null, (Object) seed);
|
||||
// Mix the output of the Linux PRNG into the OpenSSL 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();
|
||||
} catch (Exception e) {
|
||||
throw new SecurityException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,10 @@ import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@@ -29,7 +25,6 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.os.Process.myPid;
|
||||
import static android.os.Process.myUid;
|
||||
import static java.lang.Runtime.getRuntime;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.briarproject.nullsafety.NullSafety.requireNonNull;
|
||||
|
||||
@@ -43,14 +38,7 @@ public class AndroidUtils {
|
||||
private static final String STORED_LOGCAT = "dev-logcat";
|
||||
|
||||
public static Collection<String> getSupportedArchitectures() {
|
||||
List<String> abis = new ArrayList<>();
|
||||
if (SDK_INT >= 21) {
|
||||
abis.addAll(asList(Build.SUPPORTED_ABIS));
|
||||
} else {
|
||||
abis.add(Build.CPU_ABI);
|
||||
if (Build.CPU_ABI2 != null) abis.add(Build.CPU_ABI2);
|
||||
}
|
||||
return abis;
|
||||
return asList(Build.SUPPORTED_ABIS);
|
||||
}
|
||||
|
||||
public static boolean hasBtConnectPermission(Context ctx) {
|
||||
@@ -136,19 +124,6 @@ public class AndroidUtils {
|
||||
return new String[] {"image/jpeg", "image/png", "image/gif"};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getSystemProperty(String propName) {
|
||||
try {
|
||||
Process p = getRuntime().exec("getprop " + propName);
|
||||
Scanner s = new Scanner(p.getInputStream());
|
||||
String line = s.nextLine();
|
||||
s.close();
|
||||
return line;
|
||||
} catch (SecurityException | IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isUiThread() {
|
||||
return Looper.myLooper() == Looper.getMainLooper();
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ android {
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 31
|
||||
versionCode 10500
|
||||
versionName "1.5.0"
|
||||
@@ -62,7 +62,6 @@ android {
|
||||
productFlavors {
|
||||
screenshot {
|
||||
dimension "version"
|
||||
minSdkVersion 21
|
||||
applicationIdSuffix ".screenshot" // = org.briarproject.briar.android.screenshot.debug
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-test.txt'
|
||||
}
|
||||
|
||||
@@ -99,11 +99,6 @@
|
||||
android:exported="false"
|
||||
android:label="@string/app_name" />
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.splash.ExpiredOldAndroidActivity"
|
||||
android:exported="false"
|
||||
android:label="@string/app_name" />
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.login.StartupActivity"
|
||||
android:exported="false"
|
||||
|
||||
@@ -294,10 +294,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
b.setOngoing(true);
|
||||
Intent i = new Intent(appContext, SplashScreenActivity.class);
|
||||
b.setContentIntent(getActivity(appContext, 0, i, getImmutableFlags(0)));
|
||||
if (SDK_INT >= 21) {
|
||||
b.setCategory(CATEGORY_SERVICE);
|
||||
b.setVisibility(VISIBILITY_SECRET);
|
||||
}
|
||||
b.setCategory(CATEGORY_SERVICE);
|
||||
b.setVisibility(VISIBILITY_SECRET);
|
||||
b.setPriority(PRIORITY_MIN);
|
||||
return b.build();
|
||||
}
|
||||
@@ -773,8 +771,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
i.setAction(ACTION_STOP_HOTSPOT);
|
||||
PendingIntent actionIntent =
|
||||
getActivity(appContext, 0, i, getImmutableFlags(0));
|
||||
int icon = SDK_INT >= 21 ? R.drawable.ic_portable_wifi_off : 0;
|
||||
b.addAction(icon, actionTitle, actionIntent);
|
||||
b.addAction(R.drawable.ic_portable_wifi_off, actionTitle, actionIntent);
|
||||
notificationManager.notify(HOTSPOT_NOTIFICATION_ID, b.build());
|
||||
}
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@ public class AppModule {
|
||||
public Collection<SimplexPluginFactory> getSimplexFactories() {
|
||||
List<SimplexPluginFactory> simplex = new ArrayList<>();
|
||||
simplex.add(mailbox);
|
||||
if (SDK_INT >= 19) simplex.add(drive);
|
||||
simplex.add(drive);
|
||||
return simplex;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,16 +56,8 @@ public class Localizer {
|
||||
// Get Locale from BCP-47 tag
|
||||
@Nullable
|
||||
public static Locale getLocaleFromTag(String tag) {
|
||||
if (tag.equals("default"))
|
||||
return null;
|
||||
if (SDK_INT >= 21) {
|
||||
return Locale.forLanguageTag(tag);
|
||||
}
|
||||
if (tag.contains("-")) {
|
||||
String[] langArray = tag.split("-");
|
||||
return new Locale(langArray[0], langArray[1]);
|
||||
} else
|
||||
return new Locale(tag);
|
||||
if (tag.equals("default")) return null;
|
||||
return Locale.forLanguageTag(tag);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -94,12 +86,8 @@ public class Localizer {
|
||||
if (locale.equals(currentLocale))
|
||||
return context;
|
||||
Locale.setDefault(locale);
|
||||
if (SDK_INT >= 17) {
|
||||
conf.setLocale(locale);
|
||||
context = context.createConfigurationContext(conf);
|
||||
} else
|
||||
conf.locale = locale;
|
||||
//noinspection deprecation
|
||||
conf.setLocale(locale);
|
||||
context = context.createConfigurationContext(conf);
|
||||
res.updateConfiguration(conf, res.getDisplayMetrics());
|
||||
return context;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ package org.briarproject.briar.android;
|
||||
|
||||
import org.briarproject.briar.BuildConfig;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static java.util.concurrent.TimeUnit.DAYS;
|
||||
import static org.briarproject.briar.BuildConfig.BuildTimestamp;
|
||||
|
||||
public interface TestingConstants {
|
||||
|
||||
@@ -20,15 +20,9 @@ public interface TestingConstants {
|
||||
*/
|
||||
boolean PREVENT_SCREENSHOTS = !IS_DEBUG_BUILD;
|
||||
|
||||
boolean IS_OLD_ANDROID = SDK_INT <= 19;
|
||||
long OLD_ANDROID_WARN_DATE = 1659225600_000L; // 2022-07-31
|
||||
long OLD_ANDROID_EXPIRY_DATE = 1675123200_000L; // 2023-01-31
|
||||
|
||||
/**
|
||||
* Debug builds expire after 90 days. Release builds running on Android 4
|
||||
* expire at a set date, otherwise they expire after 292 million years.
|
||||
* Debug builds expire after 90 days.
|
||||
*/
|
||||
long EXPIRY_DATE = IS_DEBUG_BUILD ?
|
||||
BuildConfig.BuildTimestamp + DAYS.toMillis(90)
|
||||
: (IS_OLD_ANDROID ? OLD_ANDROID_EXPIRY_DATE : Long.MAX_VALUE);
|
||||
BuildTimestamp + DAYS.toMillis(90) : Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_KEYGU
|
||||
import static org.briarproject.briar.android.util.UiUtils.hasKeyguardLock;
|
||||
import static org.briarproject.briar.android.util.UiUtils.hasUsableFingerprint;
|
||||
|
||||
@RequiresApi(21)
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class UnlockActivity extends BaseActivity {
|
||||
|
||||
@@ -81,7 +81,6 @@ import org.briarproject.briar.android.sharing.ShareBlogFragment;
|
||||
import org.briarproject.briar.android.sharing.ShareForumActivity;
|
||||
import org.briarproject.briar.android.sharing.ShareForumFragment;
|
||||
import org.briarproject.briar.android.sharing.SharingModule;
|
||||
import org.briarproject.briar.android.splash.ExpiredOldAndroidActivity;
|
||||
import org.briarproject.briar.android.splash.SplashScreenActivity;
|
||||
import org.briarproject.briar.android.test.TestDataActivity;
|
||||
|
||||
@@ -184,8 +183,6 @@ public interface ActivityComponent {
|
||||
|
||||
void inject(RemovableDriveActivity activity);
|
||||
|
||||
void inject(ExpiredOldAndroidActivity activity);
|
||||
|
||||
// Fragments
|
||||
|
||||
void inject(SetupFragment fragment);
|
||||
|
||||
@@ -24,7 +24,6 @@ import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
@@ -105,7 +104,7 @@ public abstract class BriarActivity extends BaseActivity {
|
||||
LOG.info("Not signed in, launching StartupActivity");
|
||||
Intent i = new Intent(this, StartupActivity.class);
|
||||
startActivityForResult(i, REQUEST_PASSWORD);
|
||||
} else if (SDK_INT >= 21 && lockManager.isLocked() && !isFinishing()) {
|
||||
} else if (lockManager.isLocked() && !isFinishing()) {
|
||||
// Also check that the activity isn't finishing already.
|
||||
// This is possible if we finished in onActivityResult().
|
||||
// Launching another UnlockActivity would cause a loop.
|
||||
@@ -135,8 +134,7 @@ public abstract class BriarActivity extends BaseActivity {
|
||||
* @param exitTransition used to move views out when starting a <b>new</b> activity.
|
||||
* @param returnTransition used when window is closing, because the activity is finishing.
|
||||
*/
|
||||
@RequiresApi(api = 21)
|
||||
public void setSceneTransitionAnimation(
|
||||
protected void setSceneTransitionAnimation(
|
||||
@Nullable Transition enterTransition,
|
||||
@Nullable Transition exitTransition,
|
||||
@Nullable Transition returnTransition) {
|
||||
@@ -232,8 +230,7 @@ public abstract class BriarActivity extends BaseActivity {
|
||||
|
||||
@Wakeful
|
||||
private void finishAndExit() {
|
||||
if (SDK_INT >= 21) finishAndRemoveTask();
|
||||
else supportFinishAfterTransition();
|
||||
finishAndRemoveTask();
|
||||
LOG.info("Exiting");
|
||||
BriarApplication app = (BriarApplication) getApplication();
|
||||
if (!app.isInstrumentationTest()) System.exit(0);
|
||||
|
||||
@@ -21,7 +21,6 @@ import androidx.annotation.UiThread;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
import static org.briarproject.briar.android.activity.BriarActivity.GROUP_ID;
|
||||
@@ -134,12 +133,6 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
|
||||
} else {
|
||||
reblogger.setVisibility(GONE);
|
||||
}
|
||||
|
||||
// Apply Android 4 padding fix after setting up author/reblogger views
|
||||
if (SDK_INT < 21) {
|
||||
reblogger.setPadding(padding, padding, padding, padding);
|
||||
author.setPadding(padding, padding, padding, padding);
|
||||
}
|
||||
}
|
||||
|
||||
private void onBindComment(BlogCommentItem item, boolean authorClickable) {
|
||||
|
||||
@@ -27,11 +27,9 @@ import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
|
||||
@@ -52,7 +50,6 @@ public class RssFeedImportFragment extends BaseFragment {
|
||||
private Button importButton;
|
||||
private ProgressBar progressBar;
|
||||
|
||||
@RequiresApi(19)
|
||||
private final ActivityResultLauncher<String[]> docLauncher =
|
||||
registerForActivityResult(new OpenDocumentAdvanced(),
|
||||
this::onFileChosen);
|
||||
@@ -74,7 +71,7 @@ public class RssFeedImportFragment extends BaseFragment {
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
requireActivity().setTitle(getString(R.string.blogs_rss_feeds_import));
|
||||
if (SDK_INT >= 19) setHasOptionsMenu(true);
|
||||
setHasOptionsMenu(true);
|
||||
View v = inflater.inflate(R.layout.fragment_rss_feed_import,
|
||||
container, false);
|
||||
|
||||
@@ -117,15 +114,13 @@ public class RssFeedImportFragment extends BaseFragment {
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
if (SDK_INT >= 19) {
|
||||
inflater.inflate(R.menu.rss_feed_import_actions, menu);
|
||||
}
|
||||
inflater.inflate(R.menu.rss_feed_import_actions, menu);
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.action_import_file && SDK_INT >= 19) {
|
||||
if (item.getItemId() == R.id.action_import_file) {
|
||||
launchActivityToOpenFile(requireContext(), docLauncher,
|
||||
contentLauncher, "*/*");
|
||||
return true;
|
||||
|
||||
@@ -55,7 +55,6 @@ import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener
|
||||
import org.briarproject.briar.android.introduction.IntroductionActivity;
|
||||
import org.briarproject.briar.android.privategroup.conversation.GroupActivity;
|
||||
import org.briarproject.briar.android.removabledrive.RemovableDriveActivity;
|
||||
import org.briarproject.briar.android.util.ActivityLaunchers.GetImageAdvanced;
|
||||
import org.briarproject.briar.android.util.ActivityLaunchers.GetMultipleImagesAdvanced;
|
||||
import org.briarproject.briar.android.util.ActivityLaunchers.OpenMultipleImageDocumentsAdvanced;
|
||||
import org.briarproject.briar.android.util.BriarSnackbarBuilder;
|
||||
@@ -122,13 +121,11 @@ import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
|
||||
import de.hdodenhof.circleimageview.CircleImageView;
|
||||
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.view.Gravity.RIGHT;
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
import static androidx.core.app.ActivityOptionsCompat.makeSceneTransitionAnimation;
|
||||
import static androidx.lifecycle.Lifecycle.State.STARTED;
|
||||
import static androidx.recyclerview.widget.SortedList.INVALID_POSITION;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Collections.sort;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.logging.Level.INFO;
|
||||
@@ -200,18 +197,13 @@ public class ConversationActivity extends BriarActivity
|
||||
requireNonNull(name);
|
||||
loadMessages();
|
||||
};
|
||||
@Nullable
|
||||
private final ActivityResultLauncher<String[]> docLauncher = SDK_INT >= 19 ?
|
||||
|
||||
private final ActivityResultLauncher<String[]> docLauncher =
|
||||
registerForActivityResult(new OpenMultipleImageDocumentsAdvanced(),
|
||||
this::onImagesChosen) :
|
||||
null;
|
||||
this::onImagesChosen);
|
||||
private final ActivityResultLauncher<String> contentLauncher =
|
||||
SDK_INT >= 18 ?
|
||||
registerForActivityResult(new GetMultipleImagesAdvanced(),
|
||||
this::onImagesChosen) :
|
||||
registerForActivityResult(new GetImageAdvanced(), uri -> {
|
||||
if (uri != null) onImagesChosen(singletonList(uri));
|
||||
});
|
||||
registerForActivityResult(new GetMultipleImagesAdvanced(),
|
||||
this::onImagesChosen);
|
||||
|
||||
private AttachmentRetriever attachmentRetriever;
|
||||
private ConversationViewModel viewModel;
|
||||
@@ -242,13 +234,11 @@ public class ConversationActivity extends BriarActivity
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle state) {
|
||||
if (SDK_INT >= 21) {
|
||||
// Spurious lint warning - using END causes a crash
|
||||
@SuppressLint("RtlHardcoded")
|
||||
Transition slide = new Slide(RIGHT);
|
||||
slide.setDuration(TRANSITION_DURATION_MS);
|
||||
setSceneTransitionAnimation(slide, null, slide);
|
||||
}
|
||||
// Spurious lint warning - using END causes a crash
|
||||
@SuppressLint("RtlHardcoded")
|
||||
Transition slide = new Slide(RIGHT);
|
||||
slide.setDuration(TRANSITION_DURATION_MS);
|
||||
setSceneTransitionAnimation(slide, null, slide);
|
||||
super.onCreate(state);
|
||||
|
||||
Intent i = getIntent();
|
||||
@@ -389,10 +379,6 @@ public class ConversationActivity extends BriarActivity
|
||||
this::showIntroductionOnboarding);
|
||||
}
|
||||
});
|
||||
// Transfer Data feature only supported on API 19+
|
||||
if (SDK_INT >= 19) {
|
||||
menu.findItem(R.id.action_transfer_data).setVisible(true);
|
||||
}
|
||||
// enable alias and bluetooth action once available
|
||||
observeOnce(viewModel.getContactItem(), this, contact -> {
|
||||
menu.findItem(R.id.action_set_alias).setEnabled(true);
|
||||
@@ -434,11 +420,9 @@ public class ConversationActivity extends BriarActivity
|
||||
startActivity(intent);
|
||||
return true;
|
||||
} else if (itemId == R.id.action_transfer_data) {
|
||||
if (SDK_INT >= 19) {
|
||||
Intent intent = new Intent(this, RemovableDriveActivity.class);
|
||||
intent.putExtra(CONTACT_ID, contactId.getInt());
|
||||
startActivity(intent);
|
||||
}
|
||||
Intent intent = new Intent(this, RemovableDriveActivity.class);
|
||||
intent.putExtra(CONTACT_ID, contactId.getInt());
|
||||
startActivity(intent);
|
||||
return true;
|
||||
} else if (itemId == R.id.action_delete_all_messages) {
|
||||
askToDeleteAllMessages();
|
||||
@@ -955,14 +939,10 @@ public class ConversationActivity extends BriarActivity
|
||||
|
||||
private void showImageOnboarding(Boolean show) {
|
||||
if (!show) return;
|
||||
if (SDK_INT >= 21) {
|
||||
// show onboarding only after the enter transition has ended
|
||||
// otherwise the tap target animation won't play
|
||||
textInputView.postDelayed(this::showImageOnboarding,
|
||||
TRANSITION_DURATION_MS + ONBOARDING_DELAY_MS);
|
||||
} else {
|
||||
showImageOnboarding();
|
||||
}
|
||||
// show onboarding only after the enter transition has ended
|
||||
// otherwise the tap target animation won't play
|
||||
textInputView.postDelayed(this::showImageOnboarding,
|
||||
TRANSITION_DURATION_MS + ONBOARDING_DELAY_MS);
|
||||
}
|
||||
|
||||
private void showImageOnboarding() {
|
||||
@@ -973,14 +953,10 @@ public class ConversationActivity extends BriarActivity
|
||||
|
||||
private void showIntroductionOnboarding(@Nullable Boolean show) {
|
||||
if (show == null || !show) return;
|
||||
if (SDK_INT >= 21) {
|
||||
// show onboarding only after the enter transition has ended
|
||||
// otherwise the tap target animation won't play
|
||||
textInputView.postDelayed(this::showIntroductionOnboarding,
|
||||
TRANSITION_DURATION_MS + ONBOARDING_DELAY_MS);
|
||||
} else {
|
||||
showIntroductionOnboarding();
|
||||
}
|
||||
// show onboarding only after the enter transition has ended
|
||||
// otherwise the tap target animation won't play
|
||||
textInputView.postDelayed(this::showIntroductionOnboarding,
|
||||
TRANSITION_DURATION_MS + ONBOARDING_DELAY_MS);
|
||||
}
|
||||
|
||||
private void showIntroductionOnboarding() {
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.briarproject.briar.android.util.BriarSnackbarBuilder;
|
||||
import org.briarproject.briar.android.view.PullDownLayout;
|
||||
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -41,13 +42,11 @@ import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
import static android.graphics.Color.TRANSPARENT;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
|
||||
import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
|
||||
import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
||||
import static android.view.View.VISIBLE;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
|
||||
import static com.google.android.material.snackbar.Snackbar.LENGTH_LONG;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.briarproject.briar.android.util.UiUtils.formatDateAbsolute;
|
||||
@@ -77,11 +76,9 @@ public class ImageActivity extends BriarActivity
|
||||
private List<AttachmentItem> attachments;
|
||||
private MessageId conversationMessageId;
|
||||
|
||||
@Nullable
|
||||
private final ActivityResultLauncher<String> launcher = SDK_INT >= 19 ?
|
||||
private final ActivityResultLauncher<String> launcher =
|
||||
registerForActivityResult(new CreateDocumentAdvanced(),
|
||||
this::onImageUriSelected) :
|
||||
null;
|
||||
this::onImageUriSelected);
|
||||
|
||||
@Override
|
||||
public void injectActivity(ActivityComponent component) {
|
||||
@@ -97,10 +94,8 @@ public class ImageActivity extends BriarActivity
|
||||
// Transitions
|
||||
if (state == null) supportPostponeEnterTransition();
|
||||
Window window = getWindow();
|
||||
if (SDK_INT >= 21) {
|
||||
Transition transition = new Fade();
|
||||
setSceneTransitionAnimation(transition, null, transition);
|
||||
}
|
||||
Transition transition = new Fade();
|
||||
setSceneTransitionAnimation(transition, null, transition);
|
||||
|
||||
// Intent Extras
|
||||
Intent i = getIntent();
|
||||
@@ -124,12 +119,7 @@ public class ImageActivity extends BriarActivity
|
||||
layout.getViewTreeObserver().addOnGlobalLayoutListener(this);
|
||||
|
||||
// Status Bar
|
||||
if (SDK_INT >= 21) {
|
||||
window.setStatusBarColor(TRANSPARENT);
|
||||
} else if (SDK_INT >= 19) {
|
||||
// we can't make the status bar transparent, but translucent
|
||||
window.addFlags(FLAG_TRANSLUCENT_STATUS);
|
||||
}
|
||||
window.setStatusBarColor(TRANSPARENT);
|
||||
|
||||
// Toolbar
|
||||
appBarLayout = findViewById(R.id.appBarLayout);
|
||||
@@ -257,16 +247,12 @@ public class ImageActivity extends BriarActivity
|
||||
|
||||
private void showSaveImageDialog() {
|
||||
OnClickListener okListener = (dialog, which) -> {
|
||||
if (SDK_INT >= 19) {
|
||||
String name = viewModel.getFileName() + "." +
|
||||
getVisibleAttachment().getExtension();
|
||||
try {
|
||||
requireNonNull(launcher).launch(name);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
viewModel.onSaveImageError();
|
||||
}
|
||||
} else {
|
||||
viewModel.saveImage(getVisibleAttachment());
|
||||
String name = viewModel.getFileName() + "." +
|
||||
getVisibleAttachment().getExtension();
|
||||
try {
|
||||
launcher.launch(name);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
viewModel.onSaveImageError();
|
||||
}
|
||||
};
|
||||
Builder builder = new Builder(this, R.style.BriarDialogTheme);
|
||||
@@ -295,7 +281,7 @@ public class ImageActivity extends BriarActivity
|
||||
.show();
|
||||
}
|
||||
|
||||
AttachmentItem getVisibleAttachment() {
|
||||
private AttachmentItem getVisibleAttachment() {
|
||||
return attachments.get(viewPager.getCurrentItem());
|
||||
}
|
||||
|
||||
@@ -307,6 +293,7 @@ public class ImageActivity extends BriarActivity
|
||||
super(ImageActivity.this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Fragment createFragment(int position) {
|
||||
Fragment f = ImageFragment.newInstance(
|
||||
|
||||
@@ -31,7 +31,6 @@ import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.widget.ImageView.ScaleType.FIT_START;
|
||||
import static com.bumptech.glide.load.engine.DiskCacheStrategy.NONE;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.AVAILABLE;
|
||||
@@ -150,7 +149,7 @@ public class ImageFragment extends Fragment
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
if (SDK_INT >= 21 && !(resource instanceof Animatable)) {
|
||||
if (!(resource instanceof Animatable)) {
|
||||
// set transition name only when not animatable,
|
||||
// because the animation won't start otherwise
|
||||
photoView.setTransitionName(
|
||||
|
||||
@@ -18,7 +18,6 @@ import androidx.annotation.DrawableRes;
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager.LayoutParams;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.widget.ImageView.ScaleType.CENTER_CROP;
|
||||
import static android.widget.ImageView.ScaleType.FIT_CENTER;
|
||||
import static com.bumptech.glide.load.engine.DiskCacheStrategy.NONE;
|
||||
@@ -58,10 +57,8 @@ class ImageViewHolder extends ViewHolder {
|
||||
loadImage(attachment, r);
|
||||
imageView.setScaleType(CENTER_CROP);
|
||||
}
|
||||
if (SDK_INT >= 21) {
|
||||
imageView.setTransitionName(
|
||||
attachment.getTransitionName(conversationItemId));
|
||||
}
|
||||
imageView.setTransitionName(
|
||||
attachment.getTransitionName(conversationItemId));
|
||||
}
|
||||
|
||||
private void setImageViewDimensions(AttachmentItem a, boolean single,
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package org.briarproject.briar.android.forum;
|
||||
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.briar.api.identity.AuthorInfo;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.android.threaded.ThreadItem;
|
||||
import org.briarproject.briar.api.forum.ForumPostHeader;
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.briarproject.briar.android.hotspot;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -17,8 +16,6 @@ import org.briarproject.briar.android.util.ActivityLaunchers.CreateDocumentAdvan
|
||||
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
@@ -29,14 +26,11 @@ import androidx.lifecycle.ViewModelProvider;
|
||||
import static android.content.Intent.ACTION_SEND;
|
||||
import static android.content.Intent.EXTRA_STREAM;
|
||||
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
||||
import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.view.View.INVISIBLE;
|
||||
import static android.view.View.VISIBLE;
|
||||
import static androidx.transition.TransitionManager.beginDelayedTransition;
|
||||
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
||||
import static org.briarproject.briar.android.hotspot.HotspotViewModel.getApkFileName;
|
||||
import static org.briarproject.nullsafety.NullSafety.requireNonNull;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
@@ -48,11 +42,9 @@ public class FallbackFragment extends BaseFragment {
|
||||
ViewModelProvider.Factory viewModelFactory;
|
||||
|
||||
private HotspotViewModel viewModel;
|
||||
@Nullable
|
||||
private final ActivityResultLauncher<String> launcher = SDK_INT >= 19 ?
|
||||
private final ActivityResultLauncher<String> launcher =
|
||||
registerForActivityResult(new CreateDocumentAdvanced(),
|
||||
this::onDocumentCreated) :
|
||||
null;
|
||||
this::onDocumentCreated);
|
||||
private Button fallbackButton;
|
||||
private ProgressBar progressBar;
|
||||
|
||||
@@ -89,12 +81,7 @@ public class FallbackFragment extends BaseFragment {
|
||||
beginDelayedTransition((ViewGroup) v);
|
||||
fallbackButton.setVisibility(INVISIBLE);
|
||||
progressBar.setVisibility(VISIBLE);
|
||||
|
||||
if (SDK_INT >= 19) {
|
||||
requireNonNull(launcher).launch(getApkFileName());
|
||||
} else {
|
||||
viewModel.exportApk();
|
||||
}
|
||||
launcher.launch(getApkFileName());
|
||||
});
|
||||
viewModel.getSavedApkToUri().observeEvent(this, this::shareUri);
|
||||
}
|
||||
@@ -110,23 +97,11 @@ public class FallbackFragment extends BaseFragment {
|
||||
progressBar.setVisibility(INVISIBLE);
|
||||
}
|
||||
|
||||
void shareUri(Uri uri) {
|
||||
private void shareUri(Uri uri) {
|
||||
Intent i = new Intent(ACTION_SEND);
|
||||
i.putExtra(EXTRA_STREAM, uri);
|
||||
i.setType("*/*"); // gives us all sharing options
|
||||
i.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
|
||||
Context ctx = requireContext();
|
||||
if (SDK_INT <= 19) {
|
||||
// Workaround for Android bug:
|
||||
// ctx.grantUriPermission also needed for Android 4
|
||||
List<ResolveInfo> resInfoList = ctx.getPackageManager()
|
||||
.queryIntentActivities(i, MATCH_DEFAULT_ONLY);
|
||||
for (ResolveInfo resolveInfo : resInfoList) {
|
||||
String packageName = resolveInfo.activityInfo.packageName;
|
||||
ctx.grantUriPermission(packageName, uri,
|
||||
FLAG_GRANT_READ_URI_PERMISSION);
|
||||
}
|
||||
}
|
||||
startActivity(Intent.createChooser(i, null));
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.briarproject.nullsafety.NotNullByDefault;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -38,9 +37,6 @@ import androidx.annotation.UiThread;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.os.Environment.DIRECTORY_DOWNLOADS;
|
||||
import static android.os.Environment.getExternalStoragePublicDirectory;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
@@ -168,7 +164,6 @@ class HotspotViewModel extends DbViewModel
|
||||
}
|
||||
|
||||
void exportApk(Uri uri) {
|
||||
if (SDK_INT < 19) throw new IllegalStateException();
|
||||
try {
|
||||
OutputStream out = getApplication().getContentResolver()
|
||||
.openOutputStream(uri, "wt");
|
||||
@@ -178,20 +173,6 @@ class HotspotViewModel extends DbViewModel
|
||||
}
|
||||
}
|
||||
|
||||
void exportApk() {
|
||||
if (SDK_INT >= 19) throw new IllegalStateException();
|
||||
File path = getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS);
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
path.mkdirs();
|
||||
File file = new File(path, getApkFileName());
|
||||
try {
|
||||
OutputStream out = new FileOutputStream(file);
|
||||
writeApk(out, Uri.fromFile(file));
|
||||
} catch (FileNotFoundException e) {
|
||||
handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static String getApkFileName() {
|
||||
return "briar" + (DEBUG ? "-debug-" : "-") + VERSION_NAME + ".apk";
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import android.os.Bundle;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
|
||||
public class ExitActivity extends Activity {
|
||||
|
||||
private static final Logger LOG =
|
||||
@@ -15,8 +13,7 @@ public class ExitActivity extends Activity {
|
||||
@Override
|
||||
public void onCreate(Bundle state) {
|
||||
super.onCreate(state);
|
||||
if (SDK_INT >= 21) finishAndRemoveTask();
|
||||
else finish();
|
||||
finishAndRemoveTask();
|
||||
LOG.info("Exiting");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
@@ -75,15 +75,12 @@ import static org.briarproject.bramble.api.plugin.Plugin.State.ENABLING;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
|
||||
import static org.briarproject.briar.android.BriarService.EXTRA_STARTUP_FAILED;
|
||||
import static org.briarproject.briar.android.BriarService.EXTRA_START_RESULT;
|
||||
import static org.briarproject.briar.android.TestingConstants.EXPIRY_DATE;
|
||||
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
|
||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PASSWORD;
|
||||
import static org.briarproject.briar.android.navdrawer.IntentRouter.handleExternalIntent;
|
||||
import static org.briarproject.briar.android.util.UiUtils.formatDateFull;
|
||||
import static org.briarproject.briar.android.util.UiUtils.getDaysUntilExpiry;
|
||||
import static org.briarproject.briar.android.util.UiUtils.observeOnce;
|
||||
import static org.briarproject.briar.android.util.UiUtils.resolveColorAttribute;
|
||||
import static org.briarproject.briar.android.util.UiUtils.shouldWarnOldAndroidExpiry;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
@@ -140,11 +137,9 @@ public class NavDrawerActivity extends BriarActivity implements
|
||||
setContentView(R.layout.activity_nav_drawer);
|
||||
|
||||
BriarApplication app = (BriarApplication) getApplication();
|
||||
if (!app.isInstrumentationTest()) {
|
||||
if (IS_DEBUG_BUILD || shouldWarnOldAndroidExpiry()) {
|
||||
navDrawerViewModel.showExpiryWarning()
|
||||
.observe(this, this::showExpiryWarning);
|
||||
}
|
||||
if (IS_DEBUG_BUILD && !app.isInstrumentationTest()) {
|
||||
navDrawerViewModel.showExpiryWarning()
|
||||
.observe(this, this::showExpiryWarning);
|
||||
}
|
||||
navDrawerViewModel.shouldAskForDozeWhitelisting().observe(this, ask -> {
|
||||
if (ask) showDozeDialog(R.string.dnkm_doze_intro);
|
||||
@@ -212,7 +207,7 @@ public class NavDrawerActivity extends BriarActivity implements
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
lockManager.checkIfLockable();
|
||||
if (IS_DEBUG_BUILD || shouldWarnOldAndroidExpiry()) {
|
||||
if (IS_DEBUG_BUILD) {
|
||||
navDrawerViewModel.checkExpiryWarning();
|
||||
}
|
||||
}
|
||||
@@ -384,23 +379,14 @@ public class NavDrawerActivity extends BriarActivity implements
|
||||
return;
|
||||
}
|
||||
|
||||
String text;
|
||||
if (IS_DEBUG_BUILD) {
|
||||
text = getResources().getQuantityString(
|
||||
R.plurals.expiry_warning, (int) daysUntilExpiry,
|
||||
(int) daysUntilExpiry);
|
||||
} else {
|
||||
text = getResources().getQuantityString(
|
||||
R.plurals.old_android_expiry_warning, (int) daysUntilExpiry,
|
||||
formatDateFull(this, EXPIRY_DATE),
|
||||
(int) daysUntilExpiry);
|
||||
}
|
||||
|
||||
ViewGroup expiryWarning = findViewById(R.id.expiryWarning);
|
||||
if (show) {
|
||||
// show expiry warning text
|
||||
TextView expiryWarningText =
|
||||
expiryWarning.findViewById(R.id.expiryWarningText);
|
||||
String text = getResources().getQuantityString(
|
||||
R.plurals.expiry_warning, (int) daysUntilExpiry,
|
||||
(int) daysUntilExpiry);
|
||||
expiryWarningText.setText(text);
|
||||
// make close button functional
|
||||
ImageView expiryWarningClose =
|
||||
@@ -432,7 +418,7 @@ public class NavDrawerActivity extends BriarActivity implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView,
|
||||
public View getView(int position, @Nullable View convertView,
|
||||
ViewGroup parent) {
|
||||
View view;
|
||||
if (convertView != null) {
|
||||
|
||||
@@ -19,7 +19,6 @@ import info.guardianproject.panic.Panic;
|
||||
import info.guardianproject.panic.PanicResponder;
|
||||
import info.guardianproject.trustedintents.TrustedIntents;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.briar.android.panic.PanicPreferencesFragment.KEY_LOCK;
|
||||
import static org.briarproject.briar.android.panic.PanicPreferencesFragment.KEY_PURGE;
|
||||
@@ -73,12 +72,7 @@ public class PanicResponderActivity extends BriarActivity {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SDK_INT >= 21) {
|
||||
finishAndRemoveTask();
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
finishAndRemoveTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,7 +20,6 @@ import javax.inject.Inject;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
@@ -31,7 +30,6 @@ import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
||||
import static org.briarproject.briar.android.util.UiUtils.hideViewOnSmallScreen;
|
||||
import static org.briarproject.briar.android.util.UiUtils.launchActivityToOpenFile;
|
||||
|
||||
@RequiresApi(19)
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class ReceiveFragment extends Fragment {
|
||||
|
||||
@@ -19,7 +19,6 @@ import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
@@ -29,7 +28,6 @@ import static java.util.Objects.requireNonNull;
|
||||
import static org.briarproject.briar.android.conversation.ConversationActivity.CONTACT_ID;
|
||||
import static org.briarproject.briar.android.util.UiUtils.showFragment;
|
||||
|
||||
@RequiresApi(19)
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class RemovableDriveActivity extends BriarActivity {
|
||||
|
||||
@@ -24,7 +24,6 @@ import javax.inject.Inject;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
@@ -38,7 +37,6 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
||||
import static org.briarproject.briar.android.util.UiUtils.hideViewOnSmallScreen;
|
||||
|
||||
@RequiresApi(19)
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class SendFragment extends Fragment {
|
||||
|
||||
@@ -220,10 +220,10 @@ class BriarReportCollector {
|
||||
method.setAccessible(true);
|
||||
mobileEnabled = (Boolean) requireNonNull(method.invoke(cm));
|
||||
} catch (ClassNotFoundException
|
||||
| NoSuchMethodException
|
||||
| IllegalArgumentException
|
||||
| InvocationTargetException
|
||||
| IllegalAccessException e) {
|
||||
| NoSuchMethodException
|
||||
| IllegalArgumentException
|
||||
| InvocationTargetException
|
||||
| IllegalAccessException e) {
|
||||
connectivityInfo
|
||||
.add("MobileDataReflectionException", e.toString());
|
||||
}
|
||||
@@ -300,15 +300,12 @@ class BriarReportCollector {
|
||||
scanMode == SCAN_MODE_CONNECTABLE_DISCOVERABLE;
|
||||
connectivityInfo.add("BluetoothDiscoverable", btDiscoverable);
|
||||
|
||||
if (SDK_INT >= 21) {
|
||||
// Is Bluetooth LE scanning and advertising supported?
|
||||
boolean btLeScan = bt.getBluetoothLeScanner() != null;
|
||||
connectivityInfo.add("BluetoothLeScanningSupported", btLeScan);
|
||||
boolean btLeAdvertise =
|
||||
bt.getBluetoothLeAdvertiser() != null;
|
||||
connectivityInfo.add("BluetoothLeAdvertisingSupported",
|
||||
btLeAdvertise);
|
||||
}
|
||||
// Is Bluetooth LE scanning and advertising supported?
|
||||
boolean btLeScan = bt.getBluetoothLeScanner() != null;
|
||||
connectivityInfo.add("BluetoothLeScanningSupported", btLeScan);
|
||||
boolean btLeAdvertise = bt.getBluetoothLeAdvertiser() != null;
|
||||
connectivityInfo.add("BluetoothLeAdvertisingSupported",
|
||||
btLeAdvertise);
|
||||
|
||||
Pair<String, String> p = getBluetoothAddressAndMethod(ctx, bt);
|
||||
String address = p.getFirst();
|
||||
|
||||
@@ -27,7 +27,6 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static androidx.core.view.ViewCompat.LAYOUT_DIRECTION_LTR;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.briar.android.BriarApplication.ENTRY_ACTIVITY;
|
||||
import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.SIGN_OUT_URI;
|
||||
@@ -75,12 +74,6 @@ public class DisplayFragment extends PreferenceFragmentCompat {
|
||||
Locale locale = Localizer.getLocaleFromTag(tag);
|
||||
if (locale == null)
|
||||
throw new IllegalStateException();
|
||||
// Exclude RTL locales on API < 17, they won't be laid out correctly
|
||||
if (SDK_INT < 17 && !isLeftToRight(locale)) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Skipping RTL locale " + tag);
|
||||
continue;
|
||||
}
|
||||
String nativeName = locale.getDisplayName(locale);
|
||||
// Fallback to English if the name is unknown in both native and
|
||||
// current locale.
|
||||
|
||||
@@ -18,7 +18,6 @@ import androidx.preference.ListPreference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.SwitchPreferenceCompat;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
||||
import static org.briarproject.briar.android.settings.SettingsActivity.enableAndPersist;
|
||||
@@ -71,17 +70,12 @@ public class SecurityFragment extends PreferenceFragmentCompat {
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
if (SDK_INT < 21) {
|
||||
screenLock.setVisible(false);
|
||||
screenLockTimeout.setVisible(false);
|
||||
} else {
|
||||
// timeout depends on screenLock and gets disabled automatically
|
||||
LifecycleOwner lifecycleOwner = getViewLifecycleOwner();
|
||||
viewModel.getScreenLockTimeout().observe(lifecycleOwner, value -> {
|
||||
screenLockTimeout.setValue(value);
|
||||
enableAndPersist(screenLockTimeout);
|
||||
});
|
||||
}
|
||||
// timeout depends on screenLock and gets disabled automatically
|
||||
LifecycleOwner lifecycleOwner = getViewLifecycleOwner();
|
||||
viewModel.getScreenLockTimeout().observe(lifecycleOwner, value -> {
|
||||
screenLockTimeout.setValue(value);
|
||||
enableAndPersist(screenLockTimeout);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,7 +86,6 @@ public class SecurityFragment extends PreferenceFragmentCompat {
|
||||
}
|
||||
|
||||
private void checkScreenLock() {
|
||||
if (SDK_INT < 21) return;
|
||||
LifecycleOwner lifecycleOwner = getViewLifecycleOwner();
|
||||
viewModel.getScreenLockEnabled().removeObservers(lifecycleOwner);
|
||||
if (hasScreenLock(requireActivity())) {
|
||||
|
||||
@@ -24,7 +24,6 @@ import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.PreferenceGroup;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
||||
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
|
||||
@@ -49,11 +48,9 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
||||
private SettingsViewModel viewModel;
|
||||
private AvatarPreference prefAvatar;
|
||||
|
||||
@Nullable
|
||||
private final ActivityResultLauncher<String[]> docLauncher = SDK_INT >= 19 ?
|
||||
private final ActivityResultLauncher<String[]> docLauncher =
|
||||
registerForActivityResult(new OpenImageDocumentAdvanced(),
|
||||
this::onImageSelected) :
|
||||
null;
|
||||
this::onImageSelected);
|
||||
private final ActivityResultLauncher<String> contentLauncher =
|
||||
registerForActivityResult(new GetImageAdvanced(),
|
||||
this::onImageSelected);
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
package org.briarproject.briar.android.splash;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import org.briarproject.android.dontkillmelib.wakelock.AndroidWakeLockManager;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.activity.BaseActivity;
|
||||
import org.briarproject.briar.android.controller.BriarController;
|
||||
import org.briarproject.briar.android.logout.ExitActivity;
|
||||
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class ExpiredOldAndroidActivity extends BaseActivity {
|
||||
|
||||
@Inject
|
||||
BriarController briarController;
|
||||
@Inject
|
||||
AndroidWakeLockManager wakeLockManager;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle state) {
|
||||
super.onCreate(state);
|
||||
|
||||
setContentView(R.layout.activity_expired_old_android);
|
||||
findViewById(R.id.delete_account_button).setOnClickListener(v -> {
|
||||
// Hold a wake lock to ensure we exit before the device goes to sleep
|
||||
wakeLockManager.runWakefully(() -> {
|
||||
// we're not signed in, just go ahead and delete
|
||||
briarController.deleteAccount();
|
||||
// remove from recent apps
|
||||
Intent i = new Intent(this, ExitActivity.class);
|
||||
i.addFlags(FLAG_ACTIVITY_NEW_TASK
|
||||
| FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
|
||||
| FLAG_ACTIVITY_NO_ANIMATION
|
||||
| FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivity(i);
|
||||
}, "DeleteAccount");
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectActivity(ActivityComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import javax.inject.Inject;
|
||||
|
||||
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static androidx.preference.PreferenceManager.setDefaultValues;
|
||||
import static java.lang.System.currentTimeMillis;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
@@ -50,12 +49,8 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
public void onCreate(@Nullable Bundle state) {
|
||||
super.onCreate(state);
|
||||
|
||||
if (SDK_INT >= 21) {
|
||||
getWindow().setExitTransition(new Fade());
|
||||
}
|
||||
|
||||
getWindow().setExitTransition(new Fade());
|
||||
setPreferencesDefaults();
|
||||
|
||||
setContentView(R.layout.splash);
|
||||
|
||||
if (accountManager.hasDatabaseKey()) {
|
||||
@@ -65,14 +60,9 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
int duration =
|
||||
getResources().getInteger(R.integer.splashScreenDuration);
|
||||
new Handler().postDelayed(() -> {
|
||||
if (currentTimeMillis() >= EXPIRY_DATE) {
|
||||
if (IS_DEBUG_BUILD) {
|
||||
LOG.info("Expired: debug build");
|
||||
startNextActivity(ExpiredActivity.class);
|
||||
} else {
|
||||
LOG.info("Expired: running on old Android");
|
||||
startNextActivity(ExpiredOldAndroidActivity.class);
|
||||
}
|
||||
if (IS_DEBUG_BUILD && currentTimeMillis() >= EXPIRY_DATE) {
|
||||
LOG.info("Expired");
|
||||
startNextActivity(ExpiredActivity.class);
|
||||
} else {
|
||||
startNextActivity(ENTRY_ACTIVITY);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import androidx.activity.result.contract.ActivityResultContracts.OpenDocument;
|
||||
import androidx.activity.result.contract.ActivityResultContracts.OpenMultipleDocuments;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import static android.app.Activity.RESULT_CANCELED;
|
||||
import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE;
|
||||
@@ -26,7 +25,6 @@ import static org.briarproject.bramble.util.AndroidUtils.getSupportedImageConten
|
||||
@NotNullByDefault
|
||||
public class ActivityLaunchers {
|
||||
|
||||
@RequiresApi(19)
|
||||
public static class CreateDocumentAdvanced extends CreateDocument {
|
||||
@NonNull
|
||||
@Override
|
||||
@@ -48,7 +46,6 @@ public class ActivityLaunchers {
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(19)
|
||||
public static class OpenDocumentAdvanced extends OpenDocument {
|
||||
@NonNull
|
||||
@Override
|
||||
@@ -69,13 +66,11 @@ public class ActivityLaunchers {
|
||||
putShowAdvancedExtra(i);
|
||||
i.setType("image/*");
|
||||
i.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
|
||||
if (SDK_INT >= 19)
|
||||
i.putExtra(EXTRA_MIME_TYPES, getSupportedImageContentTypes());
|
||||
i.putExtra(EXTRA_MIME_TYPES, getSupportedImageContentTypes());
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(18)
|
||||
public static class GetMultipleImagesAdvanced extends GetMultipleContents {
|
||||
@NonNull
|
||||
@Override
|
||||
@@ -84,13 +79,11 @@ public class ActivityLaunchers {
|
||||
putShowAdvancedExtra(i);
|
||||
i.setType("image/*");
|
||||
i.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
|
||||
if (SDK_INT >= 19)
|
||||
i.putExtra(EXTRA_MIME_TYPES, getSupportedImageContentTypes());
|
||||
i.putExtra(EXTRA_MIME_TYPES, getSupportedImageContentTypes());
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(19)
|
||||
public static class OpenImageDocumentAdvanced extends OpenDocument {
|
||||
@NonNull
|
||||
@Override
|
||||
@@ -99,13 +92,11 @@ public class ActivityLaunchers {
|
||||
putShowAdvancedExtra(i);
|
||||
i.setType("image/*");
|
||||
i.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
|
||||
if (SDK_INT >= 19)
|
||||
i.putExtra(EXTRA_MIME_TYPES, getSupportedImageContentTypes());
|
||||
i.putExtra(EXTRA_MIME_TYPES, getSupportedImageContentTypes());
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(19)
|
||||
public static class OpenMultipleImageDocumentsAdvanced
|
||||
extends OpenMultipleDocuments {
|
||||
@NonNull
|
||||
@@ -115,8 +106,7 @@ public class ActivityLaunchers {
|
||||
putShowAdvancedExtra(i);
|
||||
i.setType("image/*");
|
||||
i.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
|
||||
if (SDK_INT >= 19)
|
||||
i.putExtra(EXTRA_MIME_TYPES, getSupportedImageContentTypes());
|
||||
i.putExtra(EXTRA_MIME_TYPES, getSupportedImageContentTypes());
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import androidx.annotation.ColorRes;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static androidx.core.app.NotificationCompat.VISIBILITY_PRIVATE;
|
||||
|
||||
public class BriarNotificationBuilder extends NotificationCompat.Builder {
|
||||
@@ -24,7 +23,7 @@ public class BriarNotificationBuilder extends NotificationCompat.Builder {
|
||||
|
||||
setLights(ContextCompat.getColor(context, R.color.briar_lime_400),
|
||||
750, 500);
|
||||
if (SDK_INT >= 21) setVisibility(VISIBILITY_PRIVATE);
|
||||
setVisibility(VISIBILITY_PRIVATE);
|
||||
}
|
||||
|
||||
public BriarNotificationBuilder setColorRes(@ColorRes int res) {
|
||||
@@ -33,7 +32,7 @@ public class BriarNotificationBuilder extends NotificationCompat.Builder {
|
||||
}
|
||||
|
||||
public BriarNotificationBuilder setNotificationCategory(String category) {
|
||||
if (SDK_INT >= 21) setCategory(category);
|
||||
setCategory(category);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.snackbar.Snackbar.Callback;
|
||||
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.nullsafety.NotNullByDefault;
|
||||
@@ -13,11 +12,7 @@ import androidx.annotation.ColorRes;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.view.View.INVISIBLE;
|
||||
import static android.view.View.VISIBLE;
|
||||
import static androidx.core.content.ContextCompat.getColor;
|
||||
import static com.google.android.material.snackbar.Snackbar.LENGTH_INDEFINITE;
|
||||
|
||||
@NotNullByDefault
|
||||
public class BriarSnackbarBuilder {
|
||||
@@ -37,24 +32,6 @@ public class BriarSnackbarBuilder {
|
||||
R.color.briar_button_text_positive));
|
||||
s.setAction(actionResId, onClickListener);
|
||||
}
|
||||
// Workaround for https://issuetracker.google.com/issues/64285517
|
||||
if (duration == LENGTH_INDEFINITE && SDK_INT < 21) {
|
||||
// Hide snackbar while it's opening to make bouncing less noticeable
|
||||
s.getView().setVisibility(INVISIBLE);
|
||||
s.addCallback(new Callback() {
|
||||
@Override
|
||||
public void onShown(Snackbar snackbar) {
|
||||
snackbar.getView().setVisibility(VISIBLE);
|
||||
// Request layout again in case snackbar is in wrong place
|
||||
snackbar.getView().requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismissed(Snackbar snackbar, int event) {
|
||||
snackbar.getView().setVisibility(INVISIBLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,6 @@ import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.ColorRes;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.annotation.UiThread;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.ContextCompat;
|
||||
@@ -108,8 +107,6 @@ import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.briar.android.TestingConstants.EXPIRY_DATE;
|
||||
import static org.briarproject.briar.android.TestingConstants.IS_OLD_ANDROID;
|
||||
import static org.briarproject.briar.android.TestingConstants.OLD_ANDROID_WARN_DATE;
|
||||
import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_APP_LOGCAT;
|
||||
import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_APP_START_TIME;
|
||||
import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_INITIAL_COMMENT;
|
||||
@@ -244,11 +241,6 @@ public class UiUtils {
|
||||
return (EXPIRY_DATE - now) / DAYS.toMillis(1);
|
||||
}
|
||||
|
||||
public static boolean shouldWarnOldAndroidExpiry() {
|
||||
return IS_OLD_ANDROID &&
|
||||
System.currentTimeMillis() >= OLD_ANDROID_WARN_DATE;
|
||||
}
|
||||
|
||||
public static SpannableStringBuilder getTeaser(Context ctx, Spanned text) {
|
||||
if (text.length() < TEASER_LENGTH)
|
||||
throw new IllegalArgumentException(
|
||||
@@ -376,7 +368,6 @@ public class UiUtils {
|
||||
}
|
||||
|
||||
public static boolean hasKeyguardLock(Context ctx) {
|
||||
if (SDK_INT < 21) return false;
|
||||
KeyguardManager keyguardManager =
|
||||
(KeyguardManager) ctx.getSystemService(KEYGUARD_SERVICE);
|
||||
if (keyguardManager == null) return false;
|
||||
@@ -438,7 +429,6 @@ public class UiUtils {
|
||||
keyEvent.getKeyCode() == KEYCODE_ENTER;
|
||||
}
|
||||
|
||||
@RequiresApi(api = 21)
|
||||
public static void excludeSystemUi(Transition transition) {
|
||||
transition.excludeTarget(android.R.id.statusBarBackground, true);
|
||||
transition.excludeTarget(android.R.id.navigationBarBackground, true);
|
||||
@@ -480,7 +470,6 @@ public class UiUtils {
|
||||
}
|
||||
|
||||
public static boolean isRtl(Context ctx) {
|
||||
if (SDK_INT < 17) return false;
|
||||
return ctx.getResources().getConfiguration().getLayoutDirection() ==
|
||||
LAYOUT_DIRECTION_RTL;
|
||||
}
|
||||
@@ -507,7 +496,7 @@ public class UiUtils {
|
||||
view.setVisibility(small ? GONE : VISIBLE);
|
||||
}
|
||||
|
||||
public static boolean isSmallScreenRelativeToFontSize(Context ctx) {
|
||||
private static boolean isSmallScreenRelativeToFontSize(Context ctx) {
|
||||
Configuration config = ctx.getResources().getConfiguration();
|
||||
if (config.fontScale == 0f) return true;
|
||||
return config.screenHeightDp / config.fontScale < 600;
|
||||
@@ -546,7 +535,7 @@ public class UiUtils {
|
||||
}
|
||||
|
||||
public static void launchActivityToOpenFile(Context ctx,
|
||||
@Nullable ActivityResultLauncher<String[]> docLauncher,
|
||||
ActivityResultLauncher<String[]> docLauncher,
|
||||
ActivityResultLauncher<String> contentLauncher,
|
||||
String contentType) {
|
||||
// Try GET_CONTENT, fall back to OPEN_DOCUMENT if available
|
||||
@@ -556,13 +545,11 @@ public class UiUtils {
|
||||
} catch (ActivityNotFoundException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
if (docLauncher != null) {
|
||||
try {
|
||||
docLauncher.launch(new String[] {contentType});
|
||||
return;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
try {
|
||||
docLauncher.launch(new String[] {contentType});
|
||||
return;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
Toast.makeText(ctx, R.string.error_start_activity, LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.briarproject.briar.android.widget;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
@@ -27,7 +26,6 @@ public class TouchInterceptingLinearLayout extends LinearLayout {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@TargetApi(21)
|
||||
public TouchInterceptingLinearLayout(Context context, AttributeSet attrs,
|
||||
int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
<item
|
||||
android:id="@+id/action_transfer_data"
|
||||
android:title="@string/removable_drive_menu_title"
|
||||
android:visible="false"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
@@ -55,10 +55,6 @@
|
||||
<item quantity="one">This is a test version of Briar. Your account will expire in %d day and cannot be renewed.</item>
|
||||
<item quantity="other">This is a test version of Briar. Your account will expire in %d days and cannot be renewed.</item>
|
||||
</plurals>
|
||||
<plurals name="old_android_expiry_warning">
|
||||
<item quantity="one">Android 4 is no longer supported. Briar will stop working on %s (in %d day). Please install Briar on a newer device and create a new account.</item>
|
||||
<item quantity="other">Android 4 is no longer supported. Briar will stop working on %s (in %d days). Please install Briar on a newer device and create a new account.</item>
|
||||
</plurals>
|
||||
<string name="expiry_date_reached">This software has expired.\nThank you for testing!</string>
|
||||
<string name="download_briar">To continue using Briar, please download the latest release.</string>
|
||||
<string name="create_new_account">You will need to create a new account, but you can use the same nickname.</string>
|
||||
|
||||
Reference in New Issue
Block a user