Merge changes from topic "edit_menu_v2" into rvc-dev am: 6f22413c6f
Change-Id: I3def0d889bf956388a73247b78e67f2d42abf4bc
This commit is contained in:
@@ -28,8 +28,6 @@ public final class ShortcutConstants {
|
||||
private ShortcutConstants() {}
|
||||
|
||||
public static final char SERVICES_SEPARATOR = ':';
|
||||
public static final float DISABLED_ALPHA = 0.5f;
|
||||
public static final float ENABLED_ALPHA = 1.0f;
|
||||
|
||||
/**
|
||||
* Annotation for different user shortcut type UI type.
|
||||
@@ -79,6 +77,21 @@ public final class ShortcutConstants {
|
||||
int BOUNCE = 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Annotation for different shortcut target.
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
TargetType.ACCESSIBILITY_SERVICE,
|
||||
TargetType.ACCESSIBILITY_ACTIVITY,
|
||||
TargetType.WHITE_LISTING,
|
||||
})
|
||||
public @interface TargetType {
|
||||
int ACCESSIBILITY_SERVICE = 0;
|
||||
int ACCESSIBILITY_ACTIVITY = 1;
|
||||
int WHITE_LISTING = 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Annotation for different shortcut menu mode.
|
||||
*
|
||||
|
||||
@@ -38,6 +38,33 @@ public final class ShortcutUtils {
|
||||
private static final TextUtils.SimpleStringSplitter sStringColonSplitter =
|
||||
new TextUtils.SimpleStringSplitter(SERVICES_SEPARATOR);
|
||||
|
||||
/**
|
||||
* Opts in component name into colon-separated {@link UserShortcutType}
|
||||
* key's string in Settings.
|
||||
*
|
||||
* @param context The current context.
|
||||
* @param shortcutType The preferred shortcut type user selected.
|
||||
* @param componentId The component id that need to be opted out from Settings.
|
||||
*/
|
||||
public static void optInValueToSettings(Context context, @UserShortcutType int shortcutType,
|
||||
String componentId) {
|
||||
final StringJoiner joiner = new StringJoiner(String.valueOf(SERVICES_SEPARATOR));
|
||||
final String targetKey = convertToKey(shortcutType);
|
||||
final String targetString = Settings.Secure.getString(context.getContentResolver(),
|
||||
targetKey);
|
||||
|
||||
if (hasValueInSettings(context, shortcutType, componentId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(targetString)) {
|
||||
joiner.add(targetString);
|
||||
}
|
||||
joiner.add(componentId);
|
||||
|
||||
Settings.Secure.putString(context.getContentResolver(), targetKey, joiner.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Opts out component name into colon-separated {@code shortcutType} key's string in Settings.
|
||||
*
|
||||
|
||||
@@ -23,10 +23,10 @@ import static com.android.internal.accessibility.AccessibilityShortcutController
|
||||
import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
|
||||
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
|
||||
import static com.android.internal.accessibility.common.ShortcutConstants.AccessibilityServiceFragmentType;
|
||||
import static com.android.internal.accessibility.common.ShortcutConstants.DISABLED_ALPHA;
|
||||
import static com.android.internal.accessibility.common.ShortcutConstants.ENABLED_ALPHA;
|
||||
import static com.android.internal.accessibility.common.ShortcutConstants.ShortcutMenuMode;
|
||||
import static com.android.internal.accessibility.common.ShortcutConstants.TargetType;
|
||||
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
|
||||
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
|
||||
import static com.android.internal.accessibility.common.ShortcutConstants.WhiteListingFeatureElementIndex.COMPONENT_ID;
|
||||
import static com.android.internal.accessibility.common.ShortcutConstants.WhiteListingFeatureElementIndex.FRAGMENT_TYPE;
|
||||
import static com.android.internal.accessibility.common.ShortcutConstants.WhiteListingFeatureElementIndex.ICON_ID;
|
||||
@@ -36,6 +36,7 @@ import static com.android.internal.accessibility.util.AccessibilityUtils.getAcce
|
||||
import static com.android.internal.accessibility.util.AccessibilityUtils.setAccessibilityServiceState;
|
||||
import static com.android.internal.accessibility.util.ShortcutUtils.convertToUserType;
|
||||
import static com.android.internal.accessibility.util.ShortcutUtils.hasValuesInSettings;
|
||||
import static com.android.internal.accessibility.util.ShortcutUtils.optInValueToSettings;
|
||||
import static com.android.internal.accessibility.util.ShortcutUtils.optOutValueFromSettings;
|
||||
import static com.android.internal.util.Preconditions.checkArgument;
|
||||
|
||||
@@ -50,11 +51,12 @@ import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.ColorMatrix;
|
||||
import android.graphics.ColorMatrixColorFilter;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.BidiFormatter;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -62,28 +64,33 @@ import android.view.Window;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Activity used to display and persist a service or feature target for the Accessibility button.
|
||||
*/
|
||||
public class AccessibilityButtonChooserActivity extends Activity {
|
||||
@ShortcutType
|
||||
private int mShortcutType;
|
||||
private static int sShortcutType;
|
||||
@UserShortcutType
|
||||
private int mShortcutUserType;
|
||||
private final List<AccessibilityButtonTarget> mTargets = new ArrayList<>();
|
||||
private AlertDialog mAlertDialog;
|
||||
private AlertDialog mEnableDialog;
|
||||
private TargetAdapter mTargetAdapter;
|
||||
private AccessibilityButtonTarget mCurrentCheckedTarget;
|
||||
|
||||
private static final String[][] WHITE_LISTING_FEATURES = {
|
||||
{
|
||||
@@ -118,19 +125,19 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
}
|
||||
|
||||
mShortcutType = getIntent().getIntExtra(AccessibilityManager.EXTRA_SHORTCUT_TYPE,
|
||||
sShortcutType = getIntent().getIntExtra(AccessibilityManager.EXTRA_SHORTCUT_TYPE,
|
||||
/* unexpectedShortcutType */ -1);
|
||||
final boolean existInShortcutType = (mShortcutType == ACCESSIBILITY_BUTTON)
|
||||
|| (mShortcutType == ACCESSIBILITY_SHORTCUT_KEY);
|
||||
checkArgument(existInShortcutType, "Unexpected shortcut type: " + mShortcutType);
|
||||
final boolean existInShortcutType = (sShortcutType == ACCESSIBILITY_BUTTON)
|
||||
|| (sShortcutType == ACCESSIBILITY_SHORTCUT_KEY);
|
||||
checkArgument(existInShortcutType, "Unexpected shortcut type: " + sShortcutType);
|
||||
|
||||
mShortcutUserType = convertToUserType(mShortcutType);
|
||||
mShortcutUserType = convertToUserType(sShortcutType);
|
||||
|
||||
mTargets.addAll(getServiceTargets(this, mShortcutType));
|
||||
mTargets.addAll(getServiceTargets(this, sShortcutType));
|
||||
|
||||
final String selectDialogTitle =
|
||||
getString(R.string.accessibility_select_shortcut_menu_title);
|
||||
mTargetAdapter = new TargetAdapter(mTargets, mShortcutType);
|
||||
mTargetAdapter = new TargetAdapter(mTargets);
|
||||
mAlertDialog = new AlertDialog.Builder(this)
|
||||
.setTitle(selectDialogTitle)
|
||||
.setAdapter(mTargetAdapter, /* listener= */ null)
|
||||
@@ -151,15 +158,21 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
|
||||
private static List<AccessibilityButtonTarget> getServiceTargets(@NonNull Context context,
|
||||
@ShortcutType int shortcutType) {
|
||||
final List<AccessibilityButtonTarget> targets = getInstalledServiceTargets(context);
|
||||
final AccessibilityManager ams = context.getSystemService(AccessibilityManager.class);
|
||||
final List<String> requiredTargets = ams.getAccessibilityShortcutTargets(shortcutType);
|
||||
targets.removeIf(target -> !requiredTargets.contains(target.getId()));
|
||||
|
||||
return targets;
|
||||
}
|
||||
|
||||
private static List<AccessibilityButtonTarget> getInstalledServiceTargets(
|
||||
@NonNull Context context) {
|
||||
final List<AccessibilityButtonTarget> targets = new ArrayList<>();
|
||||
targets.addAll(getAccessibilityServiceTargets(context));
|
||||
targets.addAll(getAccessibilityActivityTargets(context));
|
||||
targets.addAll(getWhiteListingServiceTargets(context));
|
||||
|
||||
final AccessibilityManager ams = context.getSystemService(AccessibilityManager.class);
|
||||
final List<String> requiredTargets = ams.getAccessibilityShortcutTargets(shortcutType);
|
||||
targets.removeIf(target -> !requiredTargets.contains(target.getId()));
|
||||
|
||||
return targets;
|
||||
}
|
||||
|
||||
@@ -174,6 +187,14 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
|
||||
final List<AccessibilityButtonTarget> targets = new ArrayList<>(installedServices.size());
|
||||
for (AccessibilityServiceInfo info : installedServices) {
|
||||
final int targetSdk =
|
||||
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion;
|
||||
final boolean hasRequestAccessibilityButtonFlag =
|
||||
(info.flags & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0;
|
||||
if ((targetSdk < Build.VERSION_CODES.R) && !hasRequestAccessibilityButtonFlag
|
||||
&& (sShortcutType == ACCESSIBILITY_BUTTON)) {
|
||||
continue;
|
||||
}
|
||||
targets.add(new AccessibilityButtonTarget(context, info));
|
||||
}
|
||||
|
||||
@@ -249,35 +270,31 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
private void disableService(String componentId) {
|
||||
private void setServiceEnabled(String componentId, boolean enabled) {
|
||||
if (isWhiteListingService(componentId)) {
|
||||
setWhiteListingServiceEnabled(componentId, /* settingsValueOff */ 0);
|
||||
setWhiteListingServiceEnabled(componentId,
|
||||
enabled ? /* settingsValueOn */ 1 : /* settingsValueOff */ 0);
|
||||
} else {
|
||||
final ComponentName componentName = ComponentName.unflattenFromString(componentId);
|
||||
setAccessibilityServiceState(this, componentName, /* enabled= */ false);
|
||||
setAccessibilityServiceState(this, componentName, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
View mItemView;
|
||||
CheckBox mCheckBox;
|
||||
ImageView mIconView;
|
||||
TextView mLabelView;
|
||||
FrameLayout mItemContainer;
|
||||
ImageView mActionViewItem;
|
||||
Switch mSwitchItem;
|
||||
}
|
||||
|
||||
private static class TargetAdapter extends BaseAdapter {
|
||||
@ShortcutMenuMode
|
||||
private int mShortcutMenuMode = ShortcutMenuMode.LAUNCH;
|
||||
@ShortcutType
|
||||
private int mShortcutButtonType;
|
||||
private List<AccessibilityButtonTarget> mButtonTargets;
|
||||
|
||||
TargetAdapter(List<AccessibilityButtonTarget> targets,
|
||||
@ShortcutType int shortcutButtonType) {
|
||||
TargetAdapter(List<AccessibilityButtonTarget> targets) {
|
||||
this.mButtonTargets = targets;
|
||||
this.mShortcutButtonType = shortcutButtonType;
|
||||
}
|
||||
|
||||
void setShortcutMenuMode(@ShortcutMenuMode int shortcutMenuMode) {
|
||||
@@ -314,13 +331,11 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
false);
|
||||
holder = new ViewHolder();
|
||||
holder.mItemView = convertView;
|
||||
holder.mCheckBox = convertView.findViewById(
|
||||
R.id.accessibility_button_target_checkbox);
|
||||
holder.mIconView = convertView.findViewById(R.id.accessibility_button_target_icon);
|
||||
holder.mLabelView = convertView.findViewById(
|
||||
R.id.accessibility_button_target_label);
|
||||
holder.mItemContainer = convertView.findViewById(
|
||||
R.id.accessibility_button_target_item_container);
|
||||
holder.mActionViewItem = convertView.findViewById(
|
||||
R.id.accessibility_button_target_view_item);
|
||||
holder.mSwitchItem = convertView.findViewById(
|
||||
R.id.accessibility_button_target_switch_item);
|
||||
convertView.setTag(holder);
|
||||
@@ -329,9 +344,6 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
}
|
||||
|
||||
final AccessibilityButtonTarget target = mButtonTargets.get(position);
|
||||
holder.mIconView.setImageDrawable(target.getDrawable());
|
||||
holder.mLabelView.setText(target.getLabel());
|
||||
|
||||
updateActionItem(context, holder, target);
|
||||
|
||||
return convertView;
|
||||
@@ -342,58 +354,42 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
|
||||
switch (target.getFragmentType()) {
|
||||
case AccessibilityServiceFragmentType.LEGACY:
|
||||
updateLegacyActionItemVisibility(context, holder);
|
||||
updateLegacyActionItemVisibility(holder, target);
|
||||
break;
|
||||
case AccessibilityServiceFragmentType.INVISIBLE:
|
||||
updateInvisibleActionItemVisibility(context, holder);
|
||||
updateInvisibleActionItemVisibility(holder, target);
|
||||
break;
|
||||
case AccessibilityServiceFragmentType.INTUITIVE:
|
||||
updateIntuitiveActionItemVisibility(context, holder, target);
|
||||
break;
|
||||
case AccessibilityServiceFragmentType.BOUNCE:
|
||||
updateBounceActionItemVisibility(context, holder);
|
||||
updateBounceActionItemVisibility(holder, target);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected fragment type");
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLegacyActionItemVisibility(@NonNull Context context,
|
||||
@NonNull ViewHolder holder) {
|
||||
private void updateLegacyActionItemVisibility(@NonNull ViewHolder holder,
|
||||
AccessibilityButtonTarget target) {
|
||||
final boolean isLaunchMenuMode = (mShortcutMenuMode == ShortcutMenuMode.LAUNCH);
|
||||
final boolean isHardwareButtonTriggered =
|
||||
(mShortcutButtonType == ACCESSIBILITY_SHORTCUT_KEY);
|
||||
final boolean enabledState = (isLaunchMenuMode || isHardwareButtonTriggered);
|
||||
final ColorMatrix grayScaleMatrix = new ColorMatrix();
|
||||
grayScaleMatrix.setSaturation(/* grayScale */0);
|
||||
|
||||
holder.mIconView.setColorFilter(enabledState
|
||||
? null : new ColorMatrixColorFilter(grayScaleMatrix));
|
||||
holder.mIconView.setAlpha(enabledState
|
||||
? ENABLED_ALPHA : DISABLED_ALPHA);
|
||||
holder.mLabelView.setEnabled(enabledState);
|
||||
holder.mActionViewItem.setEnabled(enabledState);
|
||||
holder.mActionViewItem.setImageDrawable(context.getDrawable(R.drawable.ic_delete_item));
|
||||
holder.mActionViewItem.setVisibility(View.VISIBLE);
|
||||
holder.mCheckBox.setChecked(!isLaunchMenuMode && target.isChecked());
|
||||
holder.mCheckBox.setVisibility(isLaunchMenuMode ? View.GONE : View.VISIBLE);
|
||||
holder.mIconView.setImageDrawable(target.getDrawable());
|
||||
holder.mLabelView.setText(target.getLabel());
|
||||
holder.mSwitchItem.setVisibility(View.GONE);
|
||||
holder.mItemContainer.setVisibility(isLaunchMenuMode ? View.GONE : View.VISIBLE);
|
||||
holder.mItemView.setEnabled(enabledState);
|
||||
holder.mItemView.setClickable(!enabledState);
|
||||
}
|
||||
|
||||
private void updateInvisibleActionItemVisibility(@NonNull Context context,
|
||||
@NonNull ViewHolder holder) {
|
||||
holder.mIconView.setColorFilter(null);
|
||||
holder.mIconView.setAlpha(ENABLED_ALPHA);
|
||||
holder.mLabelView.setEnabled(true);
|
||||
holder.mActionViewItem.setEnabled(true);
|
||||
holder.mActionViewItem.setImageDrawable(context.getDrawable(R.drawable.ic_delete_item));
|
||||
holder.mActionViewItem.setVisibility(View.VISIBLE);
|
||||
private void updateInvisibleActionItemVisibility(@NonNull ViewHolder holder,
|
||||
AccessibilityButtonTarget target) {
|
||||
final boolean isEditMenuMode = (mShortcutMenuMode == ShortcutMenuMode.EDIT);
|
||||
|
||||
holder.mCheckBox.setChecked(isEditMenuMode && target.isChecked());
|
||||
holder.mCheckBox.setVisibility(isEditMenuMode ? View.VISIBLE : View.GONE);
|
||||
holder.mIconView.setImageDrawable(target.getDrawable());
|
||||
holder.mLabelView.setText(target.getLabel());
|
||||
holder.mSwitchItem.setVisibility(View.GONE);
|
||||
holder.mItemContainer.setVisibility((mShortcutMenuMode == ShortcutMenuMode.EDIT)
|
||||
? View.VISIBLE : View.GONE);
|
||||
holder.mItemView.setEnabled(true);
|
||||
holder.mItemView.setClickable(false);
|
||||
}
|
||||
|
||||
private void updateIntuitiveActionItemVisibility(@NonNull Context context,
|
||||
@@ -403,37 +399,31 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
? isWhiteListingServiceEnabled(context, target)
|
||||
: isAccessibilityServiceEnabled(context, target);
|
||||
|
||||
holder.mIconView.setColorFilter(null);
|
||||
holder.mIconView.setAlpha(ENABLED_ALPHA);
|
||||
holder.mLabelView.setEnabled(true);
|
||||
holder.mActionViewItem.setEnabled(true);
|
||||
holder.mActionViewItem.setImageDrawable(context.getDrawable(R.drawable.ic_delete_item));
|
||||
holder.mActionViewItem.setVisibility(isEditMenuMode ? View.VISIBLE : View.GONE);
|
||||
holder.mCheckBox.setChecked(isEditMenuMode && target.isChecked());
|
||||
holder.mCheckBox.setVisibility(isEditMenuMode ? View.VISIBLE : View.GONE);
|
||||
holder.mIconView.setImageDrawable(target.getDrawable());
|
||||
holder.mLabelView.setText(target.getLabel());
|
||||
holder.mSwitchItem.setVisibility(isEditMenuMode ? View.GONE : View.VISIBLE);
|
||||
holder.mSwitchItem.setChecked(!isEditMenuMode && isServiceEnabled);
|
||||
holder.mItemContainer.setVisibility(View.VISIBLE);
|
||||
holder.mItemView.setEnabled(true);
|
||||
holder.mItemView.setClickable(false);
|
||||
}
|
||||
|
||||
private void updateBounceActionItemVisibility(@NonNull Context context,
|
||||
@NonNull ViewHolder holder) {
|
||||
holder.mIconView.setColorFilter(null);
|
||||
holder.mIconView.setAlpha(ENABLED_ALPHA);
|
||||
holder.mLabelView.setEnabled(true);
|
||||
holder.mActionViewItem.setEnabled(true);
|
||||
holder.mActionViewItem.setImageDrawable(context.getDrawable(R.drawable.ic_delete_item));
|
||||
holder.mActionViewItem.setVisibility((mShortcutMenuMode == ShortcutMenuMode.EDIT)
|
||||
? View.VISIBLE : View.GONE);
|
||||
private void updateBounceActionItemVisibility(@NonNull ViewHolder holder,
|
||||
AccessibilityButtonTarget target) {
|
||||
final boolean isEditMenuMode = (mShortcutMenuMode == ShortcutMenuMode.EDIT);
|
||||
|
||||
holder.mCheckBox.setChecked(isEditMenuMode && target.isChecked());
|
||||
holder.mCheckBox.setVisibility(isEditMenuMode ? View.VISIBLE : View.GONE);
|
||||
holder.mIconView.setImageDrawable(target.getDrawable());
|
||||
holder.mLabelView.setText(target.getLabel());
|
||||
holder.mSwitchItem.setVisibility(View.GONE);
|
||||
holder.mItemContainer.setVisibility(View.VISIBLE);
|
||||
holder.mItemView.setEnabled(true);
|
||||
holder.mItemView.setClickable(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static class AccessibilityButtonTarget {
|
||||
private String mId;
|
||||
@TargetType
|
||||
private int mType;
|
||||
private boolean mChecked;
|
||||
private CharSequence mLabel;
|
||||
private Drawable mDrawable;
|
||||
@AccessibilityServiceFragmentType
|
||||
@@ -442,6 +432,8 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
AccessibilityButtonTarget(@NonNull Context context,
|
||||
@NonNull AccessibilityServiceInfo serviceInfo) {
|
||||
this.mId = serviceInfo.getComponentName().flattenToString();
|
||||
this.mType = TargetType.ACCESSIBILITY_SERVICE;
|
||||
this.mChecked = isTargetShortcutUsed(context, mId);
|
||||
this.mLabel = serviceInfo.getResolveInfo().loadLabel(context.getPackageManager());
|
||||
this.mDrawable = serviceInfo.getResolveInfo().loadIcon(context.getPackageManager());
|
||||
this.mFragmentType = getAccessibilityServiceFragmentType(serviceInfo);
|
||||
@@ -450,6 +442,8 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
AccessibilityButtonTarget(@NonNull Context context,
|
||||
@NonNull AccessibilityShortcutInfo shortcutInfo) {
|
||||
this.mId = shortcutInfo.getComponentName().flattenToString();
|
||||
this.mType = TargetType.ACCESSIBILITY_ACTIVITY;
|
||||
this.mChecked = isTargetShortcutUsed(context, mId);
|
||||
this.mLabel = shortcutInfo.getActivityInfo().loadLabel(context.getPackageManager());
|
||||
this.mDrawable = shortcutInfo.getActivityInfo().loadIcon(context.getPackageManager());
|
||||
this.mFragmentType = AccessibilityServiceFragmentType.BOUNCE;
|
||||
@@ -458,15 +452,29 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
AccessibilityButtonTarget(Context context, @NonNull String id, int labelResId,
|
||||
int iconRes, @AccessibilityServiceFragmentType int fragmentType) {
|
||||
this.mId = id;
|
||||
this.mType = TargetType.WHITE_LISTING;
|
||||
this.mChecked = isTargetShortcutUsed(context, mId);
|
||||
this.mLabel = context.getText(labelResId);
|
||||
this.mDrawable = context.getDrawable(iconRes);
|
||||
this.mFragmentType = fragmentType;
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked) {
|
||||
mChecked = checked;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return mChecked;
|
||||
}
|
||||
|
||||
public CharSequence getLabel() {
|
||||
return mLabel;
|
||||
}
|
||||
@@ -519,19 +527,19 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
}
|
||||
|
||||
private void onLegacyTargetSelected(AccessibilityButtonTarget target) {
|
||||
if (mShortcutType == ACCESSIBILITY_BUTTON) {
|
||||
if (sShortcutType == ACCESSIBILITY_BUTTON) {
|
||||
final AccessibilityManager ams = getSystemService(AccessibilityManager.class);
|
||||
ams.notifyAccessibilityButtonClicked(getDisplayId(), target.getId());
|
||||
} else if (mShortcutType == ACCESSIBILITY_SHORTCUT_KEY) {
|
||||
} else if (sShortcutType == ACCESSIBILITY_SHORTCUT_KEY) {
|
||||
switchServiceState(target);
|
||||
}
|
||||
}
|
||||
|
||||
private void onInvisibleTargetSelected(AccessibilityButtonTarget target) {
|
||||
final AccessibilityManager ams = getSystemService(AccessibilityManager.class);
|
||||
if (mShortcutType == ACCESSIBILITY_BUTTON) {
|
||||
if (sShortcutType == ACCESSIBILITY_BUTTON) {
|
||||
ams.notifyAccessibilityButtonClicked(getDisplayId(), target.getId());
|
||||
} else if (mShortcutType == ACCESSIBILITY_SHORTCUT_KEY) {
|
||||
} else if (sShortcutType == ACCESSIBILITY_SHORTCUT_KEY) {
|
||||
ams.performAccessibilityShortcut(target.getId());
|
||||
}
|
||||
}
|
||||
@@ -542,9 +550,9 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
|
||||
private void onBounceTargetSelected(AccessibilityButtonTarget target) {
|
||||
final AccessibilityManager ams = getSystemService(AccessibilityManager.class);
|
||||
if (mShortcutType == ACCESSIBILITY_BUTTON) {
|
||||
if (sShortcutType == ACCESSIBILITY_BUTTON) {
|
||||
ams.notifyAccessibilityButtonClicked(getDisplayId(), target.getId());
|
||||
} else if (mShortcutType == ACCESSIBILITY_SHORTCUT_KEY) {
|
||||
} else if (sShortcutType == ACCESSIBILITY_SHORTCUT_KEY) {
|
||||
ams.performAccessibilityShortcut(target.getId());
|
||||
}
|
||||
}
|
||||
@@ -565,66 +573,101 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
private void onTargetDeleted(AdapterView<?> parent, View view, int position, long id) {
|
||||
final AccessibilityButtonTarget target = mTargets.get(position);
|
||||
final String componentId = target.getId();
|
||||
private void onTargetChecked(AdapterView<?> parent, View view, int position, long id) {
|
||||
mCurrentCheckedTarget = mTargets.get(position);
|
||||
|
||||
if ((mCurrentCheckedTarget.getType() == TargetType.ACCESSIBILITY_SERVICE)
|
||||
&& !mCurrentCheckedTarget.isChecked()) {
|
||||
mEnableDialog = new AlertDialog.Builder(this)
|
||||
.setView(createEnableDialogContentView(this, mCurrentCheckedTarget,
|
||||
this::onPermissionAllowButtonClicked,
|
||||
this::onPermissionDenyButtonClicked))
|
||||
.create();
|
||||
mEnableDialog.show();
|
||||
return;
|
||||
}
|
||||
|
||||
onTargetChecked(mCurrentCheckedTarget, !mCurrentCheckedTarget.isChecked());
|
||||
}
|
||||
|
||||
private void onTargetChecked(AccessibilityButtonTarget target, boolean checked) {
|
||||
switch (target.getFragmentType()) {
|
||||
case AccessibilityServiceFragmentType.LEGACY:
|
||||
onLegacyTargetDeleted(position, componentId);
|
||||
onLegacyTargetChecked(checked);
|
||||
break;
|
||||
case AccessibilityServiceFragmentType.INVISIBLE:
|
||||
onInvisibleTargetDeleted(position, componentId);
|
||||
onInvisibleTargetChecked(checked);
|
||||
break;
|
||||
case AccessibilityServiceFragmentType.INTUITIVE:
|
||||
onIntuitiveTargetDeleted(position, componentId);
|
||||
onIntuitiveTargetChecked(checked);
|
||||
break;
|
||||
case AccessibilityServiceFragmentType.BOUNCE:
|
||||
onBounceTargetDeleted(position, componentId);
|
||||
onBounceTargetChecked(checked);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected fragment type");
|
||||
}
|
||||
}
|
||||
|
||||
private void onLegacyTargetChecked(boolean checked) {
|
||||
if (sShortcutType == ACCESSIBILITY_BUTTON) {
|
||||
setServiceEnabled(mCurrentCheckedTarget.getId(), checked);
|
||||
if (!checked) {
|
||||
optOutValueFromSettings(this, HARDWARE, mCurrentCheckedTarget.getId());
|
||||
final String warningText =
|
||||
getString(R.string.accessibility_uncheck_legacy_item_warning,
|
||||
mCurrentCheckedTarget.getLabel());
|
||||
Toast.makeText(this, warningText, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
} else if (sShortcutType == ACCESSIBILITY_SHORTCUT_KEY) {
|
||||
updateValueToSettings(mCurrentCheckedTarget.getId(), checked);
|
||||
} else {
|
||||
throw new IllegalStateException("Unexpected shortcut type");
|
||||
}
|
||||
|
||||
mCurrentCheckedTarget.setChecked(checked);
|
||||
mTargetAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void onInvisibleTargetChecked(boolean checked) {
|
||||
final int shortcutTypes = UserShortcutType.SOFTWARE | HARDWARE;
|
||||
if (!hasValuesInSettings(this, shortcutTypes, mCurrentCheckedTarget.getId())) {
|
||||
setServiceEnabled(mCurrentCheckedTarget.getId(), checked);
|
||||
}
|
||||
|
||||
updateValueToSettings(mCurrentCheckedTarget.getId(), checked);
|
||||
mCurrentCheckedTarget.setChecked(checked);
|
||||
mTargetAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void onIntuitiveTargetChecked(boolean checked) {
|
||||
updateValueToSettings(mCurrentCheckedTarget.getId(), checked);
|
||||
mCurrentCheckedTarget.setChecked(checked);
|
||||
mTargetAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void onBounceTargetChecked(boolean checked) {
|
||||
updateValueToSettings(mCurrentCheckedTarget.getId(), checked);
|
||||
mCurrentCheckedTarget.setChecked(checked);
|
||||
mTargetAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void updateValueToSettings(String componentId, boolean checked) {
|
||||
if (checked) {
|
||||
optInValueToSettings(this, mShortcutUserType, componentId);
|
||||
} else {
|
||||
optOutValueFromSettings(this, mShortcutUserType, componentId);
|
||||
}
|
||||
}
|
||||
|
||||
private void onDoneButtonClicked() {
|
||||
mTargets.clear();
|
||||
mTargets.addAll(getServiceTargets(this, sShortcutType));
|
||||
if (mTargets.isEmpty()) {
|
||||
mAlertDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
private void onLegacyTargetDeleted(int position, String componentId) {
|
||||
if (mShortcutType == ACCESSIBILITY_SHORTCUT_KEY) {
|
||||
optOutValueFromSettings(this, mShortcutUserType, componentId);
|
||||
|
||||
mTargets.remove(position);
|
||||
mTargetAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void onInvisibleTargetDeleted(int position, String componentId) {
|
||||
optOutValueFromSettings(this, mShortcutUserType, componentId);
|
||||
|
||||
final int shortcutTypes = UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE;
|
||||
if (!hasValuesInSettings(this, shortcutTypes, componentId)) {
|
||||
disableService(componentId);
|
||||
return;
|
||||
}
|
||||
|
||||
mTargets.remove(position);
|
||||
mTargetAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void onIntuitiveTargetDeleted(int position, String componentId) {
|
||||
optOutValueFromSettings(this, mShortcutUserType, componentId);
|
||||
mTargets.remove(position);
|
||||
mTargetAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void onBounceTargetDeleted(int position, String componentId) {
|
||||
optOutValueFromSettings(this, mShortcutUserType, componentId);
|
||||
mTargets.remove(position);
|
||||
mTargetAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void onCancelButtonClicked() {
|
||||
mTargetAdapter.setShortcutMenuMode(ShortcutMenuMode.LAUNCH);
|
||||
mTargetAdapter.notifyDataSetChanged();
|
||||
|
||||
@@ -635,11 +678,13 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
}
|
||||
|
||||
private void onEditButtonClicked() {
|
||||
mTargets.clear();
|
||||
mTargets.addAll(getInstalledServiceTargets(this));
|
||||
mTargetAdapter.setShortcutMenuMode(ShortcutMenuMode.EDIT);
|
||||
mTargetAdapter.notifyDataSetChanged();
|
||||
|
||||
mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setText(
|
||||
getString(R.string.cancel_accessibility_shortcut_menu_button));
|
||||
getString(R.string.done_accessibility_shortcut_menu_button));
|
||||
|
||||
updateDialogListeners();
|
||||
}
|
||||
@@ -649,15 +694,78 @@ public class AccessibilityButtonChooserActivity extends Activity {
|
||||
(mTargetAdapter.getShortcutMenuMode() == ShortcutMenuMode.EDIT);
|
||||
final int selectDialogTitleId = R.string.accessibility_select_shortcut_menu_title;
|
||||
final int editDialogTitleId =
|
||||
(mShortcutType == ACCESSIBILITY_BUTTON)
|
||||
(sShortcutType == ACCESSIBILITY_BUTTON)
|
||||
? R.string.accessibility_edit_shortcut_menu_button_title
|
||||
: R.string.accessibility_edit_shortcut_menu_volume_title;
|
||||
|
||||
mAlertDialog.setTitle(getString(isEditMenuMode ? editDialogTitleId : selectDialogTitleId));
|
||||
|
||||
mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(
|
||||
isEditMenuMode ? view -> onCancelButtonClicked() : view -> onEditButtonClicked());
|
||||
isEditMenuMode ? view -> onDoneButtonClicked() : view -> onEditButtonClicked());
|
||||
mAlertDialog.getListView().setOnItemClickListener(
|
||||
isEditMenuMode ? this::onTargetDeleted : this::onTargetSelected);
|
||||
isEditMenuMode ? this::onTargetChecked : this::onTargetSelected);
|
||||
}
|
||||
|
||||
private static boolean isTargetShortcutUsed(@NonNull Context context, String id) {
|
||||
final AccessibilityManager ams = context.getSystemService(AccessibilityManager.class);
|
||||
final List<String> requiredTargets = ams.getAccessibilityShortcutTargets(sShortcutType);
|
||||
return requiredTargets.contains(id);
|
||||
}
|
||||
|
||||
private void onPermissionAllowButtonClicked(View view) {
|
||||
if (mCurrentCheckedTarget.getFragmentType() != AccessibilityServiceFragmentType.LEGACY) {
|
||||
updateValueToSettings(mCurrentCheckedTarget.getId(), /* checked= */ true);
|
||||
}
|
||||
onTargetChecked(mCurrentCheckedTarget, /* checked= */ true);
|
||||
mEnableDialog.dismiss();
|
||||
}
|
||||
|
||||
private void onPermissionDenyButtonClicked(View view) {
|
||||
mEnableDialog.dismiss();
|
||||
}
|
||||
|
||||
private static View createEnableDialogContentView(Context context,
|
||||
AccessibilityButtonTarget target, View.OnClickListener allowListener,
|
||||
View.OnClickListener denyListener) {
|
||||
final LayoutInflater inflater = (LayoutInflater) context.getSystemService(
|
||||
Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
final View content = inflater.inflate(
|
||||
R.layout.accessibility_enable_service_encryption_warning, /* root= */ null);
|
||||
|
||||
final TextView encryptionWarningView = (TextView) content.findViewById(
|
||||
R.id.accessibility_encryption_warning);
|
||||
if (StorageManager.isNonDefaultBlockEncrypted()) {
|
||||
final String text = context.getString(
|
||||
R.string.accessibility_enable_service_encryption_warning,
|
||||
getServiceName(context, target.getLabel()));
|
||||
encryptionWarningView.setText(text);
|
||||
encryptionWarningView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
encryptionWarningView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
final ImageView permissionDialogIcon = content.findViewById(
|
||||
R.id.accessibility_permissionDialog_icon);
|
||||
permissionDialogIcon.setImageDrawable(target.getDrawable());
|
||||
|
||||
final TextView permissionDialogTitle = content.findViewById(
|
||||
R.id.accessibility_permissionDialog_title);
|
||||
permissionDialogTitle.setText(context.getString(R.string.accessibility_enable_service_title,
|
||||
getServiceName(context, target.getLabel())));
|
||||
|
||||
final Button permissionAllowButton = content.findViewById(
|
||||
R.id.accessibility_permission_enable_allow_button);
|
||||
final Button permissionDenyButton = content.findViewById(
|
||||
R.id.accessibility_permission_enable_deny_button);
|
||||
permissionAllowButton.setOnClickListener(allowListener);
|
||||
permissionDenyButton.setOnClickListener(denyListener);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
// Gets the service name and bidi wrap it to protect from bidi side effects.
|
||||
private static CharSequence getServiceName(Context context, CharSequence label) {
|
||||
final Locale locale = context.getResources().getConfiguration().getLocales().get(0);
|
||||
return BidiFormatter.getInstance(locale).unicodeWrap(label);
|
||||
}
|
||||
}
|
||||
|
||||
26
core/res/res/drawable/ic_pan_tool.xml
Normal file
26
core/res/res/drawable/ic_pan_tool.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<!--
|
||||
Copyright (C) 2020 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.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:pathData="M23,5.5V20c0,2.2 -1.8,4 -4,4h-7.3c-1.08,0 -2.1,-0.43 -2.85,-1.19L1,14.83c0,0 1.26,-1.23 1.3,-1.25c0.22,-0.19 0.49,-0.29 0.79,-0.29c0.22,0 0.42,0.06 0.6,0.16C3.73,13.46 8,15.91 8,15.91V4c0,-0.83 0.67,-1.5 1.5,-1.5S11,3.17 11,4v7h1V1.5C12,0.67 12.67,0 13.5,0S15,0.67 15,1.5V11h1V2.5C16,1.67 16.67,1 17.5,1S19,1.67 19,2.5V11h1V5.5C20,4.67 20.67,4 21.5,4S23,4.67 23,5.5z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
</vector>
|
||||
@@ -12,7 +12,7 @@
|
||||
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.
|
||||
-->
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
@@ -21,6 +21,6 @@
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"
|
||||
android:pathData="M12,4.5C7,4.5 2.73,7.61 1,12c1.73,4.39 6,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6,-7.5 -11,-7.5zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
</vector>
|
||||
@@ -21,10 +21,17 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="12dp">
|
||||
android:padding="16dp">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/accessibility_button_target_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="16dp"
|
||||
android:background="@null"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/accessibility_button_target_icon"
|
||||
@@ -36,31 +43,18 @@
|
||||
android:id="@+id/accessibility_button_target_label"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="14dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_weight="1"
|
||||
android:textSize="20sp"
|
||||
android:textColor="?attr/textColorPrimary"
|
||||
android:fontFamily="sans-serif-medium"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/accessibility_button_target_item_container"
|
||||
<Switch
|
||||
android:id="@+id/accessibility_button_target_switch_item"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="56dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/accessibility_button_target_view_item"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"/>
|
||||
|
||||
<Switch android:id="@+id/accessibility_button_target_switch_item"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="@null"
|
||||
android:clickable="false"
|
||||
android:focusable="false"/>
|
||||
</FrameLayout>
|
||||
android:background="@null"
|
||||
android:clickable="false"
|
||||
android:focusable="false"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2020 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.
|
||||
-->
|
||||
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textDirection="locale"
|
||||
android:scrollbarStyle="outsideOverlay">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/accessibility_permissionDialog_icon"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:scaleType="fitCenter"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/accessibility_permissionDialog_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textSize="20sp"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:fontFamily="google-sans-medium"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/accessibility_encryption_warning"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dip"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/accessibility_permissionDialog_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:text="@string/accessibility_service_warning_description"
|
||||
android:textSize="16sp"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:fontFamily="sans-serif"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/accessibility_controlScreen_icon"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_marginRight="12dp"
|
||||
android:src="@android:drawable/ic_visibility"
|
||||
android:scaleType="fitCenter"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/accessibility_controlScreen_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/accessibility_service_screen_control_title"
|
||||
android:textSize="16sp"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:fontFamily="sans-serif"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/accessibility_controlScreen_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:paddingStart="30dp"
|
||||
android:text="@string/accessibility_service_screen_control_description"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:fontFamily="sans-serif"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/accessibility_performAction_icon"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:src="@android:drawable/ic_pan_tool"
|
||||
android:scaleType="fitCenter"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/accessibility_performAction_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/accessibility_service_action_perform_title"
|
||||
android:textSize="16sp"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:fontFamily="sans-serif"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/accessibility_performAction_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:paddingStart="30dp"
|
||||
android:text="@string/accessibility_service_action_perform_description"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:fontFamily="sans-serif" />
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/chooser_row_divider"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/accessibility_permission_enable_allow_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:text="@string/accessibility_dialog_button_allow"
|
||||
style="?attr/buttonBarPositiveButtonStyle"/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/chooser_row_divider"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/accessibility_permission_enable_deny_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:text="@string/accessibility_dialog_button_deny"
|
||||
style="?attr/buttonBarPositiveButtonStyle"/>
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
@@ -4403,27 +4403,72 @@
|
||||
accessibility feature.
|
||||
</string>
|
||||
|
||||
<!-- Title for a warning about security implications of enabling an accessibility
|
||||
service. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_enable_service_title">Allow
|
||||
<xliff:g id="service" example="TalkBack">%1$s</xliff:g> to have full control of your
|
||||
device?</string>
|
||||
|
||||
<!-- Warning that the device data will not be encrypted with password or PIN if
|
||||
enabling an accessibility service and there is a secure lock setup. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_enable_service_encryption_warning">If you turn on
|
||||
<xliff:g id="service" example="TalkBack">%1$s</xliff:g>, your device won’t use your screen
|
||||
lock to enhance data encryption.
|
||||
</string>
|
||||
|
||||
<!-- Warning description that explains that it's appropriate for accessibility
|
||||
services to have full control to help users with accessibility needs. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_service_warning_description">Full control is appropriate for apps
|
||||
that help you with accessibility needs, but not for most apps.
|
||||
</string>
|
||||
|
||||
<!-- Title for the screen control in accessibility dialog. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_service_screen_control_title">View and control screen</string>
|
||||
|
||||
<!-- Description for the screen control in accessibility dialog. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_service_screen_control_description">It can read all content on the
|
||||
screen and display content over other apps.
|
||||
</string>
|
||||
|
||||
<!-- Title for the action perform in accessibility dialog. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_service_action_perform_title">View and perform actions</string>
|
||||
|
||||
<!-- Description for the action perform in accessibility dialog. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_service_action_perform_description">It can track your interactions
|
||||
with an app or a hardware sensor, and interact with apps on your behalf.
|
||||
</string>
|
||||
|
||||
<!-- String for the allow button in accessibility permission dialog. [CHAR LIMIT=10] -->
|
||||
<string name="accessibility_dialog_button_allow">Allow</string>
|
||||
<!-- String for the deny button in accessibility permission dialog. [CHAR LIMIT=10] -->
|
||||
<string name="accessibility_dialog_button_deny">Deny</string>
|
||||
|
||||
<!-- Title for accessibility select shortcut menu dialog. [CHAR LIMIT=100] -->
|
||||
<string name="accessibility_select_shortcut_menu_title">Tap the accessibility app you want to use</string>
|
||||
<string name="accessibility_select_shortcut_menu_title">Tap a feature to start using it:</string>
|
||||
|
||||
<!-- Title for accessibility edit shortcut selection menu dialog, and dialog is triggered
|
||||
from accessibility button. [CHAR LIMIT=100] -->
|
||||
<string name="accessibility_edit_shortcut_menu_button_title">Choose apps you want to use with
|
||||
<string name="accessibility_edit_shortcut_menu_button_title">Choose apps to use with the
|
||||
accessibility button
|
||||
</string>
|
||||
|
||||
<!-- Title for accessibility edit shortcut selection menu dialog, and dialog is triggered
|
||||
from volume key shortcut. [CHAR LIMIT=100] -->
|
||||
<string name="accessibility_edit_shortcut_menu_volume_title">Choose apps you want to use with
|
||||
<string name="accessibility_edit_shortcut_menu_volume_title">Choose apps to use with the
|
||||
volume key shortcut
|
||||
</string>
|
||||
|
||||
<!-- Text for showing the warning to user when uncheck the legacy app item in the accessibility
|
||||
shortcut menu, user can aware the service to be disabled. [CHAR LIMIT=100] -->
|
||||
<string name="accessibility_uncheck_legacy_item_warning">
|
||||
<xliff:g id="service_name" example="TalkBack">%s</xliff:g> has been turned off</string>
|
||||
|
||||
<!-- Text in button that edit the accessibility shortcut menu, user can delete
|
||||
any service item in the menu list. [CHAR LIMIT=100] -->
|
||||
<string name="edit_accessibility_shortcut_menu_button">Edit shortcuts</string>
|
||||
|
||||
<!-- Text in button that cancel the accessibility shortcut menu changed status. [CHAR LIMIT=100] -->
|
||||
<string name="cancel_accessibility_shortcut_menu_button">Cancel</string>
|
||||
<!-- Text in button that complete the accessibility shortcut menu changed status. [CHAR LIMIT=100] -->
|
||||
<string name="done_accessibility_shortcut_menu_button">Done</string>
|
||||
|
||||
<!-- Text in button that turns off the accessibility shortcut -->
|
||||
<string name="disable_accessibility_shortcut">Turn off Shortcut</string>
|
||||
|
||||
@@ -3240,24 +3240,31 @@
|
||||
<java-symbol type="string" name="accessibility_select_shortcut_menu_title" />
|
||||
<java-symbol type="string" name="accessibility_edit_shortcut_menu_button_title" />
|
||||
<java-symbol type="string" name="accessibility_edit_shortcut_menu_volume_title" />
|
||||
<java-symbol type="string" name="accessibility_uncheck_legacy_item_warning" />
|
||||
|
||||
<java-symbol type="layout" name="accessibility_enable_service_encryption_warning" />
|
||||
<java-symbol type="id" name="accessibility_permissionDialog_icon" />
|
||||
<java-symbol type="id" name="accessibility_permissionDialog_title" />
|
||||
<java-symbol type="id" name="accessibility_encryption_warning" />
|
||||
<java-symbol type="id" name="accessibility_permission_enable_allow_button" />
|
||||
<java-symbol type="id" name="accessibility_permission_enable_deny_button" />
|
||||
<java-symbol type="string" name="accessibility_enable_service_title" />
|
||||
<java-symbol type="string" name="accessibility_enable_service_encryption_warning" />
|
||||
|
||||
<!-- Accessibility Button -->
|
||||
<java-symbol type="layout" name="accessibility_button_chooser_item" />
|
||||
<java-symbol type="id" name="accessibility_button_target_checkbox" />
|
||||
<java-symbol type="id" name="accessibility_button_target_icon" />
|
||||
<java-symbol type="id" name="accessibility_button_target_label" />
|
||||
<java-symbol type="id" name="accessibility_button_target_item_container" />
|
||||
<java-symbol type="id" name="accessibility_button_target_view_item" />
|
||||
<java-symbol type="id" name="accessibility_button_target_switch_item" />
|
||||
<java-symbol type="string" name="accessibility_magnification_chooser_text" />
|
||||
<java-symbol type="string" name="edit_accessibility_shortcut_menu_button" />
|
||||
<java-symbol type="string" name="cancel_accessibility_shortcut_menu_button" />
|
||||
<java-symbol type="string" name="done_accessibility_shortcut_menu_button" />
|
||||
|
||||
<java-symbol type="drawable" name="ic_accessibility_color_inversion" />
|
||||
<java-symbol type="drawable" name="ic_accessibility_color_correction" />
|
||||
<java-symbol type="drawable" name="ic_accessibility_magnification" />
|
||||
|
||||
<java-symbol type="drawable" name="ic_delete_item" />
|
||||
|
||||
<!-- com.android.internal.widget.RecyclerView -->
|
||||
<java-symbol type="id" name="item_touch_helper_previous_elevation"/>
|
||||
<java-symbol type="dimen" name="item_touch_helper_max_drag_scroll_per_frame"/>
|
||||
|
||||
Reference in New Issue
Block a user