Search in sources :

Example 6 with DisplayInfo

use of android.view.DisplayInfo in project android_frameworks_base by ParanoidAndroid.

the class WindowManagerService method stopFreezingDisplayLocked.

private void stopFreezingDisplayLocked() {
    if (!mDisplayFrozen) {
        return;
    }
    if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen || mClientFreezingScreen) {
        if (DEBUG_ORIENTATION)
            Slog.d(TAG, "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig + ", mAppsFreezingScreen=" + mAppsFreezingScreen + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen + ", mClientFreezingScreen=" + mClientFreezingScreen);
        return;
    }
    mDisplayFrozen = false;
    mLastDisplayFreezeDuration = (int) (SystemClock.elapsedRealtime() - mDisplayFreezeTime);
    StringBuilder sb = new StringBuilder(128);
    sb.append("Screen frozen for ");
    TimeUtils.formatDuration(mLastDisplayFreezeDuration, sb);
    if (mLastFinishedFreezeSource != null) {
        sb.append(" due to ");
        sb.append(mLastFinishedFreezeSource);
    }
    Slog.i(TAG, sb.toString());
    mH.removeMessages(H.APP_FREEZE_TIMEOUT);
    mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
    if (PROFILE_ORIENTATION) {
        Debug.stopMethodTracing();
    }
    boolean updateRotation = false;
    final DisplayContent displayContent = getDefaultDisplayContentLocked();
    final int displayId = displayContent.getDisplayId();
    ScreenRotationAnimation screenRotationAnimation = mAnimator.getScreenRotationAnimationLocked(displayId);
    if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null && screenRotationAnimation.hasScreenshot()) {
        if (DEBUG_ORIENTATION)
            Slog.i(TAG, "**** Dismissing screen rotation animation");
        // TODO(multidisplay): rotation on main screen only.
        DisplayInfo displayInfo = displayContent.getDisplayInfo();
        // Get rotation animation again, with new top window
        boolean isDimming = mAnimator.isDimmingLocked(Display.DEFAULT_DISPLAY);
        if (!mPolicy.validateRotationAnimationLw(mExitAnimId, mEnterAnimId, isDimming)) {
            mExitAnimId = mEnterAnimId = 0;
        }
        if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION, mTransitionAnimationScale, displayInfo.logicalWidth, displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) {
            scheduleAnimationLocked();
        } else {
            screenRotationAnimation.kill();
            screenRotationAnimation = null;
            mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
            updateRotation = true;
        }
    } else {
        if (screenRotationAnimation != null) {
            screenRotationAnimation.kill();
            screenRotationAnimation = null;
            mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
        }
        updateRotation = true;
    }
    mInputMonitor.thawInputDispatchingLw();
    boolean configChanged;
    // While the display is frozen we don't re-compute the orientation
    // to avoid inconsistent states.  However, something interesting
    // could have actually changed during that time so re-evaluate it
    // now to catch that.
    configChanged = updateOrientationFromAppTokensLocked(false);
    // A little kludge: a lot could have happened while the
    // display was frozen, so now that we are coming back we
    // do a gc so that any remote references the system
    // processes holds on others can be released if they are
    // no longer needed.
    mH.removeMessages(H.FORCE_GC);
    mH.sendEmptyMessageDelayed(H.FORCE_GC, 2000);
    mScreenFrozenLock.release();
    if (updateRotation) {
        if (DEBUG_ORIENTATION)
            Slog.d(TAG, "Performing post-rotate rotation");
        configChanged |= updateRotationUncheckedLocked(false);
    }
    if (configChanged) {
        mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
    }
}
Also used : DisplayInfo(android.view.DisplayInfo) Point(android.graphics.Point)

Example 7 with DisplayInfo

use of android.view.DisplayInfo in project android_frameworks_base by ParanoidAndroid.

the class WindowManagerService method adjustWallpaperWindowsLocked.

int adjustWallpaperWindowsLocked() {
    mInnerFields.mWallpaperMayChange = false;
    boolean targetChanged = false;
    // TODO(multidisplay): Wallpapers on main screen only.
    final DisplayInfo displayInfo = getDefaultDisplayContentLocked().getDisplayInfo();
    final int dw = displayInfo.appWidth;
    final int dh = displayInfo.appHeight;
    // First find top-most window that has asked to be on top of the
    // wallpaper; all wallpapers go behind it.
    final WindowList windows = getDefaultWindowListLocked();
    int N = windows.size();
    WindowState w = null;
    WindowState foundW = null;
    int foundI = 0;
    WindowState topCurW = null;
    int topCurI = 0;
    int windowDetachedI = -1;
    int i = N;
    while (i > 0) {
        i--;
        w = windows.get(i);
        if ((w.mAttrs.type == TYPE_WALLPAPER)) {
            if (topCurW == null) {
                topCurW = w;
                topCurI = i;
            }
            continue;
        }
        topCurW = null;
        if (w != mAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
            // it is of no interest to us.
            if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
                if (DEBUG_WALLPAPER)
                    Slog.v(TAG, "Skipping hidden and not animating token: " + w);
                continue;
            }
        }
        if (DEBUG_WALLPAPER)
            Slog.v(TAG, "Win #" + i + " " + w + ": isOnScreen=" + w.isOnScreen() + " mDrawState=" + w.mWinAnimator.mDrawState);
        if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0 && w.isOnScreen() && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
            if (DEBUG_WALLPAPER)
                Slog.v(TAG, "Found wallpaper target: #" + i + "=" + w);
            foundW = w;
            foundI = i;
            if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
                // out what is going on below.
                if (DEBUG_WALLPAPER)
                    Slog.v(TAG, "Win " + w + ": token animating, looking behind.");
                continue;
            }
            break;
        } else if (w == mAnimator.mWindowDetachedWallpaper) {
            windowDetachedI = i;
        }
    }
    if (foundW == null && windowDetachedI >= 0) {
        if (DEBUG_WALLPAPER_LIGHT)
            Slog.v(TAG, "Found animating detached wallpaper activity: #" + i + "=" + w);
        foundW = w;
        foundI = windowDetachedI;
    }
    if (mWallpaperTarget != foundW && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != foundW)) {
        if (DEBUG_WALLPAPER_LIGHT) {
            Slog.v(TAG, "New wallpaper target: " + foundW + " oldTarget: " + mWallpaperTarget);
        }
        mLowerWallpaperTarget = null;
        mUpperWallpaperTarget = null;
        WindowState oldW = mWallpaperTarget;
        mWallpaperTarget = foundW;
        targetChanged = true;
        // animating, then we are in our super special mode!
        if (foundW != null && oldW != null) {
            boolean oldAnim = oldW.isAnimatingLw();
            boolean foundAnim = foundW.isAnimatingLw();
            if (DEBUG_WALLPAPER_LIGHT) {
                Slog.v(TAG, "New animation: " + foundAnim + " old animation: " + oldAnim);
            }
            if (foundAnim && oldAnim) {
                int oldI = windows.indexOf(oldW);
                if (DEBUG_WALLPAPER_LIGHT) {
                    Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
                }
                if (oldI >= 0) {
                    if (DEBUG_WALLPAPER_LIGHT) {
                        Slog.v(TAG, "Animating wallpapers: old#" + oldI + "=" + oldW + "; new#" + foundI + "=" + foundW);
                    }
                    // Set the new target correctly.
                    if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
                        if (DEBUG_WALLPAPER_LIGHT) {
                            Slog.v(TAG, "Old wallpaper still the target.");
                        }
                        mWallpaperTarget = oldW;
                        foundW = oldW;
                        foundI = oldI;
                    } else // the wallpaper below the lower.
                    if (foundI > oldI) {
                        // The new target is on top of the old one.
                        if (DEBUG_WALLPAPER_LIGHT) {
                            Slog.v(TAG, "Found target above old target.");
                        }
                        mUpperWallpaperTarget = foundW;
                        mLowerWallpaperTarget = oldW;
                        foundW = oldW;
                        foundI = oldI;
                    } else {
                        // The new target is below the old one.
                        if (DEBUG_WALLPAPER_LIGHT) {
                            Slog.v(TAG, "Found target below old target.");
                        }
                        mUpperWallpaperTarget = oldW;
                        mLowerWallpaperTarget = foundW;
                    }
                }
            }
        }
    } else if (mLowerWallpaperTarget != null) {
        // Is it time to stop animating?
        if (!mLowerWallpaperTarget.isAnimatingLw() || !mUpperWallpaperTarget.isAnimatingLw()) {
            if (DEBUG_WALLPAPER_LIGHT) {
                Slog.v(TAG, "No longer animating wallpaper targets!");
            }
            mLowerWallpaperTarget = null;
            mUpperWallpaperTarget = null;
            mWallpaperTarget = foundW;
            targetChanged = true;
        }
    }
    boolean visible = foundW != null;
    if (visible) {
        // The window is visible to the compositor...  but is it visible
        // to the user?  That is what the wallpaper cares about.
        visible = isWallpaperVisible(foundW);
        if (DEBUG_WALLPAPER)
            Slog.v(TAG, "Wallpaper visibility: " + visible);
        // If the wallpaper target is animating, we may need to copy
        // its layer adjustment.  Only do this if we are not transfering
        // between two wallpaper targets.
        mWallpaperAnimLayerAdjustment = (mLowerWallpaperTarget == null && foundW.mAppToken != null) ? foundW.mAppToken.mAppAnimator.animLayerAdjustment : 0;
        final int maxLayer = mPolicy.getMaxWallpaperLayer() * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
        // maximum layer the policy allows for wallpapers.
        while (foundI > 0) {
            WindowState wb = windows.get(foundI - 1);
            if (wb.mBaseLayer < maxLayer && wb.mAttachedWindow != foundW && (foundW.mAttachedWindow == null || wb.mAttachedWindow != foundW.mAttachedWindow) && (wb.mAttrs.type != TYPE_APPLICATION_STARTING || foundW.mToken == null || wb.mToken != foundW.mToken)) {
                // interesting way, so stop here.
                break;
            }
            foundW = wb;
            foundI--;
        }
    } else {
        if (DEBUG_WALLPAPER)
            Slog.v(TAG, "No wallpaper target");
    }
    if (foundW == null && topCurW != null) {
        // There is no wallpaper target, so it goes at the bottom.
        // We will assume it is the same place as last time, if known.
        foundW = topCurW;
        foundI = topCurI + 1;
    } else {
        // Okay i is the position immediately above the wallpaper.  Look at
        // what is below it for later.
        foundW = foundI > 0 ? windows.get(foundI - 1) : null;
    }
    if (visible) {
        if (mWallpaperTarget.mWallpaperX >= 0) {
            mLastWallpaperX = mWallpaperTarget.mWallpaperX;
            mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
        }
        if (mWallpaperTarget.mWallpaperY >= 0) {
            mLastWallpaperY = mWallpaperTarget.mWallpaperY;
            mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
        }
    }
    // Start stepping backwards from here, ensuring that our wallpaper windows
    // are correctly placed.
    int changed = 0;
    int curTokenIndex = mWallpaperTokens.size();
    while (curTokenIndex > 0) {
        curTokenIndex--;
        WindowToken token = mWallpaperTokens.get(curTokenIndex);
        if (token.hidden == visible) {
            if (DEBUG_WALLPAPER_LIGHT)
                Slog.d(TAG, "Wallpaper token " + token + " hidden=" + !visible);
            changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
            token.hidden = !visible;
            // Need to do a layout to ensure the wallpaper now has the
            // correct size.
            getDefaultDisplayContentLocked().layoutNeeded = true;
        }
        int curWallpaperIndex = token.windows.size();
        while (curWallpaperIndex > 0) {
            curWallpaperIndex--;
            WindowState wallpaper = token.windows.get(curWallpaperIndex);
            if (visible) {
                updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
            }
            // First, make sure the client has the current visibility
            // state.
            dispatchWallpaperVisibility(wallpaper, visible);
            wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
            if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT)
                Slog.v(TAG, "adjustWallpaper win " + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
            // is well.
            if (wallpaper == foundW) {
                foundI--;
                foundW = foundI > 0 ? windows.get(foundI - 1) : null;
                continue;
            }
            // The window didn't match...  the current wallpaper window,
            // wherever it is, is in the wrong place, so make sure it is
            // not in the list.
            int oldIndex = windows.indexOf(wallpaper);
            if (oldIndex >= 0) {
                if (DEBUG_WINDOW_MOVEMENT)
                    Slog.v(TAG, "Wallpaper removing at " + oldIndex + ": " + wallpaper);
                windows.remove(oldIndex);
                mWindowsChanged = true;
                if (oldIndex < foundI) {
                    foundI--;
                }
            }
            // Now stick it in.
            if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
                Slog.v(TAG, "Moving wallpaper " + wallpaper + " from " + oldIndex + " to " + foundI);
            }
            windows.add(foundI, wallpaper);
            mWindowsChanged = true;
            changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
        }
    }
    if (targetChanged && DEBUG_WALLPAPER_LIGHT) {
        Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget + " lower=" + mLowerWallpaperTarget + " upper=" + mUpperWallpaperTarget);
    }
    return changed;
}
Also used : DisplayInfo(android.view.DisplayInfo) Point(android.graphics.Point)

Example 8 with DisplayInfo

use of android.view.DisplayInfo in project android_frameworks_base by ParanoidAndroid.

the class WindowManagerService method setOverscan.

@Override
public void setOverscan(int displayId, int left, int top, int right, int bottom) {
    if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) != PackageManager.PERMISSION_GRANTED) {
        throw new SecurityException("Must hold permission " + android.Manifest.permission.WRITE_SECURE_SETTINGS);
    }
    synchronized (mWindowMap) {
        DisplayContent displayContent = getDisplayContentLocked(displayId);
        if (displayContent != null) {
            mDisplayManagerService.setOverscan(displayId, left, top, right, bottom);
            final DisplayInfo displayInfo = displayContent.getDisplayInfo();
            synchronized (displayContent.mDisplaySizeLock) {
                displayInfo.overscanLeft = left;
                displayInfo.overscanTop = top;
                displayInfo.overscanRight = right;
                displayInfo.overscanBottom = bottom;
            }
            mPolicy.setDisplayOverscan(displayContent.getDisplay(), left, top, right, bottom);
            displayContent.layoutNeeded = true;
            mDisplaySettings.setOverscanLocked(displayInfo.name, left, top, right, bottom);
            mDisplaySettings.writeSettingsLocked();
            performLayoutAndPlaceSurfacesLocked();
        }
    }
}
Also used : DisplayInfo(android.view.DisplayInfo)

Example 9 with DisplayInfo

use of android.view.DisplayInfo in project android_frameworks_base by ParanoidAndroid.

the class ElectronBeam method prepare.

/**
     * Warms up the electron beam in preparation for turning on or off.
     * This method prepares a GL context, and captures a screen shot.
     *
     * @param mode The desired mode for the upcoming animation.
     * @return True if the electron beam is ready, false if it is uncontrollable.
     */
public boolean prepare(int mode) {
    if (DEBUG) {
        Slog.d(TAG, "prepare: mode=" + mode);
    }
    mMode = mode;
    // Get the display size and layer stack.
    // This is not expected to change while the electron beam surface is showing.
    DisplayInfo displayInfo = mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY);
    mDisplayLayerStack = displayInfo.layerStack;
    mDisplayWidth = displayInfo.getNaturalWidth();
    mDisplayHeight = displayInfo.getNaturalHeight();
    // Prepare the surface for drawing.
    if (!tryPrepare()) {
        dismiss();
        return false;
    }
    // Done.
    mPrepared = true;
    // painting the screenshot as-is.
    if (mode == MODE_COOL_DOWN) {
        for (int i = 0; i < DEJANK_FRAMES; i++) {
            draw(1.0f);
        }
    }
    return true;
}
Also used : DisplayInfo(android.view.DisplayInfo)

Example 10 with DisplayInfo

use of android.view.DisplayInfo in project android_frameworks_base by ParanoidAndroid.

the class WindowManagerService method relayoutWindow.

public int relayoutWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
    boolean toBeDisplayed = false;
    boolean inTouchMode;
    boolean configChanged;
    boolean surfaceChanged = false;
    boolean animating;
    // if they don't have this permission, mask out the status bar bits
    int systemUiVisibility = 0;
    if (attrs != null) {
        systemUiVisibility = (attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility);
        if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
            if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) != PackageManager.PERMISSION_GRANTED) {
                systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
            }
        }
    }
    long origId = Binder.clearCallingIdentity();
    synchronized (mWindowMap) {
        WindowState win = windowForClientLocked(session, client, false);
        if (win == null) {
            return 0;
        }
        WindowStateAnimator winAnimator = win.mWinAnimator;
        if (win.mRequestedWidth != requestedWidth || win.mRequestedHeight != requestedHeight) {
            win.mLayoutNeeded = true;
            win.mRequestedWidth = requestedWidth;
            win.mRequestedHeight = requestedHeight;
        }
        if (attrs != null && seq == win.mSeq) {
            win.mSystemUiVisibility = systemUiVisibility;
        }
        if (attrs != null) {
            mPolicy.adjustWindowParamsLw(attrs);
        }
        winAnimator.mSurfaceDestroyDeferred = (flags & WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
        int attrChanges = 0;
        int flagChanges = 0;
        if (attrs != null) {
            if (win.mAttrs.type != attrs.type) {
                throw new IllegalArgumentException("Window type can not be changed after the window is added.");
            }
            flagChanges = win.mAttrs.flags ^= attrs.flags;
            attrChanges = win.mAttrs.copyFrom(attrs);
            if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
                win.mLayoutNeeded = true;
            }
        }
        if (DEBUG_LAYOUT)
            Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
        win.mEnforceSizeCompat = (win.mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
        if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
            winAnimator.mAlpha = attrs.alpha;
        }
        final boolean scaledWindow = ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
        if (scaledWindow) {
            // requested{Width|Height} Surface's physical size
            // attrs.{width|height} Size on screen
            win.mHScale = (attrs.width != requestedWidth) ? (attrs.width / (float) requestedWidth) : 1.0f;
            win.mVScale = (attrs.height != requestedHeight) ? (attrs.height / (float) requestedHeight) : 1.0f;
        } else {
            win.mHScale = win.mVScale = 1;
        }
        boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;
        final boolean isDefaultDisplay = win.isDefaultDisplay();
        boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0) || (!win.mRelayoutCalled));
        boolean wallpaperMayMove = win.mViewVisibility != viewVisibility && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
        wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
        win.mRelayoutCalled = true;
        final int oldVisibility = win.mViewVisibility;
        win.mViewVisibility = viewVisibility;
        if (DEBUG_SCREEN_ON) {
            RuntimeException stack = new RuntimeException();
            stack.fillInStackTrace();
            Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility + " newVis=" + viewVisibility, stack);
        }
        if (viewVisibility == View.VISIBLE && (win.mAppToken == null || !win.mAppToken.clientHidden)) {
            toBeDisplayed = !win.isVisibleLw();
            if (win.mExiting) {
                winAnimator.cancelExitAnimationForNextAnimationLocked();
                win.mExiting = false;
            }
            if (win.mDestroying) {
                win.mDestroying = false;
                mDestroySurface.remove(win);
            }
            if (oldVisibility == View.GONE) {
                winAnimator.mEnterAnimationPending = true;
            }
            if (toBeDisplayed) {
                if (win.isDrawnLw() && okToDisplay()) {
                    winAnimator.applyEnterAnimationLocked();
                }
                if ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
                    if (DEBUG_VISIBILITY)
                        Slog.v(TAG, "Relayout window turning screen on: " + win);
                    win.mTurnOnScreen = true;
                }
                if (win.isConfigChanged()) {
                    if (DEBUG_CONFIGURATION)
                        Slog.i(TAG, "Window " + win + " visible with new config: " + mCurConfiguration);
                    outConfig.setTo(mCurConfiguration);
                }
            }
            if ((attrChanges & WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
                // To change the format, we need to re-build the surface.
                winAnimator.destroySurfaceLocked();
                toBeDisplayed = true;
                surfaceChanged = true;
            }
            try {
                if (!win.mHasSurface) {
                    surfaceChanged = true;
                }
                SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
                if (surfaceControl != null) {
                    outSurface.copyFrom(surfaceControl);
                    if (SHOW_TRANSACTIONS)
                        Slog.i(TAG, "  OUT SURFACE " + outSurface + ": copied");
                } else {
                    // For some reason there isn't a surface.  Clear the
                    // caller's object so they see the same state.
                    outSurface.release();
                }
            } catch (Exception e) {
                mInputMonitor.updateInputWindowsLw(true);
                Slog.w(TAG, "Exception thrown when creating surface for client " + client + " (" + win.mAttrs.getTitle() + ")", e);
                Binder.restoreCallingIdentity(origId);
                return 0;
            }
            if (toBeDisplayed) {
                focusMayChange = isDefaultDisplay;
            }
            if (win.mAttrs.type == TYPE_INPUT_METHOD && mInputMethodWindow == null) {
                mInputMethodWindow = win;
                imMayMove = true;
            }
            if (win.mAttrs.type == TYPE_BASE_APPLICATION && win.mAppToken != null && win.mAppToken.startingWindow != null) {
                // Special handling of starting window over the base
                // window of the app: propagate lock screen flags to it,
                // to provide the correct semantics while starting.
                final int mask = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
                WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
                sa.flags = (sa.flags & ~mask) | (win.mAttrs.flags & mask);
            }
        } else {
            winAnimator.mEnterAnimationPending = false;
            if (winAnimator.mSurfaceControl != null) {
                if (DEBUG_VISIBILITY)
                    Slog.i(TAG, "Relayout invis " + win + ": mExiting=" + win.mExiting);
                // need to see about starting one.
                if (!win.mExiting) {
                    surfaceChanged = true;
                    // Try starting an animation; if there isn't one, we
                    // can destroy the surface right away.
                    int transit = WindowManagerPolicy.TRANSIT_EXIT;
                    if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
                        transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
                    }
                    if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
                        focusMayChange = isDefaultDisplay;
                        win.mExiting = true;
                    } else if (win.mWinAnimator.isAnimating()) {
                        // Currently in a hide animation... turn this into
                        // an exit.
                        win.mExiting = true;
                    } else if (win == mWallpaperTarget) {
                        // If the wallpaper is currently behind this
                        // window, we need to change both of them inside
                        // of a transaction to avoid artifacts.
                        win.mExiting = true;
                        win.mWinAnimator.mAnimating = true;
                    } else {
                        if (mInputMethodWindow == win) {
                            mInputMethodWindow = null;
                        }
                        winAnimator.destroySurfaceLocked();
                    }
                    //TODO (multidisplay): Magnification is supported only for the default
                    if (mDisplayMagnifier != null && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
                        mDisplayMagnifier.onWindowTransitionLocked(win, transit);
                    }
                }
            }
            outSurface.release();
            if (DEBUG_VISIBILITY)
                Slog.i(TAG, "Releasing surface in: " + win);
        }
        if (focusMayChange) {
            //System.out.println("Focus may change: " + win.mAttrs.getTitle());
            if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, false)) {
                imMayMove = false;
            }
        //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
        }
        // reassign them at this point if the IM window state gets shuffled
        if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) {
            // Little hack here -- we -should- be able to rely on the
            // function to return true if the IME has moved and needs
            // its layer recomputed.  However, if the IME was hidden
            // and isn't actually moved in the list, its layer may be
            // out of data so we make sure to recompute it.
            assignLayersLocked(win.getWindowList());
        }
        if (wallpaperMayMove) {
            getDefaultDisplayContentLocked().pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
        }
        win.mDisplayContent.layoutNeeded = true;
        win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
        configChanged = updateOrientationFromAppTokensLocked(false);
        performLayoutAndPlaceSurfacesLocked();
        if (toBeDisplayed && win.mIsWallpaper) {
            DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
            updateWallpaperOffsetLocked(win, displayInfo.appWidth, displayInfo.appHeight, false);
        }
        if (win.mAppToken != null) {
            win.mAppToken.updateReportedVisibilityLocked();
        }
        outFrame.set(win.mCompatFrame);
        outOverscanInsets.set(win.mOverscanInsets);
        outContentInsets.set(win.mContentInsets);
        outVisibleInsets.set(win.mVisibleInsets);
        if (localLOGV)
            Slog.v(TAG, "Relayout given client " + client.asBinder() + ", requestedWidth=" + requestedWidth + ", requestedHeight=" + requestedHeight + ", viewVisibility=" + viewVisibility + "\nRelayout returning frame=" + outFrame + ", surface=" + outSurface);
        if (localLOGV || DEBUG_FOCUS)
            Slog.v(TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
        inTouchMode = mInTouchMode;
        animating = mAnimator.mAnimating;
        if (animating && !mRelayoutWhileAnimating.contains(win)) {
            mRelayoutWhileAnimating.add(win);
        }
        mInputMonitor.updateInputWindowsLw(true);
        if (DEBUG_LAYOUT) {
            Slog.v(TAG, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
        }
    }
    if (configChanged) {
        sendNewConfiguration();
    }
    Binder.restoreCallingIdentity(origId);
    return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0) | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0) | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0) | (animating ? WindowManagerGlobal.RELAYOUT_RES_ANIMATING : 0);
}
Also used : DisplayInfo(android.view.DisplayInfo) SurfaceControl(android.view.SurfaceControl) LayoutParams(android.view.WindowManager.LayoutParams) Point(android.graphics.Point) RemoteException(android.os.RemoteException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) NoSuchElementException(java.util.NoSuchElementException) PhoneWindowManager(com.android.internal.policy.impl.PhoneWindowManager) IWindowManager(android.view.IWindowManager) WindowManager(android.view.WindowManager)

Aggregations

DisplayInfo (android.view.DisplayInfo)186 Point (android.graphics.Point)53 Rect (android.graphics.Rect)29 RemoteException (android.os.RemoteException)19 Display (android.view.Display)11 Animation (android.view.animation.Animation)10 Bitmap (android.graphics.Bitmap)9 WindowManager (android.view.WindowManager)8 DividerSnapAlgorithm (com.android.internal.policy.DividerSnapAlgorithm)8 Canvas (android.graphics.Canvas)6 SurfaceControl (android.view.SurfaceControl)6 LayoutParams (android.view.WindowManager.LayoutParams)6 DisplayManager (android.hardware.display.DisplayManager)5 DisplayMetrics (android.util.DisplayMetrics)5 Surface (android.view.Surface)5 InputDevice (android.view.InputDevice)4 SnapTarget (com.android.internal.policy.DividerSnapAlgorithm.SnapTarget)4 FileNotFoundException (java.io.FileNotFoundException)4 IOException (java.io.IOException)4 OutOfResourcesException (android.view.Surface.OutOfResourcesException)3