blob: 25153fc5e24f70ae1227305254b590381a9f4390 [file] [log] [blame]
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -08001/*
2 * Copyright (C) 2015 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
17package android.app;
18
Dianne Hackbornae6688b2015-02-11 17:02:41 -080019import android.content.ComponentName;
Dianne Hackborna83ce1d2015-03-11 15:16:13 -070020import android.graphics.Paint;
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -080021import android.graphics.Rect;
Dianne Hackborna83ce1d2015-03-11 15:16:13 -070022import android.graphics.Typeface;
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -080023import android.os.Bundle;
24import android.os.Parcel;
25import android.os.Parcelable;
Dianne Hackborna83ce1d2015-03-11 15:16:13 -070026import android.os.PooledStringReader;
27import android.os.PooledStringWriter;
28import android.text.TextPaint;
29import android.text.TextUtils;
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -080030import android.util.Log;
31import android.view.View;
Dianne Hackborna83ce1d2015-03-11 15:16:13 -070032import android.view.ViewAssistStructure;
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -080033import android.view.ViewGroup;
34import android.view.ViewRootImpl;
35import android.view.WindowManagerGlobal;
36import android.widget.Checkable;
37
38import java.util.ArrayList;
39
40/**
41 * Assist data automatically created by the platform's implementation
42 * of {@link Activity#onProvideAssistData}. Retrieve it from the assist
Dianne Hackborna83ce1d2015-03-11 15:16:13 -070043 * data with {@link #getAssistStructure(android.os.Bundle)}.
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -080044 */
Dianne Hackborna83ce1d2015-03-11 15:16:13 -070045final public class AssistStructure implements Parcelable {
46 static final String TAG = "AssistStructure";
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -080047
48 /**
49 * Key name this data structure is stored in the Bundle generated by
50 * {@link Activity#onProvideAssistData}.
51 */
Dianne Hackborna83ce1d2015-03-11 15:16:13 -070052 public static final String ASSIST_KEY = "android:assist_structure";
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -080053
Dianne Hackbornae6688b2015-02-11 17:02:41 -080054 final ComponentName mActivityComponent;
55
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -080056 final ArrayList<ViewNodeImpl> mRootViews = new ArrayList<>();
57
Dianne Hackborna83ce1d2015-03-11 15:16:13 -070058 ViewAssistStructureImpl mTmpViewAssistStructureImpl = new ViewAssistStructureImpl();
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -080059 Bundle mTmpExtras = new Bundle();
60
Dianne Hackborna83ce1d2015-03-11 15:16:13 -070061 final static class ViewAssistStructureImpl extends ViewAssistStructure {
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -080062 CharSequence mText;
63 int mTextSelectionStart = -1;
64 int mTextSelectionEnd = -1;
Dianne Hackborna83ce1d2015-03-11 15:16:13 -070065 int mTextColor = ViewNode.TEXT_COLOR_UNDEFINED;
66 int mTextBackgroundColor = ViewNode.TEXT_COLOR_UNDEFINED;
67 float mTextSize = 0;
68 int mTextStyle = 0;
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -080069 CharSequence mHint;
70
71 @Override
72 public void setText(CharSequence text) {
73 mText = text;
74 mTextSelectionStart = mTextSelectionEnd = -1;
75 }
76
77 @Override
78 public void setText(CharSequence text, int selectionStart, int selectionEnd) {
79 mText = text;
80 mTextSelectionStart = selectionStart;
81 mTextSelectionEnd = selectionEnd;
82 }
83
84 @Override
Dianne Hackborna83ce1d2015-03-11 15:16:13 -070085 public void setTextPaint(TextPaint paint) {
86 mTextColor = paint.getColor();
87 mTextBackgroundColor = paint.bgColor;
88 mTextSize = paint.getTextSize();
89 mTextStyle = 0;
90 Typeface tf = paint.getTypeface();
91 if (tf != null) {
92 if (tf.isBold()) {
93 mTextStyle |= ViewNode.TEXT_STYLE_BOLD;
94 }
95 if (tf.isItalic()) {
96 mTextStyle |= ViewNode.TEXT_STYLE_ITALIC;
97 }
98 }
99 int pflags = paint.getFlags();
100 if ((pflags& Paint.FAKE_BOLD_TEXT_FLAG) != 0) {
101 mTextStyle |= ViewNode.TEXT_STYLE_BOLD;
102 }
103 if ((pflags& Paint.UNDERLINE_TEXT_FLAG) != 0) {
104 mTextStyle |= ViewNode.TEXT_STYLE_UNDERLINE;
105 }
106 if ((pflags& Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
107 mTextStyle |= ViewNode.TEXT_STYLE_STRIKE_THRU;
108 }
109 }
110
111 @Override
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800112 public void setHint(CharSequence hint) {
113 mHint = hint;
114 }
115
116 @Override
117 public CharSequence getText() {
118 return mText;
119 }
120
121 @Override
122 public int getTextSelectionStart() {
123 return mTextSelectionStart;
124 }
125
126 @Override
127 public int getTextSelectionEnd() {
128 return mTextSelectionEnd;
129 }
130
131 @Override
132 public CharSequence getHint() {
133 return mHint;
134 }
135 }
136
137 final static class ViewNodeTextImpl {
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700138 final CharSequence mText;
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800139 final int mTextSelectionStart;
140 final int mTextSelectionEnd;
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700141 int mTextColor;
142 int mTextBackgroundColor;
143 float mTextSize;
144 int mTextStyle;
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800145 final String mHint;
146
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700147 ViewNodeTextImpl(ViewAssistStructureImpl data) {
148 mText = data.mText;
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800149 mTextSelectionStart = data.mTextSelectionStart;
150 mTextSelectionEnd = data.mTextSelectionEnd;
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700151 mTextColor = data.mTextColor;
152 mTextBackgroundColor = data.mTextBackgroundColor;
153 mTextSize = data.mTextSize;
154 mTextStyle = data.mTextStyle;
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800155 mHint = data.mHint != null ? data.mHint.toString() : null;
156 }
157
158 ViewNodeTextImpl(Parcel in) {
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700159 mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800160 mTextSelectionStart = in.readInt();
161 mTextSelectionEnd = in.readInt();
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700162 mTextColor = in.readInt();
163 mTextBackgroundColor = in.readInt();
164 mTextSize = in.readFloat();
165 mTextStyle = in.readInt();
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800166 mHint = in.readString();
167 }
168
169 void writeToParcel(Parcel out) {
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700170 TextUtils.writeToParcel(mText, out, 0);
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800171 out.writeInt(mTextSelectionStart);
172 out.writeInt(mTextSelectionEnd);
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700173 out.writeInt(mTextColor);
174 out.writeInt(mTextBackgroundColor);
175 out.writeFloat(mTextSize);
176 out.writeInt(mTextStyle);
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800177 out.writeString(mHint);
178 }
179 }
180
181 final static class ViewNodeImpl {
182 final int mX;
183 final int mY;
184 final int mScrollX;
185 final int mScrollY;
186 final int mWidth;
187 final int mHeight;
188
189 static final int FLAGS_DISABLED = 0x00000001;
190 static final int FLAGS_VISIBILITY_MASK = View.VISIBLE|View.INVISIBLE|View.GONE;
191 static final int FLAGS_FOCUSABLE = 0x00000010;
192 static final int FLAGS_FOCUSED = 0x00000020;
193 static final int FLAGS_ACCESSIBILITY_FOCUSED = 0x04000000;
194 static final int FLAGS_SELECTED = 0x00000040;
195 static final int FLAGS_ACTIVATED = 0x40000000;
196 static final int FLAGS_CHECKABLE = 0x00000100;
197 static final int FLAGS_CHECKED = 0x00000200;
198 static final int FLAGS_CLICKABLE = 0x00004000;
199 static final int FLAGS_LONG_CLICKABLE = 0x00200000;
200
201 final int mFlags;
202
203 final String mClassName;
204 final String mContentDescription;
205
206 final ViewNodeTextImpl mText;
207 final Bundle mExtras;
208
209 final ViewNodeImpl[] mChildren;
210
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700211 ViewNodeImpl(AssistStructure assistStructure, View view, int left, int top,
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800212 CharSequence contentDescription) {
213 mX = left;
214 mY = top;
215 mScrollX = view.getScrollX();
216 mScrollY = view.getScrollY();
217 mWidth = view.getWidth();
218 mHeight = view.getHeight();
219 int flags = view.getVisibility();
220 if (!view.isEnabled()) {
221 flags |= FLAGS_DISABLED;
222 }
223 if (!view.isClickable()) {
224 flags |= FLAGS_CLICKABLE;
225 }
226 if (!view.isFocusable()) {
227 flags |= FLAGS_FOCUSABLE;
228 }
229 if (!view.isFocused()) {
230 flags |= FLAGS_FOCUSED;
231 }
232 if (!view.isAccessibilityFocused()) {
233 flags |= FLAGS_ACCESSIBILITY_FOCUSED;
234 }
235 if (!view.isSelected()) {
236 flags |= FLAGS_SELECTED;
237 }
238 if (!view.isActivated()) {
239 flags |= FLAGS_ACTIVATED;
240 }
241 if (!view.isLongClickable()) {
242 flags |= FLAGS_LONG_CLICKABLE;
243 }
244 if (view instanceof Checkable) {
245 flags |= FLAGS_CHECKABLE;
246 if (((Checkable)view).isChecked()) {
247 flags |= FLAGS_CHECKED;
248 }
249 }
250 mFlags = flags;
251 mClassName = view.getAccessibilityClassName().toString();
252 mContentDescription = contentDescription != null ? contentDescription.toString() : null;
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700253 final ViewAssistStructureImpl viewData = assistStructure.mTmpViewAssistStructureImpl;
254 final Bundle extras = assistStructure.mTmpExtras;
255 view.onProvideAssistStructure(viewData, extras);
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800256 if (viewData.mText != null || viewData.mHint != null) {
257 mText = new ViewNodeTextImpl(viewData);
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700258 assistStructure.mTmpViewAssistStructureImpl = new ViewAssistStructureImpl();
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800259 } else {
260 mText = null;
261 }
262 if (!extras.isEmpty()) {
263 mExtras = extras;
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700264 assistStructure.mTmpExtras = new Bundle();
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800265 } else {
266 mExtras = null;
267 }
268 if (view instanceof ViewGroup) {
269 ViewGroup vg = (ViewGroup)view;
270 final int NCHILDREN = vg.getChildCount();
271 if (NCHILDREN > 0) {
272 mChildren = new ViewNodeImpl[NCHILDREN];
273 for (int i=0; i<NCHILDREN; i++) {
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700274 mChildren[i] = new ViewNodeImpl(assistStructure, vg.getChildAt(i));
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800275 }
276 } else {
277 mChildren = null;
278 }
279 } else {
280 mChildren = null;
281 }
282 }
283
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700284 ViewNodeImpl(AssistStructure assistStructure, View view) {
285 this(assistStructure, view, view.getLeft(), view.getTop(), view.getContentDescription());
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800286 }
287
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700288 ViewNodeImpl(Parcel in, PooledStringReader preader) {
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800289 mX = in.readInt();
290 mY = in.readInt();
291 mScrollX = in.readInt();
292 mScrollY = in.readInt();
293 mWidth = in.readInt();
294 mHeight = in.readInt();
295 mFlags = in.readInt();
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700296 mClassName = preader.readString();
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800297 mContentDescription = in.readString();
298 if (in.readInt() != 0) {
299 mText = new ViewNodeTextImpl(in);
300 } else {
301 mText = null;
302 }
303 mExtras = in.readBundle();
304 final int NCHILDREN = in.readInt();
305 if (NCHILDREN > 0) {
306 mChildren = new ViewNodeImpl[NCHILDREN];
307 for (int i=0; i<NCHILDREN; i++) {
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700308 mChildren[i] = new ViewNodeImpl(in, preader);
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800309 }
310 } else {
311 mChildren = null;
312 }
313 }
314
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700315 void writeToParcel(Parcel out, PooledStringWriter pwriter) {
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800316 out.writeInt(mX);
317 out.writeInt(mY);
318 out.writeInt(mScrollX);
319 out.writeInt(mScrollY);
320 out.writeInt(mWidth);
321 out.writeInt(mHeight);
322 out.writeInt(mFlags);
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700323 pwriter.writeString(mClassName);
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800324 out.writeString(mContentDescription);
325 if (mText != null) {
326 out.writeInt(1);
327 mText.writeToParcel(out);
328 } else {
329 out.writeInt(0);
330 }
331 out.writeBundle(mExtras);
332 if (mChildren != null) {
333 final int NCHILDREN = mChildren.length;
334 out.writeInt(NCHILDREN);
335 for (int i=0; i<NCHILDREN; i++) {
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700336 mChildren[i].writeToParcel(out, pwriter);
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800337 }
338 } else {
339 out.writeInt(0);
340 }
341 }
342 }
343
344 /**
345 * Provides access to information about a single view in the assist data.
346 */
347 static public class ViewNode {
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700348 /**
349 * Magic value for text color that has not been defined, which is very unlikely
350 * to be confused with a real text color.
351 */
352 public static final int TEXT_COLOR_UNDEFINED = 1;
353
354 public static final int TEXT_STYLE_BOLD = 1<<0;
355 public static final int TEXT_STYLE_ITALIC = 1<<1;
356 public static final int TEXT_STYLE_UNDERLINE = 1<<2;
357 public static final int TEXT_STYLE_STRIKE_THRU = 1<<3;
358
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800359 ViewNodeImpl mImpl;
360
361 public ViewNode() {
362 }
363
364 public int getLeft() {
365 return mImpl.mX;
366 }
367
368 public int getTop() {
369 return mImpl.mY;
370 }
371
372 public int getScrollX() {
373 return mImpl.mScrollX;
374 }
375
376 public int getScrollY() {
377 return mImpl.mScrollY;
378 }
379
380 public int getWidth() {
381 return mImpl.mWidth;
382 }
383
384 public int getHeight() {
385 return mImpl.mHeight;
386 }
387
388 public int getVisibility() {
389 return mImpl.mFlags&ViewNodeImpl.FLAGS_VISIBILITY_MASK;
390 }
391
392 public boolean isEnabled() {
393 return (mImpl.mFlags&ViewNodeImpl.FLAGS_DISABLED) == 0;
394 }
395
396 public boolean isClickable() {
397 return (mImpl.mFlags&ViewNodeImpl.FLAGS_CLICKABLE) != 0;
398 }
399
400 public boolean isFocusable() {
401 return (mImpl.mFlags&ViewNodeImpl.FLAGS_FOCUSABLE) != 0;
402 }
403
404 public boolean isFocused() {
405 return (mImpl.mFlags&ViewNodeImpl.FLAGS_FOCUSED) != 0;
406 }
407
408 public boolean isAccessibilityFocused() {
409 return (mImpl.mFlags&ViewNodeImpl.FLAGS_ACCESSIBILITY_FOCUSED) != 0;
410 }
411
412 public boolean isCheckable() {
413 return (mImpl.mFlags&ViewNodeImpl.FLAGS_CHECKABLE) != 0;
414 }
415
416 public boolean isChecked() {
417 return (mImpl.mFlags&ViewNodeImpl.FLAGS_CHECKED) != 0;
418 }
419
420 public boolean isSelected() {
421 return (mImpl.mFlags&ViewNodeImpl.FLAGS_SELECTED) != 0;
422 }
423
424 public boolean isActivated() {
425 return (mImpl.mFlags&ViewNodeImpl.FLAGS_ACTIVATED) != 0;
426 }
427
428 public boolean isLongClickable() {
429 return (mImpl.mFlags&ViewNodeImpl.FLAGS_LONG_CLICKABLE) != 0;
430 }
431
432 public String getClassName() {
433 return mImpl.mClassName;
434 }
435
436 public String getContentDescription() {
437 return mImpl.mContentDescription;
438 }
439
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700440 public CharSequence getText() {
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800441 return mImpl.mText != null ? mImpl.mText.mText : null;
442 }
443
444 public int getTextSelectionStart() {
445 return mImpl.mText != null ? mImpl.mText.mTextSelectionStart : -1;
446 }
447
448 public int getTextSelectionEnd() {
449 return mImpl.mText != null ? mImpl.mText.mTextSelectionEnd : -1;
450 }
451
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700452 public int getTextColor() {
453 return mImpl.mText != null ? mImpl.mText.mTextColor : TEXT_COLOR_UNDEFINED;
454 }
455
456 public int getTextBackgroundColor() {
457 return mImpl.mText != null ? mImpl.mText.mTextBackgroundColor : TEXT_COLOR_UNDEFINED;
458 }
459
460 public float getTextSize() {
461 return mImpl.mText != null ? mImpl.mText.mTextSize : 0;
462 }
463
464 public int getTextStyle() {
465 return mImpl.mText != null ? mImpl.mText.mTextStyle : 0;
466 }
467
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800468 public String getHint() {
469 return mImpl.mText != null ? mImpl.mText.mHint : null;
470 }
471
472 public Bundle getExtras() {
473 return mImpl.mExtras;
474 }
475
476 public int getChildCount() {
477 return mImpl.mChildren != null ? mImpl.mChildren.length : 0;
478 }
479
480 public void getChildAt(int index, ViewNode outNode) {
481 outNode.mImpl = mImpl.mChildren[index];
482 }
483 }
484
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700485 AssistStructure(Activity activity) {
Dianne Hackbornae6688b2015-02-11 17:02:41 -0800486 mActivityComponent = activity.getComponentName();
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800487 ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
488 activity.getActivityToken());
489 for (int i=0; i<views.size(); i++) {
490 ViewRootImpl root = views.get(i);
491 View view = root.getView();
492 Rect rect = new Rect();
493 view.getBoundsOnScreen(rect);
494 CharSequence title = root.getTitle();
495 mRootViews.add(new ViewNodeImpl(this, view, rect.left, rect.top,
496 title != null ? title : view.getContentDescription()));
497 }
498 }
499
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700500 AssistStructure(Parcel in) {
501 PooledStringReader preader = new PooledStringReader(in);
Dianne Hackbornae6688b2015-02-11 17:02:41 -0800502 mActivityComponent = ComponentName.readFromParcel(in);
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800503 final int N = in.readInt();
504 for (int i=0; i<N; i++) {
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700505 mRootViews.add(new ViewNodeImpl(in, preader));
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800506 }
507 //dump();
508 }
509
Dianne Hackbornae6688b2015-02-11 17:02:41 -0800510 /** @hide */
511 public void dump() {
512 Log.i(TAG, "Activity: " + mActivityComponent.flattenToShortString());
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800513 ViewNode node = new ViewNode();
514 final int N = getWindowCount();
515 for (int i=0; i<N; i++) {
516 Log.i(TAG, "Window #" + i + ":");
517 getWindowAt(i, node);
518 dump(" ", node);
519 }
520 }
521
522 void dump(String prefix, ViewNode node) {
523 Log.i(TAG, prefix + "View [" + node.getLeft() + "," + node.getTop()
524 + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getClassName());
525 int scrollX = node.getScrollX();
526 int scrollY = node.getScrollY();
527 if (scrollX != 0 || scrollY != 0) {
528 Log.i(TAG, prefix + " Scroll: " + scrollX + "," + scrollY);
529 }
530 String contentDescription = node.getContentDescription();
531 if (contentDescription != null) {
532 Log.i(TAG, prefix + " Content description: " + contentDescription);
533 }
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700534 CharSequence text = node.getText();
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800535 if (text != null) {
Dianne Hackbornae6688b2015-02-11 17:02:41 -0800536 Log.i(TAG, prefix + " Text (sel " + node.getTextSelectionStart() + "-"
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800537 + node.getTextSelectionEnd() + "): " + text);
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700538 Log.i(TAG, prefix + " Text size: " + node.getTextSize() + " , style: #"
539 + node.getTextStyle());
540 Log.i(TAG, prefix + " Text color fg: #" + Integer.toHexString(node.getTextColor())
541 + ", bg: #" + Integer.toHexString(node.getTextBackgroundColor()));
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800542 }
543 String hint = node.getHint();
544 if (hint != null) {
545 Log.i(TAG, prefix + " Hint: " + hint);
546 }
547 Bundle extras = node.getExtras();
548 if (extras != null) {
549 Log.i(TAG, prefix + " Extras: " + extras);
550 }
551 final int NCHILDREN = node.getChildCount();
552 if (NCHILDREN > 0) {
553 Log.i(TAG, prefix + " Children:");
554 String cprefix = prefix + " ";
555 ViewNode cnode = new ViewNode();
556 for (int i=0; i<NCHILDREN; i++) {
557 node.getChildAt(i, cnode);
558 dump(cprefix, cnode);
559 }
560 }
561 }
562
563 /**
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700564 * Retrieve the framework-generated AssistStructure that is stored within
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800565 * the Bundle filled in by {@link Activity#onProvideAssistData}.
566 */
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700567 public static AssistStructure getAssistStructure(Bundle assistBundle) {
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800568 return assistBundle.getParcelable(ASSIST_KEY);
569 }
570
Dianne Hackbornae6688b2015-02-11 17:02:41 -0800571 public ComponentName getActivityComponent() {
572 return mActivityComponent;
573 }
574
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800575 /**
576 * Return the number of window contents that have been collected in this assist data.
577 */
578 public int getWindowCount() {
579 return mRootViews.size();
580 }
581
582 /**
583 * Return the root view for one of the windows in the assist data.
584 * @param index Which window to retrieve, may be 0 to {@link #getWindowCount()}-1.
585 * @param outNode Node in which to place the window's root view.
586 */
587 public void getWindowAt(int index, ViewNode outNode) {
588 outNode.mImpl = mRootViews.get(index);
589 }
590
591 public int describeContents() {
592 return 0;
593 }
594
595 public void writeToParcel(Parcel out, int flags) {
596 int start = out.dataPosition();
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700597 PooledStringWriter pwriter = new PooledStringWriter(out);
Dianne Hackbornae6688b2015-02-11 17:02:41 -0800598 ComponentName.writeToParcel(mActivityComponent, out);
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800599 final int N = mRootViews.size();
600 out.writeInt(N);
601 for (int i=0; i<N; i++) {
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700602 mRootViews.get(i).writeToParcel(out, pwriter);
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800603 }
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700604 pwriter.finish();
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800605 Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes");
606 }
607
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700608 public static final Parcelable.Creator<AssistStructure> CREATOR
609 = new Parcelable.Creator<AssistStructure>() {
610 public AssistStructure createFromParcel(Parcel in) {
611 return new AssistStructure(in);
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800612 }
613
Dianne Hackborna83ce1d2015-03-11 15:16:13 -0700614 public AssistStructure[] newArray(int size) {
615 return new AssistStructure[size];
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800616 }
617 };
618}