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