Merge "Simplify immersive mode confirmation cling logic."
This commit is contained in:
committed by
Android (Google) Code Review
commit
eb9e74b47b
@@ -19,6 +19,7 @@ package com.android.internal.policy.impl;
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -27,12 +28,12 @@ import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@@ -46,8 +47,6 @@ import android.widget.FrameLayout;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Helper to manage showing/hiding a confirmation prompt when the navigation bar is hidden
|
||||
* entering immersive mode.
|
||||
@@ -56,19 +55,19 @@ public class ImmersiveModeConfirmation {
|
||||
private static final String TAG = "ImmersiveModeConfirmation";
|
||||
private static final boolean DEBUG = false;
|
||||
private static final boolean DEBUG_SHOW_EVERY_TIME = false; // super annoying, use with caution
|
||||
private static final String CONFIRMED = "confirmed";
|
||||
|
||||
private final Context mContext;
|
||||
private final H mHandler;
|
||||
private final ArraySet<String> mConfirmedPackages = new ArraySet<String>();
|
||||
private final long mShowDelayMs;
|
||||
private final long mPanicThresholdMs;
|
||||
private final SparseBooleanArray mUserPanicResets = new SparseBooleanArray();
|
||||
|
||||
private boolean mConfirmed;
|
||||
private ClingWindowView mClingWindow;
|
||||
private String mLastPackage;
|
||||
private String mPromptPackage;
|
||||
private long mPanicTime;
|
||||
private String mPanicPackage;
|
||||
private WindowManager mWindowManager;
|
||||
private int mCurrentUserId;
|
||||
|
||||
public ImmersiveModeConfirmation(Context context) {
|
||||
mContext = context;
|
||||
@@ -86,82 +85,91 @@ public class ImmersiveModeConfirmation {
|
||||
}
|
||||
|
||||
public void loadSetting() {
|
||||
if (DEBUG) Slog.d(TAG, "loadSetting()");
|
||||
mConfirmedPackages.clear();
|
||||
String packages = null;
|
||||
mConfirmed = false;
|
||||
mCurrentUserId = getCurrentUser();
|
||||
if (DEBUG) Slog.d(TAG, String.format("loadSetting() mCurrentUserId=%d resetForPanic=%s",
|
||||
mCurrentUserId, mUserPanicResets.get(mCurrentUserId, false)));
|
||||
String value = null;
|
||||
try {
|
||||
packages = Settings.Secure.getStringForUser(mContext.getContentResolver(),
|
||||
value = Settings.Secure.getStringForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
|
||||
UserHandle.USER_CURRENT);
|
||||
if (packages != null) {
|
||||
mConfirmedPackages.addAll(Arrays.asList(packages.split(",")));
|
||||
if (DEBUG) Slog.d(TAG, "Loaded mConfirmedPackages=" + mConfirmedPackages);
|
||||
}
|
||||
mConfirmed = CONFIRMED.equals(value);
|
||||
if (DEBUG) Slog.d(TAG, "Loaded mConfirmed=" + mConfirmed);
|
||||
} catch (Throwable t) {
|
||||
Slog.w(TAG, "Error loading confirmations, packages=" + packages, t);
|
||||
Slog.w(TAG, "Error loading confirmations, value=" + value, t);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveSetting() {
|
||||
if (DEBUG) Slog.d(TAG, "saveSetting()");
|
||||
try {
|
||||
final String packages = TextUtils.join(",", mConfirmedPackages);
|
||||
final String value = mConfirmed ? CONFIRMED : null;
|
||||
Settings.Secure.putStringForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
|
||||
packages,
|
||||
value,
|
||||
UserHandle.USER_CURRENT);
|
||||
if (DEBUG) Slog.d(TAG, "Saved packages=" + packages);
|
||||
if (DEBUG) Slog.d(TAG, "Saved value=" + value);
|
||||
} catch (Throwable t) {
|
||||
Slog.w(TAG, "Error saving confirmations, mConfirmedPackages=" + mConfirmedPackages, t);
|
||||
Slog.w(TAG, "Error saving confirmations, mConfirmed=" + mConfirmed, t);
|
||||
}
|
||||
}
|
||||
|
||||
public void immersiveModeChanged(String pkg, boolean isImmersiveMode) {
|
||||
if (pkg == null || PolicyControl.disableImmersiveConfirmation(pkg)) {
|
||||
return;
|
||||
}
|
||||
mHandler.removeMessages(H.SHOW);
|
||||
if (isImmersiveMode) {
|
||||
mLastPackage = pkg;
|
||||
if (DEBUG_SHOW_EVERY_TIME || !mConfirmedPackages.contains(pkg)) {
|
||||
mHandler.sendMessageDelayed(mHandler.obtainMessage(H.SHOW, pkg), mShowDelayMs);
|
||||
final boolean disabled = PolicyControl.disableImmersiveConfirmation(pkg);
|
||||
if (DEBUG) Slog.d(TAG, String.format("immersiveModeChanged() disabled=%s mConfirmed=%s",
|
||||
disabled, mConfirmed));
|
||||
if (!disabled && (DEBUG_SHOW_EVERY_TIME || !mConfirmed)) {
|
||||
mHandler.sendEmptyMessageDelayed(H.SHOW, mShowDelayMs);
|
||||
}
|
||||
} else {
|
||||
mLastPackage = null;
|
||||
mHandler.sendEmptyMessage(H.HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
public void onPowerKeyDown(boolean isScreenOn, long time, boolean inImmersiveMode) {
|
||||
if (mPanicPackage != null && !isScreenOn && (time - mPanicTime < mPanicThresholdMs)) {
|
||||
public boolean onPowerKeyDown(boolean isScreenOn, long time, boolean inImmersiveMode) {
|
||||
if (!isScreenOn && (time - mPanicTime < mPanicThresholdMs)) {
|
||||
// turning the screen back on within the panic threshold
|
||||
unconfirmPackage(mPanicPackage);
|
||||
mHandler.sendEmptyMessage(H.PANIC);
|
||||
return mClingWindow == null;
|
||||
}
|
||||
if (isScreenOn && inImmersiveMode) {
|
||||
// turning the screen off, remember if we were in immersive mode
|
||||
mPanicTime = time;
|
||||
mPanicPackage = mLastPackage;
|
||||
} else {
|
||||
mPanicTime = 0;
|
||||
mPanicPackage = null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void confirmCurrentPrompt() {
|
||||
mHandler.post(confirmAction(mPromptPackage));
|
||||
if (mClingWindow != null) {
|
||||
if (DEBUG) Slog.d(TAG, "confirmCurrentPrompt()");
|
||||
mHandler.post(mConfirm);
|
||||
}
|
||||
}
|
||||
|
||||
private void unconfirmPackage(String pkg) {
|
||||
if (pkg != null) {
|
||||
if (DEBUG) Slog.d(TAG, "Unconfirming immersive mode confirmation for " + pkg);
|
||||
mConfirmedPackages.remove(pkg);
|
||||
saveSetting();
|
||||
private void handlePanic() {
|
||||
if (DEBUG) Slog.d(TAG, "handlePanic()");
|
||||
if (mUserPanicResets.get(mCurrentUserId, false)) return; // already reset for panic
|
||||
mUserPanicResets.put(mCurrentUserId, true);
|
||||
mConfirmed = false;
|
||||
saveSetting();
|
||||
}
|
||||
|
||||
private int getCurrentUser() {
|
||||
try {
|
||||
return ActivityManagerNative.getDefault().getCurrentUser().id;
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException(e); // local call
|
||||
}
|
||||
}
|
||||
|
||||
private void handleHide() {
|
||||
if (mClingWindow != null) {
|
||||
if (DEBUG) Slog.d(TAG, "Hiding immersive mode confirmation for " + mPromptPackage);
|
||||
if (DEBUG) Slog.d(TAG, "Hiding immersive mode confirmation");
|
||||
mWindowManager.removeView(mClingWindow);
|
||||
mClingWindow = null;
|
||||
}
|
||||
@@ -297,11 +305,10 @@ public class ImmersiveModeConfirmation {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleShow(String pkg) {
|
||||
mPromptPackage = pkg;
|
||||
if (DEBUG) Slog.d(TAG, "Showing immersive mode confirmation for " + pkg);
|
||||
private void handleShow() {
|
||||
if (DEBUG) Slog.d(TAG, "Showing immersive mode confirmation");
|
||||
|
||||
mClingWindow = new ClingWindowView(mContext, confirmAction(pkg));
|
||||
mClingWindow = new ClingWindowView(mContext, mConfirm);
|
||||
|
||||
// we will be hiding the nav bar, so layout as if it's already hidden
|
||||
mClingWindow.setSystemUiVisibility(
|
||||
@@ -313,33 +320,35 @@ public class ImmersiveModeConfirmation {
|
||||
mWindowManager.addView(mClingWindow, lp);
|
||||
}
|
||||
|
||||
private Runnable confirmAction(final String pkg) {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (pkg != null && !mConfirmedPackages.contains(pkg)) {
|
||||
if (DEBUG) Slog.d(TAG, "Confirming immersive mode for " + pkg);
|
||||
mConfirmedPackages.add(pkg);
|
||||
saveSetting();
|
||||
}
|
||||
handleHide();
|
||||
private final Runnable mConfirm = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (DEBUG) Slog.d(TAG, "mConfirm.run()");
|
||||
if (!mConfirmed) {
|
||||
mConfirmed = true;
|
||||
saveSetting();
|
||||
}
|
||||
};
|
||||
}
|
||||
handleHide();
|
||||
}
|
||||
};
|
||||
|
||||
private final class H extends Handler {
|
||||
private static final int SHOW = 0;
|
||||
private static final int HIDE = 1;
|
||||
private static final int SHOW = 1;
|
||||
private static final int HIDE = 2;
|
||||
private static final int PANIC = 3;
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch(msg.what) {
|
||||
case SHOW:
|
||||
handleShow((String)msg.obj);
|
||||
handleShow();
|
||||
break;
|
||||
case HIDE:
|
||||
handleHide();
|
||||
break;
|
||||
case PANIC:
|
||||
handlePanic();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,7 +523,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
resolver.registerContentObserver(Settings.Secure.getUriFor(
|
||||
Settings.Secure.DEFAULT_INPUT_METHOD), false, this,
|
||||
UserHandle.USER_ALL);
|
||||
resolver.registerContentObserver(Settings.System.getUriFor(
|
||||
resolver.registerContentObserver(Settings.Secure.getUriFor(
|
||||
Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS), false, this,
|
||||
UserHandle.USER_ALL);
|
||||
resolver.registerContentObserver(Settings.Global.getUriFor(
|
||||
@@ -3950,8 +3950,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
case KeyEvent.KEYCODE_POWER: {
|
||||
result &= ~ACTION_PASS_TO_USER;
|
||||
if (down) {
|
||||
mImmersiveModeConfirmation.onPowerKeyDown(isScreenOn, event.getDownTime(),
|
||||
isImmersiveMode(mLastSystemUiFlags));
|
||||
boolean panic = mImmersiveModeConfirmation.onPowerKeyDown(isScreenOn,
|
||||
event.getDownTime(), isImmersiveMode(mLastSystemUiFlags));
|
||||
if (panic) {
|
||||
mHandler.post(mRequestTransientNav);
|
||||
}
|
||||
if (isScreenOn && !mPowerKeyTriggered
|
||||
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
|
||||
mPowerKeyTriggered = true;
|
||||
@@ -4218,6 +4221,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable mRequestTransientNav = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
requestTransientBars(mNavigationBar);
|
||||
}
|
||||
};
|
||||
|
||||
private void requestTransientBars(WindowState swipeTarget) {
|
||||
synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
|
||||
boolean sb = mStatusBarController.checkShowTransientBarLw();
|
||||
|
||||
Reference in New Issue
Block a user