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