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