Search in sources :

Example 1 with Region

use of android.graphics.Region in project android_frameworks_base by ParanoidAndroid.

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 View.AttachInfo attachInfo = mAttachInfo;
    final int viewVisibility = getHostVisibility();
    boolean viewVisibilityChanged = mViewVisibility != viewVisibility || mNewSurfaceNeeded;
    WindowManager.LayoutParams params = null;
    if (mWindowAttributesChanged) {
        mWindowAttributesChanged = false;
        surfaceChanged = true;
        params = lp;
    }
    CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
    if (compatibilityInfo.supportsScreen() == mLastInCompatMode) {
        params = lp;
        mFullRedrawNeeded = true;
        mLayoutRequested = true;
        if (mLastInCompatMode) {
            params.flags &= ~WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
            mLastInCompatMode = false;
        } else {
            params.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
            mLastInCompatMode = true;
        }
    }
    mWindowAttributesChangesFlag = 0;
    Rect frame = mWinFrame;
    if (mFirst) {
        mFullRedrawNeeded = true;
        mLayoutRequested = true;
        if (lp.type == WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL) {
            // NOTE -- system code, won't try to do compat mode.
            Point size = new Point();
            mDisplay.getRealSize(size);
            desiredWindowWidth = size.x;
            desiredWindowHeight = size.y;
        } else {
            DisplayMetrics packageMetrics = mView.getContext().getResources().getDisplayMetrics();
            desiredWindowWidth = packageMetrics.widthPixels;
            desiredWindowHeight = packageMetrics.heightPixels;
        }
        // For the very first time, tell the view hierarchy that it
        // is attached to the window.  Note that at this point the surface
        // object is not initialized to its backing store, but soon it
        // will be (assuming the window is visible).
        attachInfo.mSurface = mSurface;
        // 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
        attachInfo.mUse32BitDrawingCache = true;
        attachInfo.mHasWindowFocus = false;
        attachInfo.mWindowVisibility = viewVisibility;
        attachInfo.mRecomputeGlobalAttributes = false;
        viewVisibilityChanged = 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(attachInfo, 0);
        attachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true);
        mFitSystemWindowsInsets.set(mAttachInfo.mContentInsets);
        host.fitSystemWindows(mFitSystemWindowsInsets);
    //Log.i(TAG, "Screen on initialized: " + attachInfo.mKeepScreenOn);
    } else {
        desiredWindowWidth = frame.width();
        desiredWindowHeight = frame.height();
        if (desiredWindowWidth != mWidth || desiredWindowHeight != mHeight) {
            if (DEBUG_ORIENTATION)
                Log.v(TAG, "View " + host + " resized to: " + frame);
            mFullRedrawNeeded = true;
            mLayoutRequested = true;
            windowSizeMayChange = true;
        }
    }
    if (viewVisibilityChanged) {
        attachInfo.mWindowVisibility = viewVisibility;
        host.dispatchWindowVisibilityChanged(viewVisibility);
        if (viewVisibility != View.VISIBLE || mNewSurfaceNeeded) {
            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;
        }
    }
    // Execute enqueued actions on every traversal in case a detached view enqueued an action
    getRunQueue().executeActions(attachInfo.mHandler);
    boolean insetsChanged = false;
    boolean layoutRequested = mLayoutRequested && !mStopped;
    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 (!mPendingVisibleInsets.equals(mAttachInfo.mVisibleInsets)) {
                mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets);
                if (DEBUG_LAYOUT)
                    Log.v(TAG, "Visible insets changing to: " + mAttachInfo.mVisibleInsets);
            }
            if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
                windowSizeMayChange = true;
                if (lp.type == WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL) {
                    // NOTE -- system code, won't try to do compat mode.
                    Point size = new Point();
                    mDisplay.getRealSize(size);
                    desiredWindowWidth = size.x;
                    desiredWindowHeight = size.y;
                } else {
                    DisplayMetrics packageMetrics = res.getDisplayMetrics();
                    desiredWindowWidth = packageMetrics.widthPixels;
                    desiredWindowHeight = packageMetrics.heightPixels;
                }
            }
        }
        // Ask host how big it wants to be
        windowSizeMayChange |= measureHierarchy(host, lp, res, desiredWindowWidth, desiredWindowHeight);
    }
    if (collectViewAttributes()) {
        params = lp;
    }
    if (attachInfo.mForceReportNewAttributes) {
        attachInfo.mForceReportNewAttributes = false;
        params = lp;
    }
    if (mFirst || attachInfo.mViewVisibilityChanged) {
        attachInfo.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 = attachInfo.mScrollContainers.size();
            for (int i = 0; i < N; i++) {
                if (attachInfo.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 (mFitSystemWindowsRequested) {
        mFitSystemWindowsRequested = false;
        mFitSystemWindowsInsets.set(mAttachInfo.mContentInsets);
        mLastOverscanRequested = mAttachInfo.mOverscanRequested;
        host.fitSystemWindows(mFitSystemWindowsInsets);
        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));
    final boolean computesInternalInsets = attachInfo.mTreeObserver.hasComputeInternalInsetsListeners();
    boolean insetsPending = false;
    int relayoutResult = 0;
    if (mFirst || windowShouldResize || insetsChanged || viewVisibilityChanged || params != null) {
        if (viewVisibility == View.VISIBLE) {
            // 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(TAG, "host=w:" + host.getMeasuredWidth() + ", h:" + host.getMeasuredHeight() + ", params=" + params);
            }
            final int surfaceGenerationId = mSurface.getGenerationId();
            relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
            if (!mDrawDuringWindowsAnimating) {
                mWindowsAnimating |= (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_ANIMATING) != 0;
            }
            if (DEBUG_LAYOUT)
                Log.v(TAG, "relayout: frame=" + frame.toShortString() + " overscan=" + mPendingOverscanInsets.toShortString() + " content=" + mPendingContentInsets.toShortString() + " visible=" + mPendingVisibleInsets.toShortString() + " surface=" + mSurface);
            if (mPendingConfiguration.seq != 0) {
                if (DEBUG_CONFIGURATION)
                    Log.v(TAG, "Visible with new config: " + mPendingConfiguration);
                updateConfiguration(mPendingConfiguration, !mFirst);
                mPendingConfiguration.seq = 0;
            }
            final boolean overscanInsetsChanged = !mPendingOverscanInsets.equals(mAttachInfo.mOverscanInsets);
            contentInsetsChanged = !mPendingContentInsets.equals(mAttachInfo.mContentInsets);
            final boolean visibleInsetsChanged = !mPendingVisibleInsets.equals(mAttachInfo.mVisibleInsets);
            if (contentInsetsChanged) {
                if (mWidth > 0 && mHeight > 0 && lp != null && ((lp.systemUiVisibility | lp.subtreeSystemUiVisibility) & View.SYSTEM_UI_LAYOUT_FLAGS) == 0 && mSurface != null && mSurface.isValid() && !mAttachInfo.mTurnOffWindowResizeAnim && mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled() && mAttachInfo.mHardwareRenderer.validate() && lp != null && !PixelFormat.formatHasAlpha(lp.format)) {
                    disposeResizeBuffer();
                    boolean completed = false;
                    HardwareCanvas hwRendererCanvas = mAttachInfo.mHardwareRenderer.getCanvas();
                    HardwareCanvas layerCanvas = null;
                    try {
                        if (mResizeBuffer == null) {
                            mResizeBuffer = mAttachInfo.mHardwareRenderer.createHardwareLayer(mWidth, mHeight, false);
                        } else if (mResizeBuffer.getWidth() != mWidth || mResizeBuffer.getHeight() != mHeight) {
                            mResizeBuffer.resize(mWidth, mHeight);
                        }
                        // TODO: should handle create/resize failure
                        layerCanvas = mResizeBuffer.start(hwRendererCanvas);
                        final int restoreCount = layerCanvas.save();
                        int yoff;
                        final boolean scrolling = mScroller != null && mScroller.computeScrollOffset();
                        if (scrolling) {
                            yoff = mScroller.getCurrY();
                            mScroller.abortAnimation();
                        } else {
                            yoff = mScrollY;
                        }
                        layerCanvas.translate(0, -yoff);
                        if (mTranslator != null) {
                            mTranslator.translateCanvas(layerCanvas);
                        }
                        DisplayList displayList = mView.mDisplayList;
                        if (displayList != null) {
                            layerCanvas.drawDisplayList(displayList, null, DisplayList.FLAG_CLIP_CHILDREN);
                        } else {
                            mView.draw(layerCanvas);
                        }
                        drawAccessibilityFocusedDrawableIfNeeded(layerCanvas);
                        mResizeBufferStartTime = SystemClock.uptimeMillis();
                        mResizeBufferDuration = mView.getResources().getInteger(com.android.internal.R.integer.config_mediumAnimTime);
                        completed = true;
                        layerCanvas.restoreToCount(restoreCount);
                    } catch (OutOfMemoryError e) {
                        Log.w(TAG, "Not enough memory for content change anim buffer", e);
                    } finally {
                        if (mResizeBuffer != null) {
                            mResizeBuffer.end(hwRendererCanvas);
                            if (!completed) {
                                mResizeBuffer.destroy();
                                mResizeBuffer = null;
                            }
                        }
                    }
                }
                mAttachInfo.mContentInsets.set(mPendingContentInsets);
                if (DEBUG_LAYOUT)
                    Log.v(TAG, "Content insets changing to: " + mAttachInfo.mContentInsets);
            }
            if (overscanInsetsChanged) {
                mAttachInfo.mOverscanInsets.set(mPendingOverscanInsets);
                if (DEBUG_LAYOUT)
                    Log.v(TAG, "Overscan insets changing to: " + mAttachInfo.mOverscanInsets);
                // Need to relayout with content insets.
                contentInsetsChanged = true;
            }
            if (contentInsetsChanged || mLastSystemUiVisibility != mAttachInfo.mSystemUiVisibility || mFitSystemWindowsRequested || mLastOverscanRequested != mAttachInfo.mOverscanRequested) {
                mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility;
                mLastOverscanRequested = mAttachInfo.mOverscanRequested;
                mFitSystemWindowsRequested = false;
                mFitSystemWindowsInsets.set(mAttachInfo.mContentInsets);
                host.fitSystemWindows(mFitSystemWindowsInsets);
            }
            if (visibleInsetsChanged) {
                mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets);
                if (DEBUG_LAYOUT)
                    Log.v(TAG, "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();
                    if (mAttachInfo.mHardwareRenderer != null) {
                        try {
                            hwInitialized = mAttachInfo.mHardwareRenderer.initialize(mHolder.getSurface());
                        } catch (Surface.OutOfResourcesException e) {
                            handleOutOfResourcesException(e);
                            return;
                        }
                    }
                }
            } else if (!mSurface.isValid()) {
                // positions.
                if (mLastScrolledFocus != null) {
                    mLastScrolledFocus.clear();
                }
                mScrollY = mCurScrollY = 0;
                if (mScroller != null) {
                    mScroller.abortAnimation();
                }
                disposeResizeBuffer();
                // Our surface is gone
                if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
                    mAttachInfo.mHardwareRenderer.destroy(true);
                }
            } else if (surfaceGenerationId != mSurface.getGenerationId() && mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) {
                mFullRedrawNeeded = true;
                try {
                    mAttachInfo.mHardwareRenderer.updateSurface(mHolder.getSurface());
                } catch (Surface.OutOfResourcesException e) {
                    handleOutOfResourcesException(e);
                    return;
                }
            }
        } catch (RemoteException e) {
        }
        if (DEBUG_ORIENTATION)
            Log.v(TAG, "Relayout returned: frame=" + frame + ", surface=" + mSurface);
        attachInfo.mWindowLeft = frame.left;
        attachInfo.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) {
                    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();
                }
            }
        }
        if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
            if (hwInitialized || mWidth != mAttachInfo.mHardwareRenderer.getWidth() || mHeight != mAttachInfo.mHardwareRenderer.getHeight()) {
                mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight);
                if (!hwInitialized) {
                    mAttachInfo.mHardwareRenderer.invalidate(mHolder.getSurface());
                    mFullRedrawNeeded = true;
                }
            }
        }
        if (!mStopped) {
            boolean focusChangedDueToTouchMode = ensureTouchModeLocally((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE) != 0);
            if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight() || contentInsetsChanged) {
                int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
                int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
                if (DEBUG_LAYOUT)
                    Log.v(TAG, "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(TAG, "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.
        // TODO: Well, we are checking whether the frame has changed similarly
        // to how this is done for the insets. This is however incorrect since
        // the insets and the frame are translated. For example, the old frame
        // was (1, 1 - 1, 1) and was translated to say (2, 2 - 2, 2), now the new
        // reported frame is (2, 2 - 2, 2) which implies no change but this is not
        // true since we are comparing a not translated value to a translated one.
        // This scenario is rare but we may want to fix that.
        final boolean windowMoved = (attachInfo.mWindowLeft != frame.left || attachInfo.mWindowTop != frame.top);
        if (windowMoved) {
            if (mTranslator != null) {
                mTranslator.translateRectInScreenToAppWinFrame(frame);
            }
            attachInfo.mWindowLeft = frame.left;
            attachInfo.mWindowTop = frame.top;
        }
    }
    final boolean didLayout = layoutRequested && !mStopped;
    boolean triggerGlobalLayoutListener = didLayout || attachInfo.mRecomputeGlobalAttributes;
    if (didLayout) {
        performLayout(lp, desiredWindowWidth, desiredWindowHeight);
        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) {
        attachInfo.mRecomputeGlobalAttributes = false;
        attachInfo.mTreeObserver.dispatchOnGlobalLayout();
        if (AccessibilityManager.getInstance(host.mContext).isEnabled()) {
            postSendWindowContentChangedCallback(mView);
        }
    }
    if (computesInternalInsets) {
        // Clear the original insets.
        final ViewTreeObserver.InternalInsetsInfo insets = attachInfo.mGivenInternalInsets;
        insets.reset();
        // Compute new insets in place.
        attachInfo.mTreeObserver.dispatchOnComputeInternalInsets(insets);
        // 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) {
            }
        }
    }
    boolean skipDraw = false;
    if (mFirst) {
        // handle first focus request
        if (DEBUG_INPUT_RESIZE)
            Log.v(TAG, "First: mView.hasFocus()=" + mView.hasFocus());
        if (mView != null) {
            if (!mView.hasFocus()) {
                mView.requestFocus(View.FOCUS_FORWARD);
                if (DEBUG_INPUT_RESIZE)
                    Log.v(TAG, "First: requested focused view=" + mView.findFocus());
            } else {
                if (DEBUG_INPUT_RESIZE)
                    Log.v(TAG, "First: existing focused view=" + mView.findFocus());
            }
        }
        if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_ANIMATING) != 0) {
            // The first time we relayout the window, if the system is
            // doing window animations, we want to hold of on any future
            // draws until the animation is done.
            mWindowsAnimating = true;
        }
    } else if (mWindowsAnimating) {
        skipDraw = true;
    }
    mFirst = false;
    mWillDrawSoon = false;
    mNewSurfaceNeeded = false;
    mViewVisibility = viewVisibility;
    if (mAttachInfo.mHasWindowFocus) {
        final boolean imTarget = WindowManager.LayoutParams.mayUseInputMethod(mWindowAttributes.flags);
        if (imTarget != mLastWasImTarget) {
            mLastWasImTarget = imTarget;
            InputMethodManager imm = InputMethodManager.peekInstance();
            if (imm != null && imTarget) {
                imm.startGettingWindowFocus(mView);
                imm.onWindowFocus(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 = attachInfo.mTreeObserver.dispatchOnPreDraw() || viewVisibility != View.VISIBLE;
    if (!cancelDraw && !newSurface) {
        if (!skipDraw || mReportNextDraw) {
            if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
                for (int i = 0; i < mPendingTransitions.size(); ++i) {
                    mPendingTransitions.get(i).startChangingAnimations();
                }
                mPendingTransitions.clear();
            }
            performDraw();
        }
    } else {
        if (viewVisibility == View.VISIBLE) {
            // 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 : InputMethodManager(android.view.inputmethod.InputMethodManager) DisplayMetrics(android.util.DisplayMetrics) BaseSurfaceHolder(com.android.internal.view.BaseSurfaceHolder) Rect(android.graphics.Rect) CompatibilityInfo(android.content.res.CompatibilityInfo) Point(android.graphics.Point) Paint(android.graphics.Paint) Point(android.graphics.Point) IAccessibilityInteractionConnectionCallback(android.view.accessibility.IAccessibilityInteractionConnectionCallback) Region(android.graphics.Region) Resources(android.content.res.Resources) RemoteException(android.os.RemoteException) AttachInfo(android.view.View.AttachInfo)

Example 2 with Region

use of android.graphics.Region in project android_frameworks_base by ParanoidAndroid.

the class WebViewClassic method setTouchHighlightRects.

private void setTouchHighlightRects(WebKitHitTest hit) {
    FocusTransitionDrawable transition = null;
    if (shouldAnimateTo(hit)) {
        transition = new FocusTransitionDrawable(this);
    }
    Rect[] rects = hit != null ? hit.mTouchRects : null;
    if (!mTouchHighlightRegion.isEmpty()) {
        mWebView.invalidate(mTouchHighlightRegion.getBounds());
        if (transition != null) {
            transition.mPreviousRegion = new Region(mTouchHighlightRegion);
        }
        mTouchHighlightRegion.setEmpty();
    }
    if (rects != null) {
        mTouchHightlightPaint.setColor(hit.mTapHighlightColor);
        for (Rect rect : rects) {
            Rect viewRect = contentToViewRect(rect);
            // more than half of the screen.
            if (viewRect.width() < getWidth() >> 1 || viewRect.height() < getHeight() >> 1) {
                mTouchHighlightRegion.union(viewRect);
            } else if (DebugFlags.WEB_VIEW) {
                Log.d(LOGTAG, "Skip the huge selection rect:" + viewRect);
            }
        }
        mWebView.invalidate(mTouchHighlightRegion.getBounds());
        if (transition != null && transition.mPreviousRegion != null) {
            transition.mNewRegion = new Region(mTouchHighlightRegion);
            mFocusTransition = transition;
            ObjectAnimator animator = ObjectAnimator.ofFloat(mFocusTransition, "progress", 1f);
            animator.start();
        }
    }
}
Also used : Rect(android.graphics.Rect) ObjectAnimator(android.animation.ObjectAnimator) Region(android.graphics.Region)

Example 3 with Region

use of android.graphics.Region in project android_frameworks_base by ParanoidAndroid.

the class View method applyDrawableToTransparentRegion.

/**
     * Given a Drawable whose bounds have been set to draw into this view,
     * update a Region being computed for
     * {@link #gatherTransparentRegion(android.graphics.Region)} so
     * that any non-transparent parts of the Drawable are removed from the
     * given transparent region.
     *
     * @param dr The Drawable whose transparency is to be applied to the region.
     * @param region A Region holding the current transparency information,
     * where any parts of the region that are set are considered to be
     * transparent.  On return, this region will be modified to have the
     * transparency information reduced by the corresponding parts of the
     * Drawable that are not transparent.
     * {@hide}
     */
public void applyDrawableToTransparentRegion(Drawable dr, Region region) {
    if (DBG) {
        Log.i("View", "Getting transparent region for: " + this);
    }
    final Region r = dr.getTransparentRegion();
    final Rect db = dr.getBounds();
    final AttachInfo attachInfo = mAttachInfo;
    if (r != null && attachInfo != null) {
        final int w = getRight() - getLeft();
        final int h = getBottom() - getTop();
        if (db.left > 0) {
            //Log.i("VIEW", "Drawable left " + db.left + " > view 0");
            r.op(0, 0, db.left, h, Region.Op.UNION);
        }
        if (db.right < w) {
            //Log.i("VIEW", "Drawable right " + db.right + " < view " + w);
            r.op(db.right, 0, w, h, Region.Op.UNION);
        }
        if (db.top > 0) {
            //Log.i("VIEW", "Drawable top " + db.top + " > view 0");
            r.op(0, 0, w, db.top, Region.Op.UNION);
        }
        if (db.bottom < h) {
            //Log.i("VIEW", "Drawable bottom " + db.bottom + " < view " + h);
            r.op(0, db.bottom, w, h, Region.Op.UNION);
        }
        final int[] location = attachInfo.mTransparentLocation;
        getLocationInWindow(location);
        r.translate(location[0], location[1]);
        region.op(r, Region.Op.INTERSECT);
    } else {
        region.op(db, Region.Op.DIFFERENCE);
    }
}
Also used : Rect(android.graphics.Rect) Region(android.graphics.Region) Paint(android.graphics.Paint) Point(android.graphics.Point)

Example 4 with Region

use of android.graphics.Region in project android_frameworks_base by ParanoidAndroid.

the class ScreenMagnifier method onMagnifedBoundsChanged.

@Override
public void onMagnifedBoundsChanged(Region bounds) {
    Region newBounds = Region.obtain(bounds);
    mHandler.obtainMessage(MESSAGE_ON_MAGNIFIED_BOUNDS_CHANGED, newBounds).sendToTarget();
    if (MY_PID != Binder.getCallingPid()) {
        bounds.recycle();
    }
}
Also used : Region(android.graphics.Region)

Example 5 with Region

use of android.graphics.Region in project android_frameworks_base by ParanoidAndroid.

the class WindowState method dump.

void dump(PrintWriter pw, String prefix, boolean dumpAll) {
    pw.print(prefix);
    pw.print("mDisplayId=");
    pw.print(mDisplayContent.getDisplayId());
    pw.print(" mSession=");
    pw.print(mSession);
    pw.print(" mClient=");
    pw.println(mClient.asBinder());
    pw.print(prefix);
    pw.print("mOwnerUid=");
    pw.print(mOwnerUid);
    pw.print(" mShowToOwnerOnly=");
    pw.print(mShowToOwnerOnly);
    pw.print(" package=");
    pw.print(mAttrs.packageName);
    pw.print(" appop=");
    pw.println(AppOpsManager.opToName(mAppOp));
    pw.print(prefix);
    pw.print("mAttrs=");
    pw.println(mAttrs);
    pw.print(prefix);
    pw.print("Requested w=");
    pw.print(mRequestedWidth);
    pw.print(" h=");
    pw.print(mRequestedHeight);
    pw.print(" mLayoutSeq=");
    pw.println(mLayoutSeq);
    if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
        pw.print(prefix);
        pw.print("LastRequested w=");
        pw.print(mLastRequestedWidth);
        pw.print(" h=");
        pw.println(mLastRequestedHeight);
    }
    if (mAttachedWindow != null || mLayoutAttached) {
        pw.print(prefix);
        pw.print("mAttachedWindow=");
        pw.print(mAttachedWindow);
        pw.print(" mLayoutAttached=");
        pw.println(mLayoutAttached);
    }
    if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
        pw.print(prefix);
        pw.print("mIsImWindow=");
        pw.print(mIsImWindow);
        pw.print(" mIsWallpaper=");
        pw.print(mIsWallpaper);
        pw.print(" mIsFloatingLayer=");
        pw.print(mIsFloatingLayer);
        pw.print(" mWallpaperVisible=");
        pw.println(mWallpaperVisible);
    }
    if (dumpAll) {
        pw.print(prefix);
        pw.print("mBaseLayer=");
        pw.print(mBaseLayer);
        pw.print(" mSubLayer=");
        pw.print(mSubLayer);
        pw.print(" mAnimLayer=");
        pw.print(mLayer);
        pw.print("+");
        pw.print((mTargetAppToken != null ? mTargetAppToken.mAppAnimator.animLayerAdjustment : (mAppToken != null ? mAppToken.mAppAnimator.animLayerAdjustment : 0)));
        pw.print("=");
        pw.print(mWinAnimator.mAnimLayer);
        pw.print(" mLastLayer=");
        pw.println(mWinAnimator.mLastLayer);
    }
    if (dumpAll) {
        pw.print(prefix);
        pw.print("mToken=");
        pw.println(mToken);
        pw.print(prefix);
        pw.print("mRootToken=");
        pw.println(mRootToken);
        if (mAppToken != null) {
            pw.print(prefix);
            pw.print("mAppToken=");
            pw.println(mAppToken);
        }
        if (mTargetAppToken != null) {
            pw.print(prefix);
            pw.print("mTargetAppToken=");
            pw.println(mTargetAppToken);
        }
        pw.print(prefix);
        pw.print("mViewVisibility=0x");
        pw.print(Integer.toHexString(mViewVisibility));
        pw.print(" mHaveFrame=");
        pw.print(mHaveFrame);
        pw.print(" mObscured=");
        pw.println(mObscured);
        pw.print(prefix);
        pw.print("mSeq=");
        pw.print(mSeq);
        pw.print(" mSystemUiVisibility=0x");
        pw.println(Integer.toHexString(mSystemUiVisibility));
    }
    if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || !mAppOpVisibility || mAttachedHidden) {
        pw.print(prefix);
        pw.print("mPolicyVisibility=");
        pw.print(mPolicyVisibility);
        pw.print(" mPolicyVisibilityAfterAnim=");
        pw.print(mPolicyVisibilityAfterAnim);
        pw.print(" mAppOpVisibility=");
        pw.print(mAppOpVisibility);
        pw.print(" mAttachedHidden=");
        pw.println(mAttachedHidden);
    }
    if (!mRelayoutCalled || mLayoutNeeded) {
        pw.print(prefix);
        pw.print("mRelayoutCalled=");
        pw.print(mRelayoutCalled);
        pw.print(" mLayoutNeeded=");
        pw.println(mLayoutNeeded);
    }
    if (mXOffset != 0 || mYOffset != 0) {
        pw.print(prefix);
        pw.print("Offsets x=");
        pw.print(mXOffset);
        pw.print(" y=");
        pw.println(mYOffset);
    }
    if (dumpAll) {
        pw.print(prefix);
        pw.print("mGivenContentInsets=");
        mGivenContentInsets.printShortString(pw);
        pw.print(" mGivenVisibleInsets=");
        mGivenVisibleInsets.printShortString(pw);
        pw.println();
        if (mTouchableInsets != 0 || mGivenInsetsPending) {
            pw.print(prefix);
            pw.print("mTouchableInsets=");
            pw.print(mTouchableInsets);
            pw.print(" mGivenInsetsPending=");
            pw.println(mGivenInsetsPending);
            Region region = new Region();
            getTouchableRegion(region);
            pw.print(prefix);
            pw.print("touchable region=");
            pw.println(region);
        }
        pw.print(prefix);
        pw.print("mConfiguration=");
        pw.println(mConfiguration);
    }
    pw.print(prefix);
    pw.print("mHasSurface=");
    pw.print(mHasSurface);
    pw.print(" mShownFrame=");
    mShownFrame.printShortString(pw);
    pw.print(" isReadyForDisplay()=");
    pw.println(isReadyForDisplay());
    if (dumpAll) {
        pw.print(prefix);
        pw.print("mFrame=");
        mFrame.printShortString(pw);
        pw.print(" last=");
        mLastFrame.printShortString(pw);
        pw.println();
        pw.print(prefix);
        pw.print("mSystemDecorRect=");
        mSystemDecorRect.printShortString(pw);
        pw.print(" last=");
        mLastSystemDecorRect.printShortString(pw);
        pw.println();
    }
    if (mEnforceSizeCompat) {
        pw.print(prefix);
        pw.print("mCompatFrame=");
        mCompatFrame.printShortString(pw);
        pw.println();
    }
    if (dumpAll) {
        pw.print(prefix);
        pw.print("Frames: containing=");
        mContainingFrame.printShortString(pw);
        pw.print(" parent=");
        mParentFrame.printShortString(pw);
        pw.println();
        pw.print(prefix);
        pw.print("    display=");
        mDisplayFrame.printShortString(pw);
        pw.print(" overscan=");
        mOverscanFrame.printShortString(pw);
        pw.println();
        pw.print(prefix);
        pw.print("    content=");
        mContentFrame.printShortString(pw);
        pw.print(" visible=");
        mVisibleFrame.printShortString(pw);
        pw.println();
        pw.print(prefix);
        pw.print("Cur insets: overscan=");
        mOverscanInsets.printShortString(pw);
        pw.print(" content=");
        mContentInsets.printShortString(pw);
        pw.print(" visible=");
        mVisibleInsets.printShortString(pw);
        pw.println();
        pw.print(prefix);
        pw.print("Lst insets: overscan=");
        mLastOverscanInsets.printShortString(pw);
        pw.print(" content=");
        mLastContentInsets.printShortString(pw);
        pw.print(" visible=");
        mLastVisibleInsets.printShortString(pw);
        pw.println();
    }
    pw.print(prefix);
    pw.print(mWinAnimator);
    pw.println(":");
    mWinAnimator.dump(pw, prefix + "  ", dumpAll);
    if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
        pw.print(prefix);
        pw.print("mExiting=");
        pw.print(mExiting);
        pw.print(" mRemoveOnExit=");
        pw.print(mRemoveOnExit);
        pw.print(" mDestroying=");
        pw.print(mDestroying);
        pw.print(" mRemoved=");
        pw.println(mRemoved);
    }
    if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
        pw.print(prefix);
        pw.print("mOrientationChanging=");
        pw.print(mOrientationChanging);
        pw.print(" mAppFreezing=");
        pw.print(mAppFreezing);
        pw.print(" mTurnOnScreen=");
        pw.println(mTurnOnScreen);
    }
    if (mLastFreezeDuration != 0) {
        pw.print(prefix);
        pw.print("mLastFreezeDuration=");
        TimeUtils.formatDuration(mLastFreezeDuration, pw);
        pw.println();
    }
    if (mHScale != 1 || mVScale != 1) {
        pw.print(prefix);
        pw.print("mHScale=");
        pw.print(mHScale);
        pw.print(" mVScale=");
        pw.println(mVScale);
    }
    if (mWallpaperX != -1 || mWallpaperY != -1) {
        pw.print(prefix);
        pw.print("mWallpaperX=");
        pw.print(mWallpaperX);
        pw.print(" mWallpaperY=");
        pw.println(mWallpaperY);
    }
    if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
        pw.print(prefix);
        pw.print("mWallpaperXStep=");
        pw.print(mWallpaperXStep);
        pw.print(" mWallpaperYStep=");
        pw.println(mWallpaperYStep);
    }
}
Also used : Region(android.graphics.Region)

Aggregations

Region (android.graphics.Region)55 Point (android.graphics.Point)40 RemoteException (android.os.RemoteException)33 IAccessibilityInteractionConnectionCallback (android.view.accessibility.IAccessibilityInteractionConnectionCallback)33 AccessibilityNodeInfo (android.view.accessibility.AccessibilityNodeInfo)25 SomeArgs (com.android.internal.os.SomeArgs)25 Rect (android.graphics.Rect)21 Paint (android.graphics.Paint)13 AccessibilityNodeProvider (android.view.accessibility.AccessibilityNodeProvider)10 CompatibilityInfo (android.content.res.CompatibilityInfo)8 Resources (android.content.res.Resources)8 InputMethodManager (android.view.inputmethod.InputMethodManager)8 BaseSurfaceHolder (com.android.internal.view.BaseSurfaceHolder)8 Configuration (android.content.res.Configuration)5 OutOfResourcesException (android.view.Surface.OutOfResourcesException)5 RootViewSurfaceTaker (com.android.internal.view.RootViewSurfaceTaker)5 ArrayList (java.util.ArrayList)5 LinkedList (java.util.LinkedList)5 List (java.util.List)5 DisplayMetrics (android.util.DisplayMetrics)3