Merge "Disable volume-key-accessibility shortcut upon exiting setup wizard" into tm-dev am: 6fcd7dd723
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17463205 Change-Id: Ibf77a5ffbb4e1b8f71e8888f5f1fbece139ea9f6 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.internal.accessibility;
|
package com.android.internal.accessibility;
|
||||||
|
|
||||||
|
import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
|
||||||
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
|
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
|
||||||
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
|
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
|
||||||
|
|
||||||
@@ -107,6 +108,8 @@ public class AccessibilityShortcutController {
|
|||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final Handler mHandler;
|
private final Handler mHandler;
|
||||||
|
private final UserSetupCompleteObserver mUserSetupCompleteObserver;
|
||||||
|
|
||||||
private AlertDialog mAlertDialog;
|
private AlertDialog mAlertDialog;
|
||||||
private boolean mIsShortcutEnabled;
|
private boolean mIsShortcutEnabled;
|
||||||
private boolean mEnabledOnLockScreen;
|
private boolean mEnabledOnLockScreen;
|
||||||
@@ -114,11 +117,11 @@ public class AccessibilityShortcutController {
|
|||||||
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef({
|
@IntDef({
|
||||||
DialogStaus.NOT_SHOWN,
|
DialogStatus.NOT_SHOWN,
|
||||||
DialogStaus.SHOWN,
|
DialogStatus.SHOWN,
|
||||||
})
|
})
|
||||||
/** Denotes the user shortcut type. */
|
/** Denotes the user shortcut type. */
|
||||||
private @interface DialogStaus {
|
private @interface DialogStatus {
|
||||||
int NOT_SHOWN = 0;
|
int NOT_SHOWN = 0;
|
||||||
int SHOWN = 1;
|
int SHOWN = 1;
|
||||||
}
|
}
|
||||||
@@ -163,6 +166,7 @@ public class AccessibilityShortcutController {
|
|||||||
mContext = context;
|
mContext = context;
|
||||||
mHandler = handler;
|
mHandler = handler;
|
||||||
mUserId = initialUserId;
|
mUserId = initialUserId;
|
||||||
|
mUserSetupCompleteObserver = new UserSetupCompleteObserver(handler, initialUserId);
|
||||||
|
|
||||||
// Keep track of state of shortcut settings
|
// Keep track of state of shortcut settings
|
||||||
final ContentObserver co = new ContentObserver(handler) {
|
final ContentObserver co = new ContentObserver(handler) {
|
||||||
@@ -188,6 +192,7 @@ public class AccessibilityShortcutController {
|
|||||||
public void setCurrentUser(int currentUserId) {
|
public void setCurrentUser(int currentUserId) {
|
||||||
mUserId = currentUserId;
|
mUserId = currentUserId;
|
||||||
onSettingsChanged();
|
onSettingsChanged();
|
||||||
|
mUserSetupCompleteObserver.onUserSwitched(currentUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -206,7 +211,7 @@ public class AccessibilityShortcutController {
|
|||||||
final ContentResolver cr = mContext.getContentResolver();
|
final ContentResolver cr = mContext.getContentResolver();
|
||||||
// Enable the shortcut from the lockscreen by default if the dialog has been shown
|
// Enable the shortcut from the lockscreen by default if the dialog has been shown
|
||||||
final int dialogAlreadyShown = Settings.Secure.getIntForUser(
|
final int dialogAlreadyShown = Settings.Secure.getIntForUser(
|
||||||
cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStaus.NOT_SHOWN,
|
cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStatus.NOT_SHOWN,
|
||||||
mUserId);
|
mUserId);
|
||||||
mEnabledOnLockScreen = Settings.Secure.getIntForUser(
|
mEnabledOnLockScreen = Settings.Secure.getIntForUser(
|
||||||
cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN,
|
cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN,
|
||||||
@@ -222,7 +227,7 @@ public class AccessibilityShortcutController {
|
|||||||
final ContentResolver cr = mContext.getContentResolver();
|
final ContentResolver cr = mContext.getContentResolver();
|
||||||
final int userId = ActivityManager.getCurrentUser();
|
final int userId = ActivityManager.getCurrentUser();
|
||||||
final int dialogAlreadyShown = Settings.Secure.getIntForUser(
|
final int dialogAlreadyShown = Settings.Secure.getIntForUser(
|
||||||
cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStaus.NOT_SHOWN,
|
cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStatus.NOT_SHOWN,
|
||||||
userId);
|
userId);
|
||||||
// Play a notification vibration
|
// Play a notification vibration
|
||||||
Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
|
Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
|
||||||
@@ -234,7 +239,7 @@ public class AccessibilityShortcutController {
|
|||||||
vibrator.vibrate(vibePattern, -1, VIBRATION_ATTRIBUTES);
|
vibrator.vibrate(vibePattern, -1, VIBRATION_ATTRIBUTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dialogAlreadyShown == 0) {
|
if (dialogAlreadyShown == DialogStatus.NOT_SHOWN) {
|
||||||
// The first time, we show a warning rather than toggle the service to give the user a
|
// The first time, we show a warning rather than toggle the service to give the user a
|
||||||
// chance to turn off this feature before stuff gets enabled.
|
// chance to turn off this feature before stuff gets enabled.
|
||||||
mAlertDialog = createShortcutWarningDialog(userId);
|
mAlertDialog = createShortcutWarningDialog(userId);
|
||||||
@@ -250,7 +255,7 @@ public class AccessibilityShortcutController {
|
|||||||
w.setAttributes(attr);
|
w.setAttributes(attr);
|
||||||
mAlertDialog.show();
|
mAlertDialog.show();
|
||||||
Settings.Secure.putIntForUser(
|
Settings.Secure.putIntForUser(
|
||||||
cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStaus.SHOWN,
|
cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStatus.SHOWN,
|
||||||
userId);
|
userId);
|
||||||
} else {
|
} else {
|
||||||
playNotificationTone();
|
playNotificationTone();
|
||||||
@@ -320,13 +325,13 @@ public class AccessibilityShortcutController {
|
|||||||
// If canceled, treat as if the dialog has never been shown
|
// If canceled, treat as if the dialog has never been shown
|
||||||
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
||||||
Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
|
Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
|
||||||
DialogStaus.NOT_SHOWN, userId);
|
DialogStatus.NOT_SHOWN, userId);
|
||||||
})
|
})
|
||||||
.setOnCancelListener((DialogInterface d) -> {
|
.setOnCancelListener((DialogInterface d) -> {
|
||||||
// If canceled, treat as if the dialog has never been shown
|
// If canceled, treat as if the dialog has never been shown
|
||||||
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
||||||
Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
|
Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
|
||||||
DialogStaus.NOT_SHOWN, userId);
|
DialogStatus.NOT_SHOWN, userId);
|
||||||
})
|
})
|
||||||
.create();
|
.create();
|
||||||
return alertDialog;
|
return alertDialog;
|
||||||
@@ -398,7 +403,7 @@ public class AccessibilityShortcutController {
|
|||||||
AccessibilityManager accessibilityManager =
|
AccessibilityManager accessibilityManager =
|
||||||
mFrameworkObjectProvider.getAccessibilityManagerInstance(mContext);
|
mFrameworkObjectProvider.getAccessibilityManagerInstance(mContext);
|
||||||
return accessibilityManager.getEnabledAccessibilityServiceList(
|
return accessibilityManager.getEnabledAccessibilityServiceList(
|
||||||
AccessibilityServiceInfo.FEEDBACK_ALL_MASK).contains(serviceInfo);
|
FEEDBACK_ALL_MASK).contains(serviceInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasFeatureLeanback() {
|
private boolean hasFeatureLeanback() {
|
||||||
@@ -559,6 +564,97 @@ public class AccessibilityShortcutController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class UserSetupCompleteObserver extends ContentObserver {
|
||||||
|
|
||||||
|
private boolean mIsRegistered = false;
|
||||||
|
private int mUserId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a content observer.
|
||||||
|
*
|
||||||
|
* @param handler The handler to run {@link #onChange} on, or null if none.
|
||||||
|
* @param userId The current user id.
|
||||||
|
*/
|
||||||
|
UserSetupCompleteObserver(Handler handler, int userId) {
|
||||||
|
super(handler);
|
||||||
|
mUserId = userId;
|
||||||
|
if (!isUserSetupComplete()) {
|
||||||
|
registerObserver();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isUserSetupComplete() {
|
||||||
|
return Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
||||||
|
Settings.Secure.USER_SETUP_COMPLETE, 0, mUserId) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerObserver() {
|
||||||
|
if (mIsRegistered) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mContext.getContentResolver().registerContentObserver(
|
||||||
|
Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE),
|
||||||
|
false, this, mUserId);
|
||||||
|
mIsRegistered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChange(boolean selfChange) {
|
||||||
|
if (isUserSetupComplete()) {
|
||||||
|
unregisterObserver();
|
||||||
|
setEmptyShortcutTargetIfNeeded();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unregisterObserver() {
|
||||||
|
if (!mIsRegistered) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mContext.getContentResolver().unregisterContentObserver(this);
|
||||||
|
mIsRegistered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets empty shortcut target if shortcut targets is not assigned and there is no any
|
||||||
|
* enabled service matching the default target after the setup wizard completed.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void setEmptyShortcutTargetIfNeeded() {
|
||||||
|
final ContentResolver contentResolver = mContext.getContentResolver();
|
||||||
|
|
||||||
|
final String shortcutTargets = Settings.Secure.getStringForUser(contentResolver,
|
||||||
|
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, mUserId);
|
||||||
|
if (shortcutTargets != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String defaultShortcutTarget = mContext.getString(
|
||||||
|
R.string.config_defaultAccessibilityService);
|
||||||
|
final List<AccessibilityServiceInfo> enabledServices =
|
||||||
|
mFrameworkObjectProvider.getAccessibilityManagerInstance(
|
||||||
|
mContext).getEnabledAccessibilityServiceList(FEEDBACK_ALL_MASK);
|
||||||
|
for (int i = enabledServices.size() - 1; i >= 0; i--) {
|
||||||
|
if (TextUtils.equals(defaultShortcutTarget, enabledServices.get(i).getId())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings.Secure.putStringForUser(contentResolver,
|
||||||
|
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "", mUserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUserSwitched(int userId) {
|
||||||
|
if (mUserId == userId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unregisterObserver();
|
||||||
|
mUserId = userId;
|
||||||
|
if (!isUserSetupComplete()) {
|
||||||
|
registerObserver();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immutable class to hold info about framework features that can be controlled by shortcut
|
* Immutable class to hold info about framework features that can be controlled by shortcut
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user