public void onWindowTransitionLocked(WindowState windowState, int transition) {
   if (DEBUG_WINDOW_TRANSITIONS) {
     Slog.i(
         LOG_TAG,
         "Window transition: "
             + AppTransition.appTransitionToString(transition)
             + " displayId: "
             + windowState.getDisplayId());
   }
   final boolean magnifying = mMagnifedViewport.isMagnifyingLocked();
   final int type = windowState.mAttrs.type;
   switch (transition) {
     case WindowManagerPolicy.TRANSIT_ENTER:
     case WindowManagerPolicy.TRANSIT_SHOW:
       {
         if (!magnifying) {
           break;
         }
         switch (type) {
           case WindowManager.LayoutParams.TYPE_APPLICATION:
           case WindowManager.LayoutParams.TYPE_APPLICATION_PANEL:
           case WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA:
           case WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL:
           case WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG:
           case WindowManager.LayoutParams.TYPE_SEARCH_BAR:
           case WindowManager.LayoutParams.TYPE_PHONE:
           case WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
           case WindowManager.LayoutParams.TYPE_TOAST:
           case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY:
           case WindowManager.LayoutParams.TYPE_PRIORITY_PHONE:
           case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG:
           case WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG:
           case WindowManager.LayoutParams.TYPE_SYSTEM_ERROR:
           case WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY:
           case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL:
           case WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY:
             {
               Rect magnifiedRegionBounds = mTempRect2;
               mMagnifedViewport.getMagnifiedFrameInContentCoordsLocked(magnifiedRegionBounds);
               Rect touchableRegionBounds = mTempRect1;
               windowState.getTouchableRegion(mTempRegion1);
               mTempRegion1.getBounds(touchableRegionBounds);
               if (!magnifiedRegionBounds.intersect(touchableRegionBounds)) {
                 try {
                   mCallbacks.onRectangleOnScreenRequested(
                       touchableRegionBounds.left,
                       touchableRegionBounds.top,
                       touchableRegionBounds.right,
                       touchableRegionBounds.bottom);
                 } catch (RemoteException re) {
                   /* ignore */
                 }
               }
             }
             break;
         }
         break;
       }
   }
 }
  private void addInputWindowHandleLw(
      final InputWindowHandle inputWindowHandle,
      final WindowState child,
      int flags,
      final int type,
      final boolean isVisible,
      final boolean hasFocus,
      final boolean hasWallpaper) {
    // Add a window to our list of input windows.
    inputWindowHandle.name = child.toString();
    flags = child.getTouchableRegion(inputWindowHandle.touchableRegion, flags);
    inputWindowHandle.layoutParamsFlags = flags;
    inputWindowHandle.layoutParamsType = type;
    inputWindowHandle.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
    inputWindowHandle.visible = isVisible;
    inputWindowHandle.canReceiveKeys = child.canReceiveKeys();
    inputWindowHandle.hasFocus = hasFocus;
    inputWindowHandle.hasWallpaper = hasWallpaper;
    inputWindowHandle.paused = child.mAppToken != null ? child.mAppToken.paused : false;
    inputWindowHandle.layer = child.mLayer;
    inputWindowHandle.ownerPid = child.mSession.mPid;
    inputWindowHandle.ownerUid = child.mSession.mUid;
    inputWindowHandle.inputFeatures = child.mAttrs.inputFeatures;

    final Rect frame = child.mFrame;
    inputWindowHandle.frameLeft = frame.left;
    inputWindowHandle.frameTop = frame.top;
    inputWindowHandle.frameRight = frame.right;
    inputWindowHandle.frameBottom = frame.bottom;

    if (child.isDockedInEffect()) {
      // Adjust to account for non-resizeable tasks that's scrolled
      inputWindowHandle.frameLeft += child.mXOffset;
      inputWindowHandle.frameTop += child.mYOffset;
      inputWindowHandle.frameRight += child.mXOffset;
      inputWindowHandle.frameBottom += child.mYOffset;
    }

    if (child.mGlobalScale != 1) {
      // If we are scaling the window, input coordinates need
      // to be inversely scaled to map from what is on screen
      // to what is actually being touched in the UI.
      inputWindowHandle.scaleFactor = 1.0f / child.mGlobalScale;
    } else {
      inputWindowHandle.scaleFactor = 1;
    }

    if (DEBUG_INPUT) {
      Slog.d(TAG_WM, "addInputWindowHandle: " + child + ", " + inputWindowHandle);
    }
    addInputWindowHandleLw(inputWindowHandle);
  }
 private void getWindowsOnScreenLocked(SparseArray<WindowStateInfo> outWindowStates) {
   DisplayContent displayContent = mWindowManagerService.getDefaultDisplayContentLocked();
   WindowList windowList = displayContent.getWindowList();
   final int windowCount = windowList.size();
   for (int i = 0; i < windowCount; i++) {
     WindowState windowState = windowList.get(i);
     if ((windowState.isOnScreen()
             || windowState.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND)
         && !windowState.mWinAnimator.mEnterAnimationPending) {
       outWindowStates.put(windowState.mLayer, WindowStateInfo.obtain(windowState));
     }
   }
 }
 public static WindowStateInfo obtain(WindowState windowState) {
   WindowStateInfo info = sPool.acquire();
   if (info == null) {
     info = new WindowStateInfo();
   }
   info.mWindowState = windowState;
   windowState.getTouchableRegion(mTempRegion);
   mTempRegion.getBounds(info.mTouchableRegion);
   return info;
 }
예제 #5
0
 /**
  * Get the current state of a window.
  *
  * @param hWnd native window handle
  * @return window state
  */
 private WindowState getWindowState(HWND hWnd) {
   WindowState windowState = new WindowState();
   windowState.setMaximized(ExtendedUser32.INSTANCE.IsZoomed(hWnd));
   if (windowState.getMaximized()) {
     ExtendedUser32.INSTANCE.SendMessage(
         hWnd, User32.WM_SYSCOMMAND, new WPARAM(ExtendedUser32.SC_RESTORE), new LPARAM(0));
   }
   windowState.setStyle(ExtendedUser32.INSTANCE.GetWindowLong(hWnd, ExtendedUser32.GWL_STYLE));
   windowState.setExStyle(ExtendedUser32.INSTANCE.GetWindowLong(hWnd, ExtendedUser32.GWL_EXSTYLE));
   RECT rect = new RECT();
   boolean gotWindowRect = ExtendedUser32.INSTANCE.GetWindowRect(hWnd, rect);
   if (gotWindowRect) {
     windowState.setLeft(rect.left);
     windowState.setTop(rect.top);
     windowState.setRight(rect.right);
     windowState.setBottom(rect.bottom);
   }
   return windowState;
 }
  /* Called when the current input focus changes.
   * Layer assignment is assumed to be complete by the time this is called.
   */
  public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
    if (DEBUG_FOCUS_LIGHT || DEBUG_INPUT) {
      Slog.d(TAG_WM, "Input focus has changed to " + newWindow);
    }

    if (newWindow != mInputFocus) {
      if (newWindow != null && newWindow.canReceiveKeys()) {
        // Displaying a window implicitly causes dispatching to be unpaused.
        // This is to protect against bugs if someone pauses dispatching but
        // forgets to resume.
        newWindow.mToken.paused = false;
      }

      mInputFocus = newWindow;
      setUpdateInputWindowsNeededLw();

      if (updateInputWindows) {
        updateInputWindowsLw(false /*force*/);
      }
    }
  }
 public void onAppWindowTransitionLocked(WindowState windowState, int transition) {
   if (DEBUG_WINDOW_TRANSITIONS) {
     Slog.i(
         LOG_TAG,
         "Window transition: "
             + AppTransition.appTransitionToString(transition)
             + " displayId: "
             + windowState.getDisplayId());
   }
   final boolean magnifying = mMagnifedViewport.isMagnifyingLocked();
   if (magnifying) {
     switch (transition) {
       case AppTransition.TRANSIT_ACTIVITY_OPEN:
       case AppTransition.TRANSIT_TASK_OPEN:
       case AppTransition.TRANSIT_TASK_TO_FRONT:
       case AppTransition.TRANSIT_WALLPAPER_OPEN:
       case AppTransition.TRANSIT_WALLPAPER_CLOSE:
       case AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN:
         {
           mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_USER_CONTEXT_CHANGED);
         }
     }
   }
 }
예제 #8
0
 /**
  * Set the full-screen state of the window.
  *
  * @param fullScreen <code>true</code> to set full-screen; <code>false</code> to exit full-screen
  */
 void setFullScreen(boolean fullScreen) {
   HWND hWnd = getHWND(Native.getComponentID(window));
   if (fullScreen) {
     windowState = getWindowState(hWnd);
     ExtendedUser32.INSTANCE.SetWindowLong(
         hWnd, GWL_STYLE, windowState.getStyle() & ~(WS_CAPTION | WS_THICKFRAME));
     ExtendedUser32.INSTANCE.SetWindowLong(
         hWnd,
         GWL_EXSTYLE,
         windowState.getExStyle()
             & ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
     MONITORINFO monitorInfo = getMonitorInfo(hWnd);
     RECT rect = monitorInfo.rcMonitor;
     ExtendedUser32.INSTANCE.SetWindowPos(
         hWnd,
         null,
         rect.left,
         rect.top,
         rect.right - rect.left,
         rect.bottom - rect.top,
         SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
   } else {
     ExtendedUser32.INSTANCE.SetWindowLong(hWnd, GWL_STYLE, windowState.getStyle());
     ExtendedUser32.INSTANCE.SetWindowLong(hWnd, GWL_EXSTYLE, windowState.getExStyle());
     ExtendedUser32.INSTANCE.SetWindowPos(
         hWnd,
         null,
         windowState.getLeft(),
         windowState.getTop(),
         windowState.getRight() - windowState.getLeft(),
         windowState.getBottom() - windowState.getTop(),
         SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
     if (windowState.getMaximized()) {
       ExtendedUser32.INSTANCE.SendMessage(
           hWnd, User32.WM_SYSCOMMAND, new WPARAM(WinUser.SC_MAXIMIZE), new LPARAM(0));
     }
   }
 }
  /* Updates the cached window information provided to the input dispatcher. */
  public void updateInputWindowsLw(boolean force) {
    if (!force && !mUpdateInputWindowsNeeded) {
      return;
    }
    mUpdateInputWindowsNeeded = false;

    if (false) Slog.d(TAG_WM, ">>>>>> ENTERED updateInputWindowsLw");

    // Populate the input window list with information about all of the windows that
    // could potentially receive input.
    // As an optimization, we could try to prune the list of windows but this turns
    // out to be difficult because only the native code knows for sure which window
    // currently has touch focus.
    boolean disableWallpaperTouchEvents = false;

    // If there's a drag in flight, provide a pseudowindow to catch drag input
    final boolean inDrag = (mService.mDragState != null);
    if (inDrag) {
      if (DEBUG_DRAG) {
        Log.d(TAG_WM, "Inserting drag window");
      }
      final InputWindowHandle dragWindowHandle = mService.mDragState.mDragWindowHandle;
      if (dragWindowHandle != null) {
        addInputWindowHandleLw(dragWindowHandle);
      } else {
        Slog.w(TAG_WM, "Drag is in progress but there is no " + "drag window handle.");
      }
    }

    final boolean inPositioning = (mService.mTaskPositioner != null);
    if (inPositioning) {
      if (DEBUG_TASK_POSITIONING) {
        Log.d(TAG_WM, "Inserting window handle for repositioning");
      }
      final InputWindowHandle dragWindowHandle = mService.mTaskPositioner.mDragWindowHandle;
      if (dragWindowHandle != null) {
        addInputWindowHandleLw(dragWindowHandle);
      } else {
        Slog.e(TAG_WM, "Repositioning is in progress but there is no drag window handle.");
      }
    }

    boolean addInputConsumerHandle = mService.mInputConsumer != null;

    boolean addWallpaperInputConsumerHandle = mService.mWallpaperInputConsumer != null;

    // Add all windows on the default display.
    final int numDisplays = mService.mDisplayContents.size();
    final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
    for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
      final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
      final WindowList windows = displayContent.getWindowList();
      for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
        final WindowState child = windows.get(winNdx);
        final InputChannel inputChannel = child.mInputChannel;
        final InputWindowHandle inputWindowHandle = child.mInputWindowHandle;
        if (inputChannel == null
            || inputWindowHandle == null
            || child.mRemoved
            || child.isAdjustedForMinimizedDock()) {
          // Skip this window because it cannot possibly receive input.
          continue;
        }
        if (addInputConsumerHandle
            && inputWindowHandle.layer <= mService.mInputConsumer.mWindowHandle.layer) {
          addInputWindowHandleLw(mService.mInputConsumer.mWindowHandle);
          addInputConsumerHandle = false;
        }

        if (addWallpaperInputConsumerHandle) {
          if (child.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER) {
            // Add the wallpaper input consumer above the first wallpaper window.
            addInputWindowHandleLw(mService.mWallpaperInputConsumer.mWindowHandle);
            addWallpaperInputConsumerHandle = false;
          }
        }

        final int flags = child.mAttrs.flags;
        final int privateFlags = child.mAttrs.privateFlags;
        final int type = child.mAttrs.type;

        final boolean hasFocus = (child == mInputFocus);
        final boolean isVisible = child.isVisibleLw();
        if ((privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS)
            != 0) {
          disableWallpaperTouchEvents = true;
        }
        final boolean hasWallpaper =
            wallpaperController.isWallpaperTarget(child)
                && (privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD) == 0
                && !disableWallpaperTouchEvents;
        final boolean onDefaultDisplay = (child.getDisplayId() == Display.DEFAULT_DISPLAY);

        // If there's a drag in progress and 'child' is a potential drop target,
        // make sure it's been told about the drag
        if (inDrag && isVisible && onDefaultDisplay) {
          mService.mDragState.sendDragStartedIfNeededLw(child);
        }

        addInputWindowHandleLw(
            inputWindowHandle, child, flags, type, isVisible, hasFocus, hasWallpaper);
      }
    }

    if (addWallpaperInputConsumerHandle) {
      // No wallpaper found, add the wallpaper input consumer at the end.
      addInputWindowHandleLw(mService.mWallpaperInputConsumer.mWindowHandle);
    }

    // Send windows to native code.
    mService.mInputManager.setInputWindows(mInputWindowHandles);

    // Clear the list in preparation for the next round.
    clearInputWindowHandlesLw();

    if (false) Slog.d(TAG_WM, "<<<<<<< EXITED updateInputWindowsLw");
  }
예제 #10
0
  /* Updates the cached window information provided to the input dispatcher. */
  public void updateInputWindowsLw(boolean force) {
    if (!force && !mUpdateInputWindowsNeeded) {
      return;
    }
    mUpdateInputWindowsNeeded = false;

    if (false) Slog.d(WindowManagerService.TAG, ">>>>>> ENTERED updateInputWindowsLw");

    // Populate the input window list with information about all of the windows that
    // could potentially receive input.
    // As an optimization, we could try to prune the list of windows but this turns
    // out to be difficult because only the native code knows for sure which window
    // currently has touch focus.
    final ArrayList<WindowState> windows = mService.mWindows;

    // If there's a drag in flight, provide a pseudowindow to catch drag input
    final boolean inDrag = (mService.mDragState != null);
    if (inDrag) {
      if (WindowManagerService.DEBUG_DRAG) {
        Log.d(WindowManagerService.TAG, "Inserting drag window");
      }
      final InputWindowHandle dragWindowHandle = mService.mDragState.mDragWindowHandle;
      if (dragWindowHandle != null) {
        addInputWindowHandleLw(dragWindowHandle);
      } else {
        Slog.w(
            WindowManagerService.TAG,
            "Drag is in progress but there is no " + "drag window handle.");
      }
    }

    final int NFW = mService.mFakeWindows.size();
    for (int i = 0; i < NFW; i++) {
      addInputWindowHandleLw(mService.mFakeWindows.get(i).mWindowHandle);
    }

    final int N = windows.size();
    for (int i = N - 1; i >= 0; i--) {
      final WindowState child = windows.get(i);
      final InputChannel inputChannel = child.mInputChannel;
      final InputWindowHandle inputWindowHandle = child.mInputWindowHandle;
      if (inputChannel == null || inputWindowHandle == null || child.mRemoved) {
        // Skip this window because it cannot possibly receive input.
        continue;
      }

      final int flags = child.mAttrs.flags;
      final int type = child.mAttrs.type;

      final boolean hasFocus = (child == mInputFocus);
      final boolean isVisible = child.isVisibleLw();
      final boolean hasWallpaper =
          (child == mService.mWallpaperTarget)
              && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);

      // If there's a drag in progress and 'child' is a potential drop target,
      // make sure it's been told about the drag
      if (inDrag && isVisible) {
        mService.mDragState.sendDragStartedIfNeededLw(child);
      }

      // Add a window to our list of input windows.
      inputWindowHandle.name = child.toString();
      inputWindowHandle.layoutParamsFlags = flags;
      inputWindowHandle.layoutParamsType = type;
      inputWindowHandle.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
      inputWindowHandle.visible = isVisible;
      inputWindowHandle.canReceiveKeys = child.canReceiveKeys();
      inputWindowHandle.hasFocus = hasFocus;
      inputWindowHandle.hasWallpaper = hasWallpaper;
      inputWindowHandle.paused = child.mAppToken != null ? child.mAppToken.paused : false;
      inputWindowHandle.layer = child.mLayer;
      inputWindowHandle.ownerPid = child.mSession.mPid;
      inputWindowHandle.ownerUid = child.mSession.mUid;
      inputWindowHandle.inputFeatures = child.mAttrs.inputFeatures;

      final Rect frame = child.mFrame;
      inputWindowHandle.frameLeft = frame.left;
      inputWindowHandle.frameTop = frame.top;
      inputWindowHandle.frameRight = frame.right;
      inputWindowHandle.frameBottom = frame.bottom;

      if (child.mGlobalScale != 1) {
        // If we are scaling the window, input coordinates need
        // to be inversely scaled to map from what is on screen
        // to what is actually being touched in the UI.
        inputWindowHandle.scaleFactor = 1.0f / child.mGlobalScale;
      } else {
        inputWindowHandle.scaleFactor = 1;
      }

      child.getTouchableRegion(inputWindowHandle.touchableRegion);

      addInputWindowHandleLw(inputWindowHandle);
    }

    // Send windows to native code.
    mService.mInputManager.setInputWindows(mInputWindowHandles);

    // Clear the list in preparation for the next round.
    clearInputWindowHandlesLw();

    if (false) Slog.d(WindowManagerService.TAG, "<<<<<<< EXITED updateInputWindowsLw");
  }
예제 #11
0
  private void updateWindowsAndWallpaperLocked() {
    ++mAnimTransactionSequence;

    ArrayList<WindowStateAnimator> unForceHiding = null;
    boolean wallpaperInUnForceHiding = false;

    for (int i = mService.mWindows.size() - 1; i >= 0; i--) {
      WindowState win = mService.mWindows.get(i);
      WindowStateAnimator winAnimator = win.mWinAnimator;
      final int flags = winAnimator.mAttrFlags;

      if (winAnimator.mSurface != null) {
        final boolean wasAnimating = winAnimator.mWasAnimating;
        final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime);

        if (WindowManagerService.DEBUG_WALLPAPER) {
          Slog.v(TAG, win + ": wasAnimating=" + wasAnimating + ", nowAnimating=" + nowAnimating);
        }

        // If this window is animating, make a note that we have
        // an animating window and take care of a request to run
        // a detached wallpaper animation.
        if (nowAnimating) {
          if (winAnimator.mAnimation != null) {
            if ((flags & FLAG_SHOW_WALLPAPER) != 0 && winAnimator.mAnimation.getDetachWallpaper()) {
              mDetachedWallpaper = win;
            }
            final int backgroundColor = winAnimator.mAnimation.getBackgroundColor();
            if (backgroundColor != 0) {
              if (mWindowAnimationBackground == null
                  || (winAnimator.mAnimLayer
                      < mWindowAnimationBackground.mWinAnimator.mAnimLayer)) {
                mWindowAnimationBackground = win;
                mWindowAnimationBackgroundColor = backgroundColor;
              }
            }
          }
          mAnimating = true;
        }

        // If this window's app token is running a detached wallpaper
        // animation, make a note so we can ensure the wallpaper is
        // displayed behind it.
        final AppWindowAnimator appAnimator =
            win.mAppToken == null ? null : win.mAppToken.mAppAnimator;
        if (appAnimator != null && appAnimator.animation != null && appAnimator.animating) {
          if ((flags & FLAG_SHOW_WALLPAPER) != 0 && appAnimator.animation.getDetachWallpaper()) {
            mDetachedWallpaper = win;
          }
          final int backgroundColor = appAnimator.animation.getBackgroundColor();
          if (backgroundColor != 0) {
            if (mWindowAnimationBackground == null
                || (winAnimator.mAnimLayer < mWindowAnimationBackground.mWinAnimator.mAnimLayer)) {
              mWindowAnimationBackground = win;
              mWindowAnimationBackgroundColor = backgroundColor;
            }
          }
        }

        if (wasAnimating && !winAnimator.mAnimating && mService.mWallpaperTarget == win) {
          mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
          mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
          if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
            mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 2", mPendingLayoutChanges);
          }
        }

        if (mPolicy.doesForceHide(win, win.mAttrs)) {
          if (!wasAnimating && nowAnimating) {
            if (WindowManagerService.DEBUG_ANIM || WindowManagerService.DEBUG_VISIBILITY)
              Slog.v(TAG, "Animation started that could impact force hide: " + win);
            mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED;
            mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
            if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
              mService.debugLayoutRepeats(
                  "updateWindowsAndWallpaperLocked 3", mPendingLayoutChanges);
            }
            mService.mFocusMayChange = true;
          }
          if (win.isReadyForDisplay() && winAnimator.mAnimationIsEntrance) {
            mForceHiding = true;
          }
          if (WindowManagerService.DEBUG_VISIBILITY)
            Slog.v(
                TAG,
                "Force hide "
                    + mForceHiding
                    + " hasSurface="
                    + win.mHasSurface
                    + " policyVis="
                    + win.mPolicyVisibility
                    + " destroying="
                    + win.mDestroying
                    + " attHidden="
                    + win.mAttachedHidden
                    + " vis="
                    + win.mViewVisibility
                    + " hidden="
                    + win.mRootToken.hidden
                    + " anim="
                    + win.mWinAnimator.mAnimation);
        } else if (mPolicy.canBeForceHidden(win, win.mAttrs)) {
          final boolean changed;
          if (mForceHiding
              && (!winAnimator.isAnimating()
                  || (winAnimator.mAttrFlags & FLAG_SHOW_WHEN_LOCKED) == 0)) {
            changed = win.hideLw(false, false);
            if (WindowManagerService.DEBUG_VISIBILITY && changed)
              Slog.v(TAG, "Now policy hidden: " + win);
          } else {
            changed = win.showLw(false, false);
            if (WindowManagerService.DEBUG_VISIBILITY && changed)
              Slog.v(TAG, "Now policy shown: " + win);
            if (changed) {
              if ((mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0
                  && win.isVisibleNow() /*w.isReadyForDisplay()*/) {
                if (unForceHiding == null) {
                  unForceHiding = new ArrayList<WindowStateAnimator>();
                }
                unForceHiding.add(winAnimator);
                if ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
                  wallpaperInUnForceHiding = true;
                }
              }
              if (mCurrentFocus == null || mCurrentFocus.mLayer < win.mLayer) {
                // We are showing on to of the current
                // focus, so re-evaluate focus to make
                // sure it is correct.
                mService.mFocusMayChange = true;
              }
            }
          }
          if (changed && (flags & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
            mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
            mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
            if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
              mService.debugLayoutRepeats(
                  "updateWindowsAndWallpaperLocked 4", mPendingLayoutChanges);
            }
          }
        }
      }

      final AppWindowToken atoken = win.mAppToken;
      if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) {
        if (atoken == null || atoken.allDrawn) {
          if (winAnimator.performShowLocked()) {
            mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
            if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
              mService.debugLayoutRepeats(
                  "updateWindowsAndWallpaperLocked 5", mPendingLayoutChanges);
            }
          }
        }
      }
      final AppWindowAnimator appAnimator = atoken == null ? null : atoken.mAppAnimator;
      if (appAnimator != null && appAnimator.thumbnail != null) {
        if (appAnimator.thumbnailTransactionSeq != mAnimTransactionSequence) {
          appAnimator.thumbnailTransactionSeq = mAnimTransactionSequence;
          appAnimator.thumbnailLayer = 0;
        }
        if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) {
          appAnimator.thumbnailLayer = winAnimator.mAnimLayer;
        }
      }
    } // end forall windows

    // If we have windows that are being show due to them no longer
    // being force-hidden, apply the appropriate animation to them.
    if (unForceHiding != null) {
      for (int i = unForceHiding.size() - 1; i >= 0; i--) {
        Animation a = mPolicy.createForceHideEnterAnimation(wallpaperInUnForceHiding);
        if (a != null) {
          final WindowStateAnimator winAnimator = unForceHiding.get(i);
          winAnimator.setAnimation(a);
          winAnimator.mAnimationIsEntrance = true;
        }
      }
    }
  }