am 34e13d90: Update transient navigation confirmation logic.

* commit '34e13d90eda9bfda7a70998d190a95c88aa3d3d1':
  Update transient navigation confirmation logic.
This commit is contained in:
John Spurlock
2013-08-13 10:24:24 -07:00
committed by Android Git Automerger
9 changed files with 149 additions and 107 deletions

View File

@@ -16,5 +16,5 @@
*/
-->
<resources>
<item type="string" name="hiding_navigation_confirmation_message">@string/hiding_navigation_confirmation_message_long</item>
</resources>
<item type="string" name="transient_navigation_confirmation">@string/transient_navigation_confirmation_long</item>
</resources>

View File

@@ -16,5 +16,5 @@
*/
-->
<resources>
<item type="string" name="hiding_navigation_confirmation_message">@string/hiding_navigation_confirmation_message_long</item>
</resources>
<item type="string" name="transient_navigation_confirmation">@string/transient_navigation_confirmation_long</item>
</resources>

View File

@@ -4313,4 +4313,9 @@
<item quantity="other">Incorrect PIN. Try again in <xliff:g id="count">%d</xliff:g> seconds.</item>
</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>

View File

@@ -870,6 +870,8 @@
<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_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_hours" />

View File

@@ -503,10 +503,4 @@
<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] -->
<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>

View File

@@ -57,7 +57,6 @@ import android.view.Gravity;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewPropertyAnimator;
@@ -72,7 +71,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.EventLogTags;
import com.android.systemui.R;
@@ -129,8 +128,6 @@ public class PhoneStatusBar extends BaseStatusBar {
private static final int STATUS_OR_NAV_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 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 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
notifyUiVisibilityChanged(mSystemUiVisibility);
}
@@ -1987,45 +1943,6 @@ public class PhoneStatusBar extends BaseStatusBar {
: 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
public void resumeAutohide() {
if (mAutohideSuspended) {

View File

@@ -25,8 +25,6 @@ public class Prefs {
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 HIDING_NAVIGATION_CONFIRMED = "hiding_navigation_confirmed";
public static SharedPreferences read(Context context) {
return context.getSharedPreferences(Prefs.SHARED_PREFS_NAME, Context.MODE_PRIVATE);
}

View File

@@ -558,6 +558,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private static final int TRANSIENT_BAR_HIDING = 2;
private int mStatusTransientBar;
private int mNavigationTransientBar;
private TransientNavigationConfirmation mTransientNavigationConfirmation;
private SystemGesturesPointerEventListener mSystemGestures;
@@ -942,6 +943,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
});
mTransientNavigationConfirmation = new TransientNavigationConfirmation(mContext, mHandler);
mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);
mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
@@ -3173,11 +3175,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
= mOverscanScreenTop + mOverscanScreenHeight;
} else if (mCanHideNavigationBar
&& (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
&& attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
&& attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
&& (attrs.type == TYPE_TOAST
|| (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
// 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.
// XXX This assumes that an app asking for this will also
// 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: {
result &= ~ACTION_PASS_TO_USER;
if (down) {
if (isScreenOn && isNavigationBarTransient(mLastSystemUiFlags)) {
mTransientNavigationConfirmation.unconfirmLastPackage();
}
if (isScreenOn && !mPowerKeyTriggered
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
mPowerKeyTriggered = true;
@@ -5019,7 +5025,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (mForcingShowNavBar && mFocusedWindow.getSurfaceLayer() < mForcingShowNavBarLayer) {
tmpVisibility &= ~View.SYSTEM_UI_CLEARABLE_FLAGS;
}
final int visibility = updateTransientBarsLw(tmpVisibility);
final int visibility = updateTransientBarsLw(mLastSystemUiFlags, tmpVisibility);
final int diff = visibility ^ mLastSystemUiFlags;
final boolean needsMenu = mFocusedWindow.getNeedsMenuLw(mTopFullscreenOpaqueWindowState);
if (diff == 0 && mLastFocusNeedsMenu == needsMenu
@@ -5047,7 +5053,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return diff;
}
private int updateTransientBarsLw(int vis) {
private int updateTransientBarsLw(int oldVis, int vis) {
if (ImmersiveModeTesting.enabled) {
vis = ImmersiveModeTesting.applyForced(mFocusedWindow, vis);
}
@@ -5059,9 +5065,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
| View.SYSTEM_UI_FLAG_ALLOW_TRANSIENT;
vis = (vis & ~flags) | (mLastSystemUiFlags & flags);
}
boolean transientAllowed = (vis & View.SYSTEM_UI_FLAG_ALLOW_TRANSIENT) != 0;
if (mStatusTransientBar == TRANSIENT_BAR_SHOWING) {
// status transient bar requested
boolean transientAllowed =
(vis & View.SYSTEM_UI_FLAG_ALLOW_TRANSIENT) != 0;
boolean hideStatusBarWM =
(mFocusedWindow.getAttrs().flags
& 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) {
// navigation transient bar requested
boolean hideNavigationBarSysui =
(vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
boolean transientNavigationBarAllowed =
mNavigationBar != null && hideNavigationBarSysui && transientAllowed;
if (!transientNavigationBarAllowed) {
if (!isTransientNav) {
mNavigationTransientBar = TRANSIENT_BAR_NONE;
} else {
// show navigation transient bar
@@ -5112,6 +5122,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
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) {
final int window =
win == mStatusBar ? StatusBarManager.WINDOW_STATUS_BAR

View File

@@ -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();
}
};
}
}