Update transient navigation confirmation logic.
Show the confirmation toast when hiding the transient navigation bar only the first time per app, per reboot. Hitting the power key while the transient nav is hidden is taken as a signal of possible user confusion, so reshow the prompt the next time. This requires the confirmation prompt to live in policy (not sysui). It arguably should have been here in the first place, since the transient bar state/policy was here, and sysui should not have not been able to fail to display the prompt correctly. Also take this opportunity to remove a hack wrt positioning the confirmation properly while the nav bar is transitioning. Toasts now support LAYOUT_HIDE_NAVIGATION if applied to the toast's view. Bug: 10246225 Change-Id: Ieb6355e4ca975c0758918a39e3c2ec13da81c7f4
This commit is contained in:
@@ -16,5 +16,5 @@
|
|||||||
*/
|
*/
|
||||||
-->
|
-->
|
||||||
<resources>
|
<resources>
|
||||||
<item type="string" name="hiding_navigation_confirmation_message">@string/hiding_navigation_confirmation_message_long</item>
|
<item type="string" name="transient_navigation_confirmation">@string/transient_navigation_confirmation_long</item>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -16,5 +16,5 @@
|
|||||||
*/
|
*/
|
||||||
-->
|
-->
|
||||||
<resources>
|
<resources>
|
||||||
<item type="string" name="hiding_navigation_confirmation_message">@string/hiding_navigation_confirmation_message_long</item>
|
<item type="string" name="transient_navigation_confirmation">@string/transient_navigation_confirmation_long</item>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -4313,4 +4313,9 @@
|
|||||||
<item quantity="other">Incorrect PIN. Try again in <xliff:g id="count">%d</xliff:g> seconds.</item>
|
<item quantity="other">Incorrect PIN. Try again in <xliff:g id="count">%d</xliff:g> seconds.</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
|
<!-- Toast bar message when hiding the transient navigation bar [CHAR LIMIT=35] -->
|
||||||
|
<string name="transient_navigation_confirmation">Swipe edge of screen to reveal bar</string>
|
||||||
|
|
||||||
|
<!-- Longer version of toast bar message when hiding the transient navigation bar (if room) -->
|
||||||
|
<string name="transient_navigation_confirmation_long">Swipe from edge of screen to reveal system bar</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -870,6 +870,8 @@
|
|||||||
<java-symbol type="string" name="restr_pin_enter_pin" />
|
<java-symbol type="string" name="restr_pin_enter_pin" />
|
||||||
<java-symbol type="string" name="write_fail_reason_cancelled" />
|
<java-symbol type="string" name="write_fail_reason_cancelled" />
|
||||||
<java-symbol type="string" name="write_fail_reason_cannot_write" />
|
<java-symbol type="string" name="write_fail_reason_cannot_write" />
|
||||||
|
<java-symbol type="string" name="transient_navigation_confirmation" />
|
||||||
|
<java-symbol type="string" name="transient_navigation_confirmation_long" />
|
||||||
|
|
||||||
<java-symbol type="plurals" name="abbrev_in_num_days" />
|
<java-symbol type="plurals" name="abbrev_in_num_days" />
|
||||||
<java-symbol type="plurals" name="abbrev_in_num_hours" />
|
<java-symbol type="plurals" name="abbrev_in_num_hours" />
|
||||||
|
|||||||
@@ -503,10 +503,4 @@
|
|||||||
<string name="status_bar_help_title">Notifications appear here</string>
|
<string name="status_bar_help_title">Notifications appear here</string>
|
||||||
<!-- Body of help text shown when the notification panel is pulled down for the very first time. [CHAR LIMIT=NONE] -->
|
<!-- Body of help text shown when the notification panel is pulled down for the very first time. [CHAR LIMIT=NONE] -->
|
||||||
<string name="status_bar_help_text">Access them anytime by swiping down.\nSwipe down again for system controls.</string>
|
<string name="status_bar_help_text">Access them anytime by swiping down.\nSwipe down again for system controls.</string>
|
||||||
|
|
||||||
<!-- Toast bar message when hiding the navigation bar -->
|
|
||||||
<string name="hiding_navigation_confirmation_message">Swipe edge of screen to reveal bar</string>
|
|
||||||
|
|
||||||
<!-- Longer version of toast bar message when hiding the navigation bar (if room) -->
|
|
||||||
<string name="hiding_navigation_confirmation_message_long">Swipe from edge of screen to reveal system bar</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ import android.view.Gravity;
|
|||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.VelocityTracker;
|
import android.view.VelocityTracker;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.MeasureSpec;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewGroup.LayoutParams;
|
import android.view.ViewGroup.LayoutParams;
|
||||||
import android.view.ViewPropertyAnimator;
|
import android.view.ViewPropertyAnimator;
|
||||||
@@ -72,7 +71,7 @@ import android.widget.ImageView;
|
|||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ScrollView;
|
import android.widget.ScrollView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
|
||||||
import com.android.internal.statusbar.StatusBarIcon;
|
import com.android.internal.statusbar.StatusBarIcon;
|
||||||
import com.android.systemui.EventLogTags;
|
import com.android.systemui.EventLogTags;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
@@ -129,8 +128,6 @@ public class PhoneStatusBar extends BaseStatusBar {
|
|||||||
|
|
||||||
private static final int STATUS_OR_NAV_TRANSIENT =
|
private static final int STATUS_OR_NAV_TRANSIENT =
|
||||||
View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
|
View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
|
||||||
private static final int TRANSIENT_NAV_HIDING =
|
|
||||||
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_ALLOW_TRANSIENT;
|
|
||||||
private static final long AUTOHIDE_TIMEOUT_MS = 3000;
|
private static final long AUTOHIDE_TIMEOUT_MS = 3000;
|
||||||
private static final float TRANSPARENT_ALPHA = 0.7f;
|
private static final float TRANSPARENT_ALPHA = 0.7f;
|
||||||
|
|
||||||
@@ -314,37 +311,6 @@ public class PhoneStatusBar extends BaseStatusBar {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private Toast mHidingNavigationConfirmation;
|
|
||||||
private boolean mHidingNavigationConfirmationDismissed;
|
|
||||||
|
|
||||||
private final View.OnTouchListener mDismissHidingNavigationConfirmationOnTouchOutside =
|
|
||||||
new View.OnTouchListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
|
||||||
if (event.getActionMasked() == MotionEvent.ACTION_OUTSIDE) {
|
|
||||||
dismissHidingNavigationConfirmation();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final Runnable mHidingNavigationConfirmationAction = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (mHidingNavigationConfirmation != null) {
|
|
||||||
final boolean isGloballyConfirmed = Prefs.read(mContext)
|
|
||||||
.getBoolean(Prefs.HIDING_NAVIGATION_CONFIRMED, false);
|
|
||||||
if (!isGloballyConfirmed) {
|
|
||||||
// user pressed button, consider this a confirmation
|
|
||||||
Prefs.edit(mContext)
|
|
||||||
.putBoolean(Prefs.HIDING_NAVIGATION_CONFIRMED, true)
|
|
||||||
.apply();
|
|
||||||
}
|
|
||||||
dismissHidingNavigationConfirmation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private boolean mAutohideSuspended;
|
private boolean mAutohideSuspended;
|
||||||
|
|
||||||
private final Runnable mAutohide = new Runnable() {
|
private final Runnable mAutohide = new Runnable() {
|
||||||
@@ -1955,16 +1921,6 @@ public class PhoneStatusBar extends BaseStatusBar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update hiding navigation confirmation
|
|
||||||
if (mNavigationBarView != null) {
|
|
||||||
boolean oldShowConfirm = (oldVal & TRANSIENT_NAV_HIDING) == TRANSIENT_NAV_HIDING;
|
|
||||||
boolean newShowConfirm = (newVal & TRANSIENT_NAV_HIDING) == TRANSIENT_NAV_HIDING;
|
|
||||||
if (!oldShowConfirm && newShowConfirm) {
|
|
||||||
mHidingNavigationConfirmationDismissed = false;
|
|
||||||
}
|
|
||||||
setHidingNavigationConfirmationVisible(newShowConfirm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// send updated sysui visibility to window manager
|
// send updated sysui visibility to window manager
|
||||||
notifyUiVisibilityChanged(mSystemUiVisibility);
|
notifyUiVisibilityChanged(mSystemUiVisibility);
|
||||||
}
|
}
|
||||||
@@ -1987,45 +1943,6 @@ public class PhoneStatusBar extends BaseStatusBar {
|
|||||||
: BAR_MODE_NORMAL;
|
: BAR_MODE_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dismissHidingNavigationConfirmation() {
|
|
||||||
if (mHidingNavigationConfirmation != null) {
|
|
||||||
mHidingNavigationConfirmationDismissed = true;
|
|
||||||
mHidingNavigationConfirmation.cancel();
|
|
||||||
mHidingNavigationConfirmation = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setHidingNavigationConfirmationVisible(boolean visible) {
|
|
||||||
if (DEBUG) Log.d(TAG, "setHidingNavigationConfirmationVisible " + visible);
|
|
||||||
if (visible &&
|
|
||||||
mHidingNavigationConfirmation == null && !mHidingNavigationConfirmationDismissed) {
|
|
||||||
// create the confirmation toast bar
|
|
||||||
int msg = R.string.hiding_navigation_confirmation_message;
|
|
||||||
mHidingNavigationConfirmation = Toast.makeBar(mContext, msg, Toast.LENGTH_INFINITE)
|
|
||||||
.setAction(com.android.internal.R.string.ok,
|
|
||||||
mHidingNavigationConfirmationAction);
|
|
||||||
View v = mHidingNavigationConfirmation.getView();
|
|
||||||
v.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
|
||||||
boolean isGloballyConfirmed = Prefs.read(mContext)
|
|
||||||
.getBoolean(Prefs.HIDING_NAVIGATION_CONFIRMED, false);
|
|
||||||
if (isGloballyConfirmed) {
|
|
||||||
// dismiss on outside touch if globally confirmed
|
|
||||||
v.setOnTouchListener(mDismissHidingNavigationConfirmationOnTouchOutside);
|
|
||||||
}
|
|
||||||
// position at the bottom like normal toasts, but use top gravity
|
|
||||||
// to avoid jumping around when showing/hiding the nav bar
|
|
||||||
v.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
|
|
||||||
int offsetY = mContext.getResources().getDimensionPixelSize(
|
|
||||||
com.android.internal.R.dimen.toast_y_offset);
|
|
||||||
mHidingNavigationConfirmation.setGravity(Gravity.TOP,
|
|
||||||
0, mCurrentDisplaySize.y - v.getMeasuredHeight() / 2 - offsetY);
|
|
||||||
// show the confirmation
|
|
||||||
mHidingNavigationConfirmation.show();
|
|
||||||
} else if (!visible) {
|
|
||||||
dismissHidingNavigationConfirmation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resumeAutohide() {
|
public void resumeAutohide() {
|
||||||
if (mAutohideSuspended) {
|
if (mAutohideSuspended) {
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ public class Prefs {
|
|||||||
public static final String SHOWN_COMPAT_MODE_HELP = "shown_compat_mode_help";
|
public static final String SHOWN_COMPAT_MODE_HELP = "shown_compat_mode_help";
|
||||||
public static final String SHOWN_QUICK_SETTINGS_HELP = "shown_quick_settings_help";
|
public static final String SHOWN_QUICK_SETTINGS_HELP = "shown_quick_settings_help";
|
||||||
|
|
||||||
public static final String HIDING_NAVIGATION_CONFIRMED = "hiding_navigation_confirmed";
|
|
||||||
|
|
||||||
public static SharedPreferences read(Context context) {
|
public static SharedPreferences read(Context context) {
|
||||||
return context.getSharedPreferences(Prefs.SHARED_PREFS_NAME, Context.MODE_PRIVATE);
|
return context.getSharedPreferences(Prefs.SHARED_PREFS_NAME, Context.MODE_PRIVATE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -558,6 +558,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
private static final int TRANSIENT_BAR_HIDING = 2;
|
private static final int TRANSIENT_BAR_HIDING = 2;
|
||||||
private int mStatusTransientBar;
|
private int mStatusTransientBar;
|
||||||
private int mNavigationTransientBar;
|
private int mNavigationTransientBar;
|
||||||
|
private TransientNavigationConfirmation mTransientNavigationConfirmation;
|
||||||
|
|
||||||
private SystemGesturesPointerEventListener mSystemGestures;
|
private SystemGesturesPointerEventListener mSystemGestures;
|
||||||
|
|
||||||
@@ -942,6 +943,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
mTransientNavigationConfirmation = new TransientNavigationConfirmation(mContext, mHandler);
|
||||||
mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);
|
mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);
|
||||||
|
|
||||||
mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
|
mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
|
||||||
@@ -3173,11 +3175,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
= mOverscanScreenTop + mOverscanScreenHeight;
|
= mOverscanScreenTop + mOverscanScreenHeight;
|
||||||
} else if (mCanHideNavigationBar
|
} else if (mCanHideNavigationBar
|
||||||
&& (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
|
&& (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
|
||||||
&& attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
|
&& (attrs.type == TYPE_TOAST
|
||||||
&& attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
|
|| (attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
|
||||||
|
&& attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW))) {
|
||||||
// Asking for layout as if the nav bar is hidden, lets the
|
// Asking for layout as if the nav bar is hidden, lets the
|
||||||
// application extend into the unrestricted screen area. We
|
// application extend into the unrestricted screen area. We
|
||||||
// only do this for application windows to ensure no window that
|
// only do this for application windows (or toasts) to ensure no window that
|
||||||
// can be above the nav bar can do this.
|
// can be above the nav bar can do this.
|
||||||
// XXX This assumes that an app asking for this will also
|
// XXX This assumes that an app asking for this will also
|
||||||
// ask for layout in only content. We can't currently figure out
|
// ask for layout in only content. We can't currently figure out
|
||||||
@@ -3879,6 +3882,9 @@ 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) {
|
||||||
|
if (isScreenOn && isNavigationBarTransient(mLastSystemUiFlags)) {
|
||||||
|
mTransientNavigationConfirmation.unconfirmLastPackage();
|
||||||
|
}
|
||||||
if (isScreenOn && !mPowerKeyTriggered
|
if (isScreenOn && !mPowerKeyTriggered
|
||||||
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
|
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
|
||||||
mPowerKeyTriggered = true;
|
mPowerKeyTriggered = true;
|
||||||
@@ -5019,7 +5025,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
if (mForcingShowNavBar && mFocusedWindow.getSurfaceLayer() < mForcingShowNavBarLayer) {
|
if (mForcingShowNavBar && mFocusedWindow.getSurfaceLayer() < mForcingShowNavBarLayer) {
|
||||||
tmpVisibility &= ~View.SYSTEM_UI_CLEARABLE_FLAGS;
|
tmpVisibility &= ~View.SYSTEM_UI_CLEARABLE_FLAGS;
|
||||||
}
|
}
|
||||||
final int visibility = updateTransientBarsLw(tmpVisibility);
|
final int visibility = updateTransientBarsLw(mLastSystemUiFlags, tmpVisibility);
|
||||||
final int diff = visibility ^ mLastSystemUiFlags;
|
final int diff = visibility ^ mLastSystemUiFlags;
|
||||||
final boolean needsMenu = mFocusedWindow.getNeedsMenuLw(mTopFullscreenOpaqueWindowState);
|
final boolean needsMenu = mFocusedWindow.getNeedsMenuLw(mTopFullscreenOpaqueWindowState);
|
||||||
if (diff == 0 && mLastFocusNeedsMenu == needsMenu
|
if (diff == 0 && mLastFocusNeedsMenu == needsMenu
|
||||||
@@ -5047,7 +5053,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int updateTransientBarsLw(int vis) {
|
private int updateTransientBarsLw(int oldVis, int vis) {
|
||||||
if (ImmersiveModeTesting.enabled) {
|
if (ImmersiveModeTesting.enabled) {
|
||||||
vis = ImmersiveModeTesting.applyForced(mFocusedWindow, vis);
|
vis = ImmersiveModeTesting.applyForced(mFocusedWindow, vis);
|
||||||
}
|
}
|
||||||
@@ -5059,9 +5065,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
| View.SYSTEM_UI_FLAG_ALLOW_TRANSIENT;
|
| View.SYSTEM_UI_FLAG_ALLOW_TRANSIENT;
|
||||||
vis = (vis & ~flags) | (mLastSystemUiFlags & flags);
|
vis = (vis & ~flags) | (mLastSystemUiFlags & flags);
|
||||||
}
|
}
|
||||||
boolean transientAllowed = (vis & View.SYSTEM_UI_FLAG_ALLOW_TRANSIENT) != 0;
|
|
||||||
if (mStatusTransientBar == TRANSIENT_BAR_SHOWING) {
|
if (mStatusTransientBar == TRANSIENT_BAR_SHOWING) {
|
||||||
// status transient bar requested
|
// status transient bar requested
|
||||||
|
boolean transientAllowed =
|
||||||
|
(vis & View.SYSTEM_UI_FLAG_ALLOW_TRANSIENT) != 0;
|
||||||
boolean hideStatusBarWM =
|
boolean hideStatusBarWM =
|
||||||
(mFocusedWindow.getAttrs().flags
|
(mFocusedWindow.getAttrs().flags
|
||||||
& WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
|
& WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
|
||||||
@@ -5092,13 +5099,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
boolean oldTransientNav = isNavigationBarTransient(oldVis);
|
||||||
|
boolean isTransientNav = isNavigationBarTransient(vis);
|
||||||
|
if (mFocusedWindow != null && oldTransientNav != isTransientNav) {
|
||||||
|
final int uid = getCurrentUserId();
|
||||||
|
final String pkg = mFocusedWindow.getOwningPackage();
|
||||||
|
mTransientNavigationConfirmation.transientNavigationChanged(uid, pkg, isTransientNav);
|
||||||
|
}
|
||||||
if (mNavigationTransientBar == TRANSIENT_BAR_SHOWING) {
|
if (mNavigationTransientBar == TRANSIENT_BAR_SHOWING) {
|
||||||
// navigation transient bar requested
|
// navigation transient bar requested
|
||||||
boolean hideNavigationBarSysui =
|
if (!isTransientNav) {
|
||||||
(vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
|
|
||||||
boolean transientNavigationBarAllowed =
|
|
||||||
mNavigationBar != null && hideNavigationBarSysui && transientAllowed;
|
|
||||||
if (!transientNavigationBarAllowed) {
|
|
||||||
mNavigationTransientBar = TRANSIENT_BAR_NONE;
|
mNavigationTransientBar = TRANSIENT_BAR_NONE;
|
||||||
} else {
|
} else {
|
||||||
// show navigation transient bar
|
// show navigation transient bar
|
||||||
@@ -5112,6 +5122,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
return vis;
|
return vis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isNavigationBarTransient(int vis) {
|
||||||
|
return mNavigationBar != null
|
||||||
|
&& (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0
|
||||||
|
&& (vis & View.SYSTEM_UI_FLAG_ALLOW_TRANSIENT) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean setBarShowingLw(WindowState win, final boolean show) {
|
private boolean setBarShowingLw(WindowState win, final boolean show) {
|
||||||
final int window =
|
final int window =
|
||||||
win == mStatusBar ? StatusBarManager.WINDOW_STATUS_BAR
|
win == mStatusBar ? StatusBarManager.WINDOW_STATUS_BAR
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.internal.policy.impl;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.util.ArraySet;
|
||||||
|
import android.util.Slog;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.android.internal.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to manage showing/hiding a confirmation prompt when the transient navigation bar
|
||||||
|
* is hidden.
|
||||||
|
*/
|
||||||
|
public class TransientNavigationConfirmation {
|
||||||
|
private final String TAG = "TransientNavigationConfirmation";
|
||||||
|
private final boolean DEBUG = false;
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
|
private final Handler mHandler;
|
||||||
|
private final ArraySet<String> mConfirmedUserPackages = new ArraySet<String>();
|
||||||
|
|
||||||
|
private final Runnable mHandleDismiss = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (mToast != null) {
|
||||||
|
mToast.cancel();
|
||||||
|
mToast = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private Toast mToast;
|
||||||
|
private String mLastUserPackage;
|
||||||
|
|
||||||
|
public TransientNavigationConfirmation(Context context, Handler handler) {
|
||||||
|
mContext = context;
|
||||||
|
mHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void transientNavigationChanged(int userId, String pkg, boolean isNavTransient) {
|
||||||
|
if (pkg == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String userPkg = userId + ":" + pkg;
|
||||||
|
if (isNavTransient) {
|
||||||
|
mLastUserPackage = userPkg;
|
||||||
|
if (!mConfirmedUserPackages.contains(userPkg)) {
|
||||||
|
if (DEBUG) Slog.d(TAG, "Showing transient navigation confirmation for " + userPkg);
|
||||||
|
mHandler.post(handleShowConfirmation(userPkg));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mLastUserPackage = null;
|
||||||
|
if (DEBUG) Slog.d(TAG, "Hiding transient navigation confirmation for " + userPkg);
|
||||||
|
mHandler.post(mHandleDismiss);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unconfirmLastPackage() {
|
||||||
|
if (mLastUserPackage != null) {
|
||||||
|
if (DEBUG) Slog.d(TAG, "Unconfirming transient navigation for " + mLastUserPackage);
|
||||||
|
mConfirmedUserPackages.remove(mLastUserPackage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Runnable handleShowConfirmation(final String userPkg) {
|
||||||
|
return new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// create the confirmation toast bar
|
||||||
|
final int msg = R.string.transient_navigation_confirmation;
|
||||||
|
mToast = Toast.makeBar(mContext, msg, Toast.LENGTH_INFINITE);
|
||||||
|
mToast.setAction(R.string.ok, confirmAction(userPkg));
|
||||||
|
|
||||||
|
// we will be hiding the nav bar, so layout as if it's already hidden
|
||||||
|
mToast.getView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||||
|
|
||||||
|
// show the confirmation
|
||||||
|
mToast.show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Runnable confirmAction(final String userPkg) {
|
||||||
|
return new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mConfirmedUserPackages.add(userPkg);
|
||||||
|
mHandleDismiss.run();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user