AssistVisualizer.java revision a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9d
1ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn/* 2ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * Copyright (C) 2015 The Android Open Source Project 3ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * 4ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * you may not use this file except in compliance with the License. 6ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * You may obtain a copy of the License at 7ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * 8ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * 10ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 11ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * See the License for the specific language governing permissions and 14ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn * limitations under the License. 15ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn */ 16ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 17ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornpackage com.android.test.voiceinteraction; 18ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 19ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.annotation.Nullable; 20a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9dDianne Hackbornimport android.app.AssistStructure; 21ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.content.Context; 22ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.graphics.Canvas; 23ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.graphics.Paint; 24ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.graphics.Rect; 25ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.util.AttributeSet; 26ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.util.Log; 27ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport android.view.View; 28ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 29ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornimport java.util.ArrayList; 30ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 31ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackbornpublic class AssistVisualizer extends View { 32ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn static final String TAG = "AssistVisualizer"; 33ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 34a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9dDianne Hackborn AssistStructure mAssistStructure; 35ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn final Paint mFramePaint = new Paint(); 36ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn final ArrayList<Rect> mTextRects = new ArrayList<>(); 37ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn final int[] mTmpLocation = new int[2]; 38ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 39ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn public AssistVisualizer(Context context, @Nullable AttributeSet attrs) { 40ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn super(context, attrs); 41ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn setWillNotDraw(false); 42ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn mFramePaint.setColor(0xffff0000); 43ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn mFramePaint.setStyle(Paint.Style.STROKE); 44ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn mFramePaint.setStrokeWidth(0); 45ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 46ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 47a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9dDianne Hackborn public void setAssistStructure(AssistStructure as) { 48a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9dDianne Hackborn mAssistStructure = as; 49ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn mTextRects.clear(); 50a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9dDianne Hackborn final int N = as.getWindowCount(); 51ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn if (N > 0) { 52a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9dDianne Hackborn AssistStructure.ViewNode window = new AssistStructure.ViewNode(); 53ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn for (int i=0; i<N; i++) { 54a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9dDianne Hackborn as.getWindowAt(i, window); 55ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn buildTextRects(window, 0, 0); 56ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 57ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 58ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 59ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 60ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn public void clearAssistData() { 61a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9dDianne Hackborn mAssistStructure = null; 62ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn mTextRects.clear(); 63ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn } 64ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn 65a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9dDianne Hackborn void buildTextRects(AssistStructure.ViewNode root, int parentLeft, int parentTop) { 66ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn if (root.getVisibility() != View.VISIBLE) { 67ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn return; 68ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 69ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn int left = parentLeft+root.getLeft(); 70ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn int top = parentTop+root.getTop(); 71ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn Log.d(TAG, "View " + root.getClassName() + ": " + left + ", " + top); 72ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn if (root.getText() != null) { 73ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn Rect r = new Rect(left, top, left+root.getWidth(), top+root.getHeight()); 74ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn Log.d(TAG, "Text Rect " + r.toShortString() + ": " + root.getText()); 75ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn mTextRects.add(r); 76ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 77ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn final int N = root.getChildCount(); 78ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn if (N > 0) { 79ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn left -= root.getScrollX(); 80ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn top -= root.getScrollY(); 81a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9dDianne Hackborn AssistStructure.ViewNode child = new AssistStructure.ViewNode(); 82ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn for (int i=0; i<N; i++) { 83ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn root.getChildAt(i, child); 84ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn buildTextRects(child, left, top); 85ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 86ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 87ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 88ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn 89ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn @Override 90ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn protected void onDraw(Canvas canvas) { 91ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn super.onDraw(canvas); 92ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn getLocationOnScreen(mTmpLocation); 93ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn final int N = mTextRects.size(); 94ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn for (int i=0; i<N; i++) { 95ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn Rect r = mTextRects.get(i); 96ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn canvas.drawRect(r.left-mTmpLocation[0], r.top-mTmpLocation[1], 97ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn r.right-mTmpLocation[0], r.bottom-mTmpLocation[1], mFramePaint); 98ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 99ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn } 100ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn} 101