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