diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/DozeFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/account/DozeFragment.java index 1c22e8187..64c313941 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/DozeFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/DozeFragment.java @@ -1,6 +1,7 @@ package org.briarproject.briar.android.account; import android.annotation.SuppressLint; +import android.content.ActivityNotFoundException; import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; @@ -8,6 +9,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ProgressBar; +import android.widget.Toast; import org.briarproject.briar.R; import org.briarproject.briar.android.account.PowerView.OnCheckedChangedListener; @@ -18,6 +20,7 @@ import androidx.annotation.Nullable; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; +import static android.widget.Toast.LENGTH_LONG; import static org.briarproject.android.dontkillmelib.DozeUtils.getDozeWhitelistingIntent; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_DOZE_WHITELISTING; import static org.briarproject.briar.android.util.UiUtils.showOnboardingDialog; @@ -113,7 +116,12 @@ public class DozeFragment extends SetupFragment private void askForDozeWhitelisting() { if (getContext() == null) return; Intent i = getDozeWhitelistingIntent(getContext()); - startActivityForResult(i, REQUEST_DOZE_WHITELISTING); + try { + startActivityForResult(i, REQUEST_DOZE_WHITELISTING); + } catch (ActivityNotFoundException e) { + Toast.makeText(requireContext(), + R.string.error_start_activity, LENGTH_LONG).show(); + } } @Override diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/HuaweiProtectedAppsView.java b/briar-android/src/main/java/org/briarproject/briar/android/account/HuaweiProtectedAppsView.java index ec4b442b8..225ec1265 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/HuaweiProtectedAppsView.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/HuaweiProtectedAppsView.java @@ -1,8 +1,10 @@ package org.briarproject.briar.android.account; +import android.content.ActivityNotFoundException; import android.content.Context; import android.util.AttributeSet; +import android.widget.Toast; import org.briarproject.briar.R; import org.briarproject.nullsafety.NotNullByDefault; @@ -12,6 +14,7 @@ import javax.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.UiThread; +import static android.widget.Toast.LENGTH_LONG; import static org.briarproject.android.dontkillmelib.HuaweiUtils.getHuaweiProtectedAppsIntent; import static org.briarproject.android.dontkillmelib.HuaweiUtils.protectedAppsNeedsToBeShown; @@ -49,7 +52,13 @@ class HuaweiProtectedAppsView extends PowerView { @Override protected void onButtonClick() { - getContext().startActivity(getHuaweiProtectedAppsIntent()); + Context ctx = getContext(); + try { + ctx.startActivity(getHuaweiProtectedAppsIntent()); + } catch (ActivityNotFoundException e) { + Toast.makeText(ctx, R.string.error_start_activity, LENGTH_LONG) + .show(); + } setChecked(true); } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/SetupActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/account/SetupActivity.java index 55d04c238..c53bf9352 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/SetupActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/SetupActivity.java @@ -36,7 +36,7 @@ public class SetupActivity extends BaseActivity @Inject ViewModelProvider.Factory viewModelFactory; - SetupViewModel viewModel; + private SetupViewModel viewModel; @Override public void injectActivity(ActivityComponent component) { @@ -71,16 +71,16 @@ public class SetupActivity extends BaseActivity } } - void showPasswordFragment() { + private void showPasswordFragment() { showNextFragment(SetPasswordFragment.newInstance()); } @TargetApi(23) - void showDozeFragment() { + private void showDozeFragment() { showNextFragment(DozeFragment.newInstance()); } - void showApp() { + private void showApp() { Intent i = new Intent(this, ENTRY_ACTIVITY); i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME | FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_CLEAR_TOP); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/UnlockActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/account/UnlockActivity.java index 65c357949..297b22469 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/UnlockActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/UnlockActivity.java @@ -1,6 +1,7 @@ package org.briarproject.briar.android.account; import android.app.KeyguardManager; +import android.content.ActivityNotFoundException; import android.content.Intent; import android.hardware.biometrics.BiometricPrompt; import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback; @@ -28,6 +29,7 @@ import static android.hardware.biometrics.BiometricPrompt.BIOMETRIC_ERROR_CANCEL import static android.hardware.biometrics.BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED; import static android.os.Build.VERSION.SDK_INT; import static android.view.View.INVISIBLE; +import static android.widget.Toast.LENGTH_LONG; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_KEYGUARD_UNLOCK; import static org.briarproject.briar.android.util.UiUtils.hasKeyguardLock; import static org.briarproject.briar.android.util.UiUtils.hasUsableFingerprint; @@ -191,7 +193,12 @@ public class UnlockActivity extends BaseActivity { unlock(); } else { keyguardShown = true; - startActivityForResult(intent, REQUEST_KEYGUARD_UNLOCK); + try { + startActivityForResult(intent, REQUEST_KEYGUARD_UNLOCK); + } catch (ActivityNotFoundException e) { + Toast.makeText(this, R.string.error_start_activity, LENGTH_LONG) + .show(); + } overridePendingTransition(0, 0); } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/XiaomiLockAppsView.java b/briar-android/src/main/java/org/briarproject/briar/android/account/XiaomiLockAppsView.java index d2af11a90..1b268dd89 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/XiaomiLockAppsView.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/XiaomiLockAppsView.java @@ -1,5 +1,6 @@ package org.briarproject.briar.android.account; +import android.content.ActivityNotFoundException; import android.content.Context; import android.util.AttributeSet; import android.widget.Toast; @@ -60,12 +61,12 @@ class XiaomiLockAppsView extends PowerView { getContext().startActivity(getXiaomiLockAppsIntent()); setChecked(true); return; - } catch (SecurityException e) { + } catch (SecurityException | ActivityNotFoundException e) { logException(LOG, WARNING, e); + Toast.makeText(getContext(), + R.string.dnkm_xiaomi_lock_apps_error_toast, + LENGTH_LONG).show(); } - Toast.makeText(getContext(), - R.string.dnkm_xiaomi_lock_apps_error_toast, - LENGTH_LONG).show(); // Let the user continue with setup setChecked(true); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java index 1370c5f9c..ed349038b 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java @@ -1,9 +1,11 @@ package org.briarproject.briar.android.activity; +import android.content.ActivityNotFoundException; import android.content.Intent; import android.transition.Transition; import android.view.Window; import android.widget.CheckBox; +import android.widget.Toast; import org.briarproject.android.dontkillmelib.wakelock.AndroidWakeLockManager; import org.briarproject.bramble.api.system.Wakeful; @@ -34,9 +36,12 @@ 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; import static android.os.Build.VERSION.SDK_INT; +import static android.widget.Toast.LENGTH_LONG; import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; import static org.briarproject.android.dontkillmelib.DozeUtils.getDozeWhitelistingIntent; +import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_DOZE_WHITELISTING; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PASSWORD; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_UNLOCK; @@ -179,7 +184,13 @@ public abstract class BriarActivity extends BaseActivity { b.setPositiveButton(R.string.fix, (dialog, which) -> { Intent i = getDozeWhitelistingIntent(BriarActivity.this); - startActivityForResult(i, REQUEST_DOZE_WHITELISTING); + try { + startActivityForResult(i, REQUEST_DOZE_WHITELISTING); + } catch (ActivityNotFoundException e) { + logException(LOG, WARNING, e); + Toast.makeText(this, R.string.error_start_activity, + LENGTH_LONG).show(); + } dialog.dismiss(); }); b.setNegativeButton(R.string.cancel, diff --git a/briar-android/src/main/java/org/briarproject/briar/android/fragment/ScreenFilterDialogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/fragment/ScreenFilterDialogFragment.java index 923f0f775..9b338009a 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/fragment/ScreenFilterDialogFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/fragment/ScreenFilterDialogFragment.java @@ -3,6 +3,7 @@ package org.briarproject.briar.android.fragment; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Dialog; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -12,6 +13,7 @@ import android.view.LayoutInflater; import android.view.View; import android.widget.CheckBox; import android.widget.TextView; +import android.widget.Toast; import org.briarproject.briar.R; import org.briarproject.briar.android.activity.BaseActivity; @@ -19,6 +21,7 @@ import org.briarproject.briar.api.android.ScreenFilterMonitor; import org.briarproject.briar.api.android.ScreenFilterMonitor.AppDetails; import org.briarproject.nullsafety.MethodsNotNullByDefault; import org.briarproject.nullsafety.ParametersNotNullByDefault; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collection; @@ -32,6 +35,7 @@ import androidx.fragment.app.DialogFragment; import static android.os.Build.VERSION.SDK_INT; import static android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION; import static android.view.View.GONE; +import static android.widget.Toast.LENGTH_LONG; @MethodsNotNullByDefault @ParametersNotNullByDefault @@ -68,6 +72,7 @@ public class ScreenFilterDialogFragment extends DialogFragment { ((BaseActivity) requireActivity()).getActivityComponent().inject(this); } + @NotNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { Activity activity = getActivity(); @@ -98,7 +103,13 @@ public class ScreenFilterDialogFragment extends DialogFragment { builder.setNeutralButton(R.string.screen_filter_review_apps, (dialog, which) -> { Intent i = new Intent(ACTION_MANAGE_OVERLAY_PERMISSION); - startActivity(i); + try { + startActivity(i); + } catch (ActivityNotFoundException e) { + Toast.makeText(requireContext(), + R.string.error_start_activity, LENGTH_LONG) + .show(); + } }); } builder.setPositiveButton(R.string.continue_button, (dialog, which) -> { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager.java b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager.java index 95c0d57fe..6c0312244 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager.java @@ -1,7 +1,9 @@ package org.briarproject.briar.android.hotspot; +import android.content.ActivityNotFoundException; import android.content.Intent; import android.provider.Settings; +import android.widget.Toast; import org.briarproject.briar.R; @@ -12,8 +14,11 @@ import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; import androidx.core.util.Consumer; +import static android.widget.Toast.LENGTH_LONG; import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.util.LogUtils.logException; /** * This class ensures that the conditions to open a hotspot are fulfilled on @@ -77,7 +82,13 @@ class ConditionManager extends AbstractConditionManager { } private void requestEnableWiFi() { - wifiRequest.launch(new Intent(Settings.ACTION_WIFI_SETTINGS)); + try { + wifiRequest.launch(new Intent(Settings.ACTION_WIFI_SETTINGS)); + } catch (ActivityNotFoundException e) { + logException(LOG, WARNING, e); + Toast.makeText(ctx, R.string.error_start_activity, LENGTH_LONG) + .show(); + } } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager29.java b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager29.java index d243dd320..fc5318cc8 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager29.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager29.java @@ -1,7 +1,9 @@ package org.briarproject.briar.android.hotspot; +import android.content.ActivityNotFoundException; import android.content.Intent; import android.provider.Settings; +import android.widget.Toast; import org.briarproject.briar.R; import org.briarproject.briar.android.util.Permission; @@ -19,10 +21,13 @@ import androidx.core.util.Consumer; import static android.Manifest.permission.ACCESS_FINE_LOCATION; import static android.os.Build.VERSION.SDK_INT; +import static android.widget.Toast.LENGTH_LONG; import static androidx.core.app.ActivityCompat.shouldShowRequestPermissionRationale; import static java.lang.Boolean.TRUE; import static java.util.logging.Level.INFO; +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.util.PermissionUtils.isLocationEnabledForWiFi; import static org.briarproject.briar.android.util.PermissionUtils.showLocationDialog; @@ -147,7 +152,13 @@ class ConditionManager29 extends AbstractConditionManager { } private void requestEnableWiFi() { - wifiRequest.launch(new Intent(Settings.Panel.ACTION_WIFI)); + try { + wifiRequest.launch(new Intent(Settings.Panel.ACTION_WIFI)); + } catch (ActivityNotFoundException e) { + logException(LOG, WARNING, e); + Toast.makeText(ctx, R.string.error_start_activity, LENGTH_LONG) + .show(); + } } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager33.java b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager33.java index 13a95aa84..4f4d8b23b 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager33.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/ConditionManager33.java @@ -1,7 +1,9 @@ package org.briarproject.briar.android.hotspot; +import android.content.ActivityNotFoundException; import android.content.Intent; import android.provider.Settings; +import android.widget.Toast; import org.briarproject.briar.R; import org.briarproject.briar.android.util.Permission; @@ -18,10 +20,13 @@ import androidx.annotation.RequiresApi; import androidx.core.util.Consumer; import static android.Manifest.permission.NEARBY_WIFI_DEVICES; +import static android.widget.Toast.LENGTH_LONG; import static androidx.core.app.ActivityCompat.shouldShowRequestPermissionRationale; import static java.lang.Boolean.TRUE; import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.util.LogUtils.logException; /** * This class ensures that the conditions to open a hotspot are fulfilled on @@ -133,7 +138,13 @@ class ConditionManager33 extends AbstractConditionManager { } private void requestEnableWiFi() { - wifiRequest.launch(new Intent(Settings.Panel.ACTION_WIFI)); + try { + wifiRequest.launch(new Intent(Settings.Panel.ACTION_WIFI)); + } catch (ActivityNotFoundException e) { + logException(LOG, WARNING, e); + Toast.makeText(ctx, R.string.error_start_activity, LENGTH_LONG) + .show(); + } } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/FallbackFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/FallbackFragment.java index efc81a9f6..00dfcaa01 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/FallbackFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/FallbackFragment.java @@ -1,5 +1,6 @@ package org.briarproject.briar.android.hotspot; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.net.Uri; @@ -9,6 +10,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ProgressBar; +import android.widget.Toast; import org.briarproject.briar.R; import org.briarproject.briar.android.fragment.BaseFragment; @@ -28,6 +30,7 @@ import static android.content.Intent.EXTRA_STREAM; import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; +import static android.widget.Toast.LENGTH_LONG; import static androidx.transition.TransitionManager.beginDelayedTransition; import static org.briarproject.briar.android.AppModule.getAndroidComponent; import static org.briarproject.briar.android.hotspot.HotspotViewModel.getApkFileName; @@ -102,7 +105,12 @@ public class FallbackFragment extends BaseFragment { i.putExtra(EXTRA_STREAM, uri); i.setType("*/*"); // gives us all sharing options i.addFlags(FLAG_GRANT_READ_URI_PERMISSION); - startActivity(Intent.createChooser(i, null)); + try { + startActivity(Intent.createChooser(i, null)); + } catch (ActivityNotFoundException e) { + Toast.makeText(requireContext(), R.string.error_start_activity, + LENGTH_LONG).show(); + } } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/util/PermissionUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/util/PermissionUtils.java index fdad47615..ded32de32 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/util/PermissionUtils.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/util/PermissionUtils.java @@ -47,7 +47,7 @@ public class PermissionUtils { } } - public static boolean isPermissionGranted(Context ctx, String permission) { + private static boolean isPermissionGranted(Context ctx, String permission) { return checkSelfPermission(ctx, permission) == PERMISSION_GRANTED; } @@ -68,7 +68,7 @@ public class PermissionUtils { gotPermission(ctx, grantedMap, BLUETOOTH_SCAN); } - public static DialogInterface.OnClickListener getGoToSettingsListener( + private static DialogInterface.OnClickListener getGoToSettingsListener( Context context) { return (dialog, which) -> { Intent i = new Intent(); @@ -76,7 +76,12 @@ public class PermissionUtils { i.addCategory(CATEGORY_DEFAULT); i.setData(Uri.parse("package:" + APPLICATION_ID)); i.addFlags(FLAG_ACTIVITY_NEW_TASK); - context.startActivity(i); + try { + context.startActivity(i); + } catch (ActivityNotFoundException e) { + Toast.makeText(context, R.string.error_start_activity, + LENGTH_LONG).show(); + } }; }