From e6f66ebc957fc9702a2c7c092645f33a9ebe3211 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 14 Dec 2020 10:53:12 -0300 Subject: [PATCH] Screen overlay warning: remove ability to query and remember allowed apps for API 30+ as we can't query all installed apps anymore when targeting API 30 --- .../briarproject/briar/android/AppModule.java | 5 +++- .../android/ScreenFilterMonitorImpl.java | 4 ++-- .../briar/android/activity/BaseActivity.java | 21 +++++++++++++---- .../fragment/ScreenFilterDialogFragment.java | 23 +++++++++++++++---- .../api/android/ScreenFilterMonitor.java | 4 ++++ briar-android/src/main/res/values/strings.xml | 2 ++ 6 files changed, 48 insertions(+), 11 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java index 30c510d80..298067573 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java @@ -198,7 +198,10 @@ public class AppModule { ScreenFilterMonitor provideScreenFilterMonitor( LifecycleManager lifecycleManager, ScreenFilterMonitorImpl screenFilterMonitor) { - lifecycleManager.registerService(screenFilterMonitor); + if (SDK_INT <= 29) { + // this keeps track of installed apps and does not work on API 30+ + lifecycleManager.registerService(screenFilterMonitor); + } return screenFilterMonitor; } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/ScreenFilterMonitorImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/ScreenFilterMonitorImpl.java index 1cdbb126f..0cb51987a 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/ScreenFilterMonitorImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/ScreenFilterMonitorImpl.java @@ -58,7 +58,7 @@ class ScreenFilterMonitorImpl implements ScreenFilterMonitor, Service { Logger.getLogger(ScreenFilterMonitorImpl.class.getName()); /* - * Ignore Play Services if it uses this package name and public key - it's + * Ignore Play Services if it uses this package name and public key - it's * effectively a system app, but not flagged as such on older systems */ private static final String PLAY_SERVICES_PACKAGE = @@ -108,7 +108,7 @@ class ScreenFilterMonitorImpl implements ScreenFilterMonitor, Service { Set allowed = prefs.getStringSet(PREF_KEY_ALLOWED, Collections.emptySet()); List apps = new ArrayList<>(); - List packageInfos = + @SuppressLint("QueryPermissionsNeeded") List packageInfos = pm.getInstalledPackages(GET_PERMISSIONS); for (PackageInfo packageInfo : packageInfos) { if (!allowed.contains(packageInfo.packageName) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java index f67f1fc91..a8f65f7b1 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java @@ -39,9 +39,11 @@ import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; +import static android.os.Build.VERSION.SDK_INT; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static androidx.lifecycle.Lifecycle.State.STARTED; +import static java.util.Collections.emptyList; import static java.util.logging.Level.INFO; import static java.util.logging.Logger.getLogger; import static org.briarproject.briar.android.TestingConstants.PREVENT_SCREENSHOTS; @@ -201,9 +203,15 @@ public abstract class BaseActivity extends AppCompatActivity // If the dialog is already visible, filter the tap ScreenFilterDialogFragment f = findDialogFragment(); if (f != null && f.isVisible()) return false; - Collection apps = screenFilterMonitor.getApps(); - // If all overlay apps have been allowed, allow the tap - if (apps.isEmpty()) return true; + Collection apps; + // querying all apps is only possible at API 29 and below + if (SDK_INT <= 29) { + apps = screenFilterMonitor.getApps(); + // If all overlay apps have been allowed, allow the tap + if (apps.isEmpty()) return true; + } else { + apps = emptyList(); + } // Show dialog unless onSaveInstanceState() has been called, see #1112 FragmentManager fm = getSupportFragmentManager(); if (!fm.isStateSaved()) { @@ -265,7 +273,12 @@ public abstract class BaseActivity extends AppCompatActivity private void protectToolbar() { findToolbar(); if (toolbar != null) { - boolean filter = !screenFilterMonitor.getApps().isEmpty(); + boolean filter; + if (SDK_INT <= 29) { + filter = !screenFilterMonitor.getApps().isEmpty(); + } else { + filter = true; + } UiUtils.setFilterTouchesWhenObscured(toolbar, filter); } } 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 5de6feb0c..26484301c 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 @@ -5,6 +5,7 @@ import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; import android.view.LayoutInflater; @@ -28,6 +29,10 @@ import javax.inject.Inject; import androidx.appcompat.app.AlertDialog; 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; + @MethodsNotNullByDefault @ParametersNotNullByDefault public class ScreenFilterDialogFragment extends DialogFragment { @@ -37,7 +42,7 @@ public class ScreenFilterDialogFragment extends DialogFragment { @Inject ScreenFilterMonitor screenFilterMonitor; - DismissListener dismissListener = null; + private DismissListener dismissListener = null; public static ScreenFilterDialogFragment newInstance( Collection apps) { @@ -83,10 +88,20 @@ public class ScreenFilterDialogFragment extends DialogFragment { View dialogView = inflater.inflate(R.layout.dialog_screen_filter, null); builder.setView(dialogView); TextView message = dialogView.findViewById(R.id.screen_filter_message); - message.setText(getString(R.string.screen_filter_body, - TextUtils.join("\n", appNames))); CheckBox allow = dialogView.findViewById(R.id.screen_filter_checkbox); - builder.setNeutralButton(R.string.continue_button, (dialog, which) -> { + if (SDK_INT <= 29) { + message.setText(getString(R.string.screen_filter_body, + TextUtils.join("\n", appNames))); + } else { + message.setText(R.string.screen_filter_body_api_30); + allow.setVisibility(GONE); + builder.setNeutralButton(R.string.screen_filter_review_apps, + (dialog, which) -> { + Intent i = new Intent(ACTION_MANAGE_OVERLAY_PERMISSION); + startActivity(i); + }); + } + builder.setPositiveButton(R.string.continue_button, (dialog, which) -> { if (allow.isChecked()) screenFilterMonitor.allowApps(packageNames); dialog.dismiss(); }); diff --git a/briar-android/src/main/java/org/briarproject/briar/api/android/ScreenFilterMonitor.java b/briar-android/src/main/java/org/briarproject/briar/api/android/ScreenFilterMonitor.java index b9abd669c..9d1cb9a0c 100644 --- a/briar-android/src/main/java/org/briarproject/briar/api/android/ScreenFilterMonitor.java +++ b/briar-android/src/main/java/org/briarproject/briar/api/android/ScreenFilterMonitor.java @@ -14,6 +14,8 @@ public interface ScreenFilterMonitor { * SYSTEM_ALERT_WINDOW permission, excluding system apps, Google Play * Services, and any apps that have been allowed by calling * {@link #allowApps(Collection)}. + * + * Only works on SDK_INT 29 and below. */ @UiThread Collection getApps(); @@ -21,6 +23,8 @@ public interface ScreenFilterMonitor { /** * Allows the apps with the given package names to use overlay windows. * They will not be returned by future calls to {@link #getApps()}. + * + * Only works on SDK_INT 29 and below. */ @UiThread void allowApps(Collection packageNames); diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 24c62198a..9d7e56b68 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -590,7 +590,9 @@ Screen overlay detected Another app is drawing on top of Briar. To protect your security, Briar will not respond to touches when another app is drawing on top.\n\nThe following apps might be drawing on top:\n\n%1$s + Another app is drawing on top of Briar. To protect your security, Briar will not respond to touches when another app is drawing on top.\n\nReview apps below to find the responsible app. Allow these apps to draw on top + Review apps Camera permission