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 = 48; 78 Button button = findViewById(R.id.button); 79 Function<View, Rect> withTouchableAtRight = (v) -> new Rect( 80 v.getLeft(), 0, v.getRight() + touchableSize, v.getHeight()); 81 button.getViewTreeObserver().addOnGlobalLayoutListener(setTouchDelegate(button, 82 () -> withTouchableAtRight.apply(button))::run); 83 84 Button delegated = findViewById(R.id.buttonDelegated); 85 Function<View, Rect> withTouchableAsParent = (v) -> new Rect( 86 0, 0, v.getWidth(), v.getHeight()); 87 delegated.getViewTreeObserver().addOnGlobalLayoutListener(setTouchDelegate(delegated, 88 () -> withTouchableAsParent.apply((View) delegated.getParent()))::run); 89 } 90 setTouchDelegate(View target, Supplier<Rect> rectSupplier)91 private static Runnable setTouchDelegate(View target, Supplier<Rect> rectSupplier) { 92 return () -> ((View) target.getParent()).setTouchDelegate( 93 new TouchDelegate(rectSupplier.get(), target)); 94 } 95 setReportedPackageName(String packageName)96 public void setReportedPackageName(String packageName) { 97 if (packageName != null) { 98 mPackageNameInjector = new PackageNameInjector(packageName); 99 } else { 100 mPackageNameInjector = null; 101 } 102 setPackageNameInjector(getWindow().getDecorView(), mPackageNameInjector); 103 } 104 setPackageNameInjector(View node, PackageNameInjector injector)105 private static void setPackageNameInjector(View node, PackageNameInjector injector) { 106 if (node == null) { 107 return; 108 } 109 node.setAccessibilityDelegate(injector); 110 if (node instanceof ViewGroup) { 111 final ViewGroup viewGroup = (ViewGroup) node; 112 final int childCount = viewGroup.getChildCount(); 113 for (int i = 0; i < childCount; i++) { 114 setPackageNameInjector(viewGroup.getChildAt(i), injector); 115 } 116 } 117 } 118 119 private static class PackageNameInjector extends View.AccessibilityDelegate { 120 private final String mPackageName; 121 PackageNameInjector(String packageName)122 PackageNameInjector(String packageName) { 123 mPackageName = packageName; 124 } 125 126 @Override onInitializeAccessibilityEvent(View host, AccessibilityEvent event)127 public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { 128 super.onInitializeAccessibilityEvent(host, event); 129 event.setPackageName(mPackageName); 130 } 131 132 @Override onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info)133 public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { 134 super.onInitializeAccessibilityNodeInfo(host, info); 135 info.setPackageName(mPackageName); 136 } 137 } 138 } 139