Update transient navigation confirmation wording & behavior
1. Decrease transient navigation confirmation annoyance.
- Only use the power-key as a signal if we detect a screen-off
screen-on within a short threshold value.
- Auto-confirm if user performs the indicated gesture.
- Remember confirmation across reboots.
2. Update wording to new final wording. Remove now obsolete
short + long versions. Decrease message font temporarily
until the new platform toast redesign is finalized.
3. Remove pre-ship ImmersiveModeTesting debug helper.
Bug:10602929
Change-Id: I0bff826391058c7b282eeb61817b93b79de84893
This commit is contained in:
@@ -4365,6 +4365,9 @@ public final class Settings {
|
||||
/** @hide */
|
||||
public static final String BAR_SERVICE_COMPONENT = "bar_service_component";
|
||||
|
||||
/** @hide */
|
||||
public static final String TRANSIENT_NAV_CONFIRMATIONS = "transient_nav_confirmations";
|
||||
|
||||
/**
|
||||
* This are the settings to be backed up.
|
||||
*
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
android:paddingRight="16dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp" />
|
||||
android:textSize="14sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@android:id/button1"
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
<item type="string" name="transient_navigation_confirmation">@string/transient_navigation_confirmation_long</item>
|
||||
</resources>
|
||||
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
<item type="string" name="transient_navigation_confirmation">@string/transient_navigation_confirmation_long</item>
|
||||
</resources>
|
||||
@@ -1241,4 +1241,8 @@
|
||||
To do this, add 21407 item to values-mcc214-mnc04/config.xml -->
|
||||
<string-array translatable="false" name="config_operatorConsideredNonRoaming">
|
||||
</string-array>
|
||||
|
||||
<!-- Threshold (in ms) under which a screen off / screen on will be considered a reset of the
|
||||
transient navigation confirmation prompt.-->
|
||||
<integer name="config_transient_navigation_confirmation_panic">5000</integer>
|
||||
</resources>
|
||||
|
||||
@@ -4344,9 +4344,7 @@
|
||||
<!-- PIN entry dialog tells the user to not enter a PIN for a while. [CHAR LIMIT=none] -->
|
||||
<string name="restr_pin_try_later">Try again later</string>
|
||||
|
||||
<!-- 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>
|
||||
<!-- Toast bar message when hiding the transient navigation bar [CHAR LIMIT=45] -->
|
||||
<string name="transient_navigation_confirmation">Swipe down from the top to exit full screen</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>
|
||||
|
||||
@@ -301,6 +301,7 @@
|
||||
<java-symbol type="integer" name="config_ntpThreshold" />
|
||||
<java-symbol type="integer" name="config_ntpTimeout" />
|
||||
<java-symbol type="integer" name="config_toastDefaultGravity" />
|
||||
<java-symbol type="integer" name="config_transient_navigation_confirmation_panic" />
|
||||
<java-symbol type="integer" name="config_wifi_framework_scan_interval" />
|
||||
<java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
|
||||
<java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" />
|
||||
@@ -885,7 +886,6 @@
|
||||
<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="string" name="ssl_ca_cert_noti_by_unknown" />
|
||||
<java-symbol type="string" name="ssl_ca_cert_noti_managed" />
|
||||
<java-symbol type="string" name="ssl_ca_cert_warning" />
|
||||
|
||||
@@ -34,7 +34,6 @@ import android.content.ServiceConnection;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
@@ -105,7 +104,6 @@ import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static android.view.WindowManager.LayoutParams.*;
|
||||
import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
|
||||
@@ -531,7 +529,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
Settings.Secure.DEFAULT_INPUT_METHOD), false, this,
|
||||
UserHandle.USER_ALL);
|
||||
resolver.registerContentObserver(Settings.System.getUriFor(
|
||||
ImmersiveModeTesting.ENABLED_SETTING), false, this,
|
||||
Settings.Secure.TRANSIENT_NAV_CONFIRMATIONS), false, this,
|
||||
UserHandle.USER_ALL);
|
||||
updateSettings();
|
||||
}
|
||||
@@ -947,9 +945,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
@Override
|
||||
public void onDebug() {
|
||||
if (ImmersiveModeTesting.enabled) {
|
||||
ImmersiveModeTesting.toggleForceImmersiveMode(mFocusedWindow, mContext);
|
||||
}
|
||||
// no-op
|
||||
}
|
||||
});
|
||||
mTransientNavigationConfirmation = new TransientNavigationConfirmation(mContext);
|
||||
@@ -1168,8 +1164,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
mHasSoftInput = hasSoftInput;
|
||||
updateRotation = true;
|
||||
}
|
||||
ImmersiveModeTesting.enabled = Settings.System.getIntForUser(resolver,
|
||||
ImmersiveModeTesting.ENABLED_SETTING, 0, UserHandle.USER_CURRENT) != 0;
|
||||
if (mTransientNavigationConfirmation != null) {
|
||||
mTransientNavigationConfirmation.loadSetting();
|
||||
}
|
||||
}
|
||||
if (updateRotation) {
|
||||
updateRotation(true);
|
||||
@@ -3892,9 +3889,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
case KeyEvent.KEYCODE_POWER: {
|
||||
result &= ~ACTION_PASS_TO_USER;
|
||||
if (down) {
|
||||
if (isScreenOn && isTransientNavigationAllowed(mLastSystemUiFlags)) {
|
||||
mTransientNavigationConfirmation.unconfirmLastPackage();
|
||||
}
|
||||
mTransientNavigationConfirmation.onPowerKeyDown(isScreenOn, event.getDownTime(),
|
||||
isTransientNavigationAllowed(mLastSystemUiFlags));
|
||||
if (isScreenOn && !mPowerKeyTriggered
|
||||
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
|
||||
mPowerKeyTriggered = true;
|
||||
@@ -4173,6 +4169,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
if (sb) mStatusBarController.showTransient();
|
||||
if (nb) mNavigationBarController.showTransient();
|
||||
mTransientNavigationConfirmation.confirmCurrentPrompt();
|
||||
updateSystemUiVisibilityLw();
|
||||
}
|
||||
}
|
||||
@@ -5039,10 +5036,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
|
||||
private int updateSystemBarsLw(int oldVis, int vis) {
|
||||
if (ImmersiveModeTesting.enabled) {
|
||||
vis = ImmersiveModeTesting.applyForced(mFocusedWindow, vis);
|
||||
}
|
||||
|
||||
// prevent status bar interaction from clearing certain flags
|
||||
boolean statusBarHasFocus = mFocusedWindow.getAttrs().type == TYPE_STATUS_BAR;
|
||||
if (statusBarHasFocus) {
|
||||
@@ -5086,8 +5079,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
boolean isTransientNav = isTransientNavigationAllowed(vis);
|
||||
if (mFocusedWindow != null && oldTransientNav != isTransientNav) {
|
||||
final String pkg = mFocusedWindow.getOwningPackage();
|
||||
mTransientNavigationConfirmation.transientNavigationChanged(mCurrentUserId, pkg,
|
||||
isTransientNav);
|
||||
mTransientNavigationConfirmation.transientNavigationChanged(pkg, isTransientNav);
|
||||
}
|
||||
vis = mNavigationBarController.updateVisibilityLw(isTransientNav, oldVis, vis);
|
||||
|
||||
@@ -5104,53 +5096,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
&& (vis & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0;
|
||||
}
|
||||
|
||||
// Temporary helper that allows testing immersive mode on existing apps
|
||||
// TODO remove
|
||||
private static final class ImmersiveModeTesting {
|
||||
static String ENABLED_SETTING = "immersive_mode_testing_enabled";
|
||||
static boolean enabled = false;
|
||||
private static final HashSet<String> sForced = new HashSet<String>();
|
||||
|
||||
private static String parseActivity(WindowState win) {
|
||||
if (win != null && win.getAppToken() != null) {
|
||||
String str = win.getAppToken().toString();
|
||||
int end = str.lastIndexOf(' ');
|
||||
if (end > 0) {
|
||||
int start = str.lastIndexOf(' ', end - 1);
|
||||
if (start > -1) {
|
||||
return str.substring(start + 1, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int applyForced(WindowState focused, int vis) {
|
||||
if (sForced.contains(parseActivity(focused))) {
|
||||
vis |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
||||
View.SYSTEM_UI_FLAG_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_IMMERSIVE;
|
||||
}
|
||||
return vis;
|
||||
}
|
||||
|
||||
public static void toggleForceImmersiveMode(WindowState focused, Context context) {
|
||||
String activity = parseActivity(focused);
|
||||
if (activity != null) {
|
||||
String action;
|
||||
if (sForced.contains(activity)) {
|
||||
sForced.remove(activity);
|
||||
action = "Force immersive mode disabled";
|
||||
} else {
|
||||
sForced.add(activity);
|
||||
action = "Force immersive mode enabled";
|
||||
}
|
||||
android.widget.Toast.makeText(context,
|
||||
action + " for " + activity, android.widget.Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use this instead of checking config_showNavigationBar so that it can be consistently
|
||||
// overridden by qemu.hw.mainkeys in the emulator.
|
||||
@Override
|
||||
|
||||
@@ -19,16 +19,20 @@ package com.android.internal.policy.impl;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Slog;
|
||||
import android.view.View;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationSet;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Helper to manage showing/hiding a confirmation prompt when the transient navigation bar
|
||||
* is hidden.
|
||||
@@ -39,16 +43,22 @@ public class TransientNavigationConfirmation {
|
||||
|
||||
private final Context mContext;
|
||||
private final H mHandler;
|
||||
private final ArraySet<String> mConfirmedUserPackages = new ArraySet<String>();
|
||||
private final ArraySet<String> mConfirmedPackages = new ArraySet<String>();
|
||||
private final long mShowDelayMs;
|
||||
private final long mPanicThresholdMs;
|
||||
|
||||
private Toast mToast;
|
||||
private String mLastUserPackage;
|
||||
private String mLastPackage;
|
||||
private String mPromptPackage;
|
||||
private long mPanicTime;
|
||||
private String mPanicPackage;
|
||||
|
||||
public TransientNavigationConfirmation(Context context) {
|
||||
mContext = context;
|
||||
mHandler = new H();
|
||||
mShowDelayMs = getNavBarExitDuration() * 3;
|
||||
mPanicThresholdMs = context.getResources()
|
||||
.getInteger(R.integer.config_transient_navigation_confirmation_panic);
|
||||
}
|
||||
|
||||
private long getNavBarExitDuration() {
|
||||
@@ -56,44 +66,97 @@ public class TransientNavigationConfirmation {
|
||||
return exit != null ? exit.getDuration() : 0;
|
||||
}
|
||||
|
||||
public void transientNavigationChanged(int userId, String pkg, boolean isNavTransient) {
|
||||
public void loadSetting() {
|
||||
if (DEBUG) Slog.d(TAG, "loadSetting()");
|
||||
mConfirmedPackages.clear();
|
||||
String packages = null;
|
||||
try {
|
||||
packages = Settings.Secure.getStringForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.TRANSIENT_NAV_CONFIRMATIONS,
|
||||
UserHandle.USER_CURRENT);
|
||||
if (packages != null) {
|
||||
mConfirmedPackages.addAll(Arrays.asList(packages.split(",")));
|
||||
if (DEBUG) Slog.d(TAG, "Loaded mConfirmedPackages=" + mConfirmedPackages);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Slog.w(TAG, "Error loading confirmations, packages=" + packages, t);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveSetting() {
|
||||
if (DEBUG) Slog.d(TAG, "saveSetting()");
|
||||
try {
|
||||
final String packages = TextUtils.join(",", mConfirmedPackages);
|
||||
Settings.Secure.putStringForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.TRANSIENT_NAV_CONFIRMATIONS,
|
||||
packages,
|
||||
UserHandle.USER_CURRENT);
|
||||
if (DEBUG) Slog.d(TAG, "Saved packages=" + packages);
|
||||
} catch (Throwable t) {
|
||||
Slog.w(TAG, "Error saving confirmations, mConfirmedPackages=" + mConfirmedPackages, t);
|
||||
}
|
||||
}
|
||||
|
||||
public void transientNavigationChanged(String pkg, boolean isNavTransient) {
|
||||
if (pkg == null) {
|
||||
return;
|
||||
}
|
||||
String userPkg = userId + ":" + pkg;
|
||||
mHandler.removeMessages(H.SHOW);
|
||||
if (isNavTransient) {
|
||||
mLastUserPackage = userPkg;
|
||||
if (!mConfirmedUserPackages.contains(userPkg)) {
|
||||
if (DEBUG) Slog.d(TAG, "Showing transient navigation confirmation for " + userPkg);
|
||||
mHandler.sendMessageDelayed(mHandler.obtainMessage(H.SHOW, userPkg), mShowDelayMs);
|
||||
mLastPackage = pkg;
|
||||
if (!mConfirmedPackages.contains(pkg)) {
|
||||
mHandler.sendMessageDelayed(mHandler.obtainMessage(H.SHOW, pkg), mShowDelayMs);
|
||||
}
|
||||
} else {
|
||||
mLastUserPackage = null;
|
||||
if (DEBUG) Slog.d(TAG, "Hiding transient navigation confirmation for " + userPkg);
|
||||
mLastPackage = null;
|
||||
mHandler.sendEmptyMessage(H.HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
public void unconfirmLastPackage() {
|
||||
if (mLastUserPackage != null) {
|
||||
if (DEBUG) Slog.d(TAG, "Unconfirming transient navigation for " + mLastUserPackage);
|
||||
mConfirmedUserPackages.remove(mLastUserPackage);
|
||||
public void onPowerKeyDown(boolean isScreenOn, long time, boolean transientNavigationAllowed) {
|
||||
if (mPanicPackage != null && !isScreenOn && (time - mPanicTime < mPanicThresholdMs)) {
|
||||
// turning the screen back on within the panic threshold
|
||||
unconfirmPackage(mPanicPackage);
|
||||
}
|
||||
if (isScreenOn && transientNavigationAllowed) {
|
||||
// turning the screen off, remember if we were hiding the transient nav
|
||||
mPanicTime = time;
|
||||
mPanicPackage = mLastPackage;
|
||||
} else {
|
||||
mPanicTime = 0;
|
||||
mPanicPackage = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void confirmCurrentPrompt() {
|
||||
mHandler.post(confirmAction(mPromptPackage));
|
||||
}
|
||||
|
||||
private void unconfirmPackage(String pkg) {
|
||||
if (pkg != null) {
|
||||
if (DEBUG) Slog.d(TAG, "Unconfirming transient navigation for " + pkg);
|
||||
mConfirmedPackages.remove(pkg);
|
||||
saveSetting();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleHide() {
|
||||
if (mToast != null) {
|
||||
if (DEBUG) Slog.d(TAG,
|
||||
"Hiding transient navigation confirmation for " + mPromptPackage);
|
||||
mToast.cancel();
|
||||
mToast = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleShow(String userPkg) {
|
||||
private void handleShow(String pkg) {
|
||||
mPromptPackage = pkg;
|
||||
if (DEBUG) Slog.d(TAG, "Showing transient navigation confirmation for " + pkg);
|
||||
|
||||
// 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));
|
||||
mToast.setAction(R.string.ok, confirmAction(pkg));
|
||||
|
||||
// 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);
|
||||
@@ -102,11 +165,15 @@ public class TransientNavigationConfirmation {
|
||||
mToast.show();
|
||||
}
|
||||
|
||||
private Runnable confirmAction(final String userPkg) {
|
||||
private Runnable confirmAction(final String pkg) {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mConfirmedUserPackages.add(userPkg);
|
||||
if (pkg != null && !mConfirmedPackages.contains(pkg)) {
|
||||
if (DEBUG) Slog.d(TAG, "Confirming transient navigation for " + pkg);
|
||||
mConfirmedPackages.add(pkg);
|
||||
saveSetting();
|
||||
}
|
||||
handleHide();
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user