AppWindowToken.java revision 9ef471f7f2f59de032d7cb9c3c7241486109979e
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 17package com.android.server.wm; 18 19import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; 20 21import com.android.server.input.InputApplicationHandle; 22import com.android.server.wm.WindowManagerService.H; 23 24import android.content.pm.ActivityInfo; 25import android.os.Message; 26import android.os.RemoteException; 27import android.util.Slog; 28import android.view.IApplicationToken; 29import android.view.View; 30import android.view.WindowManager; 31 32import java.io.PrintWriter; 33import java.util.ArrayList; 34 35class 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 */ 42class 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 108 boolean mDeferRemoval; 109 110 AppWindowToken(WindowManagerService _service, IApplicationToken _token) { 111 super(_service, _token.asBinder(), 112 WindowManager.LayoutParams.TYPE_APPLICATION, true); 113 appWindowToken = this; 114 appToken = _token; 115 mInputApplicationHandle = new InputApplicationHandle(this); 116 mAnimator = service.mAnimator; 117 mAppAnimator = new AppWindowAnimator(this); 118 } 119 120 void sendAppVisibilityToClients() { 121 final int N = allAppWindows.size(); 122 for (int i=0; i<N; i++) { 123 WindowState win = allAppWindows.get(i); 124 if (win == startingWindow && clientHidden) { 125 // Don't hide the starting window. 126 continue; 127 } 128 try { 129 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, 130 "Setting visibility of " + win + ": " + (!clientHidden)); 131 win.mClient.dispatchAppVisibility(!clientHidden); 132 } catch (RemoteException e) { 133 } 134 } 135 } 136 137 void updateReportedVisibilityLocked() { 138 if (appToken == null) { 139 return; 140 } 141 142 int numInteresting = 0; 143 int numVisible = 0; 144 int numDrawn = 0; 145 boolean nowGone = true; 146 147 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, 148 "Update reported visibility: " + this); 149 final int N = allAppWindows.size(); 150 for (int i=0; i<N; i++) { 151 WindowState win = allAppWindows.get(i); 152 if (win == startingWindow || win.mAppFreezing 153 || win.mViewVisibility != View.VISIBLE 154 || win.mAttrs.type == TYPE_APPLICATION_STARTING 155 || win.mDestroying) { 156 continue; 157 } 158 if (WindowManagerService.DEBUG_VISIBILITY) { 159 Slog.v(WindowManagerService.TAG, "Win " + win + ": isDrawn=" 160 + win.isDrawnLw() 161 + ", isAnimating=" + win.mWinAnimator.isAnimating()); 162 if (!win.isDrawnLw()) { 163 Slog.v(WindowManagerService.TAG, "Not displayed: s=" + win.mWinAnimator.mSurfaceControl 164 + " pv=" + win.mPolicyVisibility 165 + " mDrawState=" + win.mWinAnimator.mDrawState 166 + " ah=" + win.mAttachedHidden 167 + " th=" 168 + (win.mAppToken != null 169 ? win.mAppToken.hiddenRequested : false) 170 + " a=" + win.mWinAnimator.mAnimating); 171 } 172 } 173 numInteresting++; 174 if (win.isDrawnLw()) { 175 numDrawn++; 176 if (!win.mWinAnimator.isAnimating()) { 177 numVisible++; 178 } 179 nowGone = false; 180 } else if (win.mWinAnimator.isAnimating()) { 181 nowGone = false; 182 } 183 } 184 185 boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting; 186 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting; 187 if (!nowGone) { 188 // If the app is not yet gone, then it can only become visible/drawn. 189 if (!nowDrawn) { 190 nowDrawn = reportedDrawn; 191 } 192 if (!nowVisible) { 193 nowVisible = reportedVisible; 194 } 195 } 196 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "VIS " + this + ": interesting=" 197 + numInteresting + " visible=" + numVisible); 198 if (nowDrawn != reportedDrawn) { 199 if (nowDrawn) { 200 Message m = service.mH.obtainMessage( 201 H.REPORT_APPLICATION_TOKEN_DRAWN, this); 202 service.mH.sendMessage(m); 203 } 204 reportedDrawn = nowDrawn; 205 } 206 if (nowVisible != reportedVisible) { 207 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v( 208 WindowManagerService.TAG, "Visibility changed in " + this 209 + ": vis=" + nowVisible); 210 reportedVisible = nowVisible; 211 Message m = service.mH.obtainMessage( 212 H.REPORT_APPLICATION_TOKEN_WINDOWS, 213 nowVisible ? 1 : 0, 214 nowGone ? 1 : 0, 215 this); 216 service.mH.sendMessage(m); 217 } 218 } 219 220 WindowState findMainWindow() { 221 int j = windows.size(); 222 while (j > 0) { 223 j--; 224 WindowState win = windows.get(j); 225 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION 226 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) { 227 return win; 228 } 229 } 230 return null; 231 } 232 233 boolean isVisible() { 234 final int N = allAppWindows.size(); 235 for (int i=0; i<N; i++) { 236 WindowState win = allAppWindows.get(i); 237 if (!win.mAppFreezing 238 && (win.mViewVisibility == View.VISIBLE || 239 (win.mWinAnimator.isAnimating() && 240 !service.mAppTransition.isTransitionSet())) 241 && !win.mDestroying && win.isDrawnLw()) { 242 return true; 243 } 244 } 245 return false; 246 } 247 248 @Override 249 void dump(PrintWriter pw, String prefix) { 250 super.dump(pw, prefix); 251 if (appToken != null) { 252 pw.print(prefix); pw.println("app=true"); 253 } 254 if (allAppWindows.size() > 0) { 255 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows); 256 } 257 pw.print(prefix); pw.print("groupId="); pw.print(groupId); 258 pw.print(" appFullscreen="); pw.print(appFullscreen); 259 pw.print(" requestedOrientation="); pw.println(requestedOrientation); 260 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested); 261 pw.print(" clientHidden="); pw.print(clientHidden); 262 pw.print(" willBeHidden="); pw.print(willBeHidden); 263 pw.print(" reportedDrawn="); pw.print(reportedDrawn); 264 pw.print(" reportedVisible="); pw.println(reportedVisible); 265 if (paused) { 266 pw.print(prefix); pw.print("paused="); pw.println(paused); 267 } 268 if (numInterestingWindows != 0 || numDrawnWindows != 0 269 || allDrawn || mAppAnimator.allDrawn) { 270 pw.print(prefix); pw.print("numInterestingWindows="); 271 pw.print(numInterestingWindows); 272 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows); 273 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction); 274 pw.print(" allDrawn="); pw.print(allDrawn); 275 pw.print(" (animator="); pw.print(mAppAnimator.allDrawn); 276 pw.println(")"); 277 } 278 if (inPendingTransaction) { 279 pw.print(prefix); pw.print("inPendingTransaction="); 280 pw.println(inPendingTransaction); 281 } 282 if (startingData != null || removed || firstWindowDrawn) { 283 pw.print(prefix); pw.print("startingData="); pw.print(startingData); 284 pw.print(" removed="); pw.print(removed); 285 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn); 286 } 287 if (startingWindow != null || startingView != null 288 || startingDisplayed || startingMoved) { 289 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow); 290 pw.print(" startingView="); pw.print(startingView); 291 pw.print(" startingDisplayed="); pw.print(startingDisplayed); 292 pw.print(" startingMoved"); pw.println(startingMoved); 293 } 294 } 295 296 @Override 297 public String toString() { 298 if (stringName == null) { 299 StringBuilder sb = new StringBuilder(); 300 sb.append("AppWindowToken{"); 301 sb.append(Integer.toHexString(System.identityHashCode(this))); 302 sb.append(" token="); sb.append(token); sb.append('}'); 303 stringName = sb.toString(); 304 } 305 return stringName; 306 } 307} 308