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