Search in sources :

Example 11 with OutOfResourcesException

use of android.view.Surface.OutOfResourcesException in project android_frameworks_base by AOSPA.

the class ViewRootImpl method performTraversals.

private void performTraversals() {
    // cache mView since it is used so much below...
    final View host = mView;
    if (DBG) {
        System.out.println("======================================");
        System.out.println("performTraversals");
        host.debug();
    }
    if (host == null || !mAdded)
        return;
    mIsInTraversal = true;
    mWillDrawSoon = true;
    boolean windowSizeMayChange = false;
    boolean newSurface = false;
    boolean surfaceChanged = false;
    WindowManager.LayoutParams lp = mWindowAttributes;
    int desiredWindowWidth;
    int desiredWindowHeight;
    final int viewVisibility = getHostVisibility();
    final boolean viewVisibilityChanged = !mFirst && (mViewVisibility != viewVisibility || mNewSurfaceNeeded);
    final boolean viewUserVisibilityChanged = !mFirst && ((mViewVisibility == View.VISIBLE) != (viewVisibility == View.VISIBLE));
    WindowManager.LayoutParams params = null;
    if (mWindowAttributesChanged) {
        mWindowAttributesChanged = false;
        surfaceChanged = true;
        params = lp;
    }
    CompatibilityInfo compatibilityInfo = mDisplay.getDisplayAdjustments().getCompatibilityInfo();
    if (compatibilityInfo.supportsScreen() == mLastInCompatMode) {
        params = lp;
        mFullRedrawNeeded = true;
        mLayoutRequested = true;
        if (mLastInCompatMode) {
            params.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
            mLastInCompatMode = false;
        } else {
            params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
            mLastInCompatMode = true;
        }
    }
    mWindowAttributesChangesFlag = 0;
    Rect frame = mWinFrame;
    if (mFirst) {
        mFullRedrawNeeded = true;
        mLayoutRequested = true;
        if (shouldUseDisplaySize(lp)) {
            // NOTE -- system code, won't try to do compat mode.
            Point size = new Point();
            mDisplay.getRealSize(size);
            desiredWindowWidth = size.x;
            desiredWindowHeight = size.y;
        } else {
            Configuration config = mContext.getResources().getConfiguration();
            desiredWindowWidth = dipToPx(config.screenWidthDp);
            desiredWindowHeight = dipToPx(config.screenHeightDp);
        }
        // We used to use the following condition to choose 32 bits drawing caches:
        // PixelFormat.hasAlpha(lp.format) || lp.format == PixelFormat.RGBX_8888
        // However, windows are now always 32 bits by default, so choose 32 bits
        mAttachInfo.mUse32BitDrawingCache = true;
        mAttachInfo.mHasWindowFocus = false;
        mAttachInfo.mWindowVisibility = viewVisibility;
        mAttachInfo.mRecomputeGlobalAttributes = false;
        mLastConfiguration.setTo(host.getResources().getConfiguration());
        mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility;
        // Set the layout direction if it has not been set before (inherit is the default)
        if (mViewLayoutDirectionInitial == View.LAYOUT_DIRECTION_INHERIT) {
            host.setLayoutDirection(mLastConfiguration.getLayoutDirection());
        }
        host.dispatchAttachedToWindow(mAttachInfo, 0);
        mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true);
        dispatchApplyInsets(host);
    //Log.i(mTag, "Screen on initialized: " + attachInfo.mKeepScreenOn);
    } else {
        desiredWindowWidth = frame.width();
        desiredWindowHeight = frame.height();
        if (desiredWindowWidth != mWidth || desiredWindowHeight != mHeight) {
            if (DEBUG_ORIENTATION)
                Log.v(mTag, "View " + host + " resized to: " + frame);
            mFullRedrawNeeded = true;
            mLayoutRequested = true;
            windowSizeMayChange = true;
        }
    }
    if (viewVisibilityChanged) {
        mAttachInfo.mWindowVisibility = viewVisibility;
        host.dispatchWindowVisibilityChanged(viewVisibility);
        if (viewUserVisibilityChanged) {
            host.dispatchVisibilityAggregated(viewVisibility == View.VISIBLE);
        }
        if (viewVisibility != View.VISIBLE || mNewSurfaceNeeded) {
            endDragResizing();
            destroyHardwareResources();
        }
        if (viewVisibility == View.GONE) {
            // After making a window gone, we will count it as being
            // shown for the first time the next time it gets focus.
            mHasHadWindowFocus = false;
        }
    }
    // Non-visible windows can't hold accessibility focus.
    if (mAttachInfo.mWindowVisibility != View.VISIBLE) {
        host.clearAccessibilityFocus();
    }
    // Execute enqueued actions on every traversal in case a detached view enqueued an action
    getRunQueue().executeActions(mAttachInfo.mHandler);
    boolean insetsChanged = false;
    boolean layoutRequested = mLayoutRequested && (!mStopped || mReportNextDraw);
    if (layoutRequested) {
        final Resources res = mView.getContext().getResources();
        if (mFirst) {
            // make sure touch mode code executes by setting cached value
            // to opposite of the added touch mode.
            mAttachInfo.mInTouchMode = !mAddedTouchMode;
            ensureTouchModeLocally(mAddedTouchMode);
        } else {
            if (!mPendingOverscanInsets.equals(mAttachInfo.mOverscanInsets)) {
                insetsChanged = true;
            }
            if (!mPendingContentInsets.equals(mAttachInfo.mContentInsets)) {
                insetsChanged = true;
            }
            if (!mPendingStableInsets.equals(mAttachInfo.mStableInsets)) {
                insetsChanged = true;
            }
            if (!mPendingVisibleInsets.equals(mAttachInfo.mVisibleInsets)) {
                mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets);
                if (DEBUG_LAYOUT)
                    Log.v(mTag, "Visible insets changing to: " + mAttachInfo.mVisibleInsets);
            }
            if (!mPendingOutsets.equals(mAttachInfo.mOutsets)) {
                insetsChanged = true;
            }
            if (mPendingAlwaysConsumeNavBar != mAttachInfo.mAlwaysConsumeNavBar) {
                insetsChanged = true;
            }
            if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
                windowSizeMayChange = true;
                if (shouldUseDisplaySize(lp)) {
                    // NOTE -- system code, won't try to do compat mode.
                    Point size = new Point();
                    mDisplay.getRealSize(size);
                    desiredWindowWidth = size.x;
                    desiredWindowHeight = size.y;
                } else {
                    Configuration config = res.getConfiguration();
                    desiredWindowWidth = dipToPx(config.screenWidthDp);
                    desiredWindowHeight = dipToPx(config.screenHeightDp);
                }
            }
        }
        // Ask host how big it wants to be
        windowSizeMayChange |= measureHierarchy(host, lp, res, desiredWindowWidth, desiredWindowHeight);
    }
    if (collectViewAttributes()) {
        params = lp;
    }
    if (mAttachInfo.mForceReportNewAttributes) {
        mAttachInfo.mForceReportNewAttributes = false;
        params = lp;
    }
    if (mFirst || mAttachInfo.mViewVisibilityChanged) {
        mAttachInfo.mViewVisibilityChanged = false;
        int resizeMode = mSoftInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
        // what mode to use now.
        if (resizeMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) {
            final int N = mAttachInfo.mScrollContainers.size();
            for (int i = 0; i < N; i++) {
                if (mAttachInfo.mScrollContainers.get(i).isShown()) {
                    resizeMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
                }
            }
            if (resizeMode == 0) {
                resizeMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
            }
            if ((lp.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) != resizeMode) {
                lp.softInputMode = (lp.softInputMode & ~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) | resizeMode;
                params = lp;
            }
        }
    }
    if (params != null) {
        if ((host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) {
            if (!PixelFormat.formatHasAlpha(params.format)) {
                params.format = PixelFormat.TRANSLUCENT;
            }
        }
        mAttachInfo.mOverscanRequested = (params.flags & WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN) != 0;
    }
    if (mApplyInsetsRequested) {
        mApplyInsetsRequested = false;
        mLastOverscanRequested = mAttachInfo.mOverscanRequested;
        dispatchApplyInsets(host);
        if (mLayoutRequested) {
            // Short-circuit catching a new layout request here, so
            // we don't need to go through two layout passes when things
            // change due to fitting system windows, which can happen a lot.
            windowSizeMayChange |= measureHierarchy(host, lp, mView.getContext().getResources(), desiredWindowWidth, desiredWindowHeight);
        }
    }
    if (layoutRequested) {
        // Clear this now, so that if anything requests a layout in the
        // rest of this function we will catch it and re-run a full
        // layout pass.
        mLayoutRequested = false;
    }
    boolean windowShouldResize = layoutRequested && windowSizeMayChange && ((mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight()) || (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT && frame.width() < desiredWindowWidth && frame.width() != mWidth) || (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT && frame.height() < desiredWindowHeight && frame.height() != mHeight));
    windowShouldResize |= mDragResizing && mResizeMode == RESIZE_MODE_FREEFORM;
    // If the activity was just relaunched, it might have unfrozen the task bounds (while
    // relaunching), so we need to force a call into window manager to pick up the latest
    // bounds.
    windowShouldResize |= mActivityRelaunched;
    // Determine whether to compute insets.
    // If there are no inset listeners remaining then we may still need to compute
    // insets in case the old insets were non-empty and must be reset.
    final boolean computesInternalInsets = mAttachInfo.mTreeObserver.hasComputeInternalInsetsListeners() || mAttachInfo.mHasNonEmptyGivenInternalInsets;
    boolean insetsPending = false;
    int relayoutResult = 0;
    boolean updatedConfiguration = false;
    final int surfaceGenerationId = mSurface.getGenerationId();
    final boolean isViewVisible = viewVisibility == View.VISIBLE;
    if (mFirst || windowShouldResize || insetsChanged || viewVisibilityChanged || params != null || mForceNextWindowRelayout) {
        mForceNextWindowRelayout = false;
        if (isViewVisible) {
            // If this window is giving internal insets to the window
            // manager, and it is being added or changing its visibility,
            // then we want to first give the window manager "fake"
            // insets to cause it to effectively ignore the content of
            // the window during layout.  This avoids it briefly causing
            // other windows to resize/move based on the raw frame of the
            // window, waiting until we can finish laying out this window
            // and get back to the window manager with the ultimately
            // computed insets.
            insetsPending = computesInternalInsets && (mFirst || viewVisibilityChanged);
        }
        if (mSurfaceHolder != null) {
            mSurfaceHolder.mSurfaceLock.lock();
            mDrawingAllowed = true;
        }
        boolean hwInitialized = false;
        boolean contentInsetsChanged = false;
        boolean hadSurface = mSurface.isValid();
        try {
            if (DEBUG_LAYOUT) {
                Log.i(mTag, "host=w:" + host.getMeasuredWidth() + ", h:" + host.getMeasuredHeight() + ", params=" + params);
            }
            if (mAttachInfo.mHardwareRenderer != null) {
                // and stop using the surface in case it gets destroyed.
                if (mAttachInfo.mHardwareRenderer.pauseSurface(mSurface)) {
                    // Animations were running so we need to push a frame
                    // to resume them
                    mDirty.set(0, 0, mWidth, mHeight);
                }
                mChoreographer.mFrameInfo.addFlags(FrameInfo.FLAG_WINDOW_LAYOUT_CHANGED);
            }
            relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
            if (DEBUG_LAYOUT)
                Log.v(mTag, "relayout: frame=" + frame.toShortString() + " overscan=" + mPendingOverscanInsets.toShortString() + " content=" + mPendingContentInsets.toShortString() + " visible=" + mPendingVisibleInsets.toShortString() + " visible=" + mPendingStableInsets.toShortString() + " outsets=" + mPendingOutsets.toShortString() + " surface=" + mSurface);
            if (mPendingConfiguration.seq != 0) {
                if (DEBUG_CONFIGURATION)
                    Log.v(mTag, "Visible with new config: " + mPendingConfiguration);
                updateConfiguration(new Configuration(mPendingConfiguration), !mFirst);
                mPendingConfiguration.seq = 0;
                updatedConfiguration = true;
            }
            final boolean overscanInsetsChanged = !mPendingOverscanInsets.equals(mAttachInfo.mOverscanInsets);
            contentInsetsChanged = !mPendingContentInsets.equals(mAttachInfo.mContentInsets);
            final boolean visibleInsetsChanged = !mPendingVisibleInsets.equals(mAttachInfo.mVisibleInsets);
            final boolean stableInsetsChanged = !mPendingStableInsets.equals(mAttachInfo.mStableInsets);
            final boolean outsetsChanged = !mPendingOutsets.equals(mAttachInfo.mOutsets);
            final boolean surfaceSizeChanged = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0;
            final boolean alwaysConsumeNavBarChanged = mPendingAlwaysConsumeNavBar != mAttachInfo.mAlwaysConsumeNavBar;
            if (contentInsetsChanged) {
                mAttachInfo.mContentInsets.set(mPendingContentInsets);
                if (DEBUG_LAYOUT)
                    Log.v(mTag, "Content insets changing to: " + mAttachInfo.mContentInsets);
            }
            if (overscanInsetsChanged) {
                mAttachInfo.mOverscanInsets.set(mPendingOverscanInsets);
                if (DEBUG_LAYOUT)
                    Log.v(mTag, "Overscan insets changing to: " + mAttachInfo.mOverscanInsets);
                // Need to relayout with content insets.
                contentInsetsChanged = true;
            }
            if (stableInsetsChanged) {
                mAttachInfo.mStableInsets.set(mPendingStableInsets);
                if (DEBUG_LAYOUT)
                    Log.v(mTag, "Decor insets changing to: " + mAttachInfo.mStableInsets);
                // Need to relayout with content insets.
                contentInsetsChanged = true;
            }
            if (alwaysConsumeNavBarChanged) {
                mAttachInfo.mAlwaysConsumeNavBar = mPendingAlwaysConsumeNavBar;
                contentInsetsChanged = true;
            }
            if (contentInsetsChanged || mLastSystemUiVisibility != mAttachInfo.mSystemUiVisibility || mApplyInsetsRequested || mLastOverscanRequested != mAttachInfo.mOverscanRequested || outsetsChanged) {
                mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility;
                mLastOverscanRequested = mAttachInfo.mOverscanRequested;
                mAttachInfo.mOutsets.set(mPendingOutsets);
                mApplyInsetsRequested = false;
                dispatchApplyInsets(host);
            }
            if (visibleInsetsChanged) {
                mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets);
                if (DEBUG_LAYOUT)
                    Log.v(mTag, "Visible insets changing to: " + mAttachInfo.mVisibleInsets);
            }
            if (!hadSurface) {
                if (mSurface.isValid()) {
                    // If we are creating a new surface, then we need to
                    // completely redraw it.  Also, when we get to the
                    // point of drawing it we will hold off and schedule
                    // a new traversal instead.  This is so we can tell the
                    // window manager about all of the windows being displayed
                    // before actually drawing them, so it can display then
                    // all at once.
                    newSurface = true;
                    mFullRedrawNeeded = true;
                    mPreviousTransparentRegion.setEmpty();
                    // will be transparent
                    if (mAttachInfo.mHardwareRenderer != null) {
                        try {
                            hwInitialized = mAttachInfo.mHardwareRenderer.initialize(mSurface);
                            if (hwInitialized && (host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) {
                                // Don't pre-allocate if transparent regions
                                // are requested as they may not be needed
                                mSurface.allocateBuffers();
                            }
                        } catch (OutOfResourcesException e) {
                            handleOutOfResourcesException(e);
                            return;
                        }
                    }
                }
            } else if (!mSurface.isValid()) {
                // positions.
                if (mLastScrolledFocus != null) {
                    mLastScrolledFocus.clear();
                }
                mScrollY = mCurScrollY = 0;
                if (mView instanceof RootViewSurfaceTaker) {
                    ((RootViewSurfaceTaker) mView).onRootViewScrollYChanged(mCurScrollY);
                }
                if (mScroller != null) {
                    mScroller.abortAnimation();
                }
                // Our surface is gone
                if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
                    mAttachInfo.mHardwareRenderer.destroy();
                }
            } else if ((surfaceGenerationId != mSurface.getGenerationId() || surfaceSizeChanged) && mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) {
                mFullRedrawNeeded = true;
                try {
                    // Need to do updateSurface (which leads to CanvasContext::setSurface and
                    // re-create the EGLSurface) if either the Surface changed (as indicated by
                    // generation id), or WindowManager changed the surface size. The latter is
                    // because on some chips, changing the consumer side's BufferQueue size may
                    // not take effect immediately unless we create a new EGLSurface.
                    // Note that frame size change doesn't always imply surface size change (eg.
                    // drag resizing uses fullscreen surface), need to check surfaceSizeChanged
                    // flag from WindowManager.
                    mAttachInfo.mHardwareRenderer.updateSurface(mSurface);
                } catch (OutOfResourcesException e) {
                    handleOutOfResourcesException(e);
                    return;
                }
            }
            final boolean freeformResizing = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_FREEFORM) != 0;
            final boolean dockedResizing = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_DOCKED) != 0;
            final boolean dragResizing = freeformResizing || dockedResizing;
            if (mDragResizing != dragResizing) {
                if (dragResizing) {
                    mResizeMode = freeformResizing ? RESIZE_MODE_FREEFORM : RESIZE_MODE_DOCKED_DIVIDER;
                    startDragResizing(mPendingBackDropFrame, mWinFrame.equals(mPendingBackDropFrame), mPendingVisibleInsets, mPendingStableInsets, mResizeMode);
                } else {
                    // We shouldn't come here, but if we come we should end the resize.
                    endDragResizing();
                }
            }
            if (!USE_MT_RENDERER) {
                if (dragResizing) {
                    mCanvasOffsetX = mWinFrame.left;
                    mCanvasOffsetY = mWinFrame.top;
                } else {
                    mCanvasOffsetX = mCanvasOffsetY = 0;
                }
            }
        } catch (RemoteException e) {
        }
        if (DEBUG_ORIENTATION)
            Log.v(TAG, "Relayout returned: frame=" + frame + ", surface=" + mSurface);
        mAttachInfo.mWindowLeft = frame.left;
        mAttachInfo.mWindowTop = frame.top;
        // the window session beforehand.
        if (mWidth != frame.width() || mHeight != frame.height()) {
            mWidth = frame.width();
            mHeight = frame.height();
        }
        if (mSurfaceHolder != null) {
            // The app owns the surface; tell it about what is going on.
            if (mSurface.isValid()) {
                // XXX .copyFrom() doesn't work!
                //mSurfaceHolder.mSurface.copyFrom(mSurface);
                mSurfaceHolder.mSurface = mSurface;
            }
            mSurfaceHolder.setSurfaceFrameSize(mWidth, mHeight);
            mSurfaceHolder.mSurfaceLock.unlock();
            if (mSurface.isValid()) {
                if (!hadSurface) {
                    mSurfaceHolder.ungetCallbacks();
                    mIsCreating = true;
                    mSurfaceHolderCallback.surfaceCreated(mSurfaceHolder);
                    SurfaceHolder.Callback[] callbacks = mSurfaceHolder.getCallbacks();
                    if (callbacks != null) {
                        for (SurfaceHolder.Callback c : callbacks) {
                            c.surfaceCreated(mSurfaceHolder);
                        }
                    }
                    surfaceChanged = true;
                }
                if (surfaceChanged || surfaceGenerationId != mSurface.getGenerationId()) {
                    mSurfaceHolderCallback.surfaceChanged(mSurfaceHolder, lp.format, mWidth, mHeight);
                    SurfaceHolder.Callback[] callbacks = mSurfaceHolder.getCallbacks();
                    if (callbacks != null) {
                        for (SurfaceHolder.Callback c : callbacks) {
                            c.surfaceChanged(mSurfaceHolder, lp.format, mWidth, mHeight);
                        }
                    }
                }
                mIsCreating = false;
            } else if (hadSurface) {
                mSurfaceHolder.ungetCallbacks();
                SurfaceHolder.Callback[] callbacks = mSurfaceHolder.getCallbacks();
                mSurfaceHolderCallback.surfaceDestroyed(mSurfaceHolder);
                if (callbacks != null) {
                    for (SurfaceHolder.Callback c : callbacks) {
                        c.surfaceDestroyed(mSurfaceHolder);
                    }
                }
                mSurfaceHolder.mSurfaceLock.lock();
                try {
                    mSurfaceHolder.mSurface = new Surface();
                } finally {
                    mSurfaceHolder.mSurfaceLock.unlock();
                }
            }
        }
        final ThreadedRenderer hardwareRenderer = mAttachInfo.mHardwareRenderer;
        if (hardwareRenderer != null && hardwareRenderer.isEnabled()) {
            if (hwInitialized || mWidth != hardwareRenderer.getWidth() || mHeight != hardwareRenderer.getHeight() || mNeedsHwRendererSetup) {
                hardwareRenderer.setup(mWidth, mHeight, mAttachInfo, mWindowAttributes.surfaceInsets);
                mNeedsHwRendererSetup = false;
            }
        }
        if (!mStopped || mReportNextDraw) {
            boolean focusChangedDueToTouchMode = ensureTouchModeLocally((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE) != 0);
            if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight() || contentInsetsChanged || updatedConfiguration) {
                int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
                int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
                if (DEBUG_LAYOUT)
                    Log.v(mTag, "Ooops, something changed!  mWidth=" + mWidth + " measuredWidth=" + host.getMeasuredWidth() + " mHeight=" + mHeight + " measuredHeight=" + host.getMeasuredHeight() + " coveredInsetsChanged=" + contentInsetsChanged);
                // Ask host how big it wants to be
                performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
                // Implementation of weights from WindowManager.LayoutParams
                // We just grow the dimensions as needed and re-measure if
                // needs be
                int width = host.getMeasuredWidth();
                int height = host.getMeasuredHeight();
                boolean measureAgain = false;
                if (lp.horizontalWeight > 0.0f) {
                    width += (int) ((mWidth - width) * lp.horizontalWeight);
                    childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
                    measureAgain = true;
                }
                if (lp.verticalWeight > 0.0f) {
                    height += (int) ((mHeight - height) * lp.verticalWeight);
                    childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
                    measureAgain = true;
                }
                if (measureAgain) {
                    if (DEBUG_LAYOUT)
                        Log.v(mTag, "And hey let's measure once more: width=" + width + " height=" + height);
                    performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
                }
                layoutRequested = true;
            }
        }
    } else {
        // Not the first pass and no window/insets/visibility change but the window
        // may have moved and we need check that and if so to update the left and right
        // in the attach info. We translate only the window frame since on window move
        // the window manager tells us only for the new frame but the insets are the
        // same and we do not want to translate them more than once.
        maybeHandleWindowMove(frame);
    }
    final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw);
    boolean triggerGlobalLayoutListener = didLayout || mAttachInfo.mRecomputeGlobalAttributes;
    if (didLayout) {
        performLayout(lp, mWidth, mHeight);
        if ((host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) {
            // start out transparent
            // TODO: AVOID THAT CALL BY CACHING THE RESULT?
            host.getLocationInWindow(mTmpLocation);
            mTransparentRegion.set(mTmpLocation[0], mTmpLocation[1], mTmpLocation[0] + host.mRight - host.mLeft, mTmpLocation[1] + host.mBottom - host.mTop);
            host.gatherTransparentRegion(mTransparentRegion);
            if (mTranslator != null) {
                mTranslator.translateRegionInWindowToScreen(mTransparentRegion);
            }
            if (!mTransparentRegion.equals(mPreviousTransparentRegion)) {
                mPreviousTransparentRegion.set(mTransparentRegion);
                mFullRedrawNeeded = true;
                // reconfigure window manager
                try {
                    mWindowSession.setTransparentRegion(mWindow, mTransparentRegion);
                } catch (RemoteException e) {
                }
            }
        }
        if (DBG) {
            System.out.println("======================================");
            System.out.println("performTraversals -- after setFrame");
            host.debug();
        }
    }
    if (triggerGlobalLayoutListener) {
        mAttachInfo.mRecomputeGlobalAttributes = false;
        mAttachInfo.mTreeObserver.dispatchOnGlobalLayout();
    }
    if (computesInternalInsets) {
        // Clear the original insets.
        final ViewTreeObserver.InternalInsetsInfo insets = mAttachInfo.mGivenInternalInsets;
        insets.reset();
        // Compute new insets in place.
        mAttachInfo.mTreeObserver.dispatchOnComputeInternalInsets(insets);
        mAttachInfo.mHasNonEmptyGivenInternalInsets = !insets.isEmpty();
        // Tell the window manager.
        if (insetsPending || !mLastGivenInsets.equals(insets)) {
            mLastGivenInsets.set(insets);
            // Translate insets to screen coordinates if needed.
            final Rect contentInsets;
            final Rect visibleInsets;
            final Region touchableRegion;
            if (mTranslator != null) {
                contentInsets = mTranslator.getTranslatedContentInsets(insets.contentInsets);
                visibleInsets = mTranslator.getTranslatedVisibleInsets(insets.visibleInsets);
                touchableRegion = mTranslator.getTranslatedTouchableArea(insets.touchableRegion);
            } else {
                contentInsets = insets.contentInsets;
                visibleInsets = insets.visibleInsets;
                touchableRegion = insets.touchableRegion;
            }
            try {
                mWindowSession.setInsets(mWindow, insets.mTouchableInsets, contentInsets, visibleInsets, touchableRegion);
            } catch (RemoteException e) {
            }
        }
    }
    if (mFirst) {
        // handle first focus request
        if (DEBUG_INPUT_RESIZE)
            Log.v(mTag, "First: mView.hasFocus()=" + mView.hasFocus());
        if (mView != null) {
            if (!mView.hasFocus()) {
                mView.requestFocus(View.FOCUS_FORWARD);
                if (DEBUG_INPUT_RESIZE)
                    Log.v(mTag, "First: requested focused view=" + mView.findFocus());
            } else {
                if (DEBUG_INPUT_RESIZE)
                    Log.v(mTag, "First: existing focused view=" + mView.findFocus());
            }
        }
    }
    final boolean changedVisibility = (viewVisibilityChanged || mFirst) && isViewVisible;
    final boolean hasWindowFocus = mAttachInfo.mHasWindowFocus && isViewVisible;
    final boolean regainedFocus = hasWindowFocus && mLostWindowFocus;
    if (regainedFocus) {
        mLostWindowFocus = false;
    } else if (!hasWindowFocus && mHadWindowFocus) {
        mLostWindowFocus = true;
    }
    if (changedVisibility || regainedFocus) {
        // Toasts are presented as notifications - don't present them as windows as well
        boolean isToast = (mWindowAttributes == null) ? false : (mWindowAttributes.type == WindowManager.LayoutParams.TYPE_TOAST);
        if (!isToast) {
            host.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
        }
    }
    mFirst = false;
    mWillDrawSoon = false;
    mNewSurfaceNeeded = false;
    mActivityRelaunched = false;
    mViewVisibility = viewVisibility;
    mHadWindowFocus = hasWindowFocus;
    if (hasWindowFocus && !isInLocalFocusMode()) {
        final boolean imTarget = WindowManager.LayoutParams.mayUseInputMethod(mWindowAttributes.flags);
        if (imTarget != mLastWasImTarget) {
            mLastWasImTarget = imTarget;
            InputMethodManager imm = InputMethodManager.peekInstance();
            if (imm != null && imTarget) {
                imm.onPreWindowFocus(mView, hasWindowFocus);
                imm.onPostWindowFocus(mView, mView.findFocus(), mWindowAttributes.softInputMode, !mHasHadWindowFocus, mWindowAttributes.flags);
            }
        }
    }
    // Remember if we must report the next draw.
    if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
        mReportNextDraw = true;
    }
    boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible;
    if (!cancelDraw && !newSurface) {
        if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
            for (int i = 0; i < mPendingTransitions.size(); ++i) {
                mPendingTransitions.get(i).startChangingAnimations();
            }
            mPendingTransitions.clear();
        }
        performDraw();
    } else {
        if (isViewVisible) {
            // Try again
            scheduleTraversals();
        } else if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
            for (int i = 0; i < mPendingTransitions.size(); ++i) {
                mPendingTransitions.get(i).endChangingAnimations();
            }
            mPendingTransitions.clear();
        }
    }
    mIsInTraversal = false;
}
Also used : Rect(android.graphics.Rect) Configuration(android.content.res.Configuration) CompatibilityInfo(android.content.res.CompatibilityInfo) InputMethodManager(android.view.inputmethod.InputMethodManager) Point(android.graphics.Point) Point(android.graphics.Point) BaseSurfaceHolder(com.android.internal.view.BaseSurfaceHolder) IAccessibilityInteractionConnectionCallback(android.view.accessibility.IAccessibilityInteractionConnectionCallback) OutOfResourcesException(android.view.Surface.OutOfResourcesException) RootViewSurfaceTaker(com.android.internal.view.RootViewSurfaceTaker) Region(android.graphics.Region) Resources(android.content.res.Resources) RemoteException(android.os.RemoteException)

Example 12 with OutOfResourcesException

use of android.view.Surface.OutOfResourcesException in project android_frameworks_base by ResurrectionRemix.

the class ViewRootImpl method performTraversals.

private void performTraversals() {
    // cache mView since it is used so much below...
    final View host = mView;
    if (DBG) {
        System.out.println("======================================");
        System.out.println("performTraversals");
        host.debug();
    }
    if (host == null || !mAdded)
        return;
    mIsInTraversal = true;
    mWillDrawSoon = true;
    boolean windowSizeMayChange = false;
    boolean newSurface = false;
    boolean surfaceChanged = false;
    WindowManager.LayoutParams lp = mWindowAttributes;
    int desiredWindowWidth;
    int desiredWindowHeight;
    final int viewVisibility = getHostVisibility();
    final boolean viewVisibilityChanged = !mFirst && (mViewVisibility != viewVisibility || mNewSurfaceNeeded);
    final boolean viewUserVisibilityChanged = !mFirst && ((mViewVisibility == View.VISIBLE) != (viewVisibility == View.VISIBLE));
    WindowManager.LayoutParams params = null;
    if (mWindowAttributesChanged) {
        mWindowAttributesChanged = false;
        surfaceChanged = true;
        params = lp;
    }
    CompatibilityInfo compatibilityInfo = mDisplay.getDisplayAdjustments().getCompatibilityInfo();
    if (compatibilityInfo.supportsScreen() == mLastInCompatMode) {
        params = lp;
        mFullRedrawNeeded = true;
        mLayoutRequested = true;
        if (mLastInCompatMode) {
            params.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
            mLastInCompatMode = false;
        } else {
            params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
            mLastInCompatMode = true;
        }
    }
    mWindowAttributesChangesFlag = 0;
    Rect frame = mWinFrame;
    if (mFirst) {
        mFullRedrawNeeded = true;
        mLayoutRequested = true;
        if (shouldUseDisplaySize(lp)) {
            // NOTE -- system code, won't try to do compat mode.
            Point size = new Point();
            mDisplay.getRealSize(size);
            desiredWindowWidth = size.x;
            desiredWindowHeight = size.y;
        } else {
            Configuration config = mContext.getResources().getConfiguration();
            desiredWindowWidth = dipToPx(config.screenWidthDp);
            desiredWindowHeight = dipToPx(config.screenHeightDp);
        }
        // We used to use the following condition to choose 32 bits drawing caches:
        // PixelFormat.hasAlpha(lp.format) || lp.format == PixelFormat.RGBX_8888
        // However, windows are now always 32 bits by default, so choose 32 bits
        mAttachInfo.mUse32BitDrawingCache = true;
        mAttachInfo.mHasWindowFocus = false;
        mAttachInfo.mWindowVisibility = viewVisibility;
        mAttachInfo.mRecomputeGlobalAttributes = false;
        mLastConfiguration.setTo(host.getResources().getConfiguration());
        mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility;
        // Set the layout direction if it has not been set before (inherit is the default)
        if (mViewLayoutDirectionInitial == View.LAYOUT_DIRECTION_INHERIT) {
            host.setLayoutDirection(mLastConfiguration.getLayoutDirection());
        }
        host.dispatchAttachedToWindow(mAttachInfo, 0);
        mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true);
        dispatchApplyInsets(host);
    //Log.i(mTag, "Screen on initialized: " + attachInfo.mKeepScreenOn);
    } else {
        desiredWindowWidth = frame.width();
        desiredWindowHeight = frame.height();
        if (desiredWindowWidth != mWidth || desiredWindowHeight != mHeight) {
            if (DEBUG_ORIENTATION)
                Log.v(mTag, "View " + host + " resized to: " + frame);
            mFullRedrawNeeded = true;
            mLayoutRequested = true;
            windowSizeMayChange = true;
        }
    }
    if (viewVisibilityChanged) {
        mAttachInfo.mWindowVisibility = viewVisibility;
        host.dispatchWindowVisibilityChanged(viewVisibility);
        if (viewUserVisibilityChanged) {
            host.dispatchVisibilityAggregated(viewVisibility == View.VISIBLE);
        }
        if (viewVisibility != View.VISIBLE || mNewSurfaceNeeded) {
            endDragResizing();
            destroyHardwareResources();
        }
        if (viewVisibility == View.GONE) {
            // After making a window gone, we will count it as being
            // shown for the first time the next time it gets focus.
            mHasHadWindowFocus = false;
        }
    }
    // Non-visible windows can't hold accessibility focus.
    if (mAttachInfo.mWindowVisibility != View.VISIBLE) {
        host.clearAccessibilityFocus();
    }
    // Execute enqueued actions on every traversal in case a detached view enqueued an action
    getRunQueue().executeActions(mAttachInfo.mHandler);
    boolean insetsChanged = false;
    boolean layoutRequested = mLayoutRequested && (!mStopped || mReportNextDraw);
    if (layoutRequested) {
        final Resources res = mView.getContext().getResources();
        if (mFirst) {
            // make sure touch mode code executes by setting cached value
            // to opposite of the added touch mode.
            mAttachInfo.mInTouchMode = !mAddedTouchMode;
            ensureTouchModeLocally(mAddedTouchMode);
        } else {
            if (!mPendingOverscanInsets.equals(mAttachInfo.mOverscanInsets)) {
                insetsChanged = true;
            }
            if (!mPendingContentInsets.equals(mAttachInfo.mContentInsets)) {
                insetsChanged = true;
            }
            if (!mPendingStableInsets.equals(mAttachInfo.mStableInsets)) {
                insetsChanged = true;
            }
            if (!mPendingVisibleInsets.equals(mAttachInfo.mVisibleInsets)) {
                mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets);
                if (DEBUG_LAYOUT)
                    Log.v(mTag, "Visible insets changing to: " + mAttachInfo.mVisibleInsets);
            }
            if (!mPendingOutsets.equals(mAttachInfo.mOutsets)) {
                insetsChanged = true;
            }
            if (mPendingAlwaysConsumeNavBar != mAttachInfo.mAlwaysConsumeNavBar) {
                insetsChanged = true;
            }
            if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
                windowSizeMayChange = true;
                if (shouldUseDisplaySize(lp)) {
                    // NOTE -- system code, won't try to do compat mode.
                    Point size = new Point();
                    mDisplay.getRealSize(size);
                    desiredWindowWidth = size.x;
                    desiredWindowHeight = size.y;
                } else {
                    Configuration config = res.getConfiguration();
                    desiredWindowWidth = dipToPx(config.screenWidthDp);
                    desiredWindowHeight = dipToPx(config.screenHeightDp);
                }
            }
        }
        // Ask host how big it wants to be
        windowSizeMayChange |= measureHierarchy(host, lp, res, desiredWindowWidth, desiredWindowHeight);
    }
    if (collectViewAttributes()) {
        params = lp;
    }
    if (mAttachInfo.mForceReportNewAttributes) {
        mAttachInfo.mForceReportNewAttributes = false;
        params = lp;
    }
    if (mFirst || mAttachInfo.mViewVisibilityChanged) {
        mAttachInfo.mViewVisibilityChanged = false;
        int resizeMode = mSoftInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
        // what mode to use now.
        if (resizeMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) {
            final int N = mAttachInfo.mScrollContainers.size();
            for (int i = 0; i < N; i++) {
                if (mAttachInfo.mScrollContainers.get(i).isShown()) {
                    resizeMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
                }
            }
            if (resizeMode == 0) {
                resizeMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
            }
            if ((lp.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) != resizeMode) {
                lp.softInputMode = (lp.softInputMode & ~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) | resizeMode;
                params = lp;
            }
        }
    }
    if (params != null) {
        if ((host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) {
            if (!PixelFormat.formatHasAlpha(params.format)) {
                params.format = PixelFormat.TRANSLUCENT;
            }
        }
        mAttachInfo.mOverscanRequested = (params.flags & WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN) != 0;
    }
    if (mApplyInsetsRequested) {
        mApplyInsetsRequested = false;
        mLastOverscanRequested = mAttachInfo.mOverscanRequested;
        dispatchApplyInsets(host);
        if (mLayoutRequested) {
            // Short-circuit catching a new layout request here, so
            // we don't need to go through two layout passes when things
            // change due to fitting system windows, which can happen a lot.
            windowSizeMayChange |= measureHierarchy(host, lp, mView.getContext().getResources(), desiredWindowWidth, desiredWindowHeight);
        }
    }
    if (layoutRequested) {
        // Clear this now, so that if anything requests a layout in the
        // rest of this function we will catch it and re-run a full
        // layout pass.
        mLayoutRequested = false;
    }
    boolean windowShouldResize = layoutRequested && windowSizeMayChange && ((mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight()) || (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT && frame.width() < desiredWindowWidth && frame.width() != mWidth) || (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT && frame.height() < desiredWindowHeight && frame.height() != mHeight));
    windowShouldResize |= mDragResizing && mResizeMode == RESIZE_MODE_FREEFORM;
    // If the activity was just relaunched, it might have unfrozen the task bounds (while
    // relaunching), so we need to force a call into window manager to pick up the latest
    // bounds.
    windowShouldResize |= mActivityRelaunched;
    // Determine whether to compute insets.
    // If there are no inset listeners remaining then we may still need to compute
    // insets in case the old insets were non-empty and must be reset.
    final boolean computesInternalInsets = mAttachInfo.mTreeObserver.hasComputeInternalInsetsListeners() || mAttachInfo.mHasNonEmptyGivenInternalInsets;
    boolean insetsPending = false;
    int relayoutResult = 0;
    boolean updatedConfiguration = false;
    final int surfaceGenerationId = mSurface.getGenerationId();
    final boolean isViewVisible = viewVisibility == View.VISIBLE;
    if (mFirst || windowShouldResize || insetsChanged || viewVisibilityChanged || params != null || mForceNextWindowRelayout) {
        mForceNextWindowRelayout = false;
        if (isViewVisible) {
            // If this window is giving internal insets to the window
            // manager, and it is being added or changing its visibility,
            // then we want to first give the window manager "fake"
            // insets to cause it to effectively ignore the content of
            // the window during layout.  This avoids it briefly causing
            // other windows to resize/move based on the raw frame of the
            // window, waiting until we can finish laying out this window
            // and get back to the window manager with the ultimately
            // computed insets.
            insetsPending = computesInternalInsets && (mFirst || viewVisibilityChanged);
        }
        if (mSurfaceHolder != null) {
            mSurfaceHolder.mSurfaceLock.lock();
            mDrawingAllowed = true;
        }
        boolean hwInitialized = false;
        boolean contentInsetsChanged = false;
        boolean hadSurface = mSurface.isValid();
        try {
            if (DEBUG_LAYOUT) {
                Log.i(mTag, "host=w:" + host.getMeasuredWidth() + ", h:" + host.getMeasuredHeight() + ", params=" + params);
            }
            if (mAttachInfo.mHardwareRenderer != null) {
                // and stop using the surface in case it gets destroyed.
                if (mAttachInfo.mHardwareRenderer.pauseSurface(mSurface)) {
                    // Animations were running so we need to push a frame
                    // to resume them
                    mDirty.set(0, 0, mWidth, mHeight);
                }
                mChoreographer.mFrameInfo.addFlags(FrameInfo.FLAG_WINDOW_LAYOUT_CHANGED);
            }
            relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
            if (DEBUG_LAYOUT)
                Log.v(mTag, "relayout: frame=" + frame.toShortString() + " overscan=" + mPendingOverscanInsets.toShortString() + " content=" + mPendingContentInsets.toShortString() + " visible=" + mPendingVisibleInsets.toShortString() + " visible=" + mPendingStableInsets.toShortString() + " outsets=" + mPendingOutsets.toShortString() + " surface=" + mSurface);
            if (mPendingConfiguration.seq != 0) {
                if (DEBUG_CONFIGURATION)
                    Log.v(mTag, "Visible with new config: " + mPendingConfiguration);
                updateConfiguration(new Configuration(mPendingConfiguration), !mFirst);
                mPendingConfiguration.seq = 0;
                updatedConfiguration = true;
            }
            final boolean overscanInsetsChanged = !mPendingOverscanInsets.equals(mAttachInfo.mOverscanInsets);
            contentInsetsChanged = !mPendingContentInsets.equals(mAttachInfo.mContentInsets);
            final boolean visibleInsetsChanged = !mPendingVisibleInsets.equals(mAttachInfo.mVisibleInsets);
            final boolean stableInsetsChanged = !mPendingStableInsets.equals(mAttachInfo.mStableInsets);
            final boolean outsetsChanged = !mPendingOutsets.equals(mAttachInfo.mOutsets);
            final boolean surfaceSizeChanged = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0;
            final boolean alwaysConsumeNavBarChanged = mPendingAlwaysConsumeNavBar != mAttachInfo.mAlwaysConsumeNavBar;
            if (contentInsetsChanged) {
                mAttachInfo.mContentInsets.set(mPendingContentInsets);
                if (DEBUG_LAYOUT)
                    Log.v(mTag, "Content insets changing to: " + mAttachInfo.mContentInsets);
            }
            if (overscanInsetsChanged) {
                mAttachInfo.mOverscanInsets.set(mPendingOverscanInsets);
                if (DEBUG_LAYOUT)
                    Log.v(mTag, "Overscan insets changing to: " + mAttachInfo.mOverscanInsets);
                // Need to relayout with content insets.
                contentInsetsChanged = true;
            }
            if (stableInsetsChanged) {
                mAttachInfo.mStableInsets.set(mPendingStableInsets);
                if (DEBUG_LAYOUT)
                    Log.v(mTag, "Decor insets changing to: " + mAttachInfo.mStableInsets);
                // Need to relayout with content insets.
                contentInsetsChanged = true;
            }
            if (alwaysConsumeNavBarChanged) {
                mAttachInfo.mAlwaysConsumeNavBar = mPendingAlwaysConsumeNavBar;
                contentInsetsChanged = true;
            }
            if (contentInsetsChanged || mLastSystemUiVisibility != mAttachInfo.mSystemUiVisibility || mApplyInsetsRequested || mLastOverscanRequested != mAttachInfo.mOverscanRequested || outsetsChanged) {
                mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility;
                mLastOverscanRequested = mAttachInfo.mOverscanRequested;
                mAttachInfo.mOutsets.set(mPendingOutsets);
                mApplyInsetsRequested = false;
                dispatchApplyInsets(host);
            }
            if (visibleInsetsChanged) {
                mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets);
                if (DEBUG_LAYOUT)
                    Log.v(mTag, "Visible insets changing to: " + mAttachInfo.mVisibleInsets);
            }
            if (!hadSurface) {
                if (mSurface.isValid()) {
                    // If we are creating a new surface, then we need to
                    // completely redraw it.  Also, when we get to the
                    // point of drawing it we will hold off and schedule
                    // a new traversal instead.  This is so we can tell the
                    // window manager about all of the windows being displayed
                    // before actually drawing them, so it can display then
                    // all at once.
                    newSurface = true;
                    mFullRedrawNeeded = true;
                    mPreviousTransparentRegion.setEmpty();
                    // will be transparent
                    if (mAttachInfo.mHardwareRenderer != null) {
                        try {
                            hwInitialized = mAttachInfo.mHardwareRenderer.initialize(mSurface);
                            if (hwInitialized && (host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) {
                                // Don't pre-allocate if transparent regions
                                // are requested as they may not be needed
                                mSurface.allocateBuffers();
                            }
                        } catch (OutOfResourcesException e) {
                            handleOutOfResourcesException(e);
                            return;
                        }
                    }
                }
            } else if (!mSurface.isValid()) {
                // positions.
                if (mLastScrolledFocus != null) {
                    mLastScrolledFocus.clear();
                }
                mScrollY = mCurScrollY = 0;
                if (mView instanceof RootViewSurfaceTaker) {
                    ((RootViewSurfaceTaker) mView).onRootViewScrollYChanged(mCurScrollY);
                }
                if (mScroller != null) {
                    mScroller.abortAnimation();
                }
                // Our surface is gone
                if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
                    mAttachInfo.mHardwareRenderer.destroy();
                }
            } else if ((surfaceGenerationId != mSurface.getGenerationId() || surfaceSizeChanged) && mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) {
                mFullRedrawNeeded = true;
                try {
                    // Need to do updateSurface (which leads to CanvasContext::setSurface and
                    // re-create the EGLSurface) if either the Surface changed (as indicated by
                    // generation id), or WindowManager changed the surface size. The latter is
                    // because on some chips, changing the consumer side's BufferQueue size may
                    // not take effect immediately unless we create a new EGLSurface.
                    // Note that frame size change doesn't always imply surface size change (eg.
                    // drag resizing uses fullscreen surface), need to check surfaceSizeChanged
                    // flag from WindowManager.
                    mAttachInfo.mHardwareRenderer.updateSurface(mSurface);
                } catch (OutOfResourcesException e) {
                    handleOutOfResourcesException(e);
                    return;
                }
            }
            final boolean freeformResizing = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_FREEFORM) != 0;
            final boolean dockedResizing = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_DOCKED) != 0;
            final boolean dragResizing = freeformResizing || dockedResizing;
            if (mDragResizing != dragResizing) {
                if (dragResizing) {
                    mResizeMode = freeformResizing ? RESIZE_MODE_FREEFORM : RESIZE_MODE_DOCKED_DIVIDER;
                    startDragResizing(mPendingBackDropFrame, mWinFrame.equals(mPendingBackDropFrame), mPendingVisibleInsets, mPendingStableInsets, mResizeMode);
                } else {
                    // We shouldn't come here, but if we come we should end the resize.
                    endDragResizing();
                }
            }
            if (!USE_MT_RENDERER) {
                if (dragResizing) {
                    mCanvasOffsetX = mWinFrame.left;
                    mCanvasOffsetY = mWinFrame.top;
                } else {
                    mCanvasOffsetX = mCanvasOffsetY = 0;
                }
            }
        } catch (RemoteException e) {
        }
        if (DEBUG_ORIENTATION)
            Log.v(TAG, "Relayout returned: frame=" + frame + ", surface=" + mSurface);
        mAttachInfo.mWindowLeft = frame.left;
        mAttachInfo.mWindowTop = frame.top;
        // the window session beforehand.
        if (mWidth != frame.width() || mHeight != frame.height()) {
            mWidth = frame.width();
            mHeight = frame.height();
        }
        if (mSurfaceHolder != null) {
            // The app owns the surface; tell it about what is going on.
            if (mSurface.isValid()) {
                // XXX .copyFrom() doesn't work!
                //mSurfaceHolder.mSurface.copyFrom(mSurface);
                mSurfaceHolder.mSurface = mSurface;
            }
            mSurfaceHolder.setSurfaceFrameSize(mWidth, mHeight);
            mSurfaceHolder.mSurfaceLock.unlock();
            if (mSurface.isValid()) {
                if (!hadSurface) {
                    mSurfaceHolder.ungetCallbacks();
                    mIsCreating = true;
                    mSurfaceHolderCallback.surfaceCreated(mSurfaceHolder);
                    SurfaceHolder.Callback[] callbacks = mSurfaceHolder.getCallbacks();
                    if (callbacks != null) {
                        for (SurfaceHolder.Callback c : callbacks) {
                            c.surfaceCreated(mSurfaceHolder);
                        }
                    }
                    surfaceChanged = true;
                }
                if (surfaceChanged || surfaceGenerationId != mSurface.getGenerationId()) {
                    mSurfaceHolderCallback.surfaceChanged(mSurfaceHolder, lp.format, mWidth, mHeight);
                    SurfaceHolder.Callback[] callbacks = mSurfaceHolder.getCallbacks();
                    if (callbacks != null) {
                        for (SurfaceHolder.Callback c : callbacks) {
                            c.surfaceChanged(mSurfaceHolder, lp.format, mWidth, mHeight);
                        }
                    }
                }
                mIsCreating = false;
            } else if (hadSurface) {
                mSurfaceHolder.ungetCallbacks();
                SurfaceHolder.Callback[] callbacks = mSurfaceHolder.getCallbacks();
                mSurfaceHolderCallback.surfaceDestroyed(mSurfaceHolder);
                if (callbacks != null) {
                    for (SurfaceHolder.Callback c : callbacks) {
                        c.surfaceDestroyed(mSurfaceHolder);
                    }
                }
                mSurfaceHolder.mSurfaceLock.lock();
                try {
                    mSurfaceHolder.mSurface = new Surface();
                } finally {
                    mSurfaceHolder.mSurfaceLock.unlock();
                }
            }
        }
        final ThreadedRenderer hardwareRenderer = mAttachInfo.mHardwareRenderer;
        if (hardwareRenderer != null && hardwareRenderer.isEnabled()) {
            if (hwInitialized || mWidth != hardwareRenderer.getWidth() || mHeight != hardwareRenderer.getHeight() || mNeedsHwRendererSetup) {
                hardwareRenderer.setup(mWidth, mHeight, mAttachInfo, mWindowAttributes.surfaceInsets);
                mNeedsHwRendererSetup = false;
            }
        }
        if (!mStopped || mReportNextDraw) {
            boolean focusChangedDueToTouchMode = ensureTouchModeLocally((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE) != 0);
            if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight() || contentInsetsChanged || updatedConfiguration) {
                int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
                int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
                if (DEBUG_LAYOUT)
                    Log.v(mTag, "Ooops, something changed!  mWidth=" + mWidth + " measuredWidth=" + host.getMeasuredWidth() + " mHeight=" + mHeight + " measuredHeight=" + host.getMeasuredHeight() + " coveredInsetsChanged=" + contentInsetsChanged);
                // Ask host how big it wants to be
                performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
                // Implementation of weights from WindowManager.LayoutParams
                // We just grow the dimensions as needed and re-measure if
                // needs be
                int width = host.getMeasuredWidth();
                int height = host.getMeasuredHeight();
                boolean measureAgain = false;
                if (lp.horizontalWeight > 0.0f) {
                    width += (int) ((mWidth - width) * lp.horizontalWeight);
                    childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
                    measureAgain = true;
                }
                if (lp.verticalWeight > 0.0f) {
                    height += (int) ((mHeight - height) * lp.verticalWeight);
                    childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
                    measureAgain = true;
                }
                if (measureAgain) {
                    if (DEBUG_LAYOUT)
                        Log.v(mTag, "And hey let's measure once more: width=" + width + " height=" + height);
                    performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
                }
                layoutRequested = true;
            }
        }
    } else {
        // Not the first pass and no window/insets/visibility change but the window
        // may have moved and we need check that and if so to update the left and right
        // in the attach info. We translate only the window frame since on window move
        // the window manager tells us only for the new frame but the insets are the
        // same and we do not want to translate them more than once.
        maybeHandleWindowMove(frame);
    }
    final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw);
    boolean triggerGlobalLayoutListener = didLayout || mAttachInfo.mRecomputeGlobalAttributes;
    if (didLayout) {
        performLayout(lp, mWidth, mHeight);
        if ((host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) {
            // start out transparent
            // TODO: AVOID THAT CALL BY CACHING THE RESULT?
            host.getLocationInWindow(mTmpLocation);
            mTransparentRegion.set(mTmpLocation[0], mTmpLocation[1], mTmpLocation[0] + host.mRight - host.mLeft, mTmpLocation[1] + host.mBottom - host.mTop);
            host.gatherTransparentRegion(mTransparentRegion);
            if (mTranslator != null) {
                mTranslator.translateRegionInWindowToScreen(mTransparentRegion);
            }
            if (!mTransparentRegion.equals(mPreviousTransparentRegion)) {
                mPreviousTransparentRegion.set(mTransparentRegion);
                mFullRedrawNeeded = true;
                // reconfigure window manager
                try {
                    mWindowSession.setTransparentRegion(mWindow, mTransparentRegion);
                } catch (RemoteException e) {
                }
            }
        }
        if (DBG) {
            System.out.println("======================================");
            System.out.println("performTraversals -- after setFrame");
            host.debug();
        }
    }
    if (triggerGlobalLayoutListener) {
        mAttachInfo.mRecomputeGlobalAttributes = false;
        mAttachInfo.mTreeObserver.dispatchOnGlobalLayout();
    }
    if (computesInternalInsets) {
        // Clear the original insets.
        final ViewTreeObserver.InternalInsetsInfo insets = mAttachInfo.mGivenInternalInsets;
        insets.reset();
        // Compute new insets in place.
        mAttachInfo.mTreeObserver.dispatchOnComputeInternalInsets(insets);
        mAttachInfo.mHasNonEmptyGivenInternalInsets = !insets.isEmpty();
        // Tell the window manager.
        if (insetsPending || !mLastGivenInsets.equals(insets)) {
            mLastGivenInsets.set(insets);
            // Translate insets to screen coordinates if needed.
            final Rect contentInsets;
            final Rect visibleInsets;
            final Region touchableRegion;
            if (mTranslator != null) {
                contentInsets = mTranslator.getTranslatedContentInsets(insets.contentInsets);
                visibleInsets = mTranslator.getTranslatedVisibleInsets(insets.visibleInsets);
                touchableRegion = mTranslator.getTranslatedTouchableArea(insets.touchableRegion);
            } else {
                contentInsets = insets.contentInsets;
                visibleInsets = insets.visibleInsets;
                touchableRegion = insets.touchableRegion;
            }
            try {
                mWindowSession.setInsets(mWindow, insets.mTouchableInsets, contentInsets, visibleInsets, touchableRegion);
            } catch (RemoteException e) {
            }
        }
    }
    if (mFirst) {
        // handle first focus request
        if (DEBUG_INPUT_RESIZE)
            Log.v(mTag, "First: mView.hasFocus()=" + mView.hasFocus());
        if (mView != null) {
            if (!mView.hasFocus()) {
                mView.requestFocus(View.FOCUS_FORWARD);
                if (DEBUG_INPUT_RESIZE)
                    Log.v(mTag, "First: requested focused view=" + mView.findFocus());
            } else {
                if (DEBUG_INPUT_RESIZE)
                    Log.v(mTag, "First: existing focused view=" + mView.findFocus());
            }
        }
    }
    final boolean changedVisibility = (viewVisibilityChanged || mFirst) && isViewVisible;
    final boolean hasWindowFocus = mAttachInfo.mHasWindowFocus && isViewVisible;
    final boolean regainedFocus = hasWindowFocus && mLostWindowFocus;
    if (regainedFocus) {
        mLostWindowFocus = false;
    } else if (!hasWindowFocus && mHadWindowFocus) {
        mLostWindowFocus = true;
    }
    if (changedVisibility || regainedFocus) {
        // Toasts are presented as notifications - don't present them as windows as well
        boolean isToast = (mWindowAttributes == null) ? false : (mWindowAttributes.type == WindowManager.LayoutParams.TYPE_TOAST);
        if (!isToast) {
            host.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
        }
    }
    mFirst = false;
    mWillDrawSoon = false;
    mNewSurfaceNeeded = false;
    mActivityRelaunched = false;
    mViewVisibility = viewVisibility;
    mHadWindowFocus = hasWindowFocus;
    if (hasWindowFocus && !isInLocalFocusMode()) {
        final boolean imTarget = WindowManager.LayoutParams.mayUseInputMethod(mWindowAttributes.flags);
        if (imTarget != mLastWasImTarget) {
            mLastWasImTarget = imTarget;
            InputMethodManager imm = InputMethodManager.peekInstance();
            if (imm != null && imTarget) {
                imm.onPreWindowFocus(mView, hasWindowFocus);
                imm.onPostWindowFocus(mView, mView.findFocus(), mWindowAttributes.softInputMode, !mHasHadWindowFocus, mWindowAttributes.flags);
            }
        }
    }
    // Remember if we must report the next draw.
    if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
        mReportNextDraw = true;
    }
    boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible;
    if (!cancelDraw && !newSurface) {
        if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
            for (int i = 0; i < mPendingTransitions.size(); ++i) {
                mPendingTransitions.get(i).startChangingAnimations();
            }
            mPendingTransitions.clear();
        }
        performDraw();
    } else {
        if (isViewVisible) {
            // Try again
            scheduleTraversals();
        } else if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
            for (int i = 0; i < mPendingTransitions.size(); ++i) {
                mPendingTransitions.get(i).endChangingAnimations();
            }
            mPendingTransitions.clear();
        }
    }
    mIsInTraversal = false;
}
Also used : Rect(android.graphics.Rect) Configuration(android.content.res.Configuration) CompatibilityInfo(android.content.res.CompatibilityInfo) InputMethodManager(android.view.inputmethod.InputMethodManager) Point(android.graphics.Point) Point(android.graphics.Point) BaseSurfaceHolder(com.android.internal.view.BaseSurfaceHolder) IAccessibilityInteractionConnectionCallback(android.view.accessibility.IAccessibilityInteractionConnectionCallback) OutOfResourcesException(android.view.Surface.OutOfResourcesException) RootViewSurfaceTaker(com.android.internal.view.RootViewSurfaceTaker) Region(android.graphics.Region) Resources(android.content.res.Resources) RemoteException(android.os.RemoteException)

Example 13 with OutOfResourcesException

use of android.view.Surface.OutOfResourcesException in project android_frameworks_base by ResurrectionRemix.

the class EmulatorDisplayOverlay method drawIfNeeded.

private void drawIfNeeded() {
    if (!mDrawNeeded || !mVisible) {
        return;
    }
    mDrawNeeded = false;
    Rect dirty = new Rect(0, 0, mScreenSize.x, mScreenSize.y);
    Canvas c = null;
    try {
        c = mSurface.lockCanvas(dirty);
    } catch (IllegalArgumentException e) {
    } catch (OutOfResourcesException e) {
    }
    if (c == null) {
        return;
    }
    c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SRC);
    mSurfaceControl.setPosition(0, 0);
    // Always draw the overlay with square dimensions
    int size = Math.max(mScreenSize.x, mScreenSize.y);
    mOverlay.setBounds(0, 0, size, size);
    mOverlay.draw(c);
    mSurface.unlockCanvasAndPost(c);
}
Also used : Rect(android.graphics.Rect) OutOfResourcesException(android.view.Surface.OutOfResourcesException) Canvas(android.graphics.Canvas) Point(android.graphics.Point)

Example 14 with OutOfResourcesException

use of android.view.Surface.OutOfResourcesException in project android_frameworks_base by ResurrectionRemix.

the class ScreenRotationAnimation method startAnimation.

/**
     * Returns true if animating.
     */
private boolean startAnimation(SurfaceSession session, long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight, boolean dismissing, int exitAnim, int enterAnim) {
    if (mSurfaceControl == null) {
        // Can't do animation.
        return false;
    }
    if (mStarted) {
        return true;
    }
    mStarted = true;
    boolean firstStart = false;
    // Figure out how the screen has moved from the original rotation.
    int delta = DisplayContent.deltaRotation(mCurRotation, mOriginalRotation);
    if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null && (!dismissing || delta != Surface.ROTATION_0)) {
        if (DEBUG_STATE)
            Slog.v(TAG, "Creating start and finish animations");
        firstStart = true;
        mStartExitAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_start_exit);
        mStartEnterAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_start_enter);
        if (USE_CUSTOM_BLACK_FRAME) {
            mStartFrameAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_start_frame);
        }
        mFinishExitAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_finish_exit);
        mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_finish_enter);
        if (USE_CUSTOM_BLACK_FRAME) {
            mFinishFrameAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_finish_frame);
        }
    }
    if (DEBUG_STATE)
        Slog.v(TAG, "Rotation delta: " + delta + " finalWidth=" + finalWidth + " finalHeight=" + finalHeight + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
    final boolean customAnim;
    if (exitAnim != 0 && enterAnim != 0) {
        customAnim = true;
        mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, exitAnim);
        mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, enterAnim);
    } else {
        customAnim = false;
        switch(delta) {
            case Surface.ROTATION_0:
                mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_0_exit);
                mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_0_enter);
                if (USE_CUSTOM_BLACK_FRAME) {
                    mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_0_frame);
                }
                break;
            case Surface.ROTATION_90:
                mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_plus_90_exit);
                mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_plus_90_enter);
                if (USE_CUSTOM_BLACK_FRAME) {
                    mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_plus_90_frame);
                }
                break;
            case Surface.ROTATION_180:
                mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_180_exit);
                mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_180_enter);
                if (USE_CUSTOM_BLACK_FRAME) {
                    mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_180_frame);
                }
                break;
            case Surface.ROTATION_270:
                mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_minus_90_exit);
                mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_minus_90_enter);
                if (USE_CUSTOM_BLACK_FRAME) {
                    mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_minus_90_frame);
                }
                break;
        }
    }
    // screen's current/new size.
    if (TWO_PHASE_ANIMATION && firstStart) {
        // Compute partial steps between original and final sizes.  These
        // are used for the dimensions of the exiting and entering elements,
        // so they are never stretched too significantly.
        final int halfWidth = (finalWidth + mOriginalWidth) / 2;
        final int halfHeight = (finalHeight + mOriginalHeight) / 2;
        if (DEBUG_STATE)
            Slog.v(TAG, "Initializing start and finish animations");
        mStartEnterAnimation.initialize(finalWidth, finalHeight, halfWidth, halfHeight);
        mStartExitAnimation.initialize(halfWidth, halfHeight, mOriginalWidth, mOriginalHeight);
        mFinishEnterAnimation.initialize(finalWidth, finalHeight, halfWidth, halfHeight);
        mFinishExitAnimation.initialize(halfWidth, halfHeight, mOriginalWidth, mOriginalHeight);
        if (USE_CUSTOM_BLACK_FRAME) {
            mStartFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
            mFinishFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
        }
    }
    mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
    mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
    if (USE_CUSTOM_BLACK_FRAME) {
        mRotateFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
    }
    mAnimRunning = false;
    mFinishAnimReady = false;
    mFinishAnimStartTime = -1;
    if (TWO_PHASE_ANIMATION && firstStart) {
        mStartExitAnimation.restrictDuration(maxAnimationDuration);
        mStartExitAnimation.scaleCurrentDuration(animationScale);
        mStartEnterAnimation.restrictDuration(maxAnimationDuration);
        mStartEnterAnimation.scaleCurrentDuration(animationScale);
        mFinishExitAnimation.restrictDuration(maxAnimationDuration);
        mFinishExitAnimation.scaleCurrentDuration(animationScale);
        mFinishEnterAnimation.restrictDuration(maxAnimationDuration);
        mFinishEnterAnimation.scaleCurrentDuration(animationScale);
        if (USE_CUSTOM_BLACK_FRAME) {
            mStartFrameAnimation.restrictDuration(maxAnimationDuration);
            mStartFrameAnimation.scaleCurrentDuration(animationScale);
            mFinishFrameAnimation.restrictDuration(maxAnimationDuration);
            mFinishFrameAnimation.scaleCurrentDuration(animationScale);
        }
    }
    mRotateExitAnimation.restrictDuration(maxAnimationDuration);
    mRotateExitAnimation.scaleCurrentDuration(animationScale);
    mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
    mRotateEnterAnimation.scaleCurrentDuration(animationScale);
    if (USE_CUSTOM_BLACK_FRAME) {
        mRotateFrameAnimation.restrictDuration(maxAnimationDuration);
        mRotateFrameAnimation.scaleCurrentDuration(animationScale);
    }
    final int layerStack = mDisplayContent.getDisplay().getLayerStack();
    if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
        if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE)
            Slog.i(TAG_WM, ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
        SurfaceControl.openTransaction();
        // Compute the transformation matrix that must be applied
        // the the black frame to make it stay in the initial position
        // before the new screen rotation.  This is different than the
        // snapshot transformation because the snapshot is always based
        // of the native orientation of the screen, not the orientation
        // we were last in.
        createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
        try {
            Rect outer = new Rect(-mOriginalWidth * 1, -mOriginalHeight * 1, mOriginalWidth * 2, mOriginalHeight * 2);
            Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
            mCustomBlackFrame = new BlackFrame(session, outer, inner, SCREEN_FREEZE_LAYER_CUSTOM, layerStack, false);
            mCustomBlackFrame.setMatrix(mFrameInitialMatrix);
        } catch (OutOfResourcesException e) {
            Slog.w(TAG, "Unable to allocate black surface", e);
        } finally {
            SurfaceControl.closeTransaction();
            if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE)
                Slog.i(TAG_WM, "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
        }
    }
    if (!customAnim && mExitingBlackFrame == null) {
        if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE)
            Slog.i(TAG_WM, ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
        SurfaceControl.openTransaction();
        try {
            // Compute the transformation matrix that must be applied
            // the the black frame to make it stay in the initial position
            // before the new screen rotation.  This is different than the
            // snapshot transformation because the snapshot is always based
            // of the native orientation of the screen, not the orientation
            // we were last in.
            createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
            final Rect outer;
            final Rect inner;
            if (mForceDefaultOrientation) {
                // Going from a smaller Display to a larger Display, add curtains to sides
                // or top and bottom. Going from a larger to smaller display will result in
                // no BlackSurfaces being constructed.
                outer = mCurrentDisplayRect;
                inner = mOriginalDisplayRect;
            } else {
                outer = new Rect(-mOriginalWidth * 1, -mOriginalHeight * 1, mOriginalWidth * 2, mOriginalHeight * 2);
                inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
            }
            mExitingBlackFrame = new BlackFrame(session, outer, inner, SCREEN_FREEZE_LAYER_EXIT, layerStack, mForceDefaultOrientation);
            mExitingBlackFrame.setMatrix(mFrameInitialMatrix);
        } catch (OutOfResourcesException e) {
            Slog.w(TAG, "Unable to allocate black surface", e);
        } finally {
            SurfaceControl.closeTransaction();
            if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE)
                Slog.i(TAG_WM, "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
        }
    }
    if (customAnim && mEnteringBlackFrame == null) {
        if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE)
            Slog.i(TAG_WM, ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
        SurfaceControl.openTransaction();
        try {
            Rect outer = new Rect(-finalWidth * 1, -finalHeight * 1, finalWidth * 2, finalHeight * 2);
            Rect inner = new Rect(0, 0, finalWidth, finalHeight);
            mEnteringBlackFrame = new BlackFrame(session, outer, inner, SCREEN_FREEZE_LAYER_ENTER, layerStack, false);
        } catch (OutOfResourcesException e) {
            Slog.w(TAG, "Unable to allocate black surface", e);
        } finally {
            SurfaceControl.closeTransaction();
            if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE)
                Slog.i(TAG_WM, "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
        }
    }
    return true;
}
Also used : Rect(android.graphics.Rect) OutOfResourcesException(android.view.Surface.OutOfResourcesException)

Example 15 with OutOfResourcesException

use of android.view.Surface.OutOfResourcesException in project android_frameworks_base by ResurrectionRemix.

the class WindowManagerService method prepareDragSurface.

// -------------------------------------------------------------
// Drag and drop
// -------------------------------------------------------------
IBinder prepareDragSurface(IWindow window, SurfaceSession session, int flags, int width, int height, Surface outSurface) {
    if (DEBUG_DRAG) {
        Slog.d(TAG_WM, "prepare drag surface: w=" + width + " h=" + height + " flags=" + Integer.toHexString(flags) + " win=" + window + " asbinder=" + window.asBinder());
    }
    final int callerPid = Binder.getCallingPid();
    final int callerUid = Binder.getCallingUid();
    final long origId = Binder.clearCallingIdentity();
    IBinder token = null;
    try {
        synchronized (mWindowMap) {
            try {
                if (mDragState == null) {
                    // TODO(multi-display): support other displays
                    final DisplayContent displayContent = getDefaultDisplayContentLocked();
                    final Display display = displayContent.getDisplay();
                    SurfaceControl surface = new SurfaceControl(session, "drag surface", width, height, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
                    surface.setLayerStack(display.getLayerStack());
                    float alpha = 1;
                    if ((flags & View.DRAG_FLAG_OPAQUE) == 0) {
                        alpha = DRAG_SHADOW_ALPHA_TRANSPARENT;
                    }
                    surface.setAlpha(alpha);
                    if (SHOW_TRANSACTIONS)
                        Slog.i(TAG_WM, "  DRAG " + surface + ": CREATE");
                    outSurface.copyFrom(surface);
                    final IBinder winBinder = window.asBinder();
                    token = new Binder();
                    mDragState = new DragState(this, token, surface, flags, winBinder);
                    mDragState.mPid = callerPid;
                    mDragState.mUid = callerUid;
                    mDragState.mOriginalAlpha = alpha;
                    token = mDragState.mToken = new Binder();
                    // 5 second timeout for this window to actually begin the drag
                    mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
                    Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
                    mH.sendMessageDelayed(msg, 5000);
                } else {
                    Slog.w(TAG_WM, "Drag already in progress");
                }
            } catch (OutOfResourcesException e) {
                Slog.e(TAG_WM, "Can't allocate drag surface w=" + width + " h=" + height, e);
                if (mDragState != null) {
                    mDragState.reset();
                    mDragState = null;
                }
            }
        }
    } finally {
        Binder.restoreCallingIdentity(origId);
    }
    return token;
}
Also used : Binder(android.os.Binder) IBinder(android.os.IBinder) IBinder(android.os.IBinder) Message(android.os.Message) OutOfResourcesException(android.view.Surface.OutOfResourcesException) SurfaceControl(android.view.SurfaceControl) Point(android.graphics.Point) Display(android.view.Display)

Aggregations

OutOfResourcesException (android.view.Surface.OutOfResourcesException)31 Point (android.graphics.Point)21 Rect (android.graphics.Rect)19 RootViewSurfaceTaker (com.android.internal.view.RootViewSurfaceTaker)10 RemoteException (android.os.RemoteException)9 SurfaceControl (android.view.SurfaceControl)8 CompatibilityInfo (android.content.res.CompatibilityInfo)5 Configuration (android.content.res.Configuration)5 Resources (android.content.res.Resources)5 Canvas (android.graphics.Canvas)5 Region (android.graphics.Region)5 AnimatedVectorDrawable (android.graphics.drawable.AnimatedVectorDrawable)5 Drawable (android.graphics.drawable.Drawable)5 EGLSurface (android.opengl.EGLSurface)5 Surface (android.view.Surface)5 SurfaceSession (android.view.SurfaceSession)5 IAccessibilityInteractionConnectionCallback (android.view.accessibility.IAccessibilityInteractionConnectionCallback)5 InputMethodManager (android.view.inputmethod.InputMethodManager)5 BaseSurfaceHolder (com.android.internal.view.BaseSurfaceHolder)5 WindowManager (android.view.WindowManager)4