mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 03:09:04 +01:00
Simplify dialog handling, work around Android bug.
This commit is contained in:
@@ -4,6 +4,7 @@ import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
@@ -21,6 +22,7 @@ import org.briarproject.briar.android.controller.ActivityLifecycleController;
|
||||
import org.briarproject.briar.android.forum.ForumModule;
|
||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||
import org.briarproject.briar.android.fragment.ScreenFilterDialogFragment;
|
||||
import org.briarproject.briar.android.util.UiUtils;
|
||||
import org.briarproject.briar.android.widget.TapSafeFrameLayout;
|
||||
import org.briarproject.briar.android.widget.TapSafeFrameLayout.OnTapFilteredListener;
|
||||
import org.briarproject.briar.api.android.ScreenFilterMonitor;
|
||||
@@ -41,8 +43,6 @@ import static org.briarproject.briar.android.TestingConstants.PREVENT_SCREENSHOT
|
||||
public abstract class BaseActivity extends AppCompatActivity
|
||||
implements DestroyableContext, OnTapFilteredListener {
|
||||
|
||||
private static final String STATE_SHOULD_SHOW_DIALOG = "shouldShowDialog";
|
||||
|
||||
@Inject
|
||||
protected ScreenFilterMonitor screenFilterMonitor;
|
||||
|
||||
@@ -52,10 +52,6 @@ public abstract class BaseActivity extends AppCompatActivity
|
||||
new ArrayList<>();
|
||||
private boolean destroyed = false;
|
||||
|
||||
@Nullable
|
||||
private ScreenFilterDialogFragment dialogFrag = null;
|
||||
private boolean shouldShowDialog = false;
|
||||
|
||||
@Nullable
|
||||
private Toolbar toolbar = null;
|
||||
private boolean searchedForToolbar = false;
|
||||
@@ -86,15 +82,6 @@ public abstract class BaseActivity extends AppCompatActivity
|
||||
for (ActivityLifecycleController alc : lifecycleControllers) {
|
||||
alc.onActivityCreate(this);
|
||||
}
|
||||
|
||||
if (state != null)
|
||||
shouldShowDialog = state.getBoolean(STATE_SHOULD_SHOW_DIALOG);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle state) {
|
||||
super.onSaveInstanceState(state);
|
||||
state.putBoolean(STATE_SHOULD_SHOW_DIALOG, shouldShowDialog);
|
||||
}
|
||||
|
||||
public ActivityComponent getActivityComponent() {
|
||||
@@ -116,6 +103,16 @@ public abstract class BaseActivity extends AppCompatActivity
|
||||
for (ActivityLifecycleController alc : lifecycleControllers) {
|
||||
alc.onActivityStart();
|
||||
}
|
||||
protectToolbar();
|
||||
ScreenFilterDialogFragment f = findDialogFragment();
|
||||
if (f != null) f.setDismissListener(this::protectToolbar);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ScreenFilterDialogFragment findDialogFragment() {
|
||||
Fragment f = getSupportFragmentManager().findFragmentByTag(
|
||||
ScreenFilterDialogFragment.TAG);
|
||||
return (ScreenFilterDialogFragment) f;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,23 +123,6 @@ public abstract class BaseActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
protectToolbar();
|
||||
if (shouldShowDialog) showScreenFilterWarning();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if (dialogFrag != null) {
|
||||
dialogFrag.dismiss();
|
||||
dialogFrag = null;
|
||||
shouldShowDialog = true; // Show dialog again on resume
|
||||
}
|
||||
}
|
||||
|
||||
protected void showInitialFragment(BaseFragment f) {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.fragmentContainer, f, f.getUniqueTag())
|
||||
@@ -161,29 +141,22 @@ public abstract class BaseActivity extends AppCompatActivity
|
||||
|
||||
private boolean showScreenFilterWarning() {
|
||||
// If the dialog is already visible, filter the tap
|
||||
if (dialogFrag != null) return false;
|
||||
ScreenFilterDialogFragment f = findDialogFragment();
|
||||
if (f != null && f.isVisible()) return false;
|
||||
Collection<AppDetails> apps = screenFilterMonitor.getApps();
|
||||
// If all overlay apps have been allowed, allow the tap
|
||||
if (apps.isEmpty()) {
|
||||
shouldShowDialog = false; // May have been true when state was saved
|
||||
return true;
|
||||
}
|
||||
if (apps.isEmpty()) return true;
|
||||
// Show dialog unless onSaveInstanceState() has been called, see #1112
|
||||
FragmentManager fm = getSupportFragmentManager();
|
||||
if (!fm.isStateSaved()) {
|
||||
// Create dialog
|
||||
dialogFrag = ScreenFilterDialogFragment.newInstance(apps);
|
||||
shouldShowDialog = true;
|
||||
f = ScreenFilterDialogFragment.newInstance(apps);
|
||||
// When dialog is dismissed, update protection of toolbar
|
||||
dialogFrag.setDismissListener(() -> {
|
||||
dialogFrag = null;
|
||||
shouldShowDialog = false;
|
||||
protectToolbar();
|
||||
});
|
||||
f.setDismissListener(this::protectToolbar);
|
||||
// Hide soft keyboard when (re)showing dialog
|
||||
View focus = getCurrentFocus();
|
||||
if (focus != null) hideSoftKeyboard(focus);
|
||||
dialogFrag.show(fm, dialogFrag.getTag());
|
||||
f.show(fm, ScreenFilterDialogFragment.TAG);
|
||||
}
|
||||
// Filter the tap
|
||||
return false;
|
||||
@@ -243,7 +216,7 @@ public abstract class BaseActivity extends AppCompatActivity
|
||||
findToolbar();
|
||||
if (toolbar != null) {
|
||||
boolean filter = !screenFilterMonitor.getApps().isEmpty();
|
||||
toolbar.setFilterTouchesWhenObscured(filter);
|
||||
UiUtils.setFilterTouchesWhenObscured(toolbar, filter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,6 +230,8 @@ public abstract class BaseActivity extends AppCompatActivity
|
||||
|
||||
@Nullable
|
||||
private Toolbar findToolbar(ViewGroup vg) {
|
||||
// Views inside tap-safe layouts are already protected
|
||||
if (vg instanceof TapSafeFrameLayout) return null;
|
||||
for (int i = 0, len = vg.getChildCount(); i < len; i++) {
|
||||
View child = vg.getChildAt(i);
|
||||
if (child instanceof Toolbar) return (Toolbar) child;
|
||||
|
||||
@@ -30,6 +30,8 @@ import javax.inject.Inject;
|
||||
@ParametersNotNullByDefault
|
||||
public class ScreenFilterDialogFragment extends DialogFragment {
|
||||
|
||||
public static final String TAG = ScreenFilterDialogFragment.class.getName();
|
||||
|
||||
@Inject
|
||||
ScreenFilterMonitor screenFilterMonitor;
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import android.content.Context;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.PowerManager;
|
||||
import android.support.design.widget.TextInputLayout;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
@@ -162,7 +161,7 @@ public class UiUtils {
|
||||
}
|
||||
|
||||
public static boolean needsDozeWhitelisting(Context ctx) {
|
||||
if (Build.VERSION.SDK_INT < 23) return false;
|
||||
if (SDK_INT < 23) return false;
|
||||
PowerManager pm = (PowerManager) ctx.getSystemService(POWER_SERVICE);
|
||||
String packageName = ctx.getPackageName();
|
||||
if (pm == null) throw new AssertionError();
|
||||
@@ -182,4 +181,11 @@ public class UiUtils {
|
||||
return SDK_INT == 24 && MANUFACTURER.equalsIgnoreCase("Samsung");
|
||||
}
|
||||
|
||||
public static void setFilterTouchesWhenObscured(View v, boolean filter) {
|
||||
v.setFilterTouchesWhenObscured(filter);
|
||||
// Workaround for Android bug #13530806, see
|
||||
// https://android.googlesource.com/platform/frameworks/base/+/aba566589e0011c4b973c0d4f77be4e9ee176089%5E%21/core/java/android/view/View.java
|
||||
if (v.getFilterTouchesWhenObscured() != filter)
|
||||
v.setFilterTouchesWhenObscured(!filter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.view.MotionEvent;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.android.util.UiUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@@ -20,18 +21,18 @@ public class TapSafeFrameLayout extends FrameLayout {
|
||||
|
||||
public TapSafeFrameLayout(Context context) {
|
||||
super(context);
|
||||
setFilterTouchesWhenObscured(false);
|
||||
UiUtils.setFilterTouchesWhenObscured(this, false);
|
||||
}
|
||||
|
||||
public TapSafeFrameLayout(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setFilterTouchesWhenObscured(false);
|
||||
UiUtils.setFilterTouchesWhenObscured(this, false);
|
||||
}
|
||||
|
||||
public TapSafeFrameLayout(Context context, @Nullable AttributeSet attrs,
|
||||
@AttrRes int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setFilterTouchesWhenObscured(false);
|
||||
UiUtils.setFilterTouchesWhenObscured(this, false);
|
||||
}
|
||||
|
||||
public void setOnTapFilteredListener(OnTapFilteredListener listener) {
|
||||
|
||||
Reference in New Issue
Block a user