diff --git a/packages/SystemUI/res/values-land/refs.xml b/core/res/res/values-land/refs.xml similarity index 82% rename from packages/SystemUI/res/values-land/refs.xml rename to core/res/res/values-land/refs.xml index 62fb77dad59c0..cda38cf2f2a40 100644 --- a/packages/SystemUI/res/values-land/refs.xml +++ b/core/res/res/values-land/refs.xml @@ -16,5 +16,5 @@ */ --> - @string/hiding_navigation_confirmation_message_long - + @string/transient_navigation_confirmation_long + \ No newline at end of file diff --git a/packages/SystemUI/res/values-sw600dp-port/refs.xml b/core/res/res/values-sw600dp-port/refs.xml similarity index 82% rename from packages/SystemUI/res/values-sw600dp-port/refs.xml rename to core/res/res/values-sw600dp-port/refs.xml index 62fb77dad59c0..cda38cf2f2a40 100644 --- a/packages/SystemUI/res/values-sw600dp-port/refs.xml +++ b/core/res/res/values-sw600dp-port/refs.xml @@ -16,5 +16,5 @@ */ --> - @string/hiding_navigation_confirmation_message_long - + @string/transient_navigation_confirmation_long + \ No newline at end of file diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 138debf06f98c..e497c85c87965 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4313,4 +4313,9 @@ Incorrect PIN. Try again in %d seconds. + + Swipe edge of screen to reveal bar + + + Swipe from edge of screen to reveal system bar diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 2e05663207345..cd0c872daac91 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -870,6 +870,8 @@ + + diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 33a85c3a8ed6a..eec81778ed51f 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -503,10 +503,4 @@ Notifications appear here Access them anytime by swiping down.\nSwipe down again for system controls. - - - Swipe edge of screen to reveal bar - - - Swipe from edge of screen to reveal system bar diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index c914a340c63a8..0a09a5236fc69 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -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) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Prefs.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Prefs.java index 3d51f209798df..16a92ea8e3f87 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Prefs.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Prefs.java @@ -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); } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index ae7120f6c72a0..952dfdaf10a42 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -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 diff --git a/policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java b/policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java new file mode 100644 index 0000000000000..bd5bd80de45a5 --- /dev/null +++ b/policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java @@ -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 mConfirmedUserPackages = new ArraySet(); + + 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(); + } + }; + } +}