Home | History | Annotate | Download | only in wm
      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 
    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 
    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 
    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 
    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
    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
    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