1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.accessibility.dialog; 18 19 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE; 20 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE; 21 import static com.android.internal.accessibility.util.ShortcutUtils.optInValueToSettings; 22 import static com.android.internal.accessibility.util.ShortcutUtils.optOutValueFromSettings; 23 24 import android.annotation.NonNull; 25 import android.annotation.Nullable; 26 import android.annotation.SuppressLint; 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.graphics.drawable.Drawable; 30 import android.os.UserHandle; 31 import android.view.View; 32 import android.view.accessibility.AccessibilityManager; 33 import android.view.accessibility.Flags; 34 35 import com.android.internal.accessibility.common.ShortcutConstants; 36 import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType; 37 import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType; 38 import com.android.internal.accessibility.dialog.TargetAdapter.ViewHolder; 39 import com.android.internal.annotations.VisibleForTesting; 40 41 import java.util.Set; 42 43 /** 44 * Abstract base class for creating various target related to accessibility service, accessibility 45 * activity, and allowlisting features. 46 * 47 * <p> Disables accessibility features that are not permitted in adding a restricted padlock icon 48 * and showing admin support message dialog. 49 */ 50 public abstract class AccessibilityTarget implements TargetOperations, OnTargetSelectedListener, 51 OnTargetCheckedChangeListener { 52 private Context mContext; 53 @UserShortcutType 54 private int mShortcutType; 55 @AccessibilityFragmentType 56 private int mFragmentType; 57 private boolean mShortcutEnabled; 58 private String mId; 59 private int mUid; 60 private ComponentName mComponentName; 61 private CharSequence mLabel; 62 private Drawable mIcon; 63 private String mKey; 64 private CharSequence mStateDescription; 65 66 @VisibleForTesting AccessibilityTarget(Context context, @UserShortcutType int shortcutType, @AccessibilityFragmentType int fragmentType, boolean isShortcutSwitched, String id, int uid, CharSequence label, Drawable icon, String key)67 public AccessibilityTarget(Context context, @UserShortcutType int shortcutType, 68 @AccessibilityFragmentType int fragmentType, boolean isShortcutSwitched, String id, 69 int uid, CharSequence label, Drawable icon, String key) { 70 mContext = context; 71 mShortcutType = shortcutType; 72 mFragmentType = fragmentType; 73 mShortcutEnabled = isShortcutSwitched; 74 mId = id; 75 mUid = uid; 76 mComponentName = ComponentName.unflattenFromString(id); 77 mLabel = label; 78 mIcon = icon; 79 mKey = key; 80 } 81 82 @Override updateActionItem(@onNull ViewHolder holder, @ShortcutConstants.ShortcutMenuMode int shortcutMenuMode)83 public void updateActionItem(@NonNull ViewHolder holder, 84 @ShortcutConstants.ShortcutMenuMode int shortcutMenuMode) { 85 // Resetting the enable state of the item to avoid the previous wrong state of RecyclerView. 86 holder.mCheckBoxView.setEnabled(true); 87 holder.mIconView.setEnabled(true); 88 holder.mLabelView.setEnabled(true); 89 holder.mStatusView.setEnabled(true); 90 91 final boolean isEditMenuMode = 92 shortcutMenuMode == ShortcutConstants.ShortcutMenuMode.EDIT; 93 holder.mCheckBoxView.setChecked(isEditMenuMode && isShortcutEnabled()); 94 holder.mCheckBoxView.setVisibility(isEditMenuMode ? View.VISIBLE : View.GONE); 95 holder.mIconView.setImageDrawable(getIcon()); 96 holder.mLabelView.setText(getLabel()); 97 holder.mStatusView.setVisibility(View.GONE); 98 } 99 100 @Override onSelected()101 public void onSelected() { 102 final AccessibilityManager am = 103 getContext().getSystemService(AccessibilityManager.class); 104 switch (getShortcutType()) { 105 case SOFTWARE: 106 am.notifyAccessibilityButtonClicked(getContext().getDisplayId(), getId()); 107 return; 108 case HARDWARE: 109 am.performAccessibilityShortcut(getId()); 110 return; 111 default: 112 throw new IllegalStateException("Unexpected shortcut type"); 113 } 114 } 115 116 @SuppressLint("MissingPermission") 117 @Override onCheckedChanged(boolean isChecked)118 public void onCheckedChanged(boolean isChecked) { 119 setShortcutEnabled(isChecked); 120 if (Flags.migrateEnableShortcuts()) { 121 final AccessibilityManager am = 122 getContext().getSystemService(AccessibilityManager.class); 123 am.enableShortcutsForTargets( 124 isChecked, getShortcutType(), Set.of(mId), UserHandle.myUserId()); 125 } else { 126 if (isChecked) { 127 optInValueToSettings(getContext(), getShortcutType(), getId()); 128 } else { 129 optOutValueFromSettings(getContext(), getShortcutType(), getId()); 130 } 131 } 132 } 133 setStateDescription(CharSequence stateDescription)134 public void setStateDescription(CharSequence stateDescription) { 135 mStateDescription = stateDescription; 136 } 137 138 /** 139 * Gets the state description of this feature target. 140 * 141 * @return the state description 142 */ 143 @Nullable getStateDescription()144 public CharSequence getStateDescription() { 145 return mStateDescription; 146 } 147 setShortcutEnabled(boolean enabled)148 public void setShortcutEnabled(boolean enabled) { 149 mShortcutEnabled = enabled; 150 } 151 getContext()152 public Context getContext() { 153 return mContext; 154 } 155 getShortcutType()156 public @UserShortcutType int getShortcutType() { 157 return mShortcutType; 158 } 159 getFragmentType()160 public @AccessibilityFragmentType int getFragmentType() { 161 return mFragmentType; 162 } 163 isShortcutEnabled()164 public boolean isShortcutEnabled() { 165 return mShortcutEnabled; 166 } 167 getId()168 public String getId() { 169 return mId; 170 } 171 getUid()172 public int getUid() { 173 return mUid; 174 } 175 getComponentName()176 public ComponentName getComponentName() { 177 return mComponentName; 178 } 179 getLabel()180 public CharSequence getLabel() { 181 return mLabel; 182 } 183 getIcon()184 public Drawable getIcon() { 185 return mIcon; 186 } 187 getKey()188 public String getKey() { 189 return mKey; 190 } 191 } 192