diff options
author | John Spurlock <jspurlock@google.com> | 2014-02-06 17:02:44 -0500 |
---|---|---|
committer | John Spurlock <jspurlock@google.com> | 2014-02-12 10:33:21 -0500 |
commit | d9b70bdc1a1c6f366a8ea0dad909b6573214f4af (patch) | |
tree | 7c2f8b81f5a3362286ca1c31e6447c8ddcb33834 | |
parent | 3ff18faac21553f027cdb1ff4a98447f333750bd (diff) | |
download | frameworks_base-d9b70bdc1a1c6f366a8ea0dad909b6573214f4af.zip frameworks_base-d9b70bdc1a1c6f366a8ea0dad909b6573214f4af.tar.gz frameworks_base-d9b70bdc1a1c6f366a8ea0dad909b6573214f4af.tar.bz2 |
Simplify immersive mode confirmation cling logic.
Instead of keeping track of confirmations per-package, track
a global confirmation per-user. If the panic signal is received,
reshow the cling at most once per-user per-reboot.
Ensure the nav bar becomes visible after the panic signal.
Usually this happens as a side effect of showing the keyguard.
However, in the case where there is no keyguard (Security = None)
show the transient nav bar temporarily as a hint.
Also listen to the correct observer uri to pick up confirmation
setting changes.
Bug:12242125
Change-Id: Ic95e2a8630ec3802b8ef462fcaa92366b9343a3f
-rw-r--r-- | policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java | 127 | ||||
-rw-r--r-- | policy/src/com/android/internal/policy/impl/PhoneWindowManager.java | 16 |
2 files changed, 81 insertions, 62 deletions
diff --git a/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java b/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java index 507d385..3cc74fc 100644 --- a/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java +++ b/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java @@ -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 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 void unconfirmPackage(String pkg) { - if (pkg != null) { - if (DEBUG) Slog.d(TAG, "Unconfirming immersive mode confirmation for " + pkg); - mConfirmedPackages.remove(pkg); - 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; } } } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index b6a4052..ece4fe7 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -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(); |