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