• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 com.android.server.wm;
18 
19 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
20 
21 import com.android.server.input.InputApplicationHandle;
22 import com.android.server.wm.WindowManagerService.H;
23 
24 import android.content.pm.ActivityInfo;
25 import android.os.Message;
26 import android.os.RemoteException;
27 import android.util.Slog;
28 import android.view.IApplicationToken;
29 import android.view.View;
30 import android.view.WindowManager;
31 
32 import java.io.PrintWriter;
33 import java.util.ArrayList;
34 
35 /**
36  * Version of WindowToken that is specifically for a particular application (or
37  * really activity) that is displaying windows.
38  */
39 class AppWindowToken extends WindowToken {
40     // Non-null only for application tokens.
41     final IApplicationToken appToken;
42 
43     // All of the windows and child windows that are included in this
44     // application token.  Note this list is NOT sorted!
45     final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
46     final AppWindowAnimator mAppAnimator;
47 
48     final WindowAnimator mAnimator;
49 
50     int groupId = -1;
51     boolean appFullscreen;
52     int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
53 
54     // The input dispatching timeout for this application token in nanoseconds.
55     long inputDispatchingTimeoutNanos;
56 
57     // These are used for determining when all windows associated with
58     // an activity have been drawn, so they can be made visible together
59     // at the same time.
60     // initialize so that it doesn't match mTransactionSequence which is an int.
61     long lastTransactionSequence = Long.MIN_VALUE;
62     int numInterestingWindows;
63     int numDrawnWindows;
64     boolean inPendingTransaction;
65     boolean allDrawn;
66 
67     // Is this token going to be hidden in a little while?  If so, it
68     // won't be taken into account for setting the screen orientation.
69     boolean willBeHidden;
70 
71     // Is this window's surface needed?  This is almost like hidden, except
72     // it will sometimes be true a little earlier: when the token has
73     // been shown, but is still waiting for its app transition to execute
74     // before making its windows shown.
75     boolean hiddenRequested;
76 
77     // Have we told the window clients to hide themselves?
78     boolean clientHidden;
79 
80     // Last visibility state we reported to the app token.
81     boolean reportedVisible;
82 
83     // Last drawn state we reported to the app token.
84     boolean reportedDrawn;
85 
86     // Set to true when the token has been removed from the window mgr.
87     boolean removed;
88 
89     // Information about an application starting window if displayed.
90     StartingData startingData;
91     WindowState startingWindow;
92     View startingView;
93     boolean startingDisplayed;
94     boolean startingMoved;
95     boolean firstWindowDrawn;
96 
97     // Input application handle used by the input dispatcher.
98     final InputApplicationHandle mInputApplicationHandle;
99 
AppWindowToken(WindowManagerService _service, IApplicationToken _token)100     AppWindowToken(WindowManagerService _service, IApplicationToken _token) {
101         super(_service, _token.asBinder(),
102                 WindowManager.LayoutParams.TYPE_APPLICATION, true);
103         appWindowToken = this;
104         appToken = _token;
105         mInputApplicationHandle = new InputApplicationHandle(this);
106         mAnimator = service.mAnimator;
107         mAppAnimator = new AppWindowAnimator(_service, this);
108     }
109 
sendAppVisibilityToClients()110     void sendAppVisibilityToClients() {
111         final int N = allAppWindows.size();
112         for (int i=0; i<N; i++) {
113             WindowState win = allAppWindows.get(i);
114             if (win == startingWindow && clientHidden) {
115                 // Don't hide the starting window.
116                 continue;
117             }
118             try {
119                 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG,
120                         "Setting visibility of " + win + ": " + (!clientHidden));
121                 win.mClient.dispatchAppVisibility(!clientHidden);
122             } catch (RemoteException e) {
123             }
124         }
125     }
126 
updateReportedVisibilityLocked()127     void updateReportedVisibilityLocked() {
128         if (appToken == null) {
129             return;
130         }
131 
132         int numInteresting = 0;
133         int numVisible = 0;
134         int numDrawn = 0;
135         boolean nowGone = true;
136 
137         if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG,
138                 "Update reported visibility: " + this);
139         final int N = allAppWindows.size();
140         for (int i=0; i<N; i++) {
141             WindowState win = allAppWindows.get(i);
142             if (win == startingWindow || win.mAppFreezing
143                     || win.mViewVisibility != View.VISIBLE
144                     || win.mAttrs.type == TYPE_APPLICATION_STARTING
145                     || win.mDestroying) {
146                 continue;
147             }
148             if (WindowManagerService.DEBUG_VISIBILITY) {
149                 Slog.v(WindowManagerService.TAG, "Win " + win + ": isDrawn="
150                         + win.isDrawnLw()
151                         + ", isAnimating=" + win.mWinAnimator.isAnimating());
152                 if (!win.isDrawnLw()) {
153                     Slog.v(WindowManagerService.TAG, "Not displayed: s=" + win.mWinAnimator.mSurface
154                             + " pv=" + win.mPolicyVisibility
155                             + " mDrawState=" + win.mWinAnimator.mDrawState
156                             + " ah=" + win.mAttachedHidden
157                             + " th="
158                             + (win.mAppToken != null
159                                     ? win.mAppToken.hiddenRequested : false)
160                             + " a=" + win.mWinAnimator.mAnimating);
161                 }
162             }
163             numInteresting++;
164             if (win.isDrawnLw()) {
165                 numDrawn++;
166                 if (!win.mWinAnimator.isAnimating()) {
167                     numVisible++;
168                 }
169                 nowGone = false;
170             } else if (win.mWinAnimator.isAnimating()) {
171                 nowGone = false;
172             }
173         }
174 
175         boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
176         boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
177         if (!nowGone) {
178             // If the app is not yet gone, then it can only become visible/drawn.
179             if (!nowDrawn) {
180                 nowDrawn = reportedDrawn;
181             }
182             if (!nowVisible) {
183                 nowVisible = reportedVisible;
184             }
185         }
186         if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "VIS " + this + ": interesting="
187                 + numInteresting + " visible=" + numVisible);
188         if (nowDrawn != reportedDrawn) {
189             if (nowDrawn) {
190                 Message m = service.mH.obtainMessage(
191                         H.REPORT_APPLICATION_TOKEN_DRAWN, this);
192                 service.mH.sendMessage(m);
193             }
194             reportedDrawn = nowDrawn;
195         }
196         if (nowVisible != reportedVisible) {
197             if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(
198                     WindowManagerService.TAG, "Visibility changed in " + this
199                     + ": vis=" + nowVisible);
200             reportedVisible = nowVisible;
201             Message m = service.mH.obtainMessage(
202                     H.REPORT_APPLICATION_TOKEN_WINDOWS,
203                     nowVisible ? 1 : 0,
204                     nowGone ? 1 : 0,
205                     this);
206             service.mH.sendMessage(m);
207         }
208     }
209 
findMainWindow()210     WindowState findMainWindow() {
211         int j = windows.size();
212         while (j > 0) {
213             j--;
214             WindowState win = windows.get(j);
215             if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
216                     || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
217                 return win;
218             }
219         }
220         return null;
221     }
222 
223     @Override
dump(PrintWriter pw, String prefix)224     void dump(PrintWriter pw, String prefix) {
225         super.dump(pw, prefix);
226         if (appToken != null) {
227             pw.print(prefix); pw.println("app=true");
228         }
229         if (allAppWindows.size() > 0) {
230             pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
231         }
232         pw.print(prefix); pw.print("groupId="); pw.print(groupId);
233                 pw.print(" appFullscreen="); pw.print(appFullscreen);
234                 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
235         pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
236                 pw.print(" clientHidden="); pw.print(clientHidden);
237                 pw.print(" willBeHidden="); pw.print(willBeHidden);
238                 pw.print(" reportedDrawn="); pw.print(reportedDrawn);
239                 pw.print(" reportedVisible="); pw.println(reportedVisible);
240         if (paused) {
241             pw.print(prefix); pw.print("paused="); pw.println(paused);
242         }
243         if (numInterestingWindows != 0 || numDrawnWindows != 0
244                 || allDrawn || mAppAnimator.allDrawn) {
245             pw.print(prefix); pw.print("numInterestingWindows=");
246                     pw.print(numInterestingWindows);
247                     pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
248                     pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
249                     pw.print(" allDrawn="); pw.print(allDrawn);
250                     pw.print(" (animator="); pw.print(mAppAnimator.allDrawn);
251                     pw.println(")");
252         }
253         if (inPendingTransaction) {
254             pw.print(prefix); pw.print("inPendingTransaction=");
255                     pw.println(inPendingTransaction);
256         }
257         if (startingData != null || removed || firstWindowDrawn) {
258             pw.print(prefix); pw.print("startingData="); pw.print(startingData);
259                     pw.print(" removed="); pw.print(removed);
260                     pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
261         }
262         if (startingWindow != null || startingView != null
263                 || startingDisplayed || startingMoved) {
264             pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
265                     pw.print(" startingView="); pw.print(startingView);
266                     pw.print(" startingDisplayed="); pw.print(startingDisplayed);
267                     pw.print(" startingMoved"); pw.println(startingMoved);
268         }
269     }
270 
271     @Override
toString()272     public String toString() {
273         if (stringName == null) {
274             StringBuilder sb = new StringBuilder();
275             sb.append("AppWindowToken{");
276             sb.append(Integer.toHexString(System.identityHashCode(this)));
277             sb.append(" token="); sb.append(token); sb.append('}');
278             stringName = sb.toString();
279         }
280         return stringName;
281     }
282 }
283