1 /* 2 * Copyright (C) 2010 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 android.accessibilityservice.cts.activities; 18 19 import android.accessibilityservice.cts.R; 20 import android.graphics.Rect; 21 import android.os.Bundle; 22 import android.view.TouchDelegate; 23 import android.view.View; 24 import android.view.ViewGroup; 25 import android.view.accessibility.AccessibilityEvent; 26 import android.view.accessibility.AccessibilityNodeInfo; 27 import android.widget.BaseAdapter; 28 import android.widget.Button; 29 import android.widget.ListAdapter; 30 import android.widget.ListView; 31 import android.widget.TextView; 32 33 import java.util.function.Function; 34 import java.util.function.Supplier; 35 36 /** 37 * This class is an {@link android.app.Activity} used to perform end-to-end 38 * testing of the accessibility feature by interaction with the 39 * UI widgets. 40 */ 41 public class AccessibilityEndToEndActivity extends AccessibilityTestActivity { 42 private PackageNameInjector mPackageNameInjector; 43 44 @Override onCreate(Bundle savedInstanceState)45 protected void onCreate(Bundle savedInstanceState) { 46 super.onCreate(savedInstanceState); 47 setContentView(R.layout.end_to_end_test); 48 49 ListAdapter listAdapter = new BaseAdapter() { 50 public View getView(int position, View convertView, ViewGroup parent) { 51 TextView textView = (TextView) View 52 .inflate(AccessibilityEndToEndActivity.this, R.layout.list_view_row, null); 53 textView.setText((String) getItem(position)); 54 return textView; 55 } 56 57 public long getItemId(int position) { 58 return position; 59 } 60 61 public Object getItem(int position) { 62 if (position == 0) { 63 return AccessibilityEndToEndActivity.this.getString(R.string.first_list_item); 64 } else { 65 return AccessibilityEndToEndActivity.this.getString(R.string.second_list_item); 66 } 67 } 68 69 public int getCount() { 70 return 2; 71 } 72 }; 73 74 ListView listView = (ListView) findViewById(R.id.listview); 75 listView.setAdapter(listAdapter); 76 77 final int touchableSize = getResources().getDimensionPixelSize( 78 R.dimen.button_touchable_width_increment_amount); 79 Button button = findViewById(R.id.button); 80 Function<View, Rect> withTouchableAtRight = (v) -> new Rect( 81 v.getLeft(), 0, v.getRight() + touchableSize, v.getHeight()); 82 button.getViewTreeObserver().addOnGlobalLayoutListener(setTouchDelegate(button, 83 () -> withTouchableAtRight.apply(button))::run); 84 85 Button delegated = findViewById(R.id.buttonDelegated); 86 Function<View, Rect> withTouchableAsParent = (v) -> new Rect( 87 0, 0, v.getWidth(), v.getHeight()); 88 delegated.getViewTreeObserver().addOnGlobalLayoutListener(setTouchDelegate(delegated, 89 () -> withTouchableAsParent.apply((View) delegated.getParent()))::run); 90 } 91 setTouchDelegate(View target, Supplier<Rect> rectSupplier)92 private static Runnable setTouchDelegate(View target, Supplier<Rect> rectSupplier) { 93 return () -> ((View) target.getParent()).setTouchDelegate( 94 new TouchDelegate(rectSupplier.get(), target)); 95 } 96 setReportedPackageName(String packageName)97 public void setReportedPackageName(String packageName) { 98 if (packageName != null) { 99 mPackageNameInjector = new PackageNameInjector(packageName); 100 } else { 101 mPackageNameInjector = null; 102 } 103 setPackageNameInjector(getWindow().getDecorView(), mPackageNameInjector); 104 } 105 setPackageNameInjector(View node, PackageNameInjector injector)106 private static void setPackageNameInjector(View node, PackageNameInjector injector) { 107 if (node == null) { 108 return; 109 } 110 node.setAccessibilityDelegate(injector); 111 if (node instanceof ViewGroup) { 112 final ViewGroup viewGroup = (ViewGroup) node; 113 final int childCount = viewGroup.getChildCount(); 114 for (int i = 0; i < childCount; i++) { 115 setPackageNameInjector(viewGroup.getChildAt(i), injector); 116 } 117 } 118 } 119 120 private static class PackageNameInjector extends View.AccessibilityDelegate { 121 private final String mPackageName; 122 PackageNameInjector(String packageName)123 PackageNameInjector(String packageName) { 124 mPackageName = packageName; 125 } 126 127 @Override onInitializeAccessibilityEvent(View host, AccessibilityEvent event)128 public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { 129 super.onInitializeAccessibilityEvent(host, event); 130 event.setPackageName(mPackageName); 131 } 132 133 @Override onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info)134 public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { 135 super.onInitializeAccessibilityNodeInfo(host, info); 136 info.setPackageName(mPackageName); 137 } 138 } 139 } 140