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