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 
     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