Merge changes from topics "a11y_qs_attr_integration", "a11y_qs_tooltip_1p"

* changes:
  Integrate new accessibility tileService attr into settings
  Support accessibility settings load title from quick settings panel
  Show quick setting tooltips after shortcut edit dialog dismiss
  Show quick setting tooltips after shortcut tutorial dialog dismiss
This commit is contained in:
Menghan Li
2022-02-09 07:07:08 +00:00
committed by Android (Google) Code Review
9 changed files with 513 additions and 30 deletions

View File

@@ -221,6 +221,13 @@ public class AccessibilityDetailsSettingsFragment extends InstrumentedFragment {
extras.putString(AccessibilitySettings.EXTRA_SETTINGS_COMPONENT_NAME,
new ComponentName(packageName, settingsClassName).flattenToString());
}
final String tileServiceClassName = info.getTileServiceClassName();
if (!TextUtils.isEmpty(tileServiceClassName)) {
extras.putString(AccessibilitySettings.EXTRA_TILE_SERVICE_COMPONENT_NAME,
new ComponentName(packageName, tileServiceClassName).flattenToString());
}
extras.putParcelable(AccessibilitySettings.EXTRA_COMPONENT_NAME, componentName);
extras.putInt(AccessibilitySettings.EXTRA_ANIMATED_IMAGE_RES, info.getAnimatedImageRes());

View File

@@ -46,6 +46,7 @@ import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RawRes;
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
@@ -125,9 +126,15 @@ public final class AccessibilityGestureNavigationTutorial {
}
static AlertDialog createAccessibilityTutorialDialog(Context context, int shortcutTypes) {
return createAccessibilityTutorialDialog(context, shortcutTypes, mOnClickListener);
}
static AlertDialog createAccessibilityTutorialDialog(Context context, int shortcutTypes,
@Nullable DialogInterface.OnClickListener negativeButtonListener) {
return new AlertDialog.Builder(context)
.setView(createShortcutNavigationContentView(context, shortcutTypes))
.setNegativeButton(R.string.accessibility_tutorial_dialog_button, mOnClickListener)
.setNegativeButton(R.string.accessibility_tutorial_dialog_button,
negativeButtonListener)
.create();
}

View File

@@ -97,6 +97,7 @@ public class AccessibilitySettings extends DashboardFragment {
static final String EXTRA_SETTINGS_TITLE = "settings_title";
static final String EXTRA_COMPONENT_NAME = "component_name";
static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name";
static final String EXTRA_TILE_SERVICE_COMPONENT_NAME = "tile_service_component_name";
static final String EXTRA_VIDEO_RAW_RESOURCE_ID = "video_resource";
static final String EXTRA_LAUNCHED_FROM_SUW = "from_suw";
static final String EXTRA_ANIMATED_IMAGE_RES = "animated_image_res";
@@ -573,11 +574,13 @@ public class AccessibilitySettings extends DashboardFragment {
serviceEnabled);
final String htmlDescription = info.loadHtmlDescription(mPm);
final String settingsClassName = info.getSettingsActivityName();
final String tileServiceClassName = info.getTileServiceClassName();
putBasicExtras(preference, prefKey, title, description, imageRes, htmlDescription,
componentName);
putServiceExtras(preference, resolveInfo, serviceEnabled);
putSettingsExtras(preference, packageName, settingsClassName);
putTileServiceExtras(preference, packageName, tileServiceClassName);
preferenceList.add(preference);
}
@@ -631,10 +634,13 @@ public class AccessibilitySettings extends DashboardFragment {
final int imageRes = info.getAnimatedImageRes();
final String htmlDescription = info.loadHtmlDescription(mPm);
final String settingsClassName = info.getSettingsActivityName();
final String tileServiceClassName = info.getTileServiceClassName();
putBasicExtras(preference, prefKey, title, description, imageRes, htmlDescription,
componentName);
putSettingsExtras(preference, componentName.getPackageName(), settingsClassName);
putTileServiceExtras(preference, componentName.getPackageName(),
tileServiceClassName);
preferenceList.add(preference);
}
@@ -730,7 +736,11 @@ public class AccessibilitySettings extends DashboardFragment {
/**
* Puts the service extras into {@link RestrictedPreference}'s getExtras().
*
* Called by {@link AccessibilityServiceInfo} for now.
* <p><b>Note:</b> Called by {@link AccessibilityServiceInfo}.</p>
*
* @param preference The preference we are configuring.
* @param resolveInfo The service resolve info.
* @param serviceEnabled Whether the accessibility service is enabled.
*/
private void putServiceExtras(RestrictedPreference preference, ResolveInfo resolveInfo,
Boolean serviceEnabled) {
@@ -743,7 +753,12 @@ public class AccessibilitySettings extends DashboardFragment {
/**
* Puts the settings extras into {@link RestrictedPreference}'s getExtras().
*
* Called when settings UI is needed.
* <p><b>Note:</b> Called when settings UI is needed.</p>
*
* @param preference The preference we are configuring.
* @param packageName Package of accessibility feature.
* @param settingsClassName The component name of an activity that allows the user to modify
* the settings for this accessibility feature.
*/
private void putSettingsExtras(RestrictedPreference preference, String packageName,
String settingsClassName) {
@@ -756,5 +771,27 @@ public class AccessibilitySettings extends DashboardFragment {
new ComponentName(packageName, settingsClassName).flattenToString());
}
}
/**
* Puts the information about a particular application
* {@link android.service.quicksettings.TileService} into {@link RestrictedPreference}'s
* getExtras().
*
* <p><b>Note:</b> Called when a tooltip of
* {@link android.service.quicksettings.TileService} is needed.</p>
*
* @param preference The preference we are configuring.
* @param packageName Package of accessibility feature.
* @param tileServiceClassName The component name of tileService is associated with this
* accessibility feature.
*/
private void putTileServiceExtras(RestrictedPreference preference, String packageName,
String tileServiceClassName) {
final Bundle extras = preference.getExtras();
if (!TextUtils.isEmpty(tileServiceClassName)) {
extras.putString(EXTRA_TILE_SERVICE_COMPONENT_NAME,
new ComponentName(packageName, tileServiceClassName).flattenToString());
}
}
}
}

View File

@@ -20,9 +20,11 @@ import static com.android.settings.accessibility.AccessibilityStatsLogUtils.logA
import android.accessibilityservice.AccessibilityShortcutInfo;
import android.app.ActivityOptions;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
@@ -51,6 +53,7 @@ public class LaunchAccessibilityActivityPreferenceFragment extends ToggleFeature
private static final String TAG = "LaunchA11yActivity";
private static final String EMPTY_STRING = "";
protected static final String KEY_LAUNCH_PREFERENCE = "launch_preference";
private ComponentName mTileComponentName;
@Override
public int getMetricsCategory() {
@@ -106,6 +109,13 @@ public class LaunchAccessibilityActivityPreferenceFragment extends ToggleFeature
AccessibilitySettings.EXTRA_SETTINGS_TITLE);
mSettingsIntent = TextUtils.isEmpty(settingsTitle) ? null : getSettingsIntent(arguments);
mSettingsTitle = (mSettingsIntent == null) ? null : settingsTitle;
// Tile service.
if (arguments.containsKey(AccessibilitySettings.EXTRA_TILE_SERVICE_COMPONENT_NAME)) {
final String tileServiceComponentName = arguments.getString(
AccessibilitySettings.EXTRA_TILE_SERVICE_COMPONENT_NAME);
mTileComponentName = ComponentName.unflattenFromString(tileServiceComponentName);
}
}
@Override
@@ -116,12 +126,30 @@ public class LaunchAccessibilityActivityPreferenceFragment extends ToggleFeature
@Override
ComponentName getTileComponentName() {
return null;
return mTileComponentName;
}
@Override
CharSequence getTileName() {
return null;
final ComponentName componentName = getTileComponentName();
if (componentName == null) {
return null;
}
return loadTileLabel(getPrefContext(), componentName);
}
@Override
public Dialog onCreateDialog(int dialogId) {
switch (dialogId) {
case AccessibilityDialogUtils.DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL:
final Dialog dialog = AccessibilityGestureNavigationTutorial
.createAccessibilityTutorialDialog(getPrefContext(),
getUserShortcutTypes(), this::callOnTutorialDialogButtonClicked);
dialog.setCanceledOnTouchOutside(false);
return dialog;
default:
return super.onCreateDialog(dialogId);
}
}
@Override
@@ -208,4 +236,22 @@ public class LaunchAccessibilityActivityPreferenceFragment extends ToggleFeature
return settingsIntent;
}
/**
* This method will be invoked when a button in the tutorial dialog is clicked.
*
* @param dialog The dialog that received the click
* @param which The button that was clicked
*/
private void callOnTutorialDialogButtonClicked(DialogInterface dialog, int which) {
dialog.dismiss();
showQuickSettingsTooltipIfNeeded();
}
@Override
protected void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) {
super.callOnAlertDialogCheckboxClicked(dialog, which);
showQuickSettingsTooltipIfNeeded(getShortcutTypeCheckBoxValue());
}
}

View File

@@ -65,6 +65,7 @@ public class ToggleAccessibilityServicePreferenceFragment extends
private static final String EMPTY_STRING = "";
private Dialog mWarningDialog;
private ComponentName mTileComponentName;
private BroadcastReceiver mPackageRemovedReceiver;
private boolean mDisabledStateLogged = false;
private long mStartTimeMillsForLogging = 0;
@@ -168,9 +169,9 @@ public class ToggleAccessibilityServicePreferenceFragment extends
@Override
public Dialog onCreateDialog(int dialogId) {
final AccessibilityServiceInfo info = getAccessibilityServiceInfo();
switch (dialogId) {
case DialogEnums.ENABLE_WARNING_FROM_TOGGLE: {
final AccessibilityServiceInfo info = getAccessibilityServiceInfo();
case DialogEnums.ENABLE_WARNING_FROM_TOGGLE:
if (info == null) {
return null;
}
@@ -178,10 +179,8 @@ public class ToggleAccessibilityServicePreferenceFragment extends
.createCapabilitiesDialog(getPrefContext(), info,
this::onDialogButtonFromEnableToggleClicked,
this::onDialogButtonFromUninstallClicked);
break;
}
case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT_TOGGLE: {
final AccessibilityServiceInfo info = getAccessibilityServiceInfo();
return mWarningDialog;
case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT_TOGGLE:
if (info == null) {
return null;
}
@@ -189,10 +188,8 @@ public class ToggleAccessibilityServicePreferenceFragment extends
.createCapabilitiesDialog(getPrefContext(), info,
this::onDialogButtonFromShortcutToggleClicked,
this::onDialogButtonFromUninstallClicked);
break;
}
case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT: {
final AccessibilityServiceInfo info = getAccessibilityServiceInfo();
return mWarningDialog;
case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT:
if (info == null) {
return null;
}
@@ -200,23 +197,24 @@ public class ToggleAccessibilityServicePreferenceFragment extends
.createCapabilitiesDialog(getPrefContext(), info,
this::onDialogButtonFromShortcutClicked,
this::onDialogButtonFromUninstallClicked);
break;
}
case DialogEnums.DISABLE_WARNING_FROM_TOGGLE: {
final AccessibilityServiceInfo info = getAccessibilityServiceInfo();
return mWarningDialog;
case DialogEnums.DISABLE_WARNING_FROM_TOGGLE:
if (info == null) {
return null;
}
mWarningDialog = AccessibilityServiceWarning
.createDisableDialog(getPrefContext(), info,
this::onDialogButtonFromDisableToggleClicked);
break;
}
default: {
mWarningDialog = super.onCreateDialog(dialogId);
}
return mWarningDialog;
case DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL:
final Dialog dialog = AccessibilityGestureNavigationTutorial
.createAccessibilityTutorialDialog(getPrefContext(),
getUserShortcutTypes(), this::callOnTutorialDialogButtonClicked);
dialog.setCanceledOnTouchOutside(false);
return dialog;
default:
return super.onCreateDialog(dialogId);
}
return mWarningDialog;
}
@Override
@@ -243,12 +241,16 @@ public class ToggleAccessibilityServicePreferenceFragment extends
@Override
ComponentName getTileComponentName() {
return null;
return mTileComponentName;
}
@Override
CharSequence getTileName() {
return null;
final ComponentName componentName = getTileComponentName();
if (componentName == null) {
return null;
}
return loadTileLabel(getPrefContext(), componentName);
}
@Override
@@ -386,6 +388,12 @@ public class ToggleAccessibilityServicePreferenceFragment extends
mPackageName = getAccessibilityServiceInfo().getResolveInfo().loadLabel(
getPackageManager());
if (arguments.containsKey(AccessibilitySettings.EXTRA_TILE_SERVICE_COMPONENT_NAME)) {
final String tileServiceComponentName = arguments.getString(
AccessibilitySettings.EXTRA_TILE_SERVICE_COMPONENT_NAME);
mTileComponentName = ComponentName.unflattenFromString(tileServiceComponentName);
}
mStartTimeMillsForLogging = arguments.getLong(AccessibilitySettings.EXTRA_TIME_FOR_LOGGING);
}
@@ -488,6 +496,23 @@ public class ToggleAccessibilityServicePreferenceFragment extends
mWarningDialog.dismiss();
}
/**
* This method will be invoked when a button in the tutorial dialog is clicked.
*
* @param dialog The dialog that received the click
* @param which The button that was clicked
*/
private void callOnTutorialDialogButtonClicked(DialogInterface dialog, int which) {
dialog.dismiss();
showQuickSettingsTooltipIfNeeded();
}
@Override
protected void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) {
super.callOnAlertDialogCheckboxClicked(dialog, which);
showQuickSettingsTooltipIfNeeded(getShortcutTypeCheckBoxValue());
}
void onDialogButtonFromShortcutClicked(View view) {
final int viewId = view.getId();
if (viewId == R.id.permission_enable_allow_button) {

View File

@@ -25,7 +25,9 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.graphics.drawable.Drawable;
import android.icu.text.CaseMap;
import android.net.Uri;
@@ -33,6 +35,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.quicksettings.TileService;
import android.text.Html;
import android.text.TextUtils;
import android.view.LayoutInflater;
@@ -798,6 +801,19 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
PreferredShortcuts.saveUserShortcutType(getPrefContext(), shortcut);
}
/**
* Shows the quick settings tooltip if the quick settings service and the shortcut are assigned.
* The tooltip only shows once.
*
* @param shortcutType The shortcut type.
*/
protected void showQuickSettingsTooltipIfNeeded(@UserShortcutType int shortcutType) {
if (shortcutType == AccessibilityUtil.UserShortcutType.EMPTY) {
return;
}
showQuickSettingsTooltipIfNeeded();
}
/**
* Shows the quick settings tooltip if the quick settings service is assigned. The tooltip only
* shows once.
@@ -830,4 +846,20 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
tileComponentName);
mNeedsQSTooltipReshow = false;
}
/** Returns user visible name of the tile by given {@link ComponentName}. */
protected CharSequence loadTileLabel(Context context, ComponentName componentName) {
final PackageManager packageManager = context.getPackageManager();
final Intent queryIntent = new Intent(TileService.ACTION_QS_TILE);
final List<ResolveInfo> resolveInfos =
packageManager.queryIntentServices(queryIntent, PackageManager.GET_META_DATA);
for (ResolveInfo info : resolveInfos) {
final ServiceInfo serviceInfo = info.serviceInfo;
if (TextUtils.equals(componentName.getPackageName(), serviceInfo.packageName)
&& TextUtils.equals(componentName.getClassName(), serviceInfo.name)) {
return serviceInfo.loadLabel(packageManager);
}
}
return null;
}
}