Merge changes from topic "rhedjao_a11y_button_rollback" into rvc-dev

* changes:
  Rollback chooser menu to version Q behavior for accessibility button (2/n).
  Rollback chooser menu to version Q behavior for accessibility button (1/n).
This commit is contained in:
Jason Hsu
2020-04-24 03:07:39 +00:00
committed by Android (Google) Code Review
13 changed files with 345 additions and 32 deletions

View File

@@ -124,7 +124,7 @@ public final class AccessibilityManager {
* Activity action: Launch UI to manage which accessibility service or feature is assigned
* to the navigation bar Accessibility button.
* <p>
* Input: {@link #EXTRA_SHORTCUT_TYPE} is the shortcut type.
* Input: Nothing.
* </p>
* <p>
* Output: Nothing.
@@ -137,16 +137,7 @@ public final class AccessibilityManager {
"com.android.internal.intent.action.CHOOSE_ACCESSIBILITY_BUTTON";
/**
* Used as an int extra field in {@link #ACTION_CHOOSE_ACCESSIBILITY_BUTTON} intent to specify
* the shortcut type.
*
* @hide
*/
public static final String EXTRA_SHORTCUT_TYPE =
"com.android.internal.intent.extra.SHORTCUT_TYPE";
/**
* Used as an int value for {@link #EXTRA_SHORTCUT_TYPE} to represent the accessibility button
* Used as an int value for accessibility chooser activity to represent the accessibility button
* shortcut type.
*
* @hide
@@ -154,7 +145,7 @@ public final class AccessibilityManager {
public static final int ACCESSIBILITY_BUTTON = 0;
/**
* Used as an int value for {@link #EXTRA_SHORTCUT_TYPE} to represent hardware key shortcut,
* Used as an int value for accessibility chooser activity to represent hardware key shortcut,
* such as volume key button.
*
* @hide

View File

@@ -27,6 +27,11 @@ import java.lang.annotation.RetentionPolicy;
public final class ShortcutConstants {
private ShortcutConstants() {}
/**
* Package name of the accessibility chooser and used for {@link android.content.Intent}.
*/
public static final String CHOOSER_PACKAGE_NAME = "android";
public static final char SERVICES_SEPARATOR = ':';
/**

View File

@@ -0,0 +1,94 @@
/*
* 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.
*/
package com.android.internal.accessibility.dialog;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
import android.annotation.Nullable;
import android.app.Activity;
import android.os.Bundle;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.GridView;
import android.widget.TextView;
import com.android.internal.R;
import com.android.internal.widget.ResolverDrawerLayout;
import java.util.ArrayList;
import java.util.List;
/**
* Activity used to display and persist a service or feature target for the Accessibility button.
*/
public class AccessibilityButtonChooserActivity extends Activity {
private final List<AccessibilityTarget> mTargets = new ArrayList<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.accessibility_button_chooser);
final ResolverDrawerLayout rdl = findViewById(R.id.contentPanel);
if (rdl != null) {
rdl.setOnDismissedListener(this::finish);
}
final String component = Settings.Secure.getString(getContentResolver(),
Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT);
final AccessibilityManager accessibilityManager =
getSystemService(AccessibilityManager.class);
final boolean isTouchExploreOn =
accessibilityManager.isTouchExplorationEnabled();
final boolean isGestureNavigateEnabled =
NAV_BAR_MODE_GESTURAL == getResources().getInteger(
com.android.internal.R.integer.config_navBarInteractionMode);
if (isGestureNavigateEnabled) {
final TextView promptPrologue = findViewById(R.id.accessibility_button_prompt_prologue);
promptPrologue.setText(isTouchExploreOn
? R.string.accessibility_gesture_3finger_prompt_text
: R.string.accessibility_gesture_prompt_text);
}
if (TextUtils.isEmpty(component)) {
final TextView prompt = findViewById(R.id.accessibility_button_prompt);
if (isGestureNavigateEnabled) {
prompt.setText(isTouchExploreOn
? R.string.accessibility_gesture_3finger_instructional_text
: R.string.accessibility_gesture_instructional_text);
}
prompt.setVisibility(View.VISIBLE);
}
mTargets.addAll(getTargets(this, ACCESSIBILITY_BUTTON));
final GridView gridview = findViewById(R.id.accessibility_button_chooser_grid);
gridview.setAdapter(new ButtonTargetAdapter(mTargets));
gridview.setOnItemClickListener((parent, view, position, id) -> {
final String key = Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT;
Settings.Secure.putString(getContentResolver(), key, mTargets.get(position).getId());
finish();
});
}
}

View File

@@ -23,7 +23,6 @@ import static com.android.internal.accessibility.common.ShortcutConstants.Shortc
import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.createEnableDialogContentView;
import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getInstalledTargets;
import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
import static com.android.internal.util.Preconditions.checkArgument;
import android.annotation.Nullable;
import android.app.Activity;
@@ -33,7 +32,6 @@ import android.content.res.TypedArray;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.accessibility.AccessibilityManager;
import android.widget.AdapterView;
import com.android.internal.R;
@@ -47,7 +45,7 @@ import java.util.List;
*/
public class AccessibilityShortcutChooserActivity extends Activity {
@ShortcutType
private int mShortcutType;
private final int mShortcutType = ACCESSIBILITY_SHORTCUT_KEY;
private final List<AccessibilityTarget> mTargets = new ArrayList<>();
private AlertDialog mMenuDialog;
private AlertDialog mPermissionDialog;
@@ -62,12 +60,6 @@ public class AccessibilityShortcutChooserActivity extends Activity {
requestWindowFeature(Window.FEATURE_NO_TITLE);
}
mShortcutType = getIntent().getIntExtra(AccessibilityManager.EXTRA_SHORTCUT_TYPE,
/* unexpectedShortcutType */ -1);
final boolean existInShortcutType = (mShortcutType == ACCESSIBILITY_BUTTON)
|| (mShortcutType == ACCESSIBILITY_SHORTCUT_KEY);
checkArgument(existInShortcutType, "Unexpected shortcut type: " + mShortcutType);
mTargets.addAll(getTargets(this, mShortcutType));
final String selectDialogTitle =
@@ -149,10 +141,10 @@ public class AccessibilityShortcutChooserActivity extends Activity {
private void updateDialogListeners() {
final boolean isEditMenuMode =
(mTargetAdapter.getShortcutMenuMode() == ShortcutMenuMode.EDIT);
mTargetAdapter.getShortcutMenuMode() == ShortcutMenuMode.EDIT;
final int selectDialogTitleId = R.string.accessibility_select_shortcut_menu_title;
final int editDialogTitleId =
(mShortcutType == ACCESSIBILITY_BUTTON)
mShortcutType == ACCESSIBILITY_BUTTON
? R.string.accessibility_edit_shortcut_menu_button_title
: R.string.accessibility_edit_shortcut_menu_volume_title;

View File

@@ -0,0 +1,68 @@
/*
* 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.
*/
package com.android.internal.accessibility.dialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.internal.R;
import java.util.List;
/**
* Extension for {@link TargetAdapter} and used for AccessibilityButtonChooserActivity.
*/
class ButtonTargetAdapter extends TargetAdapter {
private List<AccessibilityTarget> mTargets;
ButtonTargetAdapter(List<AccessibilityTarget> targets) {
mTargets = targets;
}
@Override
public int getCount() {
return mTargets.size();
}
@Override
public Object getItem(int position) {
return mTargets.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final Context context = parent.getContext();
final View root = LayoutInflater.from(context).inflate(
R.layout.accessibility_button_chooser_item, parent, /* attachToRoot= */
false);
final AccessibilityTarget target = mTargets.get(position);
final ImageView iconView = root.findViewById(R.id.accessibility_button_target_icon);
final TextView labelView = root.findViewById(R.id.accessibility_button_target_label);
iconView.setImageDrawable(target.getIcon());
labelView.setText(target.getLabel());
return root;
}
}

View File

@@ -151,7 +151,7 @@ public final class ShortcutUtils {
public static String convertToKey(@UserShortcutType int type) {
switch (type) {
case UserShortcutType.SOFTWARE:
return Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT;
return Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
case UserShortcutType.HARDWARE:
return Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
case UserShortcutType.TRIPLETAP:

View File

@@ -5077,6 +5077,21 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity"
android:exported="false"
android:theme="@style/Theme.DeviceDefault.Resolver"
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true"
android:documentLaunchMode="never"
android:relinquishTaskIdentity="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
android:process=":ui"
android:visibleToInstantApps="true">
<intent-filter>
<action android:name="com.android.internal.intent.action.CHOOSE_ACCESSIBILITY_BUTTON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="com.android.internal.app.IntentForwarderActivity"
android:finishOnCloseSystemDialogs="true"
android:theme="@style/Theme.NoDisplay"

View File

@@ -0,0 +1,72 @@
<?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.
-->
<com.android.internal.widget.ResolverDrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxWidth="@dimen/resolver_max_width"
android:maxCollapsedHeight="256dp"
android:maxCollapsedHeightSmall="56dp"
android:id="@id/contentPanel">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alwaysShow="true"
android:orientation="vertical"
android:background="?attr/colorBackground"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="?attr/dialogPreferredPadding"
android:paddingEnd="?attr/dialogPreferredPadding">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="56dp"
android:id="@+id/accessibility_button_prompt_prologue"
android:textAppearance="?attr/textAppearanceMedium"
android:text="@string/accessibility_button_prompt_text"
android:gravity="start|center_vertical"
android:layout_alignParentStart="true"
android:paddingTop="8dp"
android:paddingBottom="8dp"/>
<GridView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/accessibility_button_chooser_grid"
android:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/accessibility_button_prompt"
android:textAppearance="?attr/textAppearanceMedium"
android:text="@string/accessibility_button_instructional_text"
android:gravity="start|center_vertical"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:visibility="gone"/>
</LinearLayout>
</com.android.internal.widget.ResolverDrawerLayout>

View File

@@ -0,0 +1,53 @@
<?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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="80dp"
android:gravity="center"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:background="?attr/selectableItemBackgroundBorderless">
<ImageView
android:id="@+id/accessibility_button_target_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginLeft="3dp"
android:layout_marginRight="3dp"
android:layout_marginBottom="3dp"
android:scaleType="fitCenter"/>
<TextView
android:id="@+id/accessibility_button_target_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:textAppearance="?attr/textAppearanceSmall"
android:textColor="?attr/textColorPrimary"
android:textSize="12sp"
android:fontFamily="sans-serif-condensed"
android:gravity="top|center_horizontal"
android:minLines="2"
android:maxLines="2"
android:ellipsize="marquee"/>
</LinearLayout>

View File

@@ -3241,6 +3241,18 @@
<java-symbol type="id" name="accessibility_shortcut_target_switch_item" />
<!-- Accessibility Button -->
<java-symbol type="layout" name="accessibility_button_chooser" />
<java-symbol type="layout" name="accessibility_button_chooser_item" />
<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_chooser_grid" />
<java-symbol type="id" name="accessibility_button_prompt" />
<java-symbol type="id" name="accessibility_button_prompt_prologue" />
<java-symbol type="string" name="accessibility_gesture_prompt_text" />
<java-symbol type="string" name="accessibility_gesture_3finger_prompt_text" />
<java-symbol type="string" name="accessibility_gesture_instructional_text" />
<java-symbol type="string" name="accessibility_gesture_3finger_instructional_text" />
<java-symbol type="string" name="accessibility_magnification_chooser_text" />
<java-symbol type="string" name="edit_accessibility_shortcut_menu_button" />
<java-symbol type="string" name="done_accessibility_shortcut_menu_button" />

View File

@@ -23,6 +23,7 @@ import static android.view.MotionEvent.ACTION_UP;
import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_OVERVIEW;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SUPPORTS_WINDOW_CORNERS;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
@@ -59,6 +60,7 @@ import android.view.MotionEvent;
import android.view.Surface;
import android.view.accessibility.AccessibilityManager;
import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity;
import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.internal.util.ScreenshotHelper;
import com.android.systemui.Dumpable;
@@ -354,10 +356,11 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
}
long token = Binder.clearCallingIdentity();
try {
Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
final Intent intent =
new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
final String chooserClassName = AccessibilityButtonChooserActivity.class.getName();
intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra(AccessibilityManager.EXTRA_SHORTCUT_TYPE,
AccessibilityManager.ACCESSIBILITY_BUTTON);
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
} finally {
Binder.restoreCallingIdentity(token);

View File

@@ -28,6 +28,7 @@ import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_B
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NAV_BAR_HANDLE_FORCE_OPAQUE;
import static com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
@@ -91,6 +92,7 @@ import android.view.accessibility.AccessibilityManager.AccessibilityServicesStat
import androidx.annotation.VisibleForTesting;
import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.LatencyTracker;
@@ -1136,10 +1138,10 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
private boolean onAccessibilityLongClick(View v) {
Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
final Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra(AccessibilityManager.EXTRA_SHORTCUT_TYPE,
AccessibilityManager.ACCESSIBILITY_BUTTON);
final String chooserClassName = AccessibilityButtonChooserActivity.class.getName();
intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName);
v.getContext().startActivityAsUser(intent, UserHandle.CURRENT);
return true;
}

View File

@@ -21,6 +21,7 @@ import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHOR
import static android.view.accessibility.AccessibilityManager.ShortcutType;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
import static com.android.internal.util.FunctionalUtils.ignoreRemoteException;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import static com.android.server.accessibility.AccessibilityUserState.doesShortcutTargetsStringContain;
@@ -100,6 +101,8 @@ import android.view.accessibility.IWindowMagnificationConnection;
import com.android.internal.R;
import com.android.internal.accessibility.AccessibilityShortcutController;
import com.android.internal.accessibility.AccessibilityShortcutController.ToggleableFrameworkFeatureInfo;
import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity;
import com.android.internal.accessibility.dialog.AccessibilityShortcutChooserActivity;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
@@ -1181,9 +1184,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
private void showAccessibilityTargetsSelection(int displayId,
@ShortcutType int shortcutType) {
Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
final Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
final String chooserClassName = (shortcutType == ACCESSIBILITY_SHORTCUT_KEY)
? AccessibilityShortcutChooserActivity.class.getName()
: AccessibilityButtonChooserActivity.class.getName();
intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra(AccessibilityManager.EXTRA_SHORTCUT_TYPE, shortcutType);
final Bundle bundle = ActivityOptions.makeBasic().setLaunchDisplayId(displayId).toBundle();
mContext.startActivityAsUser(intent, bundle, UserHandle.of(mCurrentUserId));
}