1 /*
2  * Copyright (C) 2014 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.view;
18 
19 import android.graphics.Rect;
20 import android.os.IBinder;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.util.Pools;
24 import android.view.accessibility.AccessibilityNodeInfo;
25 
26 import java.util.ArrayList;
27 import java.util.List;
28 
29 /**
30  * This class represents information about a window from the
31  * window manager to another part of the system.
32  *
33  * @hide
34  */
35 public class WindowInfo implements Parcelable {
36     private static final int MAX_POOL_SIZE = 10;
37 
38     private static final Pools.SynchronizedPool<WindowInfo> sPool =
39             new Pools.SynchronizedPool<WindowInfo>(MAX_POOL_SIZE);
40 
41     public int type;
42     public int layer;
43     public IBinder token;
44     public IBinder parentToken;
45     public IBinder activityToken;
46     public boolean focused;
47     public final Rect boundsInScreen = new Rect();
48     public List<IBinder> childTokens;
49     public CharSequence title;
50     public long accessibilityIdOfAnchor = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
51     public boolean inPictureInPicture;
52 
WindowInfo()53     private WindowInfo() {
54         /* do nothing - hide constructor */
55     }
56 
obtain()57     public static WindowInfo obtain() {
58         WindowInfo window = sPool.acquire();
59         if (window == null) {
60             window = new WindowInfo();
61         }
62         return window;
63     }
64 
obtain(WindowInfo other)65     public static WindowInfo obtain(WindowInfo other) {
66         WindowInfo window = obtain();
67         window.type = other.type;
68         window.layer = other.layer;
69         window.token = other.token;
70         window.parentToken = other.parentToken;
71         window.activityToken = other.activityToken;
72         window.focused = other.focused;
73         window.boundsInScreen.set(other.boundsInScreen);
74         window.title = other.title;
75         window.accessibilityIdOfAnchor = other.accessibilityIdOfAnchor;
76         window.inPictureInPicture = other.inPictureInPicture;
77 
78         if (other.childTokens != null && !other.childTokens.isEmpty()) {
79             if (window.childTokens == null) {
80                 window.childTokens = new ArrayList<IBinder>(other.childTokens);
81             } else {
82                 window.childTokens.addAll(other.childTokens);
83             }
84         }
85 
86         return window;
87     }
88 
recycle()89     public void recycle() {
90         clear();
91         sPool.release(this);
92     }
93 
94     @Override
describeContents()95     public int describeContents() {
96         return 0;
97     }
98 
99     @Override
writeToParcel(Parcel parcel, int flags)100     public void writeToParcel(Parcel parcel, int flags) {
101         parcel.writeInt(type);
102         parcel.writeInt(layer);
103         parcel.writeStrongBinder(token);
104         parcel.writeStrongBinder(parentToken);
105         parcel.writeStrongBinder(activityToken);
106         parcel.writeInt(focused ? 1 : 0);
107         boundsInScreen.writeToParcel(parcel, flags);
108         parcel.writeCharSequence(title);
109         parcel.writeLong(accessibilityIdOfAnchor);
110         parcel.writeInt(inPictureInPicture ? 1 : 0);
111 
112         if (childTokens != null && !childTokens.isEmpty()) {
113             parcel.writeInt(1);
114             parcel.writeBinderList(childTokens);
115         } else {
116             parcel.writeInt(0);
117         }
118     }
119 
120     @Override
toString()121     public String toString() {
122         StringBuilder builder = new StringBuilder();
123         builder.append("WindowInfo[");
124         builder.append("title=").append(title);
125         builder.append(", type=").append(type);
126         builder.append(", layer=").append(layer);
127         builder.append(", token=").append(token);
128         builder.append(", bounds=").append(boundsInScreen);
129         builder.append(", parent=").append(parentToken);
130         builder.append(", focused=").append(focused);
131         builder.append(", children=").append(childTokens);
132         builder.append(", accessibility anchor=").append(accessibilityIdOfAnchor);
133         builder.append(']');
134         return builder.toString();
135     }
136 
initFromParcel(Parcel parcel)137     private void initFromParcel(Parcel parcel) {
138         type = parcel.readInt();
139         layer = parcel.readInt();
140         token = parcel.readStrongBinder();
141         parentToken = parcel.readStrongBinder();
142         activityToken = parcel.readStrongBinder();
143         focused = (parcel.readInt() == 1);
144         boundsInScreen.readFromParcel(parcel);
145         title = parcel.readCharSequence();
146         accessibilityIdOfAnchor = parcel.readLong();
147         inPictureInPicture = (parcel.readInt() == 1);
148 
149         final boolean hasChildren = (parcel.readInt() == 1);
150         if (hasChildren) {
151             if (childTokens == null) {
152                 childTokens = new ArrayList<IBinder>();
153             }
154             parcel.readBinderList(childTokens);
155         }
156     }
157 
clear()158     private void clear() {
159         type = 0;
160         layer = 0;
161         token = null;
162         parentToken = null;
163         activityToken = null;
164         focused = false;
165         boundsInScreen.setEmpty();
166         if (childTokens != null) {
167             childTokens.clear();
168         }
169         inPictureInPicture = false;
170     }
171 
172     public static final Parcelable.Creator<WindowInfo> CREATOR =
173             new Creator<WindowInfo>() {
174         @Override
175         public WindowInfo createFromParcel(Parcel parcel) {
176             WindowInfo window = obtain();
177             window.initFromParcel(parcel);
178             return window;
179         }
180 
181         @Override
182         public WindowInfo[] newArray(int size) {
183             return new WindowInfo[size];
184         }
185     };
186 }
187