Search in sources :

Example 16 with MagnificationSpec

use of android.view.MagnificationSpec in project android_frameworks_base by crdroidandroid.

the class MagnificationController method updateMagnificationSpecLocked.

/**
     * Updates the current magnification spec.
     *
     * @param scale the magnification scale
     * @param centerX the unscaled, screen-relative X coordinate of the center
     *                of the viewport, or {@link Float#NaN} to leave unchanged
     * @param centerY the unscaled, screen-relative Y coordinate of the center
     *                of the viewport, or {@link Float#NaN} to leave unchanged
     * @return {@code true} if the magnification spec changed or {@code false}
     *         otherwise
     */
private boolean updateMagnificationSpecLocked(float scale, float centerX, float centerY) {
    // Handle defaults.
    if (Float.isNaN(centerX)) {
        centerX = getCenterX();
    }
    if (Float.isNaN(centerY)) {
        centerY = getCenterY();
    }
    if (Float.isNaN(scale)) {
        scale = getScale();
    }
    // Ensure requested center is within the magnification region.
    if (!magnificationRegionContains(centerX, centerY)) {
        return false;
    }
    // Compute changes.
    final MagnificationSpec currSpec = mCurrentMagnificationSpec;
    boolean changed = false;
    final float normScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
    if (Float.compare(currSpec.scale, normScale) != 0) {
        currSpec.scale = normScale;
        changed = true;
    }
    final float nonNormOffsetX = mMagnificationBounds.width() / 2.0f + mMagnificationBounds.left - centerX * scale;
    final float offsetX = MathUtils.constrain(nonNormOffsetX, getMinOffsetXLocked(), 0);
    if (Float.compare(currSpec.offsetX, offsetX) != 0) {
        currSpec.offsetX = offsetX;
        changed = true;
    }
    final float nonNormOffsetY = mMagnificationBounds.height() / 2.0f + mMagnificationBounds.top - centerY * scale;
    final float offsetY = MathUtils.constrain(nonNormOffsetY, getMinOffsetYLocked(), 0);
    if (Float.compare(currSpec.offsetY, offsetY) != 0) {
        currSpec.offsetY = offsetY;
        changed = true;
    }
    if (changed) {
        onMagnificationChangedLocked();
    }
    return changed;
}
Also used : MagnificationSpec(android.view.MagnificationSpec)

Example 17 with MagnificationSpec

use of android.view.MagnificationSpec in project android_frameworks_base by crdroidandroid.

the class MagnificationController method onMagnificationRegionChanged.

/**
     * Update our copy of the current magnification region
     *
     * @param magnified the magnified region
     * @param updateSpec {@code true} to update the scale and center based on
     *                   the region bounds, {@code false} to leave them as-is
     */
private void onMagnificationRegionChanged(Region magnified, boolean updateSpec) {
    synchronized (mLock) {
        if (!mRegistered) {
            // Don't update if we've unregistered
            return;
        }
        boolean magnificationChanged = false;
        boolean boundsChanged = false;
        if (!mMagnificationRegion.equals(magnified)) {
            mMagnificationRegion.set(magnified);
            mMagnificationRegion.getBounds(mMagnificationBounds);
            boundsChanged = true;
        }
        if (updateSpec) {
            final MagnificationSpec sentSpec = mSpecAnimationBridge.mSentMagnificationSpec;
            final float scale = sentSpec.scale;
            final float offsetX = sentSpec.offsetX;
            final float offsetY = sentSpec.offsetY;
            // Compute the new center and update spec as needed.
            final float centerX = (mMagnificationBounds.width() / 2.0f + mMagnificationBounds.left - offsetX) / scale;
            final float centerY = (mMagnificationBounds.height() / 2.0f + mMagnificationBounds.top - offsetY) / scale;
            magnificationChanged = setScaleAndCenterLocked(scale, centerX, centerY, false, INVALID_ID);
        }
        // If magnification changed we already notified for the change.
        if (boundsChanged && updateSpec && !magnificationChanged) {
            onMagnificationChangedLocked();
        }
    }
}
Also used : MagnificationSpec(android.view.MagnificationSpec)

Example 18 with MagnificationSpec

use of android.view.MagnificationSpec in project android_frameworks_base by crdroidandroid.

the class MagnificationController method resetLocked.

private boolean resetLocked(boolean animate) {
    if (!mRegistered) {
        return false;
    }
    final MagnificationSpec spec = mCurrentMagnificationSpec;
    final boolean changed = !spec.isNop();
    if (changed) {
        spec.clear();
        onMagnificationChangedLocked();
    }
    mIdOfLastServiceToMagnify = INVALID_ID;
    mSpecAnimationBridge.updateSentSpec(spec, animate);
    return changed;
}
Also used : MagnificationSpec(android.view.MagnificationSpec)

Example 19 with MagnificationSpec

use of android.view.MagnificationSpec in project android_frameworks_base by crdroidandroid.

the class MagnificationController method offsetMagnifiedRegionCenter.

/**
     * Offsets the center of the magnified region.
     *
     * @param offsetX the amount in pixels to offset the X center
     * @param offsetY the amount in pixels to offset the Y center
     * @param id the ID of the service requesting the change
     */
public void offsetMagnifiedRegionCenter(float offsetX, float offsetY, int id) {
    synchronized (mLock) {
        if (!mRegistered) {
            return;
        }
        final MagnificationSpec currSpec = mCurrentMagnificationSpec;
        final float nonNormOffsetX = currSpec.offsetX - offsetX;
        currSpec.offsetX = MathUtils.constrain(nonNormOffsetX, getMinOffsetXLocked(), 0);
        final float nonNormOffsetY = currSpec.offsetY - offsetY;
        currSpec.offsetY = MathUtils.constrain(nonNormOffsetY, getMinOffsetYLocked(), 0);
        if (id != INVALID_ID) {
            mIdOfLastServiceToMagnify = id;
        }
        mSpecAnimationBridge.updateSentSpec(currSpec, false);
    }
}
Also used : MagnificationSpec(android.view.MagnificationSpec)

Example 20 with MagnificationSpec

use of android.view.MagnificationSpec in project platform_frameworks_base by android.

the class WindowStateAnimator method computeShownFrameLocked.

void computeShownFrameLocked() {
    final boolean selfTransformation = mHasLocalTransformation;
    Transformation attachedTransformation = (mAttachedWinAnimator != null && mAttachedWinAnimator.mHasLocalTransformation) ? mAttachedWinAnimator.mTransformation : null;
    Transformation appTransformation = (mAppAnimator != null && mAppAnimator.hasTransformation) ? mAppAnimator.transformation : null;
    // Wallpapers are animated based on the "real" window they
    // are currently targeting.
    final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
    if (mIsWallpaper && wallpaperTarget != null && mService.mAnimateWallpaperWithTarget) {
        final WindowStateAnimator wallpaperAnimator = wallpaperTarget.mWinAnimator;
        if (wallpaperAnimator.mHasLocalTransformation && wallpaperAnimator.mAnimation != null && !wallpaperAnimator.mAnimation.getDetachWallpaper()) {
            attachedTransformation = wallpaperAnimator.mTransformation;
            if (DEBUG_WALLPAPER && attachedTransformation != null) {
                Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
            }
        }
        final AppWindowAnimator wpAppAnimator = wallpaperTarget.mAppToken == null ? null : wallpaperTarget.mAppToken.mAppAnimator;
        if (wpAppAnimator != null && wpAppAnimator.hasTransformation && wpAppAnimator.animation != null && !wpAppAnimator.animation.getDetachWallpaper()) {
            appTransformation = wpAppAnimator.transformation;
            if (DEBUG_WALLPAPER && appTransformation != null) {
                Slog.v(TAG, "WP target app xform: " + appTransformation);
            }
        }
    }
    final int displayId = mWin.getDisplayId();
    final ScreenRotationAnimation screenRotationAnimation = mAnimator.getScreenRotationAnimationLocked(displayId);
    final boolean screenAnimation = screenRotationAnimation != null && screenRotationAnimation.isAnimating();
    mHasClipRect = false;
    if (selfTransformation || attachedTransformation != null || appTransformation != null || screenAnimation) {
        // cache often used attributes locally
        final Rect frame = mWin.mFrame;
        final float[] tmpFloats = mService.mTmpFloats;
        final Matrix tmpMatrix = mWin.mTmpMatrix;
        // Compute the desired transformation.
        if (screenAnimation && screenRotationAnimation.isRotating()) {
            // If we are doing a screen animation, the global rotation
            // applied to windows can result in windows that are carefully
            // aligned with each other to slightly separate, allowing you
            // to see what is behind them.  An unsightly mess.  This...
            // thing...  magically makes it call good: scale each window
            // slightly (two pixels larger in each dimension, from the
            // window's center).
            final float w = frame.width();
            final float h = frame.height();
            if (w >= 1 && h >= 1) {
                tmpMatrix.setScale(1 + 2 / w, 1 + 2 / h, w / 2, h / 2);
            } else {
                tmpMatrix.reset();
            }
        } else {
            tmpMatrix.reset();
        }
        tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
        if (selfTransformation) {
            tmpMatrix.postConcat(mTransformation.getMatrix());
        }
        if (attachedTransformation != null) {
            tmpMatrix.postConcat(attachedTransformation.getMatrix());
        }
        tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
        if (appTransformation != null) {
            tmpMatrix.postConcat(appTransformation.getMatrix());
        }
        if (screenAnimation) {
            tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
        }
        //TODO (multidisplay): Magnification is supported only for the default display.
        if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
            MagnificationSpec spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
            applyMagnificationSpec(spec, tmpMatrix);
        }
        // "convert" it into SurfaceFlinger's format
        // (a 2x2 matrix + an offset)
        // Here we must not transform the position of the surface
        // since it is already included in the transformation.
        //Slog.i(TAG_WM, "Transform: " + matrix);
        mHaveMatrix = true;
        tmpMatrix.getValues(tmpFloats);
        mDsDx = tmpFloats[Matrix.MSCALE_X];
        mDtDx = tmpFloats[Matrix.MSKEW_Y];
        mDsDy = tmpFloats[Matrix.MSKEW_X];
        mDtDy = tmpFloats[Matrix.MSCALE_Y];
        float x = tmpFloats[Matrix.MTRANS_X];
        float y = tmpFloats[Matrix.MTRANS_Y];
        mWin.mShownPosition.set(Math.round(x), Math.round(y));
        // Now set the alpha...  but because our current hardware
        // can't do alpha transformation on a non-opaque surface,
        // turn it off if we are running an animation that is also
        // transforming since it is more important to have that
        // animation be smooth.
        mShownAlpha = mAlpha;
        if (!mService.mLimitedAlphaCompositing || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format) || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy) && x == frame.left && y == frame.top))) {
            //Slog.i(TAG_WM, "Applying alpha transform");
            if (selfTransformation) {
                mShownAlpha *= mTransformation.getAlpha();
            }
            if (attachedTransformation != null) {
                mShownAlpha *= attachedTransformation.getAlpha();
            }
            if (appTransformation != null) {
                mShownAlpha *= appTransformation.getAlpha();
                if (appTransformation.hasClipRect()) {
                    mClipRect.set(appTransformation.getClipRect());
                    mHasClipRect = true;
                    // bounds to compensate for this.
                    if (mWin.layoutInParentFrame()) {
                        mClipRect.offset((mWin.mContainingFrame.left - mWin.mFrame.left), mWin.mContainingFrame.top - mWin.mFrame.top);
                    }
                }
            }
            if (screenAnimation) {
                mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
            }
        } else {
        //Slog.i(TAG_WM, "Not applying alpha transform");
        }
        if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV) && (mShownAlpha == 1.0 || mShownAlpha == 0.0))
            Slog.v(TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha + " self=" + (selfTransformation ? mTransformation.getAlpha() : "null") + " attached=" + (attachedTransformation == null ? "null" : attachedTransformation.getAlpha()) + " app=" + (appTransformation == null ? "null" : appTransformation.getAlpha()) + " screen=" + (screenAnimation ? screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
        return;
    } else if (mIsWallpaper && mService.mWindowPlacerLocked.mWallpaperActionPending) {
        return;
    } else if (mWin.isDragResizeChanged()) {
        // with new geometry.
        return;
    }
    if (WindowManagerService.localLOGV)
        Slog.v(TAG, "computeShownFrameLocked: " + this + " not attached, mAlpha=" + mAlpha);
    MagnificationSpec spec = null;
    //TODO (multidisplay): Magnification is supported only for the default display.
    if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
        spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
    }
    if (spec != null) {
        final Rect frame = mWin.mFrame;
        final float[] tmpFloats = mService.mTmpFloats;
        final Matrix tmpMatrix = mWin.mTmpMatrix;
        tmpMatrix.setScale(mWin.mGlobalScale, mWin.mGlobalScale);
        tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
        applyMagnificationSpec(spec, tmpMatrix);
        tmpMatrix.getValues(tmpFloats);
        mHaveMatrix = true;
        mDsDx = tmpFloats[Matrix.MSCALE_X];
        mDtDx = tmpFloats[Matrix.MSKEW_Y];
        mDsDy = tmpFloats[Matrix.MSKEW_X];
        mDtDy = tmpFloats[Matrix.MSCALE_Y];
        float x = tmpFloats[Matrix.MTRANS_X];
        float y = tmpFloats[Matrix.MTRANS_Y];
        mWin.mShownPosition.set(Math.round(x), Math.round(y));
        mShownAlpha = mAlpha;
    } else {
        mWin.mShownPosition.set(mWin.mFrame.left, mWin.mFrame.top);
        if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
            mWin.mShownPosition.offset(mWin.mXOffset, mWin.mYOffset);
        }
        mShownAlpha = mAlpha;
        mHaveMatrix = false;
        mDsDx = mWin.mGlobalScale;
        mDtDx = 0;
        mDsDy = 0;
        mDtDy = mWin.mGlobalScale;
    }
}
Also used : MagnificationSpec(android.view.MagnificationSpec) Transformation(android.view.animation.Transformation) Rect(android.graphics.Rect) Matrix(android.graphics.Matrix) Point(android.graphics.Point)

Aggregations

MagnificationSpec (android.view.MagnificationSpec)35 Rect (android.graphics.Rect)12 Point (android.graphics.Point)7 Matrix (android.graphics.Matrix)5 Transformation (android.view.animation.Transformation)5 AccessibilityService (android.accessibilityservice.AccessibilityService)1 Paint (android.graphics.Paint)1 WindowManagerPolicy (android.view.WindowManagerPolicy)1 AccessibilityInteractionClient (android.view.accessibility.AccessibilityInteractionClient)1 AccessibilityNodeInfo (android.view.accessibility.AccessibilityNodeInfo)1 IStatusBarService (com.android.internal.statusbar.IStatusBarService)1