/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import com.android.server.wm.WindowManagerService.H; import android.content.pm.ActivityInfo; import android.graphics.Matrix; import android.os.Message; import android.os.RemoteException; import android.util.Slog; import android.view.IApplicationToken; import android.view.Surface; import android.view.View; import android.view.WindowManager; import android.view.WindowManagerPolicy; import android.view.animation.Animation; import android.view.animation.Transformation; import java.io.PrintWriter; import java.util.ArrayList; /** * Version of WindowToken that is specifically for a particular application (or * really activity) that is displaying windows. */ class AppWindowToken extends WindowToken { // Non-null only for application tokens. final IApplicationToken appToken; // All of the windows and child windows that are included in this // application token. Note this list is NOT sorted! final ArrayList allAppWindows = new ArrayList(); int groupId = -1; boolean appFullscreen; int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; // The input dispatching timeout for this application token in nanoseconds. long inputDispatchingTimeoutNanos; // These are used for determining when all windows associated with // an activity have been drawn, so they can be made visible together // at the same time. // initialize so that it doesn't match mTransactionSequence which is an int. long lastTransactionSequence = Long.MIN_VALUE; int numInterestingWindows; int numDrawnWindows; boolean inPendingTransaction; boolean allDrawn; // Is this token going to be hidden in a little while? If so, it // won't be taken into account for setting the screen orientation. boolean willBeHidden; // Is this window's surface needed? This is almost like hidden, except // it will sometimes be true a little earlier: when the token has // been shown, but is still waiting for its app transition to execute // before making its windows shown. boolean hiddenRequested; // Have we told the window clients to hide themselves? boolean clientHidden; // Last visibility state we reported to the app token. boolean reportedVisible; // Last drawn state we reported to the app token. boolean reportedDrawn; // Set to true when the token has been removed from the window mgr. boolean removed; // Have we been asked to have this token keep the screen frozen? boolean freezingScreen; boolean animating; Animation animation; boolean animInitialized; boolean hasTransformation; final Transformation transformation = new Transformation(); // Offset to the window of all layers in the token, for use by // AppWindowToken animations. int animLayerAdjustment; // Information about an application starting window if displayed. StartingData startingData; WindowState startingWindow; View startingView; boolean startingDisplayed; boolean startingMoved; boolean firstWindowDrawn; // Special surface for thumbnail animation. Surface thumbnail; int thumbnailTransactionSeq; int thumbnailX; int thumbnailY; int thumbnailLayer; Animation thumbnailAnimation; final Transformation thumbnailTransformation = new Transformation(); // Input application handle used by the input dispatcher. final InputApplicationHandle mInputApplicationHandle; AppWindowToken(WindowManagerService _service, IApplicationToken _token) { super(_service, _token.asBinder(), WindowManager.LayoutParams.TYPE_APPLICATION, true); appWindowToken = this; appToken = _token; mInputApplicationHandle = new InputApplicationHandle(this); } public void setAnimation(Animation anim, boolean initialized) { if (WindowManagerService.localLOGV) Slog.v( WindowManagerService.TAG, "Setting animation in " + this + ": " + anim); animation = anim; animating = false; animInitialized = initialized; anim.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION); anim.scaleCurrentDuration(service.mTransitionAnimationScale); int zorder = anim.getZAdjustment(); int adj = 0; if (zorder == Animation.ZORDER_TOP) { adj = WindowManagerService.TYPE_LAYER_OFFSET; } else if (zorder == Animation.ZORDER_BOTTOM) { adj = -WindowManagerService.TYPE_LAYER_OFFSET; } if (animLayerAdjustment != adj) { animLayerAdjustment = adj; updateLayers(); } // Start out animation gone if window is gone, or visible if window is visible. transformation.clear(); transformation.setAlpha(reportedVisible ? 1 : 0); hasTransformation = true; } public void setDummyAnimation() { if (animation == null) { if (WindowManagerService.localLOGV) Slog.v( WindowManagerService.TAG, "Setting dummy animation in " + this); animation = WindowManagerService.sDummyAnimation; animInitialized = false; } } public void clearAnimation() { if (animation != null) { animation = null; animating = true; animInitialized = false; } clearThumbnail(); } public void clearThumbnail() { if (thumbnail != null) { thumbnail.destroy(); thumbnail = null; } } void updateLayers() { final int N = allAppWindows.size(); final int adj = animLayerAdjustment; thumbnailLayer = -1; for (int i=0; i thumbnailLayer) { thumbnailLayer = w.mAnimLayer; } if (WindowManagerService.DEBUG_LAYERS) Slog.v(WindowManagerService.TAG, "Updating layer " + w + ": " + w.mAnimLayer); if (w == service.mInputMethodTarget && !service.mInputMethodTargetWaitingAnim) { service.setInputMethodAnimLayerAdjustment(adj); } if (w == service.mWallpaperTarget && service.mLowerWallpaperTarget == null) { service.setWallpaperAnimLayerAdjustmentLocked(adj); } } } void sendAppVisibilityToClients() { final int N = allAppWindows.size(); for (int i=0; i 0) { pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows); } pw.print(prefix); pw.print("groupId="); pw.print(groupId); pw.print(" appFullscreen="); pw.print(appFullscreen); pw.print(" requestedOrientation="); pw.println(requestedOrientation); pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested); pw.print(" clientHidden="); pw.print(clientHidden); pw.print(" willBeHidden="); pw.print(willBeHidden); pw.print(" reportedDrawn="); pw.print(reportedDrawn); pw.print(" reportedVisible="); pw.println(reportedVisible); if (paused || freezingScreen) { pw.print(prefix); pw.print("paused="); pw.print(paused); pw.print(" freezingScreen="); pw.println(freezingScreen); } if (numInterestingWindows != 0 || numDrawnWindows != 0 || inPendingTransaction || allDrawn) { pw.print(prefix); pw.print("numInterestingWindows="); pw.print(numInterestingWindows); pw.print(" numDrawnWindows="); pw.print(numDrawnWindows); pw.print(" inPendingTransaction="); pw.print(inPendingTransaction); pw.print(" allDrawn="); pw.println(allDrawn); } if (animating || animation != null) { pw.print(prefix); pw.print("animating="); pw.print(animating); pw.print(" animation="); pw.println(animation); } if (hasTransformation) { pw.print(prefix); pw.print("XForm: "); transformation.printShortString(pw); pw.println(); } if (animLayerAdjustment != 0) { pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment); } if (startingData != null || removed || firstWindowDrawn) { pw.print(prefix); pw.print("startingData="); pw.print(startingData); pw.print(" removed="); pw.print(removed); pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn); } if (startingWindow != null || startingView != null || startingDisplayed || startingMoved) { pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow); pw.print(" startingView="); pw.print(startingView); pw.print(" startingDisplayed="); pw.print(startingDisplayed); pw.print(" startingMoved"); pw.println(startingMoved); } if (thumbnail != null) { pw.print(prefix); pw.print("thumbnail="); pw.print(thumbnail); pw.print(" x="); pw.print(thumbnailX); pw.print(" y="); pw.print(thumbnailY); pw.print(" layer="); pw.println(thumbnailLayer); pw.print(prefix); pw.print("thumbnailAnimation="); pw.println(thumbnailAnimation); pw.print(prefix); pw.print("thumbnailTransformation="); pw.println(thumbnailTransformation.toShortString()); } } @Override public String toString() { if (stringName == null) { StringBuilder sb = new StringBuilder(); sb.append("AppWindowToken{"); sb.append(Integer.toHexString(System.identityHashCode(this))); sb.append(" token="); sb.append(token); sb.append('}'); stringName = sb.toString(); } return stringName; } }