From 8e31c3ef143f391b2360fd8f16ea68af9151d122 Mon Sep 17 00:00:00 2001 From: Nader Jawad Date: Sun, 14 Apr 2019 21:58:04 -0700 Subject: Added BlendMode equivalent APIs to replace deprecated PorterDuff variants Updated various framework Views to have equivalent BlendMode APIs to replace the deprecated PorterDuff equivalents. Updated InspectableProperty annotations to refer to the same xml attributes as the original tintmode APIs Bug: 126726419 Test: Added CTS tests to verify new BlendMode APIs Change-Id: Id9ab36d3d4d29f351250723e9d13d49bc6062c83 --- graphics/java/android/graphics/BaseCanvas.java | 4 ---- .../java/android/graphics/BaseRecordingCanvas.java | 4 ---- graphics/java/android/graphics/Canvas.java | 3 --- graphics/java/android/graphics/ComposeShader.java | 6 +----- graphics/java/android/graphics/Paint.java | 7 ------- graphics/java/android/graphics/PorterDuff.java | 3 +-- .../android/graphics/PorterDuffColorFilter.java | 4 ---- .../java/android/graphics/PorterDuffXfermode.java | 4 ---- .../graphics/drawable/AdaptiveIconDrawable.java | 4 ++-- .../graphics/drawable/AnimatedVectorDrawable.java | 4 ++-- .../android/graphics/drawable/BitmapDrawable.java | 2 +- .../android/graphics/drawable/ColorDrawable.java | 2 +- .../graphics/drawable/ColorStateListDrawable.java | 6 +++--- .../java/android/graphics/drawable/Drawable.java | 21 +++++++++------------ .../graphics/drawable/DrawableContainer.java | 6 +++--- .../android/graphics/drawable/DrawableWrapper.java | 4 ++-- .../android/graphics/drawable/GradientDrawable.java | 2 +- graphics/java/android/graphics/drawable/Icon.java | 7 ++----- .../android/graphics/drawable/LayerDrawable.java | 4 ++-- .../graphics/drawable/NinePatchDrawable.java | 2 +- .../android/graphics/drawable/ShapeDrawable.java | 2 +- .../android/graphics/drawable/VectorDrawable.java | 2 +- 22 files changed, 33 insertions(+), 70 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java index c9431e3178f0..6e7f286d19a7 100644 --- a/graphics/java/android/graphics/BaseCanvas.java +++ b/graphics/java/android/graphics/BaseCanvas.java @@ -243,10 +243,6 @@ public abstract class BaseCanvas { nDrawColor(mNativeCanvasWrapper, color, BlendMode.SRC_OVER.getXfermode().porterDuffMode); } - /** - * @deprecated use {@link Canvas#drawColor(int, BlendMode)} - */ - @Deprecated public void drawColor(@ColorInt int color, @NonNull PorterDuff.Mode mode) { nDrawColor(mNativeCanvasWrapper, color, mode.nativeInt); } diff --git a/graphics/java/android/graphics/BaseRecordingCanvas.java b/graphics/java/android/graphics/BaseRecordingCanvas.java index 028b784d24c2..2f5214cb1df5 100644 --- a/graphics/java/android/graphics/BaseRecordingCanvas.java +++ b/graphics/java/android/graphics/BaseRecordingCanvas.java @@ -203,10 +203,6 @@ public class BaseRecordingCanvas extends Canvas { nDrawColor(mNativeCanvasWrapper, color, BlendMode.SRC_OVER.getXfermode().porterDuffMode); } - /** - * @deprecated use {@link #drawColor(int, BlendMode)} instead - */ - @Deprecated @Override public final void drawColor(@ColorInt int color, @NonNull PorterDuff.Mode mode) { nDrawColor(mNativeCanvasWrapper, color, mode.nativeInt); diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index 6f00fc907849..d4d5ae7bdddb 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -1700,10 +1700,7 @@ public class Canvas extends BaseCanvas { * * @param color the color to draw onto the canvas * @param mode the porter-duff mode to apply to the color - * - * @deprecated use {@link #drawColor(int, BlendMode)} instead */ - @Deprecated public void drawColor(@ColorInt int color, @NonNull PorterDuff.Mode mode) { super.drawColor(color, mode); } diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java index 93ddb10d24bc..64ee6bf1f30c 100644 --- a/graphics/java/android/graphics/ComposeShader.java +++ b/graphics/java/android/graphics/ComposeShader.java @@ -39,9 +39,7 @@ public class ComposeShader extends Shader { * @param shaderB The colors from this shader are seen as the "src" by the mode * @param mode The mode that combines the colors from the two shaders. If mode * is null, then SRC_OVER is assumed. - * - * @deprecated use {@link #ComposeShader(Shader, Shader, BlendMode)} instead - */ + */ @Deprecated public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull Xfermode mode) { this(shaderA, shaderB, mode.porterDuffMode); @@ -56,9 +54,7 @@ public class ComposeShader extends Shader { * @param shaderB The colors from this shader are seen as the "src" by the mode * @param mode The PorterDuff mode that combines the colors from the two shaders. * - * @deprecated use {@link #ComposeShader(Shader, Shader, BlendMode)} instead */ - @Deprecated public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull PorterDuff.Mode mode) { this(shaderA, shaderB, mode.nativeInt); diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index db5f06524c18..b7316ab03618 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -1274,10 +1274,7 @@ public class Paint { * Get the paint's transfer mode object. * * @return the paint's transfer mode (or null) - * - * @deprecated use {@link #getBlendMode()} instead */ - @Deprecated public Xfermode getXfermode() { return mXfermode; } @@ -1308,11 +1305,7 @@ public class Paint { * * @param xfermode May be null. The xfermode to be installed in the paint * @return xfermode - * - * @deprecated Use {@link #setBlendMode} to apply a Xfermode directly - * through usage of {@link BlendMode} */ - @Deprecated public Xfermode setXfermode(Xfermode xfermode) { return installXfermode(xfermode); } diff --git a/graphics/java/android/graphics/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java index 459291b7565e..bc1f66fdd5c0 100644 --- a/graphics/java/android/graphics/PorterDuff.java +++ b/graphics/java/android/graphics/PorterDuff.java @@ -24,9 +24,8 @@ import android.annotation.UnsupportedAppUsage; * of {@link Paint}'s {@link Paint#setXfermode(Xfermode) transfer mode}. * All the available modes can be found in the {@link Mode} enum.

* - * @deprecated Use {@link BlendMode} with {@link Paint#setBlendMode(BlendMode)} instead + * Consider using {@link BlendMode} instead as it provides a wider variety of tinting options */ -@Deprecated public class PorterDuff { /** * {@usesMathJax} diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java index c2a8eb7dbab1..cc2d3a8969fc 100644 --- a/graphics/java/android/graphics/PorterDuffColorFilter.java +++ b/graphics/java/android/graphics/PorterDuffColorFilter.java @@ -23,11 +23,7 @@ import android.annotation.UnsupportedAppUsage; /** * A color filter that can be used to tint the source pixels using a single * color and a specific {@link PorterDuff Porter-Duff composite mode}. - * - * @deprecated Consider using {@link BlendModeColorFilter} instead as it supports a wider - * set of blend modes than those defined in {@link PorterDuff.Mode} */ -@Deprecated public class PorterDuffColorFilter extends ColorFilter { @ColorInt private int mColor; diff --git a/graphics/java/android/graphics/PorterDuffXfermode.java b/graphics/java/android/graphics/PorterDuffXfermode.java index 5b933c493162..ff9ff8b0069d 100644 --- a/graphics/java/android/graphics/PorterDuffXfermode.java +++ b/graphics/java/android/graphics/PorterDuffXfermode.java @@ -22,10 +22,6 @@ package android.graphics; * documentation of the {@link PorterDuff.Mode} enum for more * information on the available alpha compositing and blending modes.

* - * @deprecated Consider using {@link BlendMode} instead as it supports a wider - * set of blend modes than those defined in {@link PorterDuff.Mode} - * - * @see Paint#setBlendMode(BlendMode) */ public class PorterDuffXfermode extends Xfermode { /** diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java index 7def322c1953..fab96a1e9fbd 100644 --- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java +++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java @@ -701,13 +701,13 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback } @Override - public void setTintMode(@NonNull BlendMode blendMode) { + public void setTintBlendMode(@NonNull BlendMode blendMode) { final ChildDrawable[] array = mLayerState.mChildren; final int N = mLayerState.N_CHILDREN; for (int i = 0; i < N; i++) { final Drawable dr = array[i].mDrawable; if (dr != null) { - dr.setTintMode(blendMode); + dr.setTintBlendMode(blendMode); } } } diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index f45bf9b783e8..66947da9166f 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -477,8 +477,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { } @Override - public void setTintMode(@NonNull BlendMode blendMode) { - mAnimatedVectorState.mVectorDrawable.setTintMode(blendMode); + public void setTintBlendMode(@NonNull BlendMode blendMode) { + mAnimatedVectorState.mVectorDrawable.setTintBlendMode(blendMode); } @Override diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index 6b30158a183a..e4aa774fd434 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -685,7 +685,7 @@ public class BitmapDrawable extends Drawable { } @Override - public void setTintMode(@NonNull BlendMode blendMode) { + public void setTintBlendMode(@NonNull BlendMode blendMode) { final BitmapState state = mBitmapState; if (state.mBlendMode != blendMode) { state.mBlendMode = blendMode; diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java index efa806afce70..f5fa8c546bed 100644 --- a/graphics/java/android/graphics/drawable/ColorDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorDrawable.java @@ -215,7 +215,7 @@ public class ColorDrawable extends Drawable { } @Override - public void setTintMode(@NonNull BlendMode blendMode) { + public void setTintBlendMode(@NonNull BlendMode blendMode) { mColorState.mBlendMode = blendMode; mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mColorState.mTint, blendMode); diff --git a/graphics/java/android/graphics/drawable/ColorStateListDrawable.java b/graphics/java/android/graphics/drawable/ColorStateListDrawable.java index b94b11468371..35021a66f572 100644 --- a/graphics/java/android/graphics/drawable/ColorStateListDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorStateListDrawable.java @@ -114,9 +114,9 @@ public class ColorStateListDrawable extends Drawable implements Drawable.Callbac } @Override - public void setTintMode(@NonNull BlendMode blendMode) { + public void setTintBlendMode(@NonNull BlendMode blendMode) { mState.mBlendMode = blendMode; - mColorDrawable.setTintMode(blendMode); + mColorDrawable.setTintBlendMode(blendMode); onStateChange(getState()); } @@ -293,7 +293,7 @@ public class ColorStateListDrawable extends Drawable implements Drawable.Callbac } if (mState.mBlendMode != DEFAULT_BLEND_MODE) { - mColorDrawable.setTintMode(mState.mBlendMode); + mColorDrawable.setTintBlendMode(mState.mBlendMode); } } } diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index adc04fb03e2a..08409869c626 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -213,17 +213,17 @@ public abstract class Drawable { protected int mSrcDensityOverride = 0; /** - * Flag used to break the recursive loop between setTintMode(PorterDuff.Mode) and - * setTintMode(BlendMode) as each default implementation invokes the other in order to + * Flag used to break the recursive loop between setTintBlendMode(PorterDuff.Mode) and + * setTintBlendMode(BlendMode) as each default implementation invokes the other in order to * support new use cases that utilize the new blending modes as well as support the legacy - * use cases. This flag tracks that {@link #setTintMode(BlendMode)} is only invoked once + * use cases. This flag tracks that {@link #setTintBlendMode(BlendMode)} is only invoked once * per invocation. */ private boolean mSetBlendModeInvoked = false; /** - * Flag used to break the recursive loop between setTintMode(PorterDuff.Mode) and - * setTintMode(BlendMode) as each default implementation invokes the other in order to + * Flag used to break the recursive loop between setTintBlendMode(PorterDuff.Mode) and + * setTintBlendMode(BlendMode) as each default implementation invokes the other in order to * support new use cases that utilize the new blending modes as well as support the legacy * use cases. This flag tracks that {@link #setTintMode(Mode)} is only invoked once * per invocation; @@ -651,7 +651,7 @@ public abstract class Drawable { * @param tintColor Color to use for tinting this drawable * @see #setTintList(ColorStateList) * @see #setTintMode(PorterDuff.Mode) - * @see #setTintMode(BlendMode) + * @see #setTintBlendMode(BlendMode) */ public void setTint(@ColorInt int tintColor) { setTintList(ColorStateList.valueOf(tintColor)); @@ -673,7 +673,7 @@ public abstract class Drawable { * {@code null} to clear the tint * @see #setTint(int) * @see #setTintMode(PorterDuff.Mode) - * @see #setTintMode(BlendMode) + * @see #setTintBlendMode(BlendMode) */ public void setTintList(@Nullable ColorStateList tint) {} @@ -693,15 +693,12 @@ public abstract class Drawable { * of {@link PorterDuff.Mode#SRC_IN} * @see #setTint(int) * @see #setTintList(ColorStateList) - * - * @deprecated use {@link #setTintMode(BlendMode)} instead */ - @Deprecated public void setTintMode(@Nullable PorterDuff.Mode tintMode) { if (!mSetTintModeInvoked) { mSetTintModeInvoked = true; BlendMode mode = tintMode != null ? BlendMode.fromValue(tintMode.nativeInt) : null; - setTintMode(mode != null ? mode : Drawable.DEFAULT_BLEND_MODE); + setTintBlendMode(mode != null ? mode : Drawable.DEFAULT_BLEND_MODE); mSetTintModeInvoked = false; } } @@ -721,7 +718,7 @@ public abstract class Drawable { * @see #setTint(int) * @see #setTintList(ColorStateList) */ - public void setTintMode(@Nullable BlendMode blendMode) { + public void setTintBlendMode(@Nullable BlendMode blendMode) { if (!mSetBlendModeInvoked) { mSetBlendModeInvoked = true; PorterDuff.Mode mode = BlendMode.blendModeToPorterDuffMode(blendMode); diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index 3e0881aef9ed..090d915a2f67 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -196,14 +196,14 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } @Override - public void setTintMode(@NonNull BlendMode blendMode) { + public void setTintBlendMode(@NonNull BlendMode blendMode) { mDrawableContainerState.mHasTintMode = true; if (mDrawableContainerState.mBlendMode != blendMode) { mDrawableContainerState.mBlendMode = blendMode; if (mCurrDrawable != null) { - mCurrDrawable.setTintMode(blendMode); + mCurrDrawable.setTintBlendMode(blendMode); } } } @@ -544,7 +544,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { d.setTintList(mDrawableContainerState.mTintList); } if (mDrawableContainerState.mHasTintMode) { - d.setTintMode(mDrawableContainerState.mBlendMode); + d.setTintBlendMode(mDrawableContainerState.mBlendMode); } } diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java index d81401d451ca..64fc7042dfc7 100644 --- a/graphics/java/android/graphics/drawable/DrawableWrapper.java +++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java @@ -324,9 +324,9 @@ public abstract class DrawableWrapper extends Drawable implements Drawable.Callb } @Override - public void setTintMode(@NonNull BlendMode blendMode) { + public void setTintBlendMode(@NonNull BlendMode blendMode) { if (mDrawable != null) { - mDrawable.setTintMode(blendMode); + mDrawable.setTintBlendMode(blendMode); } } diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 6948bc4fd61b..816d1fda57d1 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -1211,7 +1211,7 @@ public class GradientDrawable extends Drawable { } @Override - public void setTintMode(@NonNull BlendMode blendMode) { + public void setTintBlendMode(@NonNull BlendMode blendMode) { mGradientState.mBlendMode = blendMode; mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mGradientState.mTint, blendMode); diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java index 5fd18a1431e0..3658f89abae1 100644 --- a/graphics/java/android/graphics/drawable/Icon.java +++ b/graphics/java/android/graphics/drawable/Icon.java @@ -324,7 +324,7 @@ public final class Icon implements Parcelable { if (result != null && (mTintList != null || mBlendMode != DEFAULT_BLEND_MODE)) { result.mutate(); result.setTintList(mTintList); - result.setTintMode(mBlendMode); + result.setTintBlendMode(mBlendMode); } return result; } @@ -696,10 +696,7 @@ public final class Icon implements Parcelable { * * @param mode a blending mode, as in {@link Drawable#setTintMode(PorterDuff.Mode)}, may be null * @return this same object, for use in chained construction - * - * @deprecated use {@link #setTintMode(BlendMode)} instead */ - @Deprecated public @NonNull Icon setTintMode(@NonNull PorterDuff.Mode mode) { mBlendMode = BlendMode.fromValue(mode.nativeInt); return this; @@ -711,7 +708,7 @@ public final class Icon implements Parcelable { * @param mode a blending mode, as in {@link Drawable#setTintMode(PorterDuff.Mode)}, may be null * @return this same object, for use in chained construction */ - public @NonNull Icon setTintMode(@NonNull BlendMode mode) { + public @NonNull Icon setTintBlendMode(@NonNull BlendMode mode) { mBlendMode = mode; return this; } diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java index e2c84927b578..f3a1b0eb52d5 100644 --- a/graphics/java/android/graphics/drawable/LayerDrawable.java +++ b/graphics/java/android/graphics/drawable/LayerDrawable.java @@ -1397,13 +1397,13 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { } @Override - public void setTintMode(@NonNull BlendMode blendMode) { + public void setTintBlendMode(@NonNull BlendMode blendMode) { final ChildDrawable[] array = mLayerState.mChildren; final int N = mLayerState.mNumChildren; for (int i = 0; i < N; i++) { final Drawable dr = array[i].mDrawable; if (dr != null) { - dr.setTintMode(blendMode); + dr.setTintBlendMode(blendMode); } } } diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index 4972e6a82b7d..8561d95ddd88 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -349,7 +349,7 @@ public class NinePatchDrawable extends Drawable { } @Override - public void setTintMode(@Nullable BlendMode blendMode) { + public void setTintBlendMode(@Nullable BlendMode blendMode) { mNinePatchState.mBlendMode = blendMode; mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, mNinePatchState.mTint, blendMode); diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java index b5fe7f9e432d..9774b59f98a9 100644 --- a/graphics/java/android/graphics/drawable/ShapeDrawable.java +++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java @@ -297,7 +297,7 @@ public class ShapeDrawable extends Drawable { } @Override - public void setTintMode(@NonNull BlendMode blendMode) { + public void setTintBlendMode(@NonNull BlendMode blendMode) { mShapeState.mBlendMode = blendMode; mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mShapeState.mTint, blendMode); diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index 43772ec20cf3..aa19b2a0e94c 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -487,7 +487,7 @@ public class VectorDrawable extends Drawable { } @Override - public void setTintMode(@NonNull BlendMode blendMode) { + public void setTintBlendMode(@NonNull BlendMode blendMode) { final VectorDrawableState state = mVectorState; if (state.mBlendMode != blendMode) { state.mBlendMode = blendMode; -- cgit v1.2.3 From ac33a487516196e9f1cf830e78313806e6daf777 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Mon, 22 Apr 2019 16:28:09 -0400 Subject: Fix fading edge effect from impacting neighboring pixels Bug: 129117085 Test: skia unit tests and test cases described in the bug Change-Id: Ieaa7c831dd6298ac0565e6f1837b1c1dbd4545da --- graphics/java/android/graphics/Canvas.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'graphics') diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index d4d5ae7bdddb..5648b854db40 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -558,6 +558,16 @@ public class Canvas extends BaseCanvas { return nSaveUnclippedLayer(mNativeCanvasWrapper, left, top, right, bottom); } + /** + * @hide + * @param saveCount The save level to restore to. + * @param paint This is copied and is applied to the area within the unclipped layer's + * bounds (i.e. equivalent to a drawPaint()) before restore() is called. + */ + public void restoreUnclippedLayer(int saveCount, Paint paint) { + nRestoreUnclippedLayer(mNativeCanvasWrapper, saveCount, paint.getNativeInstance()); + } + /** * Helper version of saveLayer() that takes 4 values rather than a RectF. * @@ -1398,6 +1408,9 @@ public class Canvas extends BaseCanvas { @CriticalNative private static native int nSaveUnclippedLayer(long nativeCanvas, int l, int t, int r, int b); @CriticalNative + private static native void nRestoreUnclippedLayer(long nativeCanvas, int saveCount, + long nativePaint); + @CriticalNative private static native boolean nRestore(long canvasHandle); @CriticalNative private static native void nRestoreToCount(long canvasHandle, int saveCount); -- cgit v1.2.3 From c492bc1ef8651f61c5c45da1f45e049d365b5dfe Mon Sep 17 00:00:00 2001 From: John Reck Date: Fri, 31 May 2019 15:16:10 -0700 Subject: Add copy constructor to PointF Fixes: 110863449 Test: builds Change-Id: Ie562f47becb52f78c406c97d3718de962eb03553 --- graphics/java/android/graphics/PointF.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'graphics') diff --git a/graphics/java/android/graphics/PointF.java b/graphics/java/android/graphics/PointF.java index f1f48adc7018..ed9df145f880 100644 --- a/graphics/java/android/graphics/PointF.java +++ b/graphics/java/android/graphics/PointF.java @@ -38,6 +38,18 @@ public class PointF implements Parcelable { this.x = p.x; this.y = p.y; } + + /** + * Create a new PointF initialized with the values in the specified + * PointF (which is left unmodified). + * + * @param p The point whose values are copied into the new + * point. + */ + public PointF(@NonNull PointF p) { + this.x = p.x; + this.y = p.y; + } /** * Set the point's x and y coordinates -- cgit v1.2.3 From 49dde45680206147637dc2be2d96ceae3c8dc17d Mon Sep 17 00:00:00 2001 From: John Reck Date: Thu, 18 Jul 2019 09:44:04 -0700 Subject: Fix RenderNode sample docs s/setLeftTopRightBottom/setPosition/ Test: none Change-Id: I5c3040370ae6c4975c171432c4339984b4a840ed --- graphics/java/android/graphics/RenderNode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java index ae7fe6c46f2f..0e635c774c84 100644 --- a/graphics/java/android/graphics/RenderNode.java +++ b/graphics/java/android/graphics/RenderNode.java @@ -63,7 +63,7 @@ import java.lang.annotation.RetentionPolicy; *

Creating a RenderNode

*
  *     RenderNode renderNode = new RenderNode("myRenderNode");
- *     renderNode.setLeftTopRightBottom(0, 0, 50, 50); // Set the size to 50x50
+ *     renderNode.setPosition(0, 0, 50, 50); // Set the size to 50x50
  *     RecordingCanvas canvas = renderNode.beginRecording();
  *     try {
  *         // Draw with the canvas
@@ -104,7 +104,7 @@ import java.lang.annotation.RetentionPolicy;
  * 
  *     private void createDisplayList() {
  *         mRenderNode = new RenderNode("MyRenderNode");
- *         mRenderNode.setLeftTopRightBottom(0, 0, width, height);
+ *         mRenderNode.setPosition(0, 0, width, height);
  *         RecordingCanvas canvas = mRenderNode.beginRecording();
  *         try {
  *             for (Bitmap b : mBitmaps) {
-- 
cgit v1.2.3


From 62b641f485c33d564b9667e5996582a43dcad78f Mon Sep 17 00:00:00 2001
From: Seigo Nonaka 
Date: Tue, 6 Aug 2019 11:29:24 -0700
Subject: Stop logspam of missing fonts.

Some system fonts may not be there because of saving storages, e.g.
on Watch OS. Stop logging missing fonts error.

Bug: 135419244
Test: N/A
Change-Id: I358f45aee35f25911a29ce272ebd0398561d8864
---
 graphics/java/android/graphics/FontFamily.java        | 2 --
 graphics/java/android/graphics/fonts/SystemFonts.java | 1 -
 2 files changed, 3 deletions(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index 5af0da85bb39..5ad93f411393 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -21,7 +21,6 @@ import android.annotation.UnsupportedAppUsage;
 import android.content.res.AssetManager;
 import android.graphics.fonts.FontVariationAxis;
 import android.text.TextUtils;
-import android.util.Log;
 
 import dalvik.annotation.optimization.CriticalNative;
 
@@ -145,7 +144,6 @@ public class FontFamily {
             }
             return nAddFont(mBuilderPtr, fontBuffer, ttcIndex, weight, italic);
         } catch (IOException e) {
-            Log.e(TAG, "Error mapping font file " + path);
             return false;
         }
     }
diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java
index 4a9cf14d04a5..95a8417b6f7f 100644
--- a/graphics/java/android/graphics/fonts/SystemFonts.java
+++ b/graphics/java/android/graphics/fonts/SystemFonts.java
@@ -105,7 +105,6 @@ public final class SystemFonts {
             final long fontSize = fileChannel.size();
             return fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize);
         } catch (IOException e) {
-            Log.e(TAG, "Error mapping font file " + fullPath);
             return null;
         }
     }
-- 
cgit v1.2.3


From cba2792567e06693c96cfeb1a14176ca14add41d Mon Sep 17 00:00:00 2001
From: Chong Zhang 
Date: Fri, 12 Jul 2019 16:38:47 -0700
Subject: Prefer animation in ImageDecoder.decodeDrawable

Pass down a flag to prefer animation over still images
when decodeDrawble is used. Pass the flag via source
to avoid adding this flag to all create/createFrom/
nCreate method variants. Check the flag only in
native_create when we actually create the decoder.

bug: 120414514
bug: 78868457

Change-Id: I84b4edd0225df9eaa59df8a787bd5902146ab500
---
 graphics/java/android/graphics/ImageDecoder.java | 80 ++++++++++++------------
 1 file changed, 41 insertions(+), 39 deletions(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 2d5babc5ebdb..150a941c061e 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -214,7 +214,7 @@ public final class ImageDecoder implements AutoCloseable {
 
         /* @hide */
         @NonNull
-        abstract ImageDecoder createImageDecoder() throws IOException;
+        abstract ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException;
     };
 
     private static class ByteArraySource extends Source {
@@ -228,8 +228,8 @@ public final class ImageDecoder implements AutoCloseable {
         private final int    mLength;
 
         @Override
-        public ImageDecoder createImageDecoder() throws IOException {
-            return nCreate(mData, mOffset, mLength, this);
+        public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException {
+            return nCreate(mData, mOffset, mLength, preferAnimation, this);
         }
     }
 
@@ -240,14 +240,14 @@ public final class ImageDecoder implements AutoCloseable {
         private final ByteBuffer mBuffer;
 
         @Override
-        public ImageDecoder createImageDecoder() throws IOException {
+        public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException {
             if (!mBuffer.isDirect() && mBuffer.hasArray()) {
                 int offset = mBuffer.arrayOffset() + mBuffer.position();
                 int length = mBuffer.limit() - mBuffer.position();
-                return nCreate(mBuffer.array(), offset, length, this);
+                return nCreate(mBuffer.array(), offset, length, preferAnimation, this);
             }
             ByteBuffer buffer = mBuffer.slice();
-            return nCreate(buffer, buffer.position(), buffer.limit(), this);
+            return nCreate(buffer, buffer.position(), buffer.limit(), preferAnimation, this);
         }
     }
 
@@ -267,7 +267,7 @@ public final class ImageDecoder implements AutoCloseable {
         Resources getResources() { return mResources; }
 
         @Override
-        public ImageDecoder createImageDecoder() throws IOException {
+        public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException {
             AssetFileDescriptor assetFd = null;
             try {
                 if (mUri.getScheme() == ContentResolver.SCHEME_CONTENT) {
@@ -284,26 +284,26 @@ public final class ImageDecoder implements AutoCloseable {
                     throw new FileNotFoundException(mUri.toString());
                 }
 
-                return createFromStream(is, true, this);
+                return createFromStream(is, true, preferAnimation, this);
             }
-            return createFromAssetFileDescriptor(assetFd, this);
+            return createFromAssetFileDescriptor(assetFd, preferAnimation, this);
         }
     }
 
     @NonNull
     private static ImageDecoder createFromFile(@NonNull File file,
-            @NonNull Source source) throws IOException {
+            boolean preferAnimation, @NonNull Source source) throws IOException {
         FileInputStream stream = new FileInputStream(file);
         FileDescriptor fd = stream.getFD();
         try {
             Os.lseek(fd, 0, SEEK_CUR);
         } catch (ErrnoException e) {
-            return createFromStream(stream, true, source);
+            return createFromStream(stream, true, preferAnimation, source);
         }
 
         ImageDecoder decoder = null;
         try {
-            decoder = nCreate(fd, source);
+            decoder = nCreate(fd, preferAnimation, source);
         } finally {
             if (decoder == null) {
                 IoUtils.closeQuietly(stream);
@@ -317,12 +317,12 @@ public final class ImageDecoder implements AutoCloseable {
 
     @NonNull
     private static ImageDecoder createFromStream(@NonNull InputStream is,
-            boolean closeInputStream, Source source) throws IOException {
+            boolean closeInputStream, boolean preferAnimation, Source source) throws IOException {
         // Arbitrary size matches BitmapFactory.
         byte[] storage = new byte[16 * 1024];
         ImageDecoder decoder = null;
         try {
-            decoder = nCreate(is, storage, source);
+            decoder = nCreate(is, storage, preferAnimation, source);
         } finally {
             if (decoder == null) {
                 if (closeInputStream) {
@@ -340,7 +340,7 @@ public final class ImageDecoder implements AutoCloseable {
 
     @NonNull
     private static ImageDecoder createFromAssetFileDescriptor(@NonNull AssetFileDescriptor assetFd,
-            Source source) throws IOException {
+            boolean preferAnimation, Source source) throws IOException {
         final FileDescriptor fd = assetFd.getFileDescriptor();
         final long offset = assetFd.getStartOffset();
 
@@ -348,9 +348,9 @@ public final class ImageDecoder implements AutoCloseable {
         try {
             try {
                 Os.lseek(fd, offset, SEEK_SET);
-                decoder = nCreate(fd, source);
+                decoder = nCreate(fd, preferAnimation, source);
             } catch (ErrnoException e) {
-                decoder = createFromStream(new FileInputStream(fd), true, source);
+                decoder = createFromStream(new FileInputStream(fd), true, preferAnimation, source);
             }
         } finally {
             if (decoder == null) {
@@ -388,7 +388,7 @@ public final class ImageDecoder implements AutoCloseable {
         public int getDensity() { return mInputDensity; }
 
         @Override
-        public ImageDecoder createImageDecoder() throws IOException {
+        public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException {
 
             synchronized (this) {
                 if (mInputStream == null) {
@@ -396,7 +396,7 @@ public final class ImageDecoder implements AutoCloseable {
                 }
                 InputStream is = mInputStream;
                 mInputStream = null;
-                return createFromStream(is, false, this);
+                return createFromStream(is, false, preferAnimation, this);
             }
         }
     }
@@ -434,14 +434,14 @@ public final class ImageDecoder implements AutoCloseable {
         }
 
         @Override
-        public ImageDecoder createImageDecoder() throws IOException {
+        public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException {
             synchronized (this) {
                 if (mAssetInputStream == null) {
                     throw new IOException("Cannot reuse AssetInputStreamSource");
                 }
                 AssetInputStream ais = mAssetInputStream;
                 mAssetInputStream = null;
-                return createFromAsset(ais, this);
+                return createFromAsset(ais, preferAnimation, this);
             }
         }
     }
@@ -469,7 +469,7 @@ public final class ImageDecoder implements AutoCloseable {
         }
 
         @Override
-        public ImageDecoder createImageDecoder() throws IOException {
+        public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException {
             TypedValue value = new TypedValue();
             // This is just used in order to access the underlying Asset and
             // keep it alive.
@@ -483,7 +483,7 @@ public final class ImageDecoder implements AutoCloseable {
                 }
             }
 
-            return createFromAsset((AssetInputStream) is, this);
+            return createFromAsset((AssetInputStream) is, preferAnimation, this);
         }
     }
 
@@ -491,11 +491,11 @@ public final class ImageDecoder implements AutoCloseable {
      *  ImageDecoder will own the AssetInputStream.
      */
     private static ImageDecoder createFromAsset(AssetInputStream ais,
-            Source source) throws IOException {
+            boolean preferAnimation, Source source) throws IOException {
         ImageDecoder decoder = null;
         try {
             long asset = ais.getNativeAsset();
-            decoder = nCreate(asset, source);
+            decoder = nCreate(asset, preferAnimation, source);
         } finally {
             if (decoder == null) {
                 IoUtils.closeQuietly(ais);
@@ -517,9 +517,9 @@ public final class ImageDecoder implements AutoCloseable {
         private final String mFileName;
 
         @Override
-        public ImageDecoder createImageDecoder() throws IOException {
+        public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException {
             InputStream is = mAssets.open(mFileName);
-            return createFromAsset((AssetInputStream) is, this);
+            return createFromAsset((AssetInputStream) is, preferAnimation, this);
         }
     }
 
@@ -531,8 +531,8 @@ public final class ImageDecoder implements AutoCloseable {
         private final File mFile;
 
         @Override
-        public ImageDecoder createImageDecoder() throws IOException {
-            return createFromFile(mFile, this);
+        public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException {
+            return createFromFile(mFile, preferAnimation, this);
         }
     }
 
@@ -544,7 +544,7 @@ public final class ImageDecoder implements AutoCloseable {
         private final Callable mCallable;
 
         @Override
-        public ImageDecoder createImageDecoder() throws IOException {
+        public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException {
             AssetFileDescriptor assetFd = null;
             try {
                 assetFd = mCallable.call();
@@ -555,7 +555,7 @@ public final class ImageDecoder implements AutoCloseable {
                     throw new IOException(e);
                 }
             }
-            return createFromAssetFileDescriptor(assetFd, this);
+            return createFromAssetFileDescriptor(assetFd, preferAnimation, this);
         }
     }
 
@@ -1740,7 +1740,7 @@ public final class ImageDecoder implements AutoCloseable {
     @NonNull
     private static Drawable decodeDrawableImpl(@NonNull Source src,
             @Nullable OnHeaderDecodedListener listener) throws IOException {
-        try (ImageDecoder decoder = src.createImageDecoder()) {
+        try (ImageDecoder decoder = src.createImageDecoder(true /*preferAnimation*/)) {
             decoder.mSource = src;
             decoder.callHeaderDecoded(listener, src);
 
@@ -1844,7 +1844,7 @@ public final class ImageDecoder implements AutoCloseable {
     @NonNull
     private static Bitmap decodeBitmapImpl(@NonNull Source src,
             @Nullable OnHeaderDecodedListener listener) throws IOException {
-        try (ImageDecoder decoder = src.createImageDecoder()) {
+        try (ImageDecoder decoder = src.createImageDecoder(false /*preferAnimation*/)) {
             decoder.mSource = src;
             decoder.callHeaderDecoded(listener, src);
 
@@ -1971,15 +1971,17 @@ public final class ImageDecoder implements AutoCloseable {
         }
     }
 
-    private static native ImageDecoder nCreate(long asset, Source src) throws IOException;
-    private static native ImageDecoder nCreate(ByteBuffer buffer, int position,
-                                               int limit, Source src) throws IOException;
+    private static native ImageDecoder nCreate(long asset,
+            boolean preferAnimation, Source src) throws IOException;
+    private static native ImageDecoder nCreate(ByteBuffer buffer, int position, int limit,
+            boolean preferAnimation, Source src) throws IOException;
     private static native ImageDecoder nCreate(byte[] data, int offset, int length,
-                                               Source src) throws IOException;
+            boolean preferAnimation, Source src) throws IOException;
     private static native ImageDecoder nCreate(InputStream is, byte[] storage,
-                                               Source src) throws IOException;
+            boolean preferAnimation, Source src) throws IOException;
     // The fd must be seekable.
-    private static native ImageDecoder nCreate(FileDescriptor fd, Source src) throws IOException;
+    private static native ImageDecoder nCreate(FileDescriptor fd,
+            boolean preferAnimation, Source src) throws IOException;
     @NonNull
     private static native Bitmap nDecodeBitmap(long nativePtr,
             @NonNull ImageDecoder decoder,
-- 
cgit v1.2.3


From bd00e4c6c0e56f20d7274817477035c4d4924c3d Mon Sep 17 00:00:00 2001
From: Nader Jawad 
Date: Thu, 22 Aug 2019 11:24:51 -0700
Subject: Fixed default angle to be Orientation.LEFT_RIGHT

Fixed issue where in Android Q if no angle measurement
was specified the default gradient orientation of TOP_BOTTOM
was applied instead of the previous behavior of LEFT_RIGHT

Bug: 139822941
Test: Added CTS test to verify GradientDrawableTest
Change-Id: Ia8c53455740a29e1d123c90616066e16ddb4a241
---
 graphics/java/android/graphics/drawable/GradientDrawable.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index b9945cc735d8..e6eaa6964d49 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -207,7 +207,7 @@ public class GradientDrawable extends Drawable {
     }
 
     public GradientDrawable() {
-        this(new GradientState(Orientation.TOP_BOTTOM, null), null);
+        this(new GradientState(Orientation.LEFT_RIGHT, null), null);
     }
 
     /**
-- 
cgit v1.2.3


From 3d7ae4efffcf3c4cbe17131a76d3020107d051fb Mon Sep 17 00:00:00 2001
From: Leon Scroggins III 
Date: Tue, 17 Sep 2019 14:13:18 -0400
Subject: ImageDecoder: throw FileNotFoundException on null

Bug: 140961740
Test: I41a93b47acde6a7985c53107f448a8b647d245d7

If ImageDecoder has a null AssetFileDescriptor, either from a Callable
or from a ContentResolver directly, throw a FileNotFoundException.
Previously, a NullPointerException was thrown attempting to dereference
it.

Change-Id: Ie738b9edc062e520835010befc001578fce09832
---
 graphics/java/android/graphics/ImageDecoder.java | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 150a941c061e..6619dba159c2 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -286,6 +286,9 @@ public final class ImageDecoder implements AutoCloseable {
 
                 return createFromStream(is, true, preferAnimation, this);
             }
+            if (assetFd == null) {
+                throw new FileNotFoundException(mUri.toString());
+            }
             return createFromAssetFileDescriptor(assetFd, preferAnimation, this);
         }
     }
@@ -341,6 +344,9 @@ public final class ImageDecoder implements AutoCloseable {
     @NonNull
     private static ImageDecoder createFromAssetFileDescriptor(@NonNull AssetFileDescriptor assetFd,
             boolean preferAnimation, Source source) throws IOException {
+        if (assetFd == null) {
+            throw new FileNotFoundException();
+        }
         final FileDescriptor fd = assetFd.getFileDescriptor();
         final long offset = assetFd.getStartOffset();
 
-- 
cgit v1.2.3


From 87e5b74f8da3a2f7860f5f2918163862d82ec1f7 Mon Sep 17 00:00:00 2001
From: Nader Jawad 
Date: Thu, 19 Sep 2019 22:04:13 +0000
Subject: Revert "Fixed default angle to be Orientation.LEFT_RIGHT"

This reverts commit d31d0967209775ae352092d3125adfd59c8040d0.

Reason for revert: Although this change fixed the behavior change for for creation of
GradientDrawables defined in xml, the default value for GradientDrawables defined
programmatically is different. The default orientation for GradientDrawables defined
in xml is LEFT_RIGHT, however, the default orientation for GradientDrawables defined
programmatically is TOP_BOTTOM. Since a fix for AAPT has been made to automatically
insert an angle measurement of 0 if one is not defined, we can revert this CL and target
a proper fix in master.

Change-Id: Ib8983386832fb25f53b5e68e76e9d41d9d26fec9
---
 graphics/java/android/graphics/drawable/GradientDrawable.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index e6eaa6964d49..b9945cc735d8 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -207,7 +207,7 @@ public class GradientDrawable extends Drawable {
     }
 
     public GradientDrawable() {
-        this(new GradientState(Orientation.LEFT_RIGHT, null), null);
+        this(new GradientState(Orientation.TOP_BOTTOM, null), null);
     }
 
     /**
-- 
cgit v1.2.3


From 9f560fefbc49c2157c3e93989c30c204a74a8798 Mon Sep 17 00:00:00 2001
From: Nader Jawad 
Date: Thu, 19 Sep 2019 15:59:53 -0700
Subject: Restored default behavior of GradientDrawable orientation

Fixed issue where GradientDrawable orientation had diverged
from the default behavior. Ensured that orientation by default
is configured to LEFT_RIGHT for xml defined GradientDrawables
and programmatically defined GradientDrawables have the
same default orientation of TOP_BOTTOM.

Refactored previous logic that would keep both the mAngle
parameter used in xml inflation and the mOrientation parameter
that is used to configure the angle of the gradient to no longer
keep these 2 values in sync.

Test: Added CTS test to verify orientation for xml and programmatically
defined GradientDrawables
Bug: 140835351
Bug: 139822941

Change-Id: I594496afe48d04d108053bf284e92bbfd3591fa3
---
 .../graphics/drawable/GradientDrawable.java        | 117 ++++++---------------
 1 file changed, 31 insertions(+), 86 deletions(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index b9945cc735d8..96ac0f9b38b5 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -637,7 +637,7 @@ public class GradientDrawable extends Drawable {
      * @see #setOrientation(Orientation)
      */
     public Orientation getOrientation() {
-        return mGradientState.getOrientation();
+        return mGradientState.mOrientation;
     }
 
     /**
@@ -653,7 +653,7 @@ public class GradientDrawable extends Drawable {
      * @see #getOrientation()
      */
     public void setOrientation(Orientation orientation) {
-        mGradientState.setOrientation(orientation);
+        mGradientState.mOrientation = orientation;
         mGradientIsDirty = true;
         invalidateSelf();
     }
@@ -1270,7 +1270,7 @@ public class GradientDrawable extends Drawable {
 
                 if (st.mGradient == LINEAR_GRADIENT) {
                     final float level = st.mUseLevel ? getLevel() / 10000.0f : 1.0f;
-                    switch (st.getOrientation()) {
+                    switch (st.mOrientation) {
                     case TOP_BOTTOM:
                         x0 = r.left;            y0 = r.top;
                         x1 = x0;                y1 = level * r.bottom;
@@ -1759,6 +1759,33 @@ public class GradientDrawable extends Drawable {
         int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle);
         st.mAngle = ((angle % 360) + 360) % 360; // offset negative angle measures
 
+        switch (st.mAngle) {
+            case 0:
+                st.mOrientation = Orientation.LEFT_RIGHT;
+                break;
+            case 45:
+                st.mOrientation = Orientation.BL_TR;
+                break;
+            case 90:
+                st.mOrientation = Orientation.BOTTOM_TOP;
+                break;
+            case 135:
+                st.mOrientation = Orientation.BR_TL;
+                break;
+            case 180:
+                st.mOrientation = Orientation.RIGHT_LEFT;
+                break;
+            case 225:
+                st.mOrientation = Orientation.TR_BL;
+                break;
+            case 270:
+                st.mOrientation = Orientation.TOP_BOTTOM;
+                break;
+            case 315:
+                st.mOrientation = Orientation.TL_BR;
+                break;
+        }
+
         final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius);
         if (tv != null) {
             final float radius;
@@ -1981,7 +2008,7 @@ public class GradientDrawable extends Drawable {
         int[] mAttrPadding;
 
         public GradientState(Orientation orientation, int[] gradientColors) {
-            setOrientation(orientation);
+            mOrientation = orientation;
             setGradientColors(gradientColors);
         }
 
@@ -2184,93 +2211,11 @@ public class GradientDrawable extends Drawable {
             mCenterY = y;
         }
 
-        public void setOrientation(Orientation orientation) {
-            // Update the angle here so that subsequent attempts to obtain the orientation
-            // from the angle overwrite previously configured values during inflation
-            mAngle = getAngleFromOrientation(orientation);
-            mOrientation = orientation;
-        }
-
         @NonNull
         public Orientation getOrientation() {
-            updateGradientStateOrientation();
             return mOrientation;
         }
 
-        /**
-         * Update the orientation of the gradient based on the given angle only if the type is
-         * {@link #LINEAR_GRADIENT}
-         */
-        private void updateGradientStateOrientation() {
-            if (mGradient == LINEAR_GRADIENT) {
-                int angle = mAngle;
-                if (angle % 45 != 0) {
-                    throw new IllegalArgumentException("Linear gradient requires 'angle' attribute "
-                            + "to be a multiple of 45");
-                }
-
-                Orientation orientation;
-                switch (angle) {
-                    case 0:
-                        orientation = Orientation.LEFT_RIGHT;
-                        break;
-                    case 45:
-                        orientation = Orientation.BL_TR;
-                        break;
-                    case 90:
-                        orientation = Orientation.BOTTOM_TOP;
-                        break;
-                    case 135:
-                        orientation = Orientation.BR_TL;
-                        break;
-                    case 180:
-                        orientation = Orientation.RIGHT_LEFT;
-                        break;
-                    case 225:
-                        orientation = Orientation.TR_BL;
-                        break;
-                    case 270:
-                        orientation = Orientation.TOP_BOTTOM;
-                        break;
-                    case 315:
-                        orientation = Orientation.TL_BR;
-                        break;
-                    default:
-                        // Should not get here as exception is thrown above if angle is not multiple
-                        // of 45 degrees
-                        orientation = Orientation.LEFT_RIGHT;
-                        break;
-                }
-                mOrientation = orientation;
-            }
-        }
-
-        private int getAngleFromOrientation(@Nullable Orientation orientation) {
-            if (orientation != null) {
-                switch (orientation) {
-                    default:
-                    case LEFT_RIGHT:
-                        return 0;
-                    case BL_TR:
-                        return 45;
-                    case BOTTOM_TOP:
-                        return 90;
-                    case BR_TL:
-                        return 135;
-                    case RIGHT_LEFT:
-                        return 180;
-                    case TR_BL:
-                        return 225;
-                    case TOP_BOTTOM:
-                        return 270;
-                    case TL_BR:
-                        return 315;
-                }
-            } else {
-                return 0;
-            }
-        }
-
         public void setGradientColors(@Nullable int[] colors) {
             mGradientColors = colors;
             mSolidColors = null;
-- 
cgit v1.2.3


From 94d294bb5215719363a746a6371abe9bb1100626 Mon Sep 17 00:00:00 2001
From: Leon Scroggins III 
Date: Fri, 6 Sep 2019 13:22:46 -0400
Subject: Add Bitmap.CompressFormat#WEBP_LOSSY/LOSSLESS

Bug: 135133301
Test: Iadbd8cf3b69a150b9e38ad556392346e1bb27084

WEBP does not give clients explicit control of how to do their WEBP
encode. Add new formats that do. Update the docs for the existing
formats (and the new ones) to explain more precisely how quality is
interpreted.

Change-Id: I9583903c21ab2048fed8e7ed501ee8377ea5ba36
---
 graphics/java/android/graphics/Bitmap.java | 47 +++++++++++++++++++++++++-----
 1 file changed, 40 insertions(+), 7 deletions(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 44710178da5e..d900a42b1e66 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1359,9 +1359,44 @@ public final class Bitmap implements Parcelable {
      * Specifies the known formats a bitmap can be compressed into
      */
     public enum CompressFormat {
-        JPEG    (0),
-        PNG     (1),
-        WEBP    (2);
+        /**
+         * Compress to the JPEG format. {@code quality} of {@code 0} means
+         * compress for the smallest size. {@code 100} means compress for max
+         * visual quality.
+         */
+        JPEG          (0),
+        /**
+         * Compress to the PNG format. PNG is lossless, so {@code quality} is
+         * ignored.
+         */
+        PNG           (1),
+        /**
+         * Compress to the WEBP format. {@code quality} of {@code 0} means
+         * compress for the smallest size. {@code 100} means compress for max
+         * visual quality. As of {@link android.os.Build.VERSION_CODES#Q}, a
+         * value of {@code 100} results in a file in the lossless WEBP format.
+         * Otherwise the file will be in the lossy WEBP format.
+         *
+         * @deprecated in favor of the more explicit
+         *             {@link CompressFormat#WEBP_LOSSY} and
+         *             {@link CompressFormat#WEBP_LOSSLESS}.
+         */
+        @Deprecated
+        WEBP          (2),
+        /**
+         * Compress to the WEBP lossy format. {@code quality} of {@code 0} means
+         * compress for the smallest size. {@code 100} means compress for max
+         * visual quality.
+         */
+        WEBP_LOSSY    (3),
+        /**
+         * Compress to the WEBP lossless format. {@code quality} refers to how
+         * much effort to put into compression. A value of {@code 0} means to
+         * compress quickly, resulting in a relatively large file size.
+         * {@code 100} means to spend more time compressing, resulting in a
+         * smaller file.
+         */
+        WEBP_LOSSLESS (4);
 
         CompressFormat(int nativeInt) {
             this.nativeInt = nativeInt;
@@ -1385,10 +1420,8 @@ public final class Bitmap implements Parcelable {
      * pixels).
      *
      * @param format   The format of the compressed image
-     * @param quality  Hint to the compressor, 0-100. 0 meaning compress for
-     *                 small size, 100 meaning compress for max quality. Some
-     *                 formats, like PNG which is lossless, will ignore the
-     *                 quality setting
+     * @param quality  Hint to the compressor, 0-100. The value is interpreted
+     *                 differently depending on the {@link CompressFormat}.
      * @param stream   The outputstream to write the compressed data.
      * @return true if successfully compressed to the specified stream.
      */
-- 
cgit v1.2.3


From 48ec4e0b5ca7d5fb65645e06c92b0fd29c974b27 Mon Sep 17 00:00:00 2001
From: Robert Carr 
Date: Tue, 16 Jul 2019 14:28:47 -0700
Subject: ViewRootImpl: Add USE_BLAST flag.

Add support for ViewRootImpl submitting buffers using
BLAST and put this support behind a disabled-by-default
FLAG.

Bug: 135786080
Change-Id: Ia3f205e34db9f9aa574c9c2e2c499dd3046af220
---
 .../java/android/graphics/BLASTBufferQueue.java    | 67 ++++++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 graphics/java/android/graphics/BLASTBufferQueue.java

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java
new file mode 100644
index 000000000000..8c6a9371d53b
--- /dev/null
+++ b/graphics/java/android/graphics/BLASTBufferQueue.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import android.view.Surface;
+import android.view.SurfaceControl;
+
+/**
+ * @hide
+ */
+public final class BLASTBufferQueue {
+    // Note: This field is accessed by native code.
+    private long mNativeObject; // BLASTBufferQueue*
+
+    private static native long nativeCreate(long surfaceControl, long width, long height);
+    private static native void nativeDestroy(long ptr);
+    private static native Surface nativeGetSurface(long ptr);
+    private static native void nativeSetNextTransaction(long ptr, long transactionPtr);
+    private static native void nativeUpdate(long ptr, long surfaceControl, long width, long height);
+
+    /** Create a new connection with the surface flinger. */
+    public BLASTBufferQueue(SurfaceControl sc, int width, int height) {
+        mNativeObject = nativeCreate(sc.mNativeObject, width, height);
+    }
+
+    public void destroy() {
+        nativeDestroy(mNativeObject);
+    }
+
+    public Surface getSurface() {
+        return nativeGetSurface(mNativeObject);
+    }
+
+    public void setNextTransaction(SurfaceControl.Transaction t) {
+        nativeSetNextTransaction(mNativeObject, t.mNativeObject);
+    }
+
+    public void update(SurfaceControl sc, int width, int height) {
+        nativeUpdate(mNativeObject, sc.mNativeObject, width, height);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mNativeObject != 0) {
+                nativeDestroy(mNativeObject);
+            }
+        } finally {
+            super.finalize();
+        }
+    }
+}
+
-- 
cgit v1.2.3


From 183e1380cef0f63610497abed01e16036a2ea2d4 Mon Sep 17 00:00:00 2001
From: John Reck 
Date: Wed, 9 Oct 2019 13:41:18 -0700
Subject: Improve dumping of display list memory usage

The first step of improving is measuring. So measure better.

Bug: 138856108
Test: dump
Change-Id: I076b904a1f0dfb209622c76bcb8778a10cd2b7db
---
 graphics/java/android/graphics/RenderNode.java | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 0e635c774c84..17e3b4465130 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -1380,7 +1380,22 @@ public final class RenderNode {
      * @return Approximate memory usage in bytes.
      */
     public @BytesLong long computeApproximateMemoryUsage() {
-        return nGetDebugSize(mNativeRenderNode);
+        return nGetUsageSize(mNativeRenderNode);
+    }
+
+    /**
+     * Gets the approximate amount of memory allocated for the RenderNode for debug purposes.
+     * Does not include the memory allocated by any child RenderNodes nor any bitmaps, only the
+     * memory allocated for this RenderNode and any data it owns.
+     *
+     * The difference between this and {@link #computeApproximateMemoryUsage()} is this includes
+     * memory allocated but not used. In particular structures such as DisplayLists are similar
+     * to things like ArrayLists - they need to resize as commands are added to them. As such,
+     * memory used can be less than memory allocated.
+     *
+     * @hide */
+    public @BytesLong long computeApproximateMemoryAllocated() {
+        return nGetAllocatedSize(mNativeRenderNode);
     }
 
     /**
@@ -1485,7 +1500,8 @@ public final class RenderNode {
 
     private static native void nOutput(long renderNode);
 
-    private static native int nGetDebugSize(long renderNode);
+    private static native int nGetUsageSize(long renderNode);
+    private static native int nGetAllocatedSize(long renderNode);
 
     private static native void nRequestPositionUpdates(long renderNode,
             PositionUpdateListener callback);
-- 
cgit v1.2.3


From 5baa087037a6d66a2cabd771b2e0ef7130ee037a Mon Sep 17 00:00:00 2001
From: Nader Jawad 
Date: Tue, 8 Oct 2019 17:24:01 -0700
Subject: Do not parse angle if it is negative

If the Gradient angle is negative after
modding by 360, maintain the previous platform
behavior of TOP_BOTTOM oreintation instead of
attempting to wrap it

Test: Added CTS test to verify various negative
angle measurements
Bug: 142111195

Change-Id: Id9c050a9e15717bfaff331c6a37cb34cbce0f060
---
 .../graphics/drawable/GradientDrawable.java        | 80 ++++++++++++++--------
 1 file changed, 53 insertions(+), 27 deletions(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 96ac0f9b38b5..c6586ecfceb9 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -97,6 +97,14 @@ import java.lang.annotation.RetentionPolicy;
  * @attr ref android.R.styleable#GradientDrawablePadding_bottom
  */
 public class GradientDrawable extends Drawable {
+
+    /**
+     * Flag to determine if we should wrap negative gradient angle measurements
+     * for API levels that support it
+     * @hide
+     */
+    public static boolean sWrapNegativeAngleMeasurements = true;
+
     /**
      * Shape is a rectangle, possibly with rounded corners
      */
@@ -151,6 +159,9 @@ public class GradientDrawable extends Drawable {
     /** Radius is a fraction of the bounds size. */
     private static final int RADIUS_TYPE_FRACTION_PARENT = 2;
 
+    /** Default orientation for GradientDrawable **/
+    private static final Orientation DEFAULT_ORIENTATION = Orientation.TOP_BOTTOM;
+
     /** @hide */
     @IntDef({RADIUS_TYPE_PIXELS, RADIUS_TYPE_FRACTION, RADIUS_TYPE_FRACTION_PARENT})
     @Retention(RetentionPolicy.SOURCE)
@@ -207,7 +218,7 @@ public class GradientDrawable extends Drawable {
     }
 
     public GradientDrawable() {
-        this(new GradientState(Orientation.TOP_BOTTOM, null), null);
+        this(new GradientState(DEFAULT_ORIENTATION, null), null);
     }
 
     /**
@@ -1757,33 +1768,48 @@ public class GradientDrawable extends Drawable {
         }
 
         int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle);
-        st.mAngle = ((angle % 360) + 360) % 360; // offset negative angle measures
 
-        switch (st.mAngle) {
-            case 0:
-                st.mOrientation = Orientation.LEFT_RIGHT;
-                break;
-            case 45:
-                st.mOrientation = Orientation.BL_TR;
-                break;
-            case 90:
-                st.mOrientation = Orientation.BOTTOM_TOP;
-                break;
-            case 135:
-                st.mOrientation = Orientation.BR_TL;
-                break;
-            case 180:
-                st.mOrientation = Orientation.RIGHT_LEFT;
-                break;
-            case 225:
-                st.mOrientation = Orientation.TR_BL;
-                break;
-            case 270:
-                st.mOrientation = Orientation.TOP_BOTTOM;
-                break;
-            case 315:
-                st.mOrientation = Orientation.TL_BR;
-                break;
+        // GradientDrawable historically has not parsed negative angle measurements and always
+        // stays on the default orientation for API levels older than Q.
+        // Only configure the orientation if the angle is greater than zero.
+        // Otherwise fallback on Orientation.TOP_BOTTOM
+        // In Android Q and later, actually wrap the negative angle measurement to the correct
+        // value
+        if (sWrapNegativeAngleMeasurements) {
+            st.mAngle = ((angle % 360) + 360) % 360; // offset negative angle measures
+        } else {
+            st.mAngle = angle % 360;
+        }
+
+        if (st.mAngle >= 0) {
+            switch (st.mAngle) {
+                case 0:
+                    st.mOrientation = Orientation.LEFT_RIGHT;
+                    break;
+                case 45:
+                    st.mOrientation = Orientation.BL_TR;
+                    break;
+                case 90:
+                    st.mOrientation = Orientation.BOTTOM_TOP;
+                    break;
+                case 135:
+                    st.mOrientation = Orientation.BR_TL;
+                    break;
+                case 180:
+                    st.mOrientation = Orientation.RIGHT_LEFT;
+                    break;
+                case 225:
+                    st.mOrientation = Orientation.TR_BL;
+                    break;
+                case 270:
+                    st.mOrientation = Orientation.TOP_BOTTOM;
+                    break;
+                case 315:
+                    st.mOrientation = Orientation.TL_BR;
+                    break;
+            }
+        } else {
+            st.mOrientation = DEFAULT_ORIENTATION;
         }
 
         final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius);
-- 
cgit v1.2.3


From e8da8b12c3ee0449ed60f7c28ce983c3ea2b4749 Mon Sep 17 00:00:00 2001
From: Leon Scroggins III 
Date: Tue, 8 Oct 2019 12:45:23 -0400
Subject: Handle null assetFd like a FNF

Bug: 140961740
Test: TODO

We already catch an FNF and attempt to open the file as an InputStream.
Do the same if null is returned.

I haven't figured out a way to make assetFd set to null and yet opening
an InputStream succeeds, so this is untested.

Change-Id: Iabd05db714bc693ead2dc8cc4c0b46fef9f33d5a
---
 graphics/java/android/graphics/ImageDecoder.java | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 6619dba159c2..e7b0e2899421 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -277,6 +277,10 @@ public final class ImageDecoder implements AutoCloseable {
                     assetFd = mResolver.openAssetFileDescriptor(mUri, "r");
                 }
             } catch (FileNotFoundException e) {
+                // Handled below, along with the case where assetFd was set to null.
+            }
+
+            if (assetFd == null) {
                 // Some images cannot be opened as AssetFileDescriptors (e.g.
                 // bmp, ico). Open them as InputStreams.
                 InputStream is = mResolver.openInputStream(mUri);
@@ -286,9 +290,7 @@ public final class ImageDecoder implements AutoCloseable {
 
                 return createFromStream(is, true, preferAnimation, this);
             }
-            if (assetFd == null) {
-                throw new FileNotFoundException(mUri.toString());
-            }
+
             return createFromAssetFileDescriptor(assetFd, preferAnimation, this);
         }
     }
-- 
cgit v1.2.3


From c137f1c6791934b9ef98d055d801f92b538292eb Mon Sep 17 00:00:00 2001
From: "Philip P. Moltmann" 
Date: Fri, 11 Oct 2019 12:08:40 -0700
Subject: Add TEST_MAPPING for print and pdf tests

Test: TH
Change-Id: I7157c630fccb8b4d50672ac014e5cd020f1ac71f
---
 graphics/java/android/graphics/pdf/TEST_MAPPING | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 graphics/java/android/graphics/pdf/TEST_MAPPING

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/pdf/TEST_MAPPING b/graphics/java/android/graphics/pdf/TEST_MAPPING
new file mode 100644
index 000000000000..d763598f5ba0
--- /dev/null
+++ b/graphics/java/android/graphics/pdf/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsPdfTestCases"
+    }
+  ]
+}
-- 
cgit v1.2.3


From da94981b194b56a5d4f17825dfe31efdfb349573 Mon Sep 17 00:00:00 2001
From: John Reck 
Date: Wed, 16 Oct 2019 16:18:28 -0700
Subject: Fix ColorSpace#get allocating

Test: none
Change-Id: Ia4d380a74ac8f99ac408f52a602713823db43f50
---
 graphics/java/android/graphics/ColorSpace.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java
index 9c4b5e8b0165..06d4fbdd85b1 100644
--- a/graphics/java/android/graphics/ColorSpace.java
+++ b/graphics/java/android/graphics/ColorSpace.java
@@ -1380,9 +1380,9 @@ public abstract class ColorSpace {
      */
     @NonNull
     static ColorSpace get(@IntRange(from = MIN_ID, to = MAX_ID) int index) {
-        if (index < 0 || index >= Named.values().length) {
+        if (index < 0 || index >= sNamedColorSpaces.length) {
             throw new IllegalArgumentException("Invalid ID, must be in the range [0.." +
-                    Named.values().length + ")");
+                    sNamedColorSpaces.length + ")");
         }
         return sNamedColorSpaces[index];
     }
-- 
cgit v1.2.3


From 79201b16f1dbfcfd23c1bbde08fd86b078a593bf Mon Sep 17 00:00:00 2001
From: Derek Sollenberger 
Date: Fri, 30 Aug 2019 13:53:29 -0400
Subject: Remove native calls to HWUI from Surface and use the public API
 instead

Test: CtsGraphicsTestCases
Bug: 137655431
Change-Id: I1eda485282306d571ca973e179e7202958b59105
---
 graphics/java/android/graphics/HardwareRenderer.java | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index b6b2d4e1c46a..3f3ad578e8d7 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -286,10 +286,24 @@ public class HardwareRenderer {
      *                non-null then {@link Surface#isValid()} must be true.
      */
     public void setSurface(@Nullable Surface surface) {
+        setSurface(surface, false);
+    }
+
+    /**
+     * See {@link #setSurface(Surface)}
+     *
+     * @hide
+     * @param discardBuffer determines whether the surface will attempt to preserve its contents
+     *                      between frames.  If set to true the renderer will attempt to preserve
+     *                      the contents of the buffer between frames if the implementation allows
+     *                      it.  If set to false no attempt will be made to preserve the buffer's
+     *                      contents between frames.
+     */
+    public void setSurface(@Nullable Surface surface, boolean discardBuffer) {
         if (surface != null && !surface.isValid()) {
             throw new IllegalArgumentException("Surface is invalid. surface.isValid() == false.");
         }
-        nSetSurface(mNativeProxy, surface);
+        nSetSurface(mNativeProxy, surface, discardBuffer);
     }
 
     /**
@@ -1084,7 +1098,7 @@ public class HardwareRenderer {
 
     private static native void nSetName(long nativeProxy, String name);
 
-    private static native void nSetSurface(long nativeProxy, Surface window);
+    private static native void nSetSurface(long nativeProxy, Surface window, boolean discardBuffer);
 
     private static native boolean nPause(long nativeProxy);
 
-- 
cgit v1.2.3


From 01709c7469b59e451f064c266bbe442e9bef0ab4 Mon Sep 17 00:00:00 2001
From: Seigo Nonaka 
Date: Thu, 24 Oct 2019 18:50:51 -0700
Subject: Make AFont_getLocale work

There are multiple problems here:
- Java Font.equals and hashCode doesn't look at locale list. Due to this
issue, the CTS tests have been passing unexpectedly.
- The null pointer check in the AFont_getLoacle was inversed. Should
return only when it is non-null.
- Looks like we cannot get the parent's attribute which always returns
null. Instead, read the "lang" attribute when we read the family tag.

Bug: 139201432
Test: atest NativeSystemFontTest
Test: atest TypefaceEqualsTest
Change-Id: I0514847bbf46a73358afab374ccfce2db09b2ec0
---
 graphics/java/android/graphics/fonts/Font.java | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
index 552088f7c478..ba96a06cc852 100644
--- a/graphics/java/android/graphics/fonts/Font.java
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -519,12 +519,13 @@ public final class Font {
         }
         Font f = (Font) o;
         return mFontStyle.equals(f.mFontStyle) && f.mTtcIndex == mTtcIndex
-                && Arrays.equals(f.mAxes, mAxes) && f.mBuffer.equals(mBuffer);
+                && Arrays.equals(f.mAxes, mAxes) && f.mBuffer.equals(mBuffer)
+                && Objects.equals(f.mLocaleList, mLocaleList);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mFontStyle, mTtcIndex, Arrays.hashCode(mAxes), mBuffer);
+        return Objects.hash(mFontStyle, mTtcIndex, Arrays.hashCode(mAxes), mBuffer, mLocaleList);
     }
 
     @Override
-- 
cgit v1.2.3


From a320e92c56a17a4c70e58e56b2df3d966510196c Mon Sep 17 00:00:00 2001
From: Derek Sollenberger 
Date: Wed, 30 Oct 2019 13:17:41 +0000
Subject: Revert "Remove native calls to HWUI from Surface and use the public
 API instead"

This reverts commit 79201b16f1dbfcfd23c1bbde08fd86b078a593bf.

Reason for revert: breaks wm-presubmit

Change-Id: I3245e202f88b16d30b924e229cbc05fca37a3759
---
 graphics/java/android/graphics/HardwareRenderer.java | 18 ++----------------
 1 file changed, 2 insertions(+), 16 deletions(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index 3f3ad578e8d7..b6b2d4e1c46a 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -286,24 +286,10 @@ public class HardwareRenderer {
      *                non-null then {@link Surface#isValid()} must be true.
      */
     public void setSurface(@Nullable Surface surface) {
-        setSurface(surface, false);
-    }
-
-    /**
-     * See {@link #setSurface(Surface)}
-     *
-     * @hide
-     * @param discardBuffer determines whether the surface will attempt to preserve its contents
-     *                      between frames.  If set to true the renderer will attempt to preserve
-     *                      the contents of the buffer between frames if the implementation allows
-     *                      it.  If set to false no attempt will be made to preserve the buffer's
-     *                      contents between frames.
-     */
-    public void setSurface(@Nullable Surface surface, boolean discardBuffer) {
         if (surface != null && !surface.isValid()) {
             throw new IllegalArgumentException("Surface is invalid. surface.isValid() == false.");
         }
-        nSetSurface(mNativeProxy, surface, discardBuffer);
+        nSetSurface(mNativeProxy, surface);
     }
 
     /**
@@ -1098,7 +1084,7 @@ public class HardwareRenderer {
 
     private static native void nSetName(long nativeProxy, String name);
 
-    private static native void nSetSurface(long nativeProxy, Surface window, boolean discardBuffer);
+    private static native void nSetSurface(long nativeProxy, Surface window);
 
     private static native boolean nPause(long nativeProxy);
 
-- 
cgit v1.2.3


From 214e485373ed88d8fd74351023c49c2c922f91de Mon Sep 17 00:00:00 2001
From: Nader Jawad 
Date: Thu, 31 Oct 2019 11:09:18 -0700
Subject: Fixed issue where tint would be applied to solid region of
 GradientDrawable even if none was defined

Fixed issue where solid black would be applied through
modulated default alpha value if both solid and gradient
colors were not applied to the gradient.

Test: Added CTS test
Bug: 142733137
Change-Id: Iecb7010f6d318cc962113528aac694b0de47d9dd
---
 graphics/java/android/graphics/drawable/GradientDrawable.java | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 96ac0f9b38b5..3f887f720e23 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -773,7 +773,9 @@ public class GradientDrawable extends Drawable {
             mFillPaint.setDither(st.mDither);
             mFillPaint.setColorFilter(colorFilter);
             if (colorFilter != null && st.mSolidColors == null) {
-                mFillPaint.setColor(mAlpha << 24);
+                // If we don't have a solid color and we don't have a gradient,
+                // the app is stroking the shape, set the color to transparent
+                mFillPaint.setColor(st.mGradientColors != null ? mAlpha << 24 : 0);
             }
             if (haveStroke) {
                 mStrokePaint.setAlpha(currStrokeAlpha);
-- 
cgit v1.2.3


From 6b8e944486d94b456bf91b59b50dfa9b4fa88abb Mon Sep 17 00:00:00 2001
From: Nader Jawad 
Date: Thu, 31 Oct 2019 13:38:38 -0700
Subject: Delegated implementation of Drawable#jumpToCurrentState

Updated DrawableWrapper to provide an implementation
of Drawable#jumpToCurrentState to call into the
internal Drawable's implementation

Test: Added CTS test to DrawableWrapper
Bug: 142867050
Change-Id: Ifd095c3174da2e240fdfe4a27cfe081db16a6db5
---
 graphics/java/android/graphics/drawable/DrawableWrapper.java | 7 +++++++
 1 file changed, 7 insertions(+)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index 64fc7042dfc7..6c90c4c6c8a4 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -363,6 +363,13 @@ public abstract class DrawableWrapper extends Drawable implements Drawable.Callb
         return false;
     }
 
+    @Override
+    public void jumpToCurrentState() {
+        if (mDrawable != null) {
+            mDrawable.jumpToCurrentState();
+        }
+    }
+
     @Override
     protected boolean onLevelChange(int level) {
         return mDrawable != null && mDrawable.setLevel(level);
-- 
cgit v1.2.3


From 4aa30d07c542cec423ec36db7c294825e757a157 Mon Sep 17 00:00:00 2001
From: Derek Sollenberger 
Date: Fri, 30 Aug 2019 13:53:29 -0400
Subject: Remove native calls to HWUI from Surface and use the public API
 instead

Test: CtsGraphicsTestCases and CtsWindowManagerDeviceTestCases
Bug: 137655431
Change-Id: I8427f96e4f33905e8cabb6d48a0cc29443b9ed63
---
 graphics/java/android/graphics/HardwareRenderer.java | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index b6b2d4e1c46a..3f3ad578e8d7 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -286,10 +286,24 @@ public class HardwareRenderer {
      *                non-null then {@link Surface#isValid()} must be true.
      */
     public void setSurface(@Nullable Surface surface) {
+        setSurface(surface, false);
+    }
+
+    /**
+     * See {@link #setSurface(Surface)}
+     *
+     * @hide
+     * @param discardBuffer determines whether the surface will attempt to preserve its contents
+     *                      between frames.  If set to true the renderer will attempt to preserve
+     *                      the contents of the buffer between frames if the implementation allows
+     *                      it.  If set to false no attempt will be made to preserve the buffer's
+     *                      contents between frames.
+     */
+    public void setSurface(@Nullable Surface surface, boolean discardBuffer) {
         if (surface != null && !surface.isValid()) {
             throw new IllegalArgumentException("Surface is invalid. surface.isValid() == false.");
         }
-        nSetSurface(mNativeProxy, surface);
+        nSetSurface(mNativeProxy, surface, discardBuffer);
     }
 
     /**
@@ -1084,7 +1098,7 @@ public class HardwareRenderer {
 
     private static native void nSetName(long nativeProxy, String name);
 
-    private static native void nSetSurface(long nativeProxy, Surface window);
+    private static native void nSetSurface(long nativeProxy, Surface window, boolean discardBuffer);
 
     private static native boolean nPause(long nativeProxy);
 
-- 
cgit v1.2.3


From f86ed37ce0d2ee475c27ed4105fae1303ee1649c Mon Sep 17 00:00:00 2001
From: Mehdi Alizadeh 
Date: Tue, 1 Oct 2019 14:27:42 -0700
Subject: Adds adaptive bitmap support to URI based icons

Adds a new creator method to accept a Uri and set an internal flag for
Adaptive bitmap, and return adaptive bitmap drawable on loadDrawable().

Bug: 142831407
Test: atest IconTest
Change-Id: Iefee1aaa154a47fc9e5ed1e1c03587a3c8fb6da9
---
 graphics/java/android/graphics/drawable/Icon.java | 106 +++++++++++++++++-----
 1 file changed, 82 insertions(+), 24 deletions(-)

(limited to 'graphics')

diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 3658f89abae1..c2e3c6419400 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -92,11 +92,17 @@ public final class Icon implements Parcelable {
      * @see #getType
      */
     public static final int TYPE_ADAPTIVE_BITMAP = 5;
+    /**
+     * An icon that was created using {@link Icon#createWithAdaptiveBitmapContentUri}.
+     * @see #getType
+     */
+    public static final int TYPE_URI_ADAPTIVE_BITMAP = 6;
 
     /**
      * @hide
      */
-    @IntDef({TYPE_BITMAP, TYPE_RESOURCE, TYPE_DATA, TYPE_URI, TYPE_ADAPTIVE_BITMAP})
+    @IntDef({TYPE_BITMAP, TYPE_RESOURCE, TYPE_DATA, TYPE_URI, TYPE_ADAPTIVE_BITMAP,
+            TYPE_URI_ADAPTIVE_BITMAP})
     public @interface IconType {
     }
 
@@ -113,12 +119,14 @@ public final class Icon implements Parcelable {
     // based on the value of mType.
 
     // TYPE_BITMAP: Bitmap
+    // TYPE_ADAPTIVE_BITMAP: Bitmap
     // TYPE_RESOURCE: Resources
     // TYPE_DATA: DataBytes
     private Object          mObj1;
 
     // TYPE_RESOURCE: package name
     // TYPE_URI: uri string
+    // TYPE_URI_ADAPTIVE_BITMAP: uri string
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     private String          mString1;
 
@@ -141,7 +149,8 @@ public final class Icon implements Parcelable {
     }
 
     /**
-     * @return The {@link android.graphics.Bitmap} held by this {@link #TYPE_BITMAP} Icon.
+     * @return The {@link android.graphics.Bitmap} held by this {@link #TYPE_BITMAP} or
+     * {@link #TYPE_ADAPTIVE_BITMAP} Icon.
      * @hide
      */
     @UnsupportedAppUsage
@@ -243,11 +252,12 @@ public final class Icon implements Parcelable {
     }
 
     /**
-     * @return The URI (as a String) for this {@link #TYPE_URI} Icon.
+     * @return The URI (as a String) for this {@link #TYPE_URI} or {@link #TYPE_URI_ADAPTIVE_BITMAP}
+     * Icon.
      * @hide
      */
     public String getUriString() {
-        if (mType != TYPE_URI) {
+        if (mType != TYPE_URI && mType != TYPE_URI_ADAPTIVE_BITMAP) {
             throw new IllegalStateException("called getUriString() on " + this);
         }
         return mString1;
@@ -256,7 +266,7 @@ public final class Icon implements Parcelable {
     /**
      * Gets the uri used to create this icon.
      * 

- * Only valid for icons of type {@link #TYPE_URI}. + * Only valid for icons of type {@link #TYPE_URI} and {@link #TYPE_URI_ADAPTIVE_BITMAP}. * Note: This uri may not be available in the future, and it is * up to the caller to ensure safety if this uri is re-used and/or persisted. */ @@ -272,6 +282,7 @@ public final class Icon implements Parcelable { case TYPE_DATA: return "DATA"; case TYPE_RESOURCE: return "RESOURCE"; case TYPE_URI: return "URI"; + case TYPE_URI_ADAPTIVE_BITMAP: return "URI_MASKABLE"; default: return "UNKNOWN"; } } @@ -380,28 +391,39 @@ public final class Icon implements Parcelable { BitmapFactory.decodeByteArray(getDataBytes(), getDataOffset(), getDataLength()) ); case TYPE_URI: - final Uri uri = getUri(); - final String scheme = uri.getScheme(); - InputStream is = null; - if (ContentResolver.SCHEME_CONTENT.equals(scheme) - || ContentResolver.SCHEME_FILE.equals(scheme)) { - try { - is = context.getContentResolver().openInputStream(uri); - } catch (Exception e) { - Log.w(TAG, "Unable to load image from URI: " + uri, e); - } - } else { - try { - is = new FileInputStream(new File(mString1)); - } catch (FileNotFoundException e) { - Log.w(TAG, "Unable to load image from path: " + uri, e); - } - } + InputStream is = getUriInputStream(context); if (is != null) { return new BitmapDrawable(context.getResources(), BitmapFactory.decodeStream(is)); } break; + case TYPE_URI_ADAPTIVE_BITMAP: + is = getUriInputStream(context); + if (is != null) { + return new AdaptiveIconDrawable(null, new BitmapDrawable(context.getResources(), + BitmapFactory.decodeStream(is))); + } + break; + } + return null; + } + + private InputStream getUriInputStream(Context context) { + final Uri uri = getUri(); + final String scheme = uri.getScheme(); + if (ContentResolver.SCHEME_CONTENT.equals(scheme) + || ContentResolver.SCHEME_FILE.equals(scheme)) { + try { + return context.getContentResolver().openInputStream(uri); + } catch (Exception e) { + Log.w(TAG, "Unable to load image from URI: " + uri, e); + } + } else { + try { + return new FileInputStream(new File(mString1)); + } catch (FileNotFoundException e) { + Log.w(TAG, "Unable to load image from path: " + uri, e); + } } return null; } @@ -475,6 +497,7 @@ public final class Icon implements Parcelable { dataStream.writeInt(getResId()); break; case TYPE_URI: + case TYPE_URI_ADAPTIVE_BITMAP: dataStream.writeUTF(getUriString()); break; } @@ -513,6 +536,9 @@ public final class Icon implements Parcelable { case TYPE_URI: final String uriOrPath = inputStream.readUTF(); return createWithContentUri(uriOrPath); + case TYPE_URI_ADAPTIVE_BITMAP: + final String uri = inputStream.readUTF(); + return createWithAdaptiveBitmapContentUri(uri); } } return null; @@ -545,6 +571,7 @@ public final class Icon implements Parcelable { return getResId() == otherIcon.getResId() && Objects.equals(getResPackage(), otherIcon.getResPackage()); case TYPE_URI: + case TYPE_URI_ADAPTIVE_BITMAP: return Objects.equals(getUriString(), otherIcon.getUriString()); } return false; @@ -665,11 +692,39 @@ public final class Icon implements Parcelable { if (uri == null) { throw new IllegalArgumentException("Uri must not be null."); } - final Icon rep = new Icon(TYPE_URI); - rep.mString1 = uri.toString(); + return createWithContentUri(uri.toString()); + } + + /** + * Create an Icon pointing to an image file specified by URI. Image file should follow the icon + * design guideline defined by {@link AdaptiveIconDrawable}. + * + * @param uri A uri referring to local content:// or file:// image data. + */ + @NonNull + public static Icon createWithAdaptiveBitmapContentUri(@NonNull String uri) { + if (uri == null) { + throw new IllegalArgumentException("Uri must not be null."); + } + final Icon rep = new Icon(TYPE_URI_ADAPTIVE_BITMAP); + rep.mString1 = uri; return rep; } + /** + * Create an Icon pointing to an image file specified by URI. Image file should follow the icon + * design guideline defined by {@link AdaptiveIconDrawable}. + * + * @param uri A uri referring to local content:// or file:// image data. + */ + @NonNull + public static Icon createWithAdaptiveBitmapContentUri(@NonNull Uri uri) { + if (uri == null) { + throw new IllegalArgumentException("Uri must not be null."); + } + return createWithAdaptiveBitmapContentUri(uri.toString()); + } + /** * Store a color to use whenever this Icon is drawn. * @@ -758,6 +813,7 @@ public final class Icon implements Parcelable { } break; case TYPE_URI: + case TYPE_URI_ADAPTIVE_BITMAP: sb.append(" uri=").append(getUriString()); break; } @@ -809,6 +865,7 @@ public final class Icon implements Parcelable { mObj1 = a; break; case TYPE_URI: + case TYPE_URI_ADAPTIVE_BITMAP: final String uri = in.readString(); mString1 = uri; break; @@ -840,6 +897,7 @@ public final class Icon implements Parcelable { dest.writeBlob(getDataBytes(), getDataOffset(), getDataLength()); break; case TYPE_URI: + case TYPE_URI_ADAPTIVE_BITMAP: dest.writeString(getUriString()); break; } -- cgit v1.2.3 From 637efbaa0a75c72461b325f3648ab4dababad0bb Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Tue, 19 Nov 2019 13:53:29 -0500 Subject: ImageDecoder: compare Strings with .equals() Bug: 143231863 Test: Infeasible? Previously we compared with "==", which requires that the two String objects be the same to return true. We want to return true if the two Strings are logically equal, even if they are different objects. Prior to this commit, we may have accidentally called openAssetFileDescriptor when we should have called openTypedAssetFileDescriptor. Change-Id: I9229039b752bafa9a9b85b914a62093dff1eec34 --- graphics/java/android/graphics/ImageDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java index 6619dba159c2..aaaa7491f2ef 100644 --- a/graphics/java/android/graphics/ImageDecoder.java +++ b/graphics/java/android/graphics/ImageDecoder.java @@ -270,7 +270,7 @@ public final class ImageDecoder implements AutoCloseable { public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException { AssetFileDescriptor assetFd = null; try { - if (mUri.getScheme() == ContentResolver.SCHEME_CONTENT) { + if (mUri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) { assetFd = mResolver.openTypedAssetFileDescriptor(mUri, "image/*", null); } else { -- cgit v1.2.3 From 6867fc8778dff60f68f9cff1f82d5fd0f899ba55 Mon Sep 17 00:00:00 2001 From: Stan Iliev Date: Fri, 22 Nov 2019 18:00:01 -0500 Subject: Implement a new Shader API, which can run custom code on GPU Add RuntimeShader hidden API, which calculates pixel output with a fragment shader running on GPU. Extend ColorFiltersMutateActivity HWUI test to use new API and show how to animate uniforms on UI thread. Test: Updated HwAccelerationTest Change-Id: Ia26e44259b12099924facba250880cbbd9be21c7 --- graphics/java/android/graphics/RuntimeShader.java | 88 +++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 graphics/java/android/graphics/RuntimeShader.java (limited to 'graphics') diff --git a/graphics/java/android/graphics/RuntimeShader.java b/graphics/java/android/graphics/RuntimeShader.java new file mode 100644 index 000000000000..613ce9042056 --- /dev/null +++ b/graphics/java/android/graphics/RuntimeShader.java @@ -0,0 +1,88 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics; + +import android.annotation.NonNull; +import android.annotation.Nullable; + +import libcore.util.NativeAllocationRegistry; + +/** + * Shader that calculates pixel output with a program (fragment shader) running on a GPU. + * @hide + */ +public class RuntimeShader extends Shader { + + private static class NoImagePreloadHolder { + public static final NativeAllocationRegistry sRegistry = + NativeAllocationRegistry.createMalloced( + RuntimeShader.class.getClassLoader(), nativeGetFinalizer()); + } + + private byte[] mUniforms; + + /** + * Current native shader factory instance. + */ + private long mNativeInstanceRuntimeShaderFactory; + + /** + * Creates a new RuntimeShader. + * + * @param sksl The text of SKSL program to run on the GPU. + * @param uniforms Array of parameters passed by the SKSL shader. Array size depends + * on number of uniforms declared by sksl. + * @param isOpaque True if all pixels have alpha 1.0f. + */ + public RuntimeShader(@NonNull String sksl, @Nullable byte[] uniforms, boolean isOpaque) { + this(sksl, uniforms, isOpaque, ColorSpace.get(ColorSpace.Named.SRGB)); + } + + private RuntimeShader(@NonNull String sksl, @Nullable byte[] uniforms, boolean isOpaque, + ColorSpace colorSpace) { + super(colorSpace); + mUniforms = uniforms; + mNativeInstanceRuntimeShaderFactory = nativeCreateShaderFactory(sksl, isOpaque); + NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, + mNativeInstanceRuntimeShaderFactory); + } + + /** + * Sets new value for shader parameters. + * + * @param uniforms Array of parameters passed by the SKSL shader. Array size depends + * on number of uniforms declared by mSksl. + */ + public void updateUniforms(@Nullable byte[] uniforms) { + mUniforms = uniforms; + discardNativeInstance(); + } + + @Override + long createNativeInstance(long nativeMatrix) { + return nativeCreate(mNativeInstanceRuntimeShaderFactory, nativeMatrix, mUniforms, + colorSpace().getNativeInstance()); + } + + private static native long nativeCreate(long shaderFactory, long matrix, byte[] inputs, + long colorSpaceHandle); + + private static native long nativeCreateShaderFactory(String sksl, boolean isOpaque); + + private static native long nativeGetFinalizer(); +} + -- cgit v1.2.3 From cb78285b81eb731bf75a7cd869657505caec06ae Mon Sep 17 00:00:00 2001 From: Jeffrey Huang Date: Thu, 5 Dec 2019 11:28:11 -0800 Subject: Rename writeToProto to be dumpDebug We want to eventually migrate some of these APIs to be @SystemApi for mainline modules. The #dumpDebug name is more appropriate than #writeToProto. Bug: 142279786 Test: Manual Change-Id: I60793e91cedf6b720d4ecef6a8484f4fed4ff30f --- graphics/java/android/graphics/Point.java | 2 +- graphics/java/android/graphics/Rect.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/Point.java b/graphics/java/android/graphics/Point.java index 3614f3bcb3be..9f71a0fedd05 100644 --- a/graphics/java/android/graphics/Point.java +++ b/graphics/java/android/graphics/Point.java @@ -132,7 +132,7 @@ public class Point implements Parcelable { * @param fieldId Field Id of the Rect as defined in the parent message * @hide */ - public void writeToProto(@NonNull ProtoOutputStream protoOutputStream, long fieldId) { + public void dumpDebug(@NonNull ProtoOutputStream protoOutputStream, long fieldId) { final long token = protoOutputStream.start(fieldId); protoOutputStream.write(PointProto.X, x); protoOutputStream.write(PointProto.Y, y); diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java index d47f682ec2d3..9e1946c557d2 100644 --- a/graphics/java/android/graphics/Rect.java +++ b/graphics/java/android/graphics/Rect.java @@ -239,7 +239,7 @@ public final class Rect implements Parcelable { * @param fieldId Field Id of the Rect as defined in the parent message * @hide */ - public void writeToProto(@NonNull ProtoOutputStream protoOutputStream, long fieldId) { + public void dumpDebug(@NonNull ProtoOutputStream protoOutputStream, long fieldId) { final long token = protoOutputStream.start(fieldId); protoOutputStream.write(RectProto.LEFT, left); protoOutputStream.write(RectProto.TOP, top); -- cgit v1.2.3 From beebd3ca9bd3289f2bf76e0cd0814e34505d5ab6 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Fri, 6 Dec 2019 12:45:11 -0500 Subject: ImageDecoder: Disallow empty/unsorted crop rects Bug: 135133301 Test: Idf64474f28c0bf3f77616a31d843d84fbfd570ab If the specified crop Rect is empty or unsorted, throw an IllegalStateException, like we do if the Rect does not fit in the target size. This is a change in behavior to make it more consistent. Here are the specific behavior changes: - an empty crop rect was previously supported in all cases, but would result in a zero width and/or height Bitmap/Drawable. If one dimension is non-zero, it still affects layout, though nothing is drawn. This is not useful, so the new Exception is more helpful. (It is also more consistent with setTargetSize, which throws an IllegalArgumentException for non-positive dimensions.) - a negative width or height in decodeBitmap, or on a static image in decodeDrawable, previously threw an IOException when trying to call SkBitmap::setInfo with a negative width or height. Throwing an IllegalStateException is more consistent with other invalid crop rects - a negative width or height in decodeDrawable on an animated image previously resulted in an AnimatedImageDrawable with a negative intrinsic width and/or height. When passed to an ImageView, this dimension ends up being 1. Again, this does not seem useful. Change-Id: I15d2f77125799413eaf55d417e98ff34599e2eb4 --- graphics/java/android/graphics/ImageDecoder.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'graphics') diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java index 6619dba159c2..8ebac667aca3 100644 --- a/graphics/java/android/graphics/ImageDecoder.java +++ b/graphics/java/android/graphics/ImageDecoder.java @@ -1675,6 +1675,9 @@ public final class ImageDecoder implements AutoCloseable { if (r == null) { return; } + if (r.width() <= 0 || r.height() <= 0) { + throw new IllegalStateException("Subset " + r + " is empty/unsorted"); + } if (r.left < 0 || r.top < 0 || r.right > width || r.bottom > height) { throw new IllegalStateException("Subset " + r + " not contained by " + "scaled image bounds: (" + width + " x " + height + ")"); -- cgit v1.2.3 From 351df0901d4e00d7360c5a94fe089db152aea6c4 Mon Sep 17 00:00:00 2001 From: Haoyu Zhang Date: Thu, 12 Dec 2019 13:38:16 -0800 Subject: Rmove @UnsupportedAppUsage Bug: 145986883 Test: atest FontFamilyTest Test: adb shell am instrument -w -r -e class 'androidx.core.graphics.TypefaceCompatTest' androidx.core.test/androidx.test.runner.AndroidJUnitRunner Change-Id: Iac6b9cb0dde2289604e5ec4b9bff8930fd9a4229 --- graphics/java/android/graphics/FontFamily.java | 9 --------- 1 file changed, 9 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java index 5ad93f411393..2648008b8f80 100644 --- a/graphics/java/android/graphics/FontFamily.java +++ b/graphics/java/android/graphics/FontFamily.java @@ -17,7 +17,6 @@ package android.graphics; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.graphics.fonts.FontVariationAxis; import android.text.TextUtils; @@ -58,7 +57,6 @@ public class FontFamily { * * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) public long mNativePtr; // Points native font family builder. Must be zero after freezing this family. @@ -67,7 +65,6 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) public FontFamily() { mBuilderPtr = nInitBuilder(null, 0); mNativeBuilderCleaner = sBuilderRegistry.registerNativeAllocation(this, mBuilderPtr); @@ -76,7 +73,6 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) public FontFamily(@Nullable String[] langs, int variant) { final String langsString; if (langs == null || langs.length == 0) { @@ -98,7 +94,6 @@ public class FontFamily { * * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) public boolean freeze() { if (mBuilderPtr == 0) { throw new IllegalStateException("This FontFamily is already frozen"); @@ -115,7 +110,6 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) public void abortCreation() { if (mBuilderPtr == 0) { throw new IllegalStateException("This FontFamily is already frozen or abandoned"); @@ -127,7 +121,6 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) public boolean addFont(String path, int ttcIndex, FontVariationAxis[] axes, int weight, int italic) { if (mBuilderPtr == 0) { @@ -151,7 +144,6 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) public boolean addFontFromBuffer(ByteBuffer font, int ttcIndex, FontVariationAxis[] axes, int weight, int italic) { if (mBuilderPtr == 0) { @@ -179,7 +171,6 @@ public class FontFamily { * * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) public boolean addFontFromAssetManager(AssetManager mgr, String path, int cookie, boolean isAsset, int ttcIndex, int weight, int isItalic, FontVariationAxis[] axes) { -- cgit v1.2.3 From fe7b206c8d00a44ff51901ea4f620fc2f29b84b3 Mon Sep 17 00:00:00 2001 From: Haoyu Zhang Date: Mon, 16 Dec 2019 21:46:58 +0000 Subject: Revert "Rmove @UnsupportedAppUsage" This reverts commit 351df0901d4e00d7360c5a94fe089db152aea6c4. Bug: 146181012 Bug: 145986883 Bug: 146318594 Bug: 146316215 Bug: 146315595 Reason for revert: This changed caused APP crash. Change-Id: I0a1863176bf80ba5ad044621b5a2ff72e0d57fa4 --- graphics/java/android/graphics/FontFamily.java | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'graphics') diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java index 2648008b8f80..5ad93f411393 100644 --- a/graphics/java/android/graphics/FontFamily.java +++ b/graphics/java/android/graphics/FontFamily.java @@ -17,6 +17,7 @@ package android.graphics; import android.annotation.Nullable; +import android.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.graphics.fonts.FontVariationAxis; import android.text.TextUtils; @@ -57,6 +58,7 @@ public class FontFamily { * * This cannot be deleted because it's in use by AndroidX. */ + @UnsupportedAppUsage(trackingBug = 123768928) public long mNativePtr; // Points native font family builder. Must be zero after freezing this family. @@ -65,6 +67,7 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ + @UnsupportedAppUsage(trackingBug = 123768928) public FontFamily() { mBuilderPtr = nInitBuilder(null, 0); mNativeBuilderCleaner = sBuilderRegistry.registerNativeAllocation(this, mBuilderPtr); @@ -73,6 +76,7 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ + @UnsupportedAppUsage(trackingBug = 123768928) public FontFamily(@Nullable String[] langs, int variant) { final String langsString; if (langs == null || langs.length == 0) { @@ -94,6 +98,7 @@ public class FontFamily { * * This cannot be deleted because it's in use by AndroidX. */ + @UnsupportedAppUsage(trackingBug = 123768928) public boolean freeze() { if (mBuilderPtr == 0) { throw new IllegalStateException("This FontFamily is already frozen"); @@ -110,6 +115,7 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ + @UnsupportedAppUsage(trackingBug = 123768928) public void abortCreation() { if (mBuilderPtr == 0) { throw new IllegalStateException("This FontFamily is already frozen or abandoned"); @@ -121,6 +127,7 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ + @UnsupportedAppUsage(trackingBug = 123768928) public boolean addFont(String path, int ttcIndex, FontVariationAxis[] axes, int weight, int italic) { if (mBuilderPtr == 0) { @@ -144,6 +151,7 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ + @UnsupportedAppUsage(trackingBug = 123768928) public boolean addFontFromBuffer(ByteBuffer font, int ttcIndex, FontVariationAxis[] axes, int weight, int italic) { if (mBuilderPtr == 0) { @@ -171,6 +179,7 @@ public class FontFamily { * * This cannot be deleted because it's in use by AndroidX. */ + @UnsupportedAppUsage(trackingBug = 123768928) public boolean addFontFromAssetManager(AssetManager mgr, String path, int cookie, boolean isAsset, int ttcIndex, int weight, int isItalic, FontVariationAxis[] axes) { -- cgit v1.2.3 From 913dd6b9a9f43d21c5d2baa39a2bcd2239252b17 Mon Sep 17 00:00:00 2001 From: Nader Jawad Date: Mon, 16 Dec 2019 23:32:29 +0000 Subject: Revert submission Reason for revert: Causes regressions tracked in: b/145900622 b/145864909 b/145948923 Change-Id: Ia24ece94d5281cd25d990d8cae923cf50497e1f1 --- graphics/java/android/graphics/drawable/GradientDrawable.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 45b2de5f4b31..c6586ecfceb9 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -784,9 +784,7 @@ public class GradientDrawable extends Drawable { mFillPaint.setDither(st.mDither); mFillPaint.setColorFilter(colorFilter); if (colorFilter != null && st.mSolidColors == null) { - // If we don't have a solid color and we don't have a gradient, - // the app is stroking the shape, set the color to transparent - mFillPaint.setColor(st.mGradientColors != null ? mAlpha << 24 : 0); + mFillPaint.setColor(mAlpha << 24); } if (haveStroke) { mStrokePaint.setAlpha(currStrokeAlpha); -- cgit v1.2.3 From c4ef2c702a744c8d0a918d5dceb8d88bf3713908 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Mon, 9 Dec 2019 12:38:59 -0500 Subject: Move FrameMetricsObserver logic into UI Module. Introduce HardwareRendererObserver to isolate the android.graphics package from the android.view package. The native code that interacts with the observer was also moved from libandroid_runtime to libandroid_graphics to keep it within the confines of the UI Rendering module. Bug: 137655431 Test: CtsUiRenderingTestCases Change-Id: Ibccecbeda0c4d9501d86514a53eb98548233ba6a --- .../java/android/graphics/HardwareRenderer.java | 18 ++-- .../android/graphics/HardwareRendererObserver.java | 103 +++++++++++++++++++++ 2 files changed, 109 insertions(+), 12 deletions(-) create mode 100644 graphics/java/android/graphics/HardwareRendererObserver.java (limited to 'graphics') diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java index 3f3ad578e8d7..3b864139cf71 100644 --- a/graphics/java/android/graphics/HardwareRenderer.java +++ b/graphics/java/android/graphics/HardwareRenderer.java @@ -28,7 +28,6 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; import android.util.TimeUtils; -import android.view.FrameMetricsObserver; import android.view.IGraphicsStats; import android.view.IGraphicsStatsCallback; import android.view.NativeVectorDrawableAnimator; @@ -38,8 +37,6 @@ import android.view.SurfaceHolder; import android.view.TextureLayer; import android.view.animation.AnimationUtils; -import com.android.internal.util.VirtualRefBasePtr; - import java.io.File; import java.io.FileDescriptor; import java.lang.annotation.Retention; @@ -598,9 +595,8 @@ public class HardwareRenderer { * * @hide */ - public void addFrameMetricsObserver(FrameMetricsObserver observer) { - long nativeObserver = nAddFrameMetricsObserver(mNativeProxy, observer); - observer.mNative = new VirtualRefBasePtr(nativeObserver); + public void addObserver(HardwareRendererObserver observer) { + nAddObserver(mNativeProxy, observer.getNativeInstance()); } /** @@ -608,9 +604,8 @@ public class HardwareRenderer { * * @hide */ - public void removeFrameMetricsObserver(FrameMetricsObserver observer) { - nRemoveFrameMetricsObserver(mNativeProxy, observer.mNative.get()); - observer.mNative = null; + public void removeObserver(HardwareRendererObserver observer) { + nRemoveObserver(mNativeProxy, observer.getNativeInstance()); } /** @@ -1170,10 +1165,9 @@ public class HardwareRenderer { private static native void nSetFrameCompleteCallback(long nativeProxy, FrameCompleteCallback callback); - private static native long nAddFrameMetricsObserver(long nativeProxy, - FrameMetricsObserver observer); + private static native void nAddObserver(long nativeProxy, long nativeObserver); - private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver); + private static native void nRemoveObserver(long nativeProxy, long nativeObserver); private static native int nCopySurfaceInto(Surface surface, int srcLeft, int srcTop, int srcRight, int srcBottom, long bitmapHandle); diff --git a/graphics/java/android/graphics/HardwareRendererObserver.java b/graphics/java/android/graphics/HardwareRendererObserver.java new file mode 100644 index 000000000000..da9d03c639f7 --- /dev/null +++ b/graphics/java/android/graphics/HardwareRendererObserver.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics; + +import android.annotation.NonNull; +import android.os.Handler; + +import com.android.internal.util.VirtualRefBasePtr; + +/** + * Provides streaming access to frame stats information from HardwareRenderer to apps. + * + * @hide + */ +public class HardwareRendererObserver { + private final long[] mFrameMetrics; + private final Handler mHandler; + private final OnFrameMetricsAvailableListener mListener; + private VirtualRefBasePtr mNativePtr; + + /** + * Interface for clients that want frame timing information for each frame rendered. + * @hide + */ + public interface OnFrameMetricsAvailableListener { + /** + * Called when information is available for the previously rendered frame. + * + * Reports can be dropped if this callback takes too long to execute, as the report producer + * cannot wait for the consumer to complete. + * + * It is highly recommended that clients copy the metrics array within this method + * and defer additional computation or storage to another thread to avoid unnecessarily + * dropping reports. + * + * @param dropCountSinceLastInvocation the number of reports dropped since the last time + * this callback was invoked. + */ + void onFrameMetricsAvailable(int dropCountSinceLastInvocation); + } + + /** + * Creates a FrameMetricsObserver + * + * @param frameMetrics the available metrics. This array is reused on every call to the listener + * and thus this reference should only be used within the scope of the listener callback + * as data is not guaranteed to be valid outside the scope of that method. + * @param handler the Handler to use when invoking callbacks + */ + public HardwareRendererObserver(@NonNull OnFrameMetricsAvailableListener listener, + @NonNull long[] frameMetrics, @NonNull Handler handler) { + if (handler == null || handler.getLooper() == null) { + throw new NullPointerException("handler and its looper cannot be null"); + } + + if (handler.getLooper().getQueue() == null) { + throw new IllegalStateException("invalid looper, null message queue\n"); + } + + mFrameMetrics = frameMetrics; + mHandler = handler; + mListener = listener; + mNativePtr = new VirtualRefBasePtr(nCreateObserver()); + } + + /*package*/ long getNativeInstance() { + return mNativePtr.get(); + } + + // Called by native on the provided Handler + @SuppressWarnings("unused") + private void notifyDataAvailable() { + mHandler.post(() -> { + boolean hasMoreData = true; + while (hasMoreData) { + // a drop count of -1 is a sentinel that no more buffers are available + int dropCount = nGetNextBuffer(mNativePtr.get(), mFrameMetrics); + if (dropCount >= 0) { + mListener.onFrameMetricsAvailable(dropCount); + } else { + hasMoreData = false; + } + } + }); + } + + private native long nCreateObserver(); + private static native int nGetNextBuffer(long nativePtr, long[] data); +} -- cgit v1.2.3 From 53fe96661be60ee70e16d3039339b9f069904a61 Mon Sep 17 00:00:00 2001 From: Artur Satayev Date: Tue, 10 Dec 2019 17:47:55 +0000 Subject: Use new UnsupportedAppUsage annotation. Existing annotations in libcore/ and frameworks/ will deleted after the migration. This also means that any java library that compiles @UnsupportedAppUsage requires a direct dependency on "unsupportedappusage" java_library. Bug: 145132366 Test: m && diff unsupportedappusage_index.csv Change-Id: I4bc8c9482e4bb1af21363f951affff7ee3fefeab --- .../android/graphics/drawable/ColorDrawable.java | 2 +- .../java/android/graphics/drawable/Drawable.java | 2 +- .../android/graphics/drawable/DrawableContainer.java | 2 +- .../android/graphics/drawable/DrawableInflater.java | 8 ++++---- .../android/graphics/drawable/DrawableWrapper.java | 2 +- .../android/graphics/drawable/GradientDrawable.java | 2 +- graphics/java/android/graphics/drawable/Icon.java | 2 +- .../android/graphics/drawable/InsetDrawable.java | 2 +- .../android/graphics/drawable/LayerDrawable.java | 2 +- .../android/graphics/drawable/NinePatchDrawable.java | 2 +- .../android/graphics/drawable/RippleDrawable.java | 2 +- .../android/graphics/drawable/RotateDrawable.java | 20 ++++++++++---------- .../android/graphics/drawable/ScaleDrawable.java | 12 ++++++------ .../android/graphics/drawable/StateListDrawable.java | 2 +- .../graphics/drawable/TransitionDrawable.java | 2 +- .../android/graphics/drawable/VectorDrawable.java | 2 +- .../android/graphics/fonts/FontVariationAxis.java | 2 +- graphics/java/android/graphics/pdf/PdfRenderer.java | 4 +++- 18 files changed, 37 insertions(+), 35 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java index f5fa8c546bed..e93e7dfbe22c 100644 --- a/graphics/java/android/graphics/drawable/ColorDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorDrawable.java @@ -20,7 +20,7 @@ import android.annotation.ColorInt; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 08409869c626..e70529b6cd1a 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -22,7 +22,7 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index 090d915a2f67..51b299c9ee5e 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -17,7 +17,7 @@ package android.graphics.drawable; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/DrawableInflater.java b/graphics/java/android/graphics/drawable/DrawableInflater.java index bad3791a9c24..3408b64e7536 100644 --- a/graphics/java/android/graphics/drawable/DrawableInflater.java +++ b/graphics/java/android/graphics/drawable/DrawableInflater.java @@ -16,19 +16,19 @@ package android.graphics.drawable; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.util.AttributeSet; import android.view.InflateException; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + import java.io.IOException; import java.lang.reflect.Constructor; import java.util.HashMap; diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java index 6c90c4c6c8a4..e197e7123fed 100644 --- a/graphics/java/android/graphics/drawable/DrawableWrapper.java +++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index c6586ecfceb9..3881955d2632 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -22,7 +22,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Px; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java index c2e3c6419400..cc7182c3fd1c 100644 --- a/graphics/java/android/graphics/drawable/Icon.java +++ b/graphics/java/android/graphics/drawable/Icon.java @@ -21,7 +21,7 @@ import android.annotation.DrawableRes; import android.annotation.IdRes; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.Context; import android.content.pm.ApplicationInfo; diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java index bc8a4cbd7e9d..005a4d175fd5 100644 --- a/graphics/java/android/graphics/drawable/InsetDrawable.java +++ b/graphics/java/android/graphics/drawable/InsetDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java index 760d554888ee..fb4146f04bc9 100644 --- a/graphics/java/android/graphics/drawable/LayerDrawable.java +++ b/graphics/java/android/graphics/drawable/LayerDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index 8561d95ddd88..99d27ba4c469 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index 1540cc22e295..e5e4d4527fca 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java index db5f082bd853..43766b636adb 100644 --- a/graphics/java/android/graphics/drawable/RotateDrawable.java +++ b/graphics/java/android/graphics/drawable/RotateDrawable.java @@ -16,22 +16,22 @@ package android.graphics.drawable; -import com.android.internal.R; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; -import android.graphics.Canvas; -import android.graphics.Rect; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; -import android.content.res.TypedArray; import android.content.res.Resources.Theme; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.util.AttributeSet; import android.util.MathUtils; import android.util.TypedValue; -import android.util.AttributeSet; + +import com.android.internal.R; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java index 91ed061e511d..af7eed4b3897 100644 --- a/graphics/java/android/graphics/drawable/ScaleDrawable.java +++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java @@ -16,14 +16,9 @@ package android.graphics.drawable; -import com.android.internal.R; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; @@ -34,6 +29,11 @@ import android.util.AttributeSet; import android.util.TypedValue; import android.view.Gravity; +import com.android.internal.R; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + import java.io.IOException; /** diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java index f67188c22609..2920acbe514c 100644 --- a/graphics/java/android/graphics/drawable/StateListDrawable.java +++ b/graphics/java/android/graphics/drawable/StateListDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; diff --git a/graphics/java/android/graphics/drawable/TransitionDrawable.java b/graphics/java/android/graphics/drawable/TransitionDrawable.java index 276f3662189b..401e05ffc139 100644 --- a/graphics/java/android/graphics/drawable/TransitionDrawable.java +++ b/graphics/java/android/graphics/drawable/TransitionDrawable.java @@ -16,7 +16,7 @@ package android.graphics.drawable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.Resources; import android.graphics.Canvas; diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index aa19b2a0e94c..e6fa866df3ab 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -16,7 +16,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.ComplexColor; diff --git a/graphics/java/android/graphics/fonts/FontVariationAxis.java b/graphics/java/android/graphics/fonts/FontVariationAxis.java index bcee559d8291..4e6580ea5f53 100644 --- a/graphics/java/android/graphics/fonts/FontVariationAxis.java +++ b/graphics/java/android/graphics/fonts/FontVariationAxis.java @@ -18,7 +18,7 @@ package android.graphics.fonts; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.text.TextUtils; diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java index bd1a49205fd5..54710e58687c 100644 --- a/graphics/java/android/graphics/pdf/PdfRenderer.java +++ b/graphics/java/android/graphics/pdf/PdfRenderer.java @@ -19,7 +19,7 @@ package android.graphics.pdf; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Matrix; @@ -29,7 +29,9 @@ import android.os.ParcelFileDescriptor; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; + import com.android.internal.util.Preconditions; + import dalvik.system.CloseGuard; import libcore.io.IoUtils; -- cgit v1.2.3 From bc44fa0fa84a296bcd3506dfabc83f6b221ff1b4 Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Fri, 3 Jan 2020 15:28:06 -0500 Subject: Use SkRuntimeEffect rather than SkRuntimeShaderFactory The old API was a shim over the new API, and will be deleted soon. The new API is actually public, simpler, and more powerful. Test: Everything still builds. Change-Id: I11af8da9132e23a070e87dd5a7401c4854dd102a --- graphics/java/android/graphics/RuntimeShader.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/RuntimeShader.java b/graphics/java/android/graphics/RuntimeShader.java index 613ce9042056..5a3f2a96e31d 100644 --- a/graphics/java/android/graphics/RuntimeShader.java +++ b/graphics/java/android/graphics/RuntimeShader.java @@ -34,6 +34,7 @@ public class RuntimeShader extends Shader { } private byte[] mUniforms; + private boolean mIsOpaque; /** * Current native shader factory instance. @@ -56,7 +57,8 @@ public class RuntimeShader extends Shader { ColorSpace colorSpace) { super(colorSpace); mUniforms = uniforms; - mNativeInstanceRuntimeShaderFactory = nativeCreateShaderFactory(sksl, isOpaque); + mIsOpaque = isOpaque; + mNativeInstanceRuntimeShaderFactory = nativeCreateShaderFactory(sksl); NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeInstanceRuntimeShaderFactory); } @@ -75,13 +77,13 @@ public class RuntimeShader extends Shader { @Override long createNativeInstance(long nativeMatrix) { return nativeCreate(mNativeInstanceRuntimeShaderFactory, nativeMatrix, mUniforms, - colorSpace().getNativeInstance()); + colorSpace().getNativeInstance(), mIsOpaque); } private static native long nativeCreate(long shaderFactory, long matrix, byte[] inputs, - long colorSpaceHandle); + long colorSpaceHandle, boolean isOpaque); - private static native long nativeCreateShaderFactory(String sksl, boolean isOpaque); + private static native long nativeCreateShaderFactory(String sksl); private static native long nativeGetFinalizer(); } -- cgit v1.2.3 From 00f8b53650ab3a46a401712b87a597ffe7d1b98d Mon Sep 17 00:00:00 2001 From: Artur Satayev Date: Tue, 10 Dec 2019 17:47:55 +0000 Subject: Use new UnsupportedAppUsage annotation. Existing annotations in libcore/ and frameworks/ will deleted after the migration. This also means that any java library that compiles @UnsupportedAppUsage requires a direct dependency on "unsupportedappusage" java_library. Bug: 145132366 Test: m && diff unsupportedappusage_index.csv Change-Id: I8ffa1da1bcd43c25f4ff817575db77a33c0f3d31 --- graphics/java/android/graphics/BaseCanvas.java | 2 +- graphics/java/android/graphics/Bitmap.java | 2 +- graphics/java/android/graphics/BitmapFactory.java | 2 +- .../java/android/graphics/BitmapRegionDecoder.java | 2 +- graphics/java/android/graphics/BitmapShader.java | 2 +- graphics/java/android/graphics/Camera.java | 2 +- graphics/java/android/graphics/Canvas.java | 2 +- graphics/java/android/graphics/CanvasProperty.java | 3 ++- .../android/graphics/ColorMatrixColorFilter.java | 2 +- graphics/java/android/graphics/FontFamily.java | 2 +- graphics/java/android/graphics/FontListParser.java | 2 +- graphics/java/android/graphics/GraphicBuffer.java | 2 +- graphics/java/android/graphics/ImageDecoder.java | 2 +- .../java/android/graphics/LightingColorFilter.java | 2 +- graphics/java/android/graphics/LinearGradient.java | 2 +- graphics/java/android/graphics/Matrix.java | 2 +- graphics/java/android/graphics/Movie.java | 2 +- graphics/java/android/graphics/NinePatch.java | 2 +- graphics/java/android/graphics/Outline.java | 2 +- graphics/java/android/graphics/Paint.java | 2 +- graphics/java/android/graphics/Path.java | 2 +- graphics/java/android/graphics/Picture.java | 2 +- graphics/java/android/graphics/PorterDuff.java | 2 +- .../java/android/graphics/PorterDuffColorFilter.java | 2 +- graphics/java/android/graphics/RadialGradient.java | 2 +- graphics/java/android/graphics/Rect.java | 2 +- graphics/java/android/graphics/Region.java | 2 +- graphics/java/android/graphics/Shader.java | 2 +- graphics/java/android/graphics/SurfaceTexture.java | 2 +- graphics/java/android/graphics/SweepGradient.java | 2 +- graphics/java/android/graphics/TableMaskFilter.java | 2 +- graphics/java/android/graphics/TemporaryBuffer.java | 3 ++- graphics/java/android/graphics/Typeface.java | 2 +- graphics/java/android/graphics/Xfermode.java | 2 +- .../graphics/drawable/AnimatedImageDrawable.java | 2 +- .../graphics/drawable/AnimatedRotateDrawable.java | 14 +++++++------- .../graphics/drawable/AnimatedStateListDrawable.java | 2 +- .../graphics/drawable/AnimatedVectorDrawable.java | 2 +- .../android/graphics/drawable/AnimationDrawable.java | 18 +++++++++--------- .../android/graphics/drawable/BitmapDrawable.java | 2 +- .../java/android/graphics/drawable/ClipDrawable.java | 20 +++++++++++--------- 41 files changed, 67 insertions(+), 63 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java index 6e7f286d19a7..bee8d5efc933 100644 --- a/graphics/java/android/graphics/BaseCanvas.java +++ b/graphics/java/android/graphics/BaseCanvas.java @@ -21,7 +21,7 @@ import android.annotation.ColorLong; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Canvas.VertexMode; import android.graphics.text.MeasuredText; import android.text.GraphicsOperations; diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index d900a42b1e66..ac094ba5d5d2 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -21,8 +21,8 @@ import android.annotation.ColorInt; import android.annotation.ColorLong; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.annotation.WorkerThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.ResourcesImpl; import android.hardware.HardwareBuffer; import android.os.Build; diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index 5623a8a49b35..bad487b47682 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -20,7 +20,7 @@ import static android.graphics.BitmapFactory.Options.validate; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.content.res.Resources; import android.os.Trace; diff --git a/graphics/java/android/graphics/BitmapRegionDecoder.java b/graphics/java/android/graphics/BitmapRegionDecoder.java index 629d8c131b68..34eba97819aa 100644 --- a/graphics/java/android/graphics/BitmapRegionDecoder.java +++ b/graphics/java/android/graphics/BitmapRegionDecoder.java @@ -15,7 +15,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.os.Build; diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java index 198d1e7bc956..edf53c491311 100644 --- a/graphics/java/android/graphics/BitmapShader.java +++ b/graphics/java/android/graphics/BitmapShader.java @@ -17,7 +17,7 @@ package android.graphics; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Shader used to draw a bitmap as a texture. The bitmap can be repeated or diff --git a/graphics/java/android/graphics/Camera.java b/graphics/java/android/graphics/Camera.java index cbd4eadca30a..80a3740d2f4e 100644 --- a/graphics/java/android/graphics/Camera.java +++ b/graphics/java/android/graphics/Camera.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * A camera instance can be used to compute 3D transformations and diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index a815f20293c5..9a0ca3e4ad9b 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -22,7 +22,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.text.MeasuredText; import android.os.Build; diff --git a/graphics/java/android/graphics/CanvasProperty.java b/graphics/java/android/graphics/CanvasProperty.java index 1275e0827580..4263772c1c2c 100644 --- a/graphics/java/android/graphics/CanvasProperty.java +++ b/graphics/java/android/graphics/CanvasProperty.java @@ -16,7 +16,8 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import com.android.internal.util.VirtualRefBasePtr; /** diff --git a/graphics/java/android/graphics/ColorMatrixColorFilter.java b/graphics/java/android/graphics/ColorMatrixColorFilter.java index 0f7980cc32e4..a8b18a9fcb1f 100644 --- a/graphics/java/android/graphics/ColorMatrixColorFilter.java +++ b/graphics/java/android/graphics/ColorMatrixColorFilter.java @@ -18,7 +18,7 @@ package android.graphics; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * A color filter that transforms colors through a 4x5 color matrix. This filter diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java index 5ad93f411393..ae90995573dc 100644 --- a/graphics/java/android/graphics/FontFamily.java +++ b/graphics/java/android/graphics/FontFamily.java @@ -17,7 +17,7 @@ package android.graphics; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.graphics.fonts.FontVariationAxis; import android.text.TextUtils; diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java index 21cc3757a40e..c146bbd4441b 100644 --- a/graphics/java/android/graphics/FontListParser.java +++ b/graphics/java/android/graphics/FontListParser.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.fonts.FontVariationAxis; import android.text.FontConfig; import android.util.Xml; diff --git a/graphics/java/android/graphics/GraphicBuffer.java b/graphics/java/android/graphics/GraphicBuffer.java index 3b1fc70397ea..99fa5eef7bbd 100644 --- a/graphics/java/android/graphics/GraphicBuffer.java +++ b/graphics/java/android/graphics/GraphicBuffer.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java index aecef8ee3413..97a2e0f42694 100644 --- a/graphics/java/android/graphics/ImageDecoder.java +++ b/graphics/java/android/graphics/ImageDecoder.java @@ -28,8 +28,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Px; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.WorkerThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.res.AssetFileDescriptor; import android.content.res.AssetManager; diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java index 62a890ff4f0b..221dfa192795 100644 --- a/graphics/java/android/graphics/LightingColorFilter.java +++ b/graphics/java/android/graphics/LightingColorFilter.java @@ -22,7 +22,7 @@ package android.graphics; import android.annotation.ColorInt; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * A color filter that can be used to simulate simple lighting effects. diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java index 12e63c09d76b..3f3ad967fe97 100644 --- a/graphics/java/android/graphics/LinearGradient.java +++ b/graphics/java/android/graphics/LinearGradient.java @@ -20,7 +20,7 @@ import android.annotation.ColorInt; import android.annotation.ColorLong; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; public class LinearGradient extends Shader { diff --git a/graphics/java/android/graphics/Matrix.java b/graphics/java/android/graphics/Matrix.java index 22b6401fdc2e..cf914c2c3eae 100644 --- a/graphics/java/android/graphics/Matrix.java +++ b/graphics/java/android/graphics/Matrix.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import dalvik.annotation.optimization.CriticalNative; import dalvik.annotation.optimization.FastNative; diff --git a/graphics/java/android/graphics/Movie.java b/graphics/java/android/graphics/Movie.java index 6f030ffac2df..4b3924f0d55f 100644 --- a/graphics/java/android/graphics/Movie.java +++ b/graphics/java/android/graphics/Movie.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.os.Build; diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java index c4c1eaceb4fc..ff3239348240 100644 --- a/graphics/java/android/graphics/NinePatch.java +++ b/graphics/java/android/graphics/NinePatch.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * The NinePatch class permits drawing a bitmap in nine or more sections. diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java index 1fc056c3652f..91a60c327bf0 100644 --- a/graphics/java/android/graphics/Outline.java +++ b/graphics/java/android/graphics/Outline.java @@ -19,7 +19,7 @@ package android.graphics; import android.annotation.FloatRange; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.drawable.Drawable; import java.lang.annotation.Retention; diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index 109d8631284d..3b586242e5b1 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -24,7 +24,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Px; import android.annotation.Size; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.fonts.FontVariationAxis; import android.os.Build; import android.os.LocaleList; diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java index 7282d52d6e23..1362fd864d29 100644 --- a/graphics/java/android/graphics/Path.java +++ b/graphics/java/android/graphics/Path.java @@ -20,7 +20,7 @@ import android.annotation.FloatRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import dalvik.annotation.optimization.CriticalNative; import dalvik.annotation.optimization.FastNative; diff --git a/graphics/java/android/graphics/Picture.java b/graphics/java/android/graphics/Picture.java index 8d12cbffc793..390d3d414346 100644 --- a/graphics/java/android/graphics/Picture.java +++ b/graphics/java/android/graphics/Picture.java @@ -17,7 +17,7 @@ package android.graphics; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.io.InputStream; import java.io.OutputStream; diff --git a/graphics/java/android/graphics/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java index bc1f66fdd5c0..1275cb9ca4f9 100644 --- a/graphics/java/android/graphics/PorterDuff.java +++ b/graphics/java/android/graphics/PorterDuff.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** *

This class contains the list of alpha compositing and blending modes diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java index cc2d3a8969fc..50ecb62e7fcc 100644 --- a/graphics/java/android/graphics/PorterDuffColorFilter.java +++ b/graphics/java/android/graphics/PorterDuffColorFilter.java @@ -18,7 +18,7 @@ package android.graphics; import android.annotation.ColorInt; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * A color filter that can be used to tint the source pixels using a single diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java index acbe3da75247..96b7b9a78ba8 100644 --- a/graphics/java/android/graphics/RadialGradient.java +++ b/graphics/java/android/graphics/RadialGradient.java @@ -20,7 +20,7 @@ import android.annotation.ColorInt; import android.annotation.ColorLong; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; public class RadialGradient extends Shader { @UnsupportedAppUsage diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java index 9e1946c557d2..081b851d1333 100644 --- a/graphics/java/android/graphics/Rect.java +++ b/graphics/java/android/graphics/Rect.java @@ -19,7 +19,7 @@ package android.graphics; import android.annotation.CheckResult; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; diff --git a/graphics/java/android/graphics/Region.java b/graphics/java/android/graphics/Region.java index ec7f7a05b685..d8d96413a93d 100644 --- a/graphics/java/android/graphics/Region.java +++ b/graphics/java/android/graphics/Region.java @@ -17,7 +17,7 @@ package android.graphics; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.Pools.SynchronizedPool; diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java index 3050d1dae5e4..5335aa4725ad 100644 --- a/graphics/java/android/graphics/Shader.java +++ b/graphics/java/android/graphics/Shader.java @@ -20,7 +20,7 @@ import android.annotation.ColorInt; import android.annotation.ColorLong; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import libcore.util.NativeAllocationRegistry; diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index 99f440d599cb..697daa8b7b70 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -17,7 +17,7 @@ package android.graphics; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.Looper; import android.os.Message; diff --git a/graphics/java/android/graphics/SweepGradient.java b/graphics/java/android/graphics/SweepGradient.java index 667f45afe500..08520048b787 100644 --- a/graphics/java/android/graphics/SweepGradient.java +++ b/graphics/java/android/graphics/SweepGradient.java @@ -20,7 +20,7 @@ import android.annotation.ColorInt; import android.annotation.ColorLong; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; public class SweepGradient extends Shader { @UnsupportedAppUsage diff --git a/graphics/java/android/graphics/TableMaskFilter.java b/graphics/java/android/graphics/TableMaskFilter.java index d81c491e07e0..204f9705852a 100644 --- a/graphics/java/android/graphics/TableMaskFilter.java +++ b/graphics/java/android/graphics/TableMaskFilter.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * @hide diff --git a/graphics/java/android/graphics/TemporaryBuffer.java b/graphics/java/android/graphics/TemporaryBuffer.java index 0ae2c703c21c..ef3f7f704e0d 100644 --- a/graphics/java/android/graphics/TemporaryBuffer.java +++ b/graphics/java/android/graphics/TemporaryBuffer.java @@ -16,7 +16,8 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import com.android.internal.util.ArrayUtils; /** diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 6d20ec32cdc4..a2dd9a8322b6 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -25,7 +25,7 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.graphics.fonts.Font; import android.graphics.fonts.FontFamily; diff --git a/graphics/java/android/graphics/Xfermode.java b/graphics/java/android/graphics/Xfermode.java index 6f4adfde7ff9..e79fb76d806e 100644 --- a/graphics/java/android/graphics/Xfermode.java +++ b/graphics/java/android/graphics/Xfermode.java @@ -21,7 +21,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Xfermode is the base class for objects that are called to implement custom diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java index 82f587086428..d8946009483c 100644 --- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java @@ -19,7 +19,7 @@ package android.graphics.drawable; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetFileDescriptor; import android.content.res.Resources; import android.content.res.Resources.Theme; diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java index b29fd4db5803..686f146e9c18 100644 --- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java @@ -18,23 +18,23 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; -import android.graphics.Canvas; -import android.graphics.Rect; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; -import android.content.res.TypedArray; import android.content.res.Resources.Theme; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.os.SystemClock; import android.util.AttributeSet; import android.util.TypedValue; -import android.os.SystemClock; + +import com.android.internal.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; -import com.android.internal.R; - /** * @hide */ diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java index 11a46c4ba9b9..06159d8a0558 100644 --- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java @@ -20,7 +20,7 @@ import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index 66947da9166f..1acf6c512fbd 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -25,9 +25,9 @@ import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.app.Application; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java index 57764c2cb693..8c3fa441cbb0 100644 --- a/graphics/java/android/graphics/drawable/AnimationDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java @@ -16,21 +16,21 @@ package android.graphics.drawable; -import com.android.internal.R; - -import java.io.IOException; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; -import android.content.res.TypedArray; import android.content.res.Resources.Theme; +import android.content.res.TypedArray; import android.os.SystemClock; import android.util.AttributeSet; +import com.android.internal.R; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; + /** * An object used to create frame-by-frame animations, defined by a series of * Drawable objects, which can be used as a View object's background. diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index e4aa774fd434..4e768c9eddfb 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -17,7 +17,7 @@ package android.graphics.drawable; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java index 31fdb025bbc5..69ed9b423d48 100644 --- a/graphics/java/android/graphics/drawable/ClipDrawable.java +++ b/graphics/java/android/graphics/drawable/ClipDrawable.java @@ -16,20 +16,22 @@ package android.graphics.drawable; -import com.android.internal.R; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; -import android.content.res.TypedArray; import android.content.res.Resources.Theme; -import android.graphics.*; -import android.view.Gravity; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.PixelFormat; +import android.graphics.Rect; import android.util.AttributeSet; +import android.view.Gravity; + +import com.android.internal.R; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; -- cgit v1.2.3 From 9f9301ccc243803bd4f9d5fc7d1dd75767eeab5d Mon Sep 17 00:00:00 2001 From: Haoyu Zhang Date: Tue, 14 Jan 2020 12:15:05 -0800 Subject: Restrict UnsupportedAppUsage after Q Bug: 145986883 Test: atest FontFamilyTest Test: adb shell am instrument -w -r -e class 'androidx.core.graphics.TypefaceCompatTest' androidx.core.test/androidx.test.runner.AndroidJUnitRunner Change-Id: I1cf0444b93df00532536531903e889ade9612597 --- graphics/java/android/graphics/FontFamily.java | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java index ae90995573dc..447f043392c2 100644 --- a/graphics/java/android/graphics/FontFamily.java +++ b/graphics/java/android/graphics/FontFamily.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.graphics.fonts.FontVariationAxis; +import android.os.Build; import android.text.TextUtils; import dalvik.annotation.optimization.CriticalNative; @@ -58,7 +59,8 @@ public class FontFamily { * * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, + publicAlternatives = "Use {@link android.graphics.fonts.FontFamily} instead.") public long mNativePtr; // Points native font family builder. Must be zero after freezing this family. @@ -67,7 +69,8 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, + publicAlternatives = "Use {@link android.graphics.fonts.FontFamily} instead.") public FontFamily() { mBuilderPtr = nInitBuilder(null, 0); mNativeBuilderCleaner = sBuilderRegistry.registerNativeAllocation(this, mBuilderPtr); @@ -76,7 +79,8 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, + publicAlternatives = "Use {@link android.graphics.fonts.FontFamily} instead.") public FontFamily(@Nullable String[] langs, int variant) { final String langsString; if (langs == null || langs.length == 0) { @@ -98,7 +102,8 @@ public class FontFamily { * * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, + publicAlternatives = "Use {@link android.graphics.fonts.FontFamily} instead.") public boolean freeze() { if (mBuilderPtr == 0) { throw new IllegalStateException("This FontFamily is already frozen"); @@ -115,7 +120,8 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, + publicAlternatives = "Use {@link android.graphics.fonts.FontFamily} instead.") public void abortCreation() { if (mBuilderPtr == 0) { throw new IllegalStateException("This FontFamily is already frozen or abandoned"); @@ -127,7 +133,8 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, + publicAlternatives = "Use {@link android.graphics.fonts.FontFamily} instead.") public boolean addFont(String path, int ttcIndex, FontVariationAxis[] axes, int weight, int italic) { if (mBuilderPtr == 0) { @@ -151,7 +158,8 @@ public class FontFamily { /** * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, + publicAlternatives = "Use {@link android.graphics.fonts.FontFamily} instead.") public boolean addFontFromBuffer(ByteBuffer font, int ttcIndex, FontVariationAxis[] axes, int weight, int italic) { if (mBuilderPtr == 0) { @@ -179,7 +187,8 @@ public class FontFamily { * * This cannot be deleted because it's in use by AndroidX. */ - @UnsupportedAppUsage(trackingBug = 123768928) + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, + publicAlternatives = "Use {@link android.graphics.fonts.FontFamily} instead.") public boolean addFontFromAssetManager(AssetManager mgr, String path, int cookie, boolean isAsset, int ttcIndex, int weight, int isItalic, FontVariationAxis[] axes) { -- cgit v1.2.3 From 77a2416924c1a58945bd29c272efa336ee1274f7 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 17 Jan 2020 10:05:50 -0800 Subject: Adding API to check if an icon returned by PackageManager is a fallback icon Bug: 141588119 Test: atest PackageManagerTest Change-Id: I9ae5a74dd0b0c0c49a078d46914986ecb0d27a94 --- .../android/graphics/drawable/AdaptiveIconDrawable.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'graphics') diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java index fab96a1e9fbd..928e607abbbe 100644 --- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java +++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java @@ -16,6 +16,7 @@ package android.graphics.drawable; +import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; @@ -223,6 +224,7 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback final int deviceDensity = Drawable.resolveDensity(r, 0); state.setDensity(deviceDensity); state.mSrcDensityOverride = mSrcDensityOverride; + state.mSourceDrawableId = Resources.getAttributeSetSourceResId(attrs); final ChildDrawable[] array = state.mChildren; for (int i = 0; i < state.mChildren.length; i++) { @@ -445,6 +447,17 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback } } + /** + * If the drawable was inflated from XML, this returns the resource ID for the drawable + * + * @hide + */ + @DrawableRes + public int getSourceDrawableResId() { + final LayerState state = mLayerState; + return state == null ? Resources.ID_NULL : state.mSourceDrawableId; + } + /** * Inflates child layers using the specified parser. */ @@ -944,6 +957,8 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback @Config int mChangingConfigurations; @Config int mChildrenChangingConfigurations; + @DrawableRes int mSourceDrawableId = Resources.ID_NULL; + private boolean mCheckedOpacity; private int mOpacity; -- cgit v1.2.3 From 6a0cdd24df52283d5e22157f3ddc8a35671ea2d4 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Thu, 23 Jan 2020 12:41:08 -0500 Subject: Deprecate Path#isConvex Bug: 133807397 Test: No change in behavior, no new tests isConvex is unreliable. We may change how we compute it from release to release, and it could change based on various factors like a rotation. Change-Id: Ib76246fc24f09bd13cf63b4b96b56afa613d0bc9 --- graphics/java/android/graphics/Path.java | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'graphics') diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java index 1362fd864d29..84fe39290681 100644 --- a/graphics/java/android/graphics/Path.java +++ b/graphics/java/android/graphics/Path.java @@ -209,7 +209,13 @@ public class Path { * points, and cache the result. * * @return True if the path is convex. + * + * @deprecated This method is not reliable. The way convexity is computed may change from + * release to release, and convexity could change based on a matrix as well. This method was + * useful when non-convex Paths were unable to be used in certain contexts, but that is no + * longer the case. */ + @Deprecated public boolean isConvex() { return nIsConvex(mNativePath); } -- cgit v1.2.3 From 2410b90e066b75b14798b2c60c77e00865654496 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Thu, 23 Jan 2020 12:55:53 -0500 Subject: Deprecate Canvas.EdgeType Bug: 129694386 Test: No change in behavior, no new tests EdgeType is only used as a parameter to quickReject, but it is always ignored. Deprecate it and the existing quickReject methods. Add new versions of quickReject without EdgeType parameters. Switch clients to the new versions. Change-Id: Id932f10915a8c4959fe0e85f507ce7fd2da8a576 --- graphics/java/android/graphics/Canvas.java | 60 ++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'graphics') diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index 9a0ca3e4ad9b..d949444d44d6 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -1162,6 +1162,7 @@ public class Canvas extends BaseCanvas { * @see #quickReject(float, float, float, float, EdgeType) * @see #quickReject(Path, EdgeType) * @see #quickReject(RectF, EdgeType) + * @deprecated quickReject no longer uses this. */ public enum EdgeType { @@ -1197,12 +1198,29 @@ public class Canvas extends BaseCanvas { * non-antialiased ({@link Canvas.EdgeType#BW}). * @return true if the rect (transformed by the canvas' matrix) * does not intersect with the canvas' clip + * @deprecated The EdgeType is ignored. Use {@link #quickReject(RectF)} instead. */ + @Deprecated public boolean quickReject(@NonNull RectF rect, @NonNull EdgeType type) { return nQuickReject(mNativeCanvasWrapper, rect.left, rect.top, rect.right, rect.bottom); } + /** + * Return true if the specified rectangle, after being transformed by the + * current matrix, would lie completely outside of the current clip. Call + * this to check if an area you intend to draw into is clipped out (and + * therefore you can skip making the draw calls). + * + * @param rect the rect to compare with the current clip + * @return true if the rect (transformed by the canvas' matrix) + * does not intersect with the canvas' clip + */ + public boolean quickReject(@NonNull RectF rect) { + return nQuickReject(mNativeCanvasWrapper, + rect.left, rect.top, rect.right, rect.bottom); + } + /** * Return true if the specified path, after being transformed by the * current matrix, would lie completely outside of the current clip. Call @@ -1217,11 +1235,29 @@ public class Canvas extends BaseCanvas { * non-antialiased ({@link Canvas.EdgeType#BW}). * @return true if the path (transformed by the canvas' matrix) * does not intersect with the canvas' clip + * @deprecated The EdgeType is ignored. Use {@link #quickReject(Path)} instead. */ + @Deprecated public boolean quickReject(@NonNull Path path, @NonNull EdgeType type) { return nQuickReject(mNativeCanvasWrapper, path.readOnlyNI()); } + /** + * Return true if the specified path, after being transformed by the + * current matrix, would lie completely outside of the current clip. Call + * this to check if an area you intend to draw into is clipped out (and + * therefore you can skip making the draw calls). Note: for speed it may + * return false even if the path itself might not intersect the clip + * (i.e. the bounds of the path intersects, but the path does not). + * + * @param path The path to compare with the current clip + * @return true if the path (transformed by the canvas' matrix) + * does not intersect with the canvas' clip + */ + public boolean quickReject(@NonNull Path path) { + return nQuickReject(mNativeCanvasWrapper, path.readOnlyNI()); + } + /** * Return true if the specified rectangle, after being transformed by the * current matrix, would lie completely outside of the current clip. Call @@ -1241,12 +1277,36 @@ public class Canvas extends BaseCanvas { * non-antialiased ({@link Canvas.EdgeType#BW}). * @return true if the rect (transformed by the canvas' matrix) * does not intersect with the canvas' clip + * @deprecated The EdgeType is ignored. Use {@link #quickReject(float, float, float, float)} + * instead. */ + @Deprecated public boolean quickReject(float left, float top, float right, float bottom, @NonNull EdgeType type) { return nQuickReject(mNativeCanvasWrapper, left, top, right, bottom); } + /** + * Return true if the specified rectangle, after being transformed by the + * current matrix, would lie completely outside of the current clip. Call + * this to check if an area you intend to draw into is clipped out (and + * therefore you can skip making the draw calls). + * + * @param left The left side of the rectangle to compare with the + * current clip + * @param top The top of the rectangle to compare with the current + * clip + * @param right The right side of the rectangle to compare with the + * current clip + * @param bottom The bottom of the rectangle to compare with the + * current clip + * @return true if the rect (transformed by the canvas' matrix) + * does not intersect with the canvas' clip + */ + public boolean quickReject(float left, float top, float right, float bottom) { + return nQuickReject(mNativeCanvasWrapper, left, top, right, bottom); + } + /** * Return the bounds of the current clip (in local coordinates) in the * bounds parameter, and return true if it is non-empty. This can be useful -- cgit v1.2.3 From efac0521d620823cbb885d165c84363984c66b97 Mon Sep 17 00:00:00 2001 From: John Reck Date: Fri, 24 Jan 2020 16:04:26 -0800 Subject: Improve bitmap IPC Make all received bitmaps immutable as this improves re-use for subsequent transfers. Remove minimum size to stay on ashmem, as Parcel's writeBlob already has similar logic. This effectively reduces the minimum size to 16kB. Bug: 148301859 Test: device booted, a notification showed up Change-Id: I2fafb0989944c0ef82de6edcb4924056a592cf66 --- graphics/java/android/graphics/Bitmap.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index ac094ba5d5d2..9c2e95fab455 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -2132,7 +2132,7 @@ public final class Bitmap implements Parcelable { public void writeToParcel(Parcel p, int flags) { checkRecycled("Can't parcel a recycled bitmap"); noteHardwareBitmapSlowCall(); - if (!nativeWriteToParcel(mNativePtr, isMutable(), mDensity, p)) { + if (!nativeWriteToParcel(mNativePtr, mDensity, p)) { throw new RuntimeException("native writeToParcel failed"); } } @@ -2285,7 +2285,6 @@ public final class Bitmap implements Parcelable { private static native Bitmap nativeCreateFromParcel(Parcel p); // returns true on success private static native boolean nativeWriteToParcel(long nativeBitmap, - boolean isMutable, int density, Parcel p); // returns a new bitmap built from the native bitmap's alpha, and the paint -- cgit v1.2.3 From a49beaaa693d0900a65c8ebf2a1f44242e469f59 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Thu, 30 Jan 2020 15:34:13 -0500 Subject: Replace Outline#setConvexPath with Outline#setPath Bug: 148544953 Test: No change in behavior, no new tests setConvexPath no longer requires that the Path be Convex, so deprecate the method and replace it with a name that does not imply it must be Convex. Update internal references to the Path being Convex as well. Change-Id: I8935dc8ac7f7fb7db0d667e35fda67afdf2e6ac8 --- graphics/java/android/graphics/Outline.java | 38 ++++++++++++++-------- graphics/java/android/graphics/RenderNode.java | 6 ++-- .../graphics/drawable/AdaptiveIconDrawable.java | 2 +- .../graphics/drawable/GradientDrawable.java | 2 +- .../graphics/drawable/shapes/RoundRectShape.java | 2 +- 5 files changed, 31 insertions(+), 19 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java index 91a60c327bf0..c12159cfd7a4 100644 --- a/graphics/java/android/graphics/Outline.java +++ b/graphics/java/android/graphics/Outline.java @@ -43,7 +43,7 @@ public final class Outline { /** @hide */ public static final int MODE_ROUND_RECT = 1; /** @hide */ - public static final int MODE_CONVEX_PATH = 2; + public static final int MODE_PATH = 2; /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -51,7 +51,7 @@ public final class Outline { value = { MODE_EMPTY, MODE_ROUND_RECT, - MODE_CONVEX_PATH, + MODE_PATH, }) public @interface Mode {} @@ -60,7 +60,7 @@ public final class Outline { public int mMode = MODE_EMPTY; /** - * Only guaranteed to be non-null when mode == MODE_CONVEX_PATH + * Only guaranteed to be non-null when mode == MODE_PATH * * @hide */ @@ -124,7 +124,7 @@ public final class Outline { * @see android.view.View#setClipToOutline(boolean) */ public boolean canClip() { - return mMode != MODE_CONVEX_PATH; + return mMode != MODE_PATH; } /** @@ -157,7 +157,7 @@ public final class Outline { */ public void set(@NonNull Outline src) { mMode = src.mMode; - if (src.mMode == MODE_CONVEX_PATH) { + if (src.mMode == MODE_PATH) { if (mPath == null) { mPath = new Path(); } @@ -194,7 +194,7 @@ public final class Outline { return; } - if (mMode == MODE_CONVEX_PATH) { + if (mMode == MODE_PATH) { // rewind here to avoid thrashing the allocations, but could alternately clear ref mPath.rewind(); } @@ -213,7 +213,7 @@ public final class Outline { /** * Populates {@code outBounds} with the outline bounds, if set, and returns * {@code true}. If no outline bounds are set, or if a path has been set - * via {@link #setConvexPath(Path)}, returns {@code false}. + * via {@link #setPath(Path)}, returns {@code false}. * * @param outRect the rect to populate with the outline bounds, if set * @return {@code true} if {@code outBounds} was populated with outline @@ -229,7 +229,7 @@ public final class Outline { /** * Returns the rounded rect radius, if set, or a value less than 0 if a path has - * been set via {@link #setConvexPath(Path)}. A return value of {@code 0} + * been set via {@link #setPath(Path)}. A return value of {@code 0} * indicates a non-rounded rect. * * @return the rounded rect radius, or value < 0 @@ -259,7 +259,7 @@ public final class Outline { mPath.rewind(); } - mMode = MODE_CONVEX_PATH; + mMode = MODE_PATH; mPath.addOval(left, top, right, bottom, Path.Direction.CW); mRect.setEmpty(); mRadius = RADIUS_UNDEFINED; @@ -279,9 +279,21 @@ public final class Outline { * @param convexPath used to construct the Outline. As of * {@link android.os.Build.VERSION_CODES#Q}, it is no longer required to be * convex. + * + * @deprecated The path is no longer required to be convex. Use {@link #setPath} instead. */ + @Deprecated public void setConvexPath(@NonNull Path convexPath) { - if (convexPath.isEmpty()) { + setPath(convexPath); + } + + /** + * Sets the Outline to a {@link android.graphics.Path path}. + * + * @param path used to construct the Outline. + */ + public void setPath(@NonNull Path path) { + if (path.isEmpty()) { setEmpty(); return; } @@ -290,8 +302,8 @@ public final class Outline { mPath = new Path(); } - mMode = MODE_CONVEX_PATH; - mPath.set(convexPath); + mMode = MODE_PATH; + mPath.set(path); mRect.setEmpty(); mRadius = RADIUS_UNDEFINED; } @@ -302,7 +314,7 @@ public final class Outline { public void offset(int dx, int dy) { if (mMode == MODE_ROUND_RECT) { mRect.offset(dx, dy); - } else if (mMode == MODE_CONVEX_PATH) { + } else if (mMode == MODE_PATH) { mPath.offset(dx, dy); } } diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java index 17e3b4465130..3835b2d493c5 100644 --- a/graphics/java/android/graphics/RenderNode.java +++ b/graphics/java/android/graphics/RenderNode.java @@ -687,8 +687,8 @@ public final class RenderNode { outline.mRect.left, outline.mRect.top, outline.mRect.right, outline.mRect.bottom, outline.mRadius, outline.mAlpha); - case Outline.MODE_CONVEX_PATH: - return nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath, + case Outline.MODE_PATH: + return nSetOutlinePath(mNativeRenderNode, outline.mPath.mNativePath, outline.mAlpha); } @@ -1620,7 +1620,7 @@ public final class RenderNode { int right, int bottom, float radius, float alpha); @CriticalNative - private static native boolean nSetOutlineConvexPath(long renderNode, long nativePath, + private static native boolean nSetOutlinePath(long renderNode, long nativePath, float alpha); @CriticalNative diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java index 928e607abbbe..746378e10bc7 100644 --- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java +++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java @@ -387,7 +387,7 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback @Override public void getOutline(@NonNull Outline outline) { - outline.setConvexPath(mMask); + outline.setPath(mMask); } /** @hide */ diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 3881955d2632..f053f392b97e 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -1915,7 +1915,7 @@ public class GradientDrawable extends Drawable { case RECTANGLE: if (st.mRadiusArray != null) { buildPathIfDirty(); - outline.setConvexPath(mPath); + outline.setPath(mPath); return; } diff --git a/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java b/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java index 475e0bb70f2b..28ba60577fb1 100644 --- a/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java +++ b/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java @@ -94,7 +94,7 @@ public class RoundRectShape extends RectShape { for (int i = 1; i < 8; i++) { if (mOuterRadii[i] != radius) { // can't call simple constructors, use path - outline.setConvexPath(mPath); + outline.setPath(mPath); return; } } -- cgit v1.2.3 From 1863d94e9a32a210cfb50d7c22bbac30dc33e010 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Wed, 5 Feb 2020 15:41:51 -0500 Subject: Ensure SkiaPipeline always has a valid colorspace. Previously we didn't assign a colorspace to the pipeline until it was provided a surface to render into. This resulted in undefined behavior if the application attempted to render an offscreen layer before the OS provided the main window with its surface. Now instead of deferring setting whether or not the application is wide gamut we do initialize it to a default setting when the pipeline is created. Bug: 148042673 Test: apct/device_boot_health_check_extra_postsubmit Change-Id: I84d743511e949ac977486470bb14eec936de7f88 --- graphics/java/android/graphics/HardwareRenderer.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java index 3b864139cf71..d08bfcf45a5c 100644 --- a/graphics/java/android/graphics/HardwareRenderer.java +++ b/graphics/java/android/graphics/HardwareRenderer.java @@ -157,7 +157,7 @@ public class HardwareRenderer { public HardwareRenderer() { mRootNode = RenderNode.adopt(nCreateRootRenderNode()); mRootNode.setClipToBounds(false); - mNativeProxy = nCreateProxy(!mOpaque, mRootNode.mNativeRenderNode); + mNativeProxy = nCreateProxy(!mOpaque, mIsWideGamut, mRootNode.mNativeRenderNode); if (mNativeProxy == 0) { throw new OutOfMemoryError("Unable to create hardware renderer"); } @@ -1085,7 +1085,8 @@ public class HardwareRenderer { private static native long nCreateRootRenderNode(); - private static native long nCreateProxy(boolean translucent, long rootRenderNode); + private static native long nCreateProxy(boolean translucent, boolean isWideGamut, + long rootRenderNode); private static native void nDeleteProxy(long nativeProxy); -- cgit v1.2.3 From c90438175fcd83c8890c426c28a3ded006faee35 Mon Sep 17 00:00:00 2001 From: Stan Iliev Date: Mon, 3 Feb 2020 16:57:09 -0500 Subject: Refactor GraphicsStatsService for updateability Move GraphicsStatsService to android.graphics package. Move GraphicsStatsService JNI from libservices.core to libandroid_runtime. Declare GraphicsStatsService ctor as the only @SystemApi. Remove MemoryFile usage from GraphicsStatsService, but use SharedMemory and other SDK APIs instead. This is done to avoid using unstable API MemoryFile.getFileDescriptor. Propose new SharedMemory.getFdDup API for next release, which is hidden for now. Refactor statsd puller to avoid proto serialization by moving data directly into AStatsEventList. "libprotoutil" is added as a static dependancy to libhwui, which should be fine because its implementation does not link anything. Bug: 146353313 Test: Ran "adb shell cmd stats pull-source 10068" Test: Passed unit tests and GraphicsStatsValidationTest CTS Change-Id: If16c5addbd519cba33e03bd84ac312595032e0e1 --- .../android/graphics/GraphicsStatsService.java | 566 +++++++++++++++++++++ 1 file changed, 566 insertions(+) create mode 100644 graphics/java/android/graphics/GraphicsStatsService.java (limited to 'graphics') diff --git a/graphics/java/android/graphics/GraphicsStatsService.java b/graphics/java/android/graphics/GraphicsStatsService.java new file mode 100644 index 000000000000..8dfd6ee92a9a --- /dev/null +++ b/graphics/java/android/graphics/GraphicsStatsService.java @@ -0,0 +1,566 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics; + +import android.annotation.SystemApi; +import android.app.AlarmManager; +import android.app.AppOpsManager; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Binder; +import android.os.Environment; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.IBinder; +import android.os.Message; +import android.os.ParcelFileDescriptor; +import android.os.Process; +import android.os.RemoteException; +import android.os.SharedMemory; +import android.os.Trace; +import android.os.UserHandle; +import android.system.ErrnoException; +import android.util.Log; +import android.view.IGraphicsStats; +import android.view.IGraphicsStatsCallback; + +import com.android.internal.util.DumpUtils; +import com.android.internal.util.FastPrintWriter; + +import java.io.File; +import java.io.FileDescriptor; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.HashSet; +import java.util.TimeZone; + +/** + * This service's job is to collect aggregate rendering profile data. It + * does this by allowing rendering processes to request an ashmem buffer + * to place their stats into. + * + * Buffers are rotated on a daily (in UTC) basis and only the 3 most-recent days + * are kept. + * + * The primary consumer of this is incident reports and automated metric checking. It is not + * intended for end-developer consumption, for that we have gfxinfo. + * + * Buffer rotation process: + * 1) Alarm fires + * 2) onRotateGraphicsStatsBuffer() is sent to all active processes + * 3) Upon receiving the callback, the process will stop using the previous ashmem buffer and + * request a new one. + * 4) When that request is received we now know that the ashmem region is no longer in use so + * it gets queued up for saving to disk and a new ashmem region is created and returned + * for the process to use. + * + * @hide */ +public class GraphicsStatsService extends IGraphicsStats.Stub { + public static final String GRAPHICS_STATS_SERVICE = "graphicsstats"; + + private static final String TAG = "GraphicsStatsService"; + + private static final int SAVE_BUFFER = 1; + private static final int DELETE_OLD = 2; + + private static final int AID_STATSD = 1066; // Statsd uid is set to 1066 forever. + + // This isn't static because we need this to happen after registerNativeMethods, however + // the class is loaded (and thus static ctor happens) before that occurs. + private final int mAshmemSize = nGetAshmemSize(); + private final byte[] mZeroData = new byte[mAshmemSize]; + + private final Context mContext; + private final AppOpsManager mAppOps; + private final AlarmManager mAlarmManager; + private final Object mLock = new Object(); + private ArrayList mActive = new ArrayList<>(); + private File mGraphicsStatsDir; + private final Object mFileAccessLock = new Object(); + private Handler mWriteOutHandler; + private boolean mRotateIsScheduled = false; + + @SystemApi + public GraphicsStatsService(Context context) { + mContext = context; + mAppOps = context.getSystemService(AppOpsManager.class); + mAlarmManager = context.getSystemService(AlarmManager.class); + File systemDataDir = new File(Environment.getDataDirectory(), "system"); + mGraphicsStatsDir = new File(systemDataDir, "graphicsstats"); + mGraphicsStatsDir.mkdirs(); + if (!mGraphicsStatsDir.exists()) { + throw new IllegalStateException("Graphics stats directory does not exist: " + + mGraphicsStatsDir.getAbsolutePath()); + } + HandlerThread bgthread = new HandlerThread("GraphicsStats-disk", + Process.THREAD_PRIORITY_BACKGROUND); + bgthread.start(); + + mWriteOutHandler = new Handler(bgthread.getLooper(), new Handler.Callback() { + @Override + public boolean handleMessage(Message msg) { + switch (msg.what) { + case SAVE_BUFFER: + saveBuffer((HistoricalBuffer) msg.obj); + break; + case DELETE_OLD: + deleteOldBuffers(); + break; + } + return true; + } + }); + nativeInit(); + } + + /** + * Current rotation policy is to rotate at midnight UTC. We don't specify RTC_WAKEUP because + * rotation can be delayed if there's otherwise no activity. However exact is used because + * we don't want the system to delay it by TOO much. + */ + private void scheduleRotateLocked() { + if (mRotateIsScheduled) { + return; + } + mRotateIsScheduled = true; + Calendar calendar = normalizeDate(System.currentTimeMillis()); + calendar.add(Calendar.DATE, 1); + mAlarmManager.setExact(AlarmManager.RTC, calendar.getTimeInMillis(), TAG, this::onAlarm, + mWriteOutHandler); + } + + private void onAlarm() { + // We need to make a copy since some of the callbacks won't be proxy and thus + // can result in a re-entrant acquisition of mLock that would result in a modification + // of mActive during iteration. + ActiveBuffer[] activeCopy; + synchronized (mLock) { + mRotateIsScheduled = false; + scheduleRotateLocked(); + activeCopy = mActive.toArray(new ActiveBuffer[0]); + } + for (ActiveBuffer active : activeCopy) { + try { + active.mCallback.onRotateGraphicsStatsBuffer(); + } catch (RemoteException e) { + Log.w(TAG, String.format("Failed to notify '%s' (pid=%d) to rotate buffers", + active.mInfo.mPackageName, active.mPid), e); + } + } + // Give a few seconds for everyone to rotate before doing the cleanup + mWriteOutHandler.sendEmptyMessageDelayed(DELETE_OLD, 10000); + } + + @Override + public ParcelFileDescriptor requestBufferForProcess(String packageName, + IGraphicsStatsCallback token) throws RemoteException { + int uid = Binder.getCallingUid(); + int pid = Binder.getCallingPid(); + ParcelFileDescriptor pfd = null; + long callingIdentity = Binder.clearCallingIdentity(); + try { + mAppOps.checkPackage(uid, packageName); + PackageInfo info = mContext.getPackageManager().getPackageInfoAsUser( + packageName, + 0, + UserHandle.getUserId(uid)); + synchronized (mLock) { + pfd = requestBufferForProcessLocked(token, uid, pid, packageName, + info.getLongVersionCode()); + } + } catch (PackageManager.NameNotFoundException ex) { + throw new RemoteException("Unable to find package: '" + packageName + "'"); + } finally { + Binder.restoreCallingIdentity(callingIdentity); + } + return pfd; + } + + // If lastFullDay is true, pullGraphicsStats returns stats for the last complete day/24h period + // that does not include today. If lastFullDay is false, pullGraphicsStats returns stats for the + // current day. + // This method is invoked from native code only. + @SuppressWarnings({"UnusedDeclaration"}) + private void pullGraphicsStats(boolean lastFullDay, long pulledData) throws RemoteException { + int uid = Binder.getCallingUid(); + + // DUMP and PACKAGE_USAGE_STATS permissions are required to invoke this method. + // TODO: remove exception for statsd daemon after required permissions are granted. statsd + // TODO: should have these permissions granted by data/etc/platform.xml, but it does not. + if (uid != AID_STATSD) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new FastPrintWriter(sw); + if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) { + pw.flush(); + throw new RemoteException(sw.toString()); + } + } + + long callingIdentity = Binder.clearCallingIdentity(); + try { + pullGraphicsStatsImpl(lastFullDay, pulledData); + } finally { + Binder.restoreCallingIdentity(callingIdentity); + } + } + + private void pullGraphicsStatsImpl(boolean lastFullDay, long pulledData) { + long targetDay; + if (lastFullDay) { + // Get stats from yesterday. Stats stay constant, because the day is over. + targetDay = normalizeDate(System.currentTimeMillis() - 86400000).getTimeInMillis(); + } else { + // Get stats from today. Stats may change as more apps are run today. + targetDay = normalizeDate(System.currentTimeMillis()).getTimeInMillis(); + } + + // Find active buffers for targetDay. + ArrayList buffers; + synchronized (mLock) { + buffers = new ArrayList<>(mActive.size()); + for (int i = 0; i < mActive.size(); i++) { + ActiveBuffer buffer = mActive.get(i); + if (buffer.mInfo.mStartTime == targetDay) { + try { + buffers.add(new HistoricalBuffer(buffer)); + } catch (IOException ex) { + // Ignore + } + } + } + } + + // Dump active and historic buffers for targetDay in a serialized + // GraphicsStatsServiceDumpProto proto. + long dump = nCreateDump(-1, true); + try { + synchronized (mFileAccessLock) { + HashSet skipList = dumpActiveLocked(dump, buffers); + buffers.clear(); + String subPath = String.format("%d", targetDay); + File dateDir = new File(mGraphicsStatsDir, subPath); + if (dateDir.exists()) { + for (File pkg : dateDir.listFiles()) { + for (File version : pkg.listFiles()) { + File data = new File(version, "total"); + if (skipList.contains(data)) { + continue; + } + nAddToDump(dump, data.getAbsolutePath()); + } + } + } + } + } finally { + nFinishDumpInMemory(dump, pulledData, lastFullDay); + } + } + + private ParcelFileDescriptor requestBufferForProcessLocked(IGraphicsStatsCallback token, + int uid, int pid, String packageName, long versionCode) throws RemoteException { + ActiveBuffer buffer = fetchActiveBuffersLocked(token, uid, pid, packageName, versionCode); + scheduleRotateLocked(); + return buffer.getPfd(); + } + + private Calendar normalizeDate(long timestamp) { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + calendar.setTimeInMillis(timestamp); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + return calendar; + } + + private File pathForApp(BufferInfo info) { + String subPath = String.format("%d/%s/%d/total", + normalizeDate(info.mStartTime).getTimeInMillis(), info.mPackageName, + info.mVersionCode); + return new File(mGraphicsStatsDir, subPath); + } + + private void saveBuffer(HistoricalBuffer buffer) { + if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) { + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, + "saving graphicsstats for " + buffer.mInfo.mPackageName); + } + synchronized (mFileAccessLock) { + File path = pathForApp(buffer.mInfo); + File parent = path.getParentFile(); + parent.mkdirs(); + if (!parent.exists()) { + Log.w(TAG, "Unable to create path: '" + parent.getAbsolutePath() + "'"); + return; + } + nSaveBuffer(path.getAbsolutePath(), buffer.mInfo.mPackageName, + buffer.mInfo.mVersionCode, buffer.mInfo.mStartTime, buffer.mInfo.mEndTime, + buffer.mData); + } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + } + + private void deleteRecursiveLocked(File file) { + if (file.isDirectory()) { + for (File child : file.listFiles()) { + deleteRecursiveLocked(child); + } + } + if (!file.delete()) { + Log.w(TAG, "Failed to delete '" + file.getAbsolutePath() + "'!"); + } + } + + private void deleteOldBuffers() { + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "deleting old graphicsstats buffers"); + synchronized (mFileAccessLock) { + File[] files = mGraphicsStatsDir.listFiles(); + if (files == null || files.length <= 3) { + return; + } + long[] sortedDates = new long[files.length]; + for (int i = 0; i < files.length; i++) { + try { + sortedDates[i] = Long.parseLong(files[i].getName()); + } catch (NumberFormatException ex) { + // Skip unrecognized folders + } + } + if (sortedDates.length <= 3) { + return; + } + Arrays.sort(sortedDates); + for (int i = 0; i < sortedDates.length - 3; i++) { + deleteRecursiveLocked(new File(mGraphicsStatsDir, Long.toString(sortedDates[i]))); + } + } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + } + + private void addToSaveQueue(ActiveBuffer buffer) { + try { + HistoricalBuffer data = new HistoricalBuffer(buffer); + Message.obtain(mWriteOutHandler, SAVE_BUFFER, data).sendToTarget(); + } catch (IOException e) { + Log.w(TAG, "Failed to copy graphicsstats from " + buffer.mInfo.mPackageName, e); + } + buffer.closeAllBuffers(); + } + + private void processDied(ActiveBuffer buffer) { + synchronized (mLock) { + mActive.remove(buffer); + } + addToSaveQueue(buffer); + } + + private ActiveBuffer fetchActiveBuffersLocked(IGraphicsStatsCallback token, int uid, int pid, + String packageName, long versionCode) throws RemoteException { + int size = mActive.size(); + long today = normalizeDate(System.currentTimeMillis()).getTimeInMillis(); + for (int i = 0; i < size; i++) { + ActiveBuffer buffer = mActive.get(i); + if (buffer.mPid == pid + && buffer.mUid == uid) { + // If the buffer is too old we remove it and return a new one + if (buffer.mInfo.mStartTime < today) { + buffer.binderDied(); + break; + } else { + return buffer; + } + } + } + // Didn't find one, need to create it + try { + ActiveBuffer buffers = new ActiveBuffer(token, uid, pid, packageName, versionCode); + mActive.add(buffers); + return buffers; + } catch (IOException ex) { + throw new RemoteException("Failed to allocate space"); + } + } + + private HashSet dumpActiveLocked(long dump, ArrayList buffers) { + HashSet skipFiles = new HashSet<>(buffers.size()); + for (int i = 0; i < buffers.size(); i++) { + HistoricalBuffer buffer = buffers.get(i); + File path = pathForApp(buffer.mInfo); + skipFiles.add(path); + nAddToDump(dump, path.getAbsolutePath(), buffer.mInfo.mPackageName, + buffer.mInfo.mVersionCode, buffer.mInfo.mStartTime, buffer.mInfo.mEndTime, + buffer.mData); + } + return skipFiles; + } + + private void dumpHistoricalLocked(long dump, HashSet skipFiles) { + for (File date : mGraphicsStatsDir.listFiles()) { + for (File pkg : date.listFiles()) { + for (File version : pkg.listFiles()) { + File data = new File(version, "total"); + if (skipFiles.contains(data)) { + continue; + } + nAddToDump(dump, data.getAbsolutePath()); + } + } + } + } + + @Override + protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { + if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, fout)) return; + boolean dumpProto = false; + for (String str : args) { + if ("--proto".equals(str)) { + dumpProto = true; + break; + } + } + ArrayList buffers; + synchronized (mLock) { + buffers = new ArrayList<>(mActive.size()); + for (int i = 0; i < mActive.size(); i++) { + try { + buffers.add(new HistoricalBuffer(mActive.get(i))); + } catch (IOException ex) { + // Ignore + } + } + } + long dump = nCreateDump(fd.getInt$(), dumpProto); + try { + synchronized (mFileAccessLock) { + HashSet skipList = dumpActiveLocked(dump, buffers); + buffers.clear(); + dumpHistoricalLocked(dump, skipList); + } + } finally { + nFinishDump(dump); + } + } + + @Override + protected void finalize() throws Throwable { + nativeDestructor(); + } + + private native void nativeInit(); + private static native void nativeDestructor(); + + private static native int nGetAshmemSize(); + private static native long nCreateDump(int outFd, boolean isProto); + private static native void nAddToDump(long dump, String path, String packageName, + long versionCode, long startTime, long endTime, byte[] data); + private static native void nAddToDump(long dump, String path); + private static native void nFinishDump(long dump); + private static native void nFinishDumpInMemory(long dump, long pulledData, boolean lastFullDay); + private static native void nSaveBuffer(String path, String packageName, long versionCode, + long startTime, long endTime, byte[] data); + + private final class BufferInfo { + final String mPackageName; + final long mVersionCode; + long mStartTime; + long mEndTime; + + BufferInfo(String packageName, long versionCode, long startTime) { + this.mPackageName = packageName; + this.mVersionCode = versionCode; + this.mStartTime = startTime; + } + } + + private final class ActiveBuffer implements DeathRecipient { + final BufferInfo mInfo; + final int mUid; + final int mPid; + final IGraphicsStatsCallback mCallback; + final IBinder mToken; + SharedMemory mProcessBuffer; + ByteBuffer mMapping; + + ActiveBuffer(IGraphicsStatsCallback token, int uid, int pid, String packageName, + long versionCode) + throws RemoteException, IOException { + mInfo = new BufferInfo(packageName, versionCode, System.currentTimeMillis()); + mUid = uid; + mPid = pid; + mCallback = token; + mToken = mCallback.asBinder(); + mToken.linkToDeath(this, 0); + try { + mProcessBuffer = SharedMemory.create("GFXStats-" + pid, mAshmemSize); + mMapping = mProcessBuffer.mapReadWrite(); + } catch (ErrnoException ex) { + ex.rethrowAsIOException(); + } + mMapping.position(0); + mMapping.put(mZeroData, 0, mAshmemSize); + } + + @Override + public void binderDied() { + mToken.unlinkToDeath(this, 0); + processDied(this); + } + + void closeAllBuffers() { + if (mMapping != null) { + SharedMemory.unmap(mMapping); + mMapping = null; + } + if (mProcessBuffer != null) { + mProcessBuffer.close(); + mProcessBuffer = null; + } + } + + ParcelFileDescriptor getPfd() { + try { + return mProcessBuffer.getFdDup(); + } catch (IOException ex) { + throw new IllegalStateException("Failed to get PFD from memory file", ex); + } + } + + void readBytes(byte[] buffer, int count) throws IOException { + if (mMapping == null) { + throw new IOException("SharedMemory has been deactivated"); + } + mMapping.position(0); + mMapping.get(buffer, 0, count); + } + } + + private final class HistoricalBuffer { + final BufferInfo mInfo; + final byte[] mData = new byte[mAshmemSize]; + HistoricalBuffer(ActiveBuffer active) throws IOException { + mInfo = active.mInfo; + mInfo.mEndTime = System.currentTimeMillis(); + active.readBytes(mData, mAshmemSize); + } + } +} -- cgit v1.2.3 From 4db7bd28e76897a97a848adfd1051904492bf400 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Mon, 6 Jan 2020 11:24:34 -0500 Subject: Consolidate AssetManager calls in Font/FontFamily The Font/FontFamily classes use private API calls in native code to get the contents of an Asset. These calls need to be made on public APIs in order to isolate the graphics module from the rest of the system. Public Java APIs already exist so this CL refactors the code to use those methods. Test: CtsTextTestCases Bug: 147136234 Change-Id: I35a6558b597684e59279d7a841669c5f909d5152 --- graphics/java/android/graphics/FontFamily.java | 20 ++--- graphics/java/android/graphics/fonts/Font.java | 104 ++++++++++++++++--------- 2 files changed, 75 insertions(+), 49 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java index 447f043392c2..f50de1665453 100644 --- a/graphics/java/android/graphics/FontFamily.java +++ b/graphics/java/android/graphics/FontFamily.java @@ -19,6 +19,7 @@ package android.graphics; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; +import android.graphics.fonts.Font; import android.graphics.fonts.FontVariationAxis; import android.os.Build; import android.text.TextUtils; @@ -195,18 +196,13 @@ public class FontFamily { if (mBuilderPtr == 0) { throw new IllegalStateException("Unable to call addFontFromAsset after freezing."); } - if (axes != null) { - for (FontVariationAxis axis : axes) { - nAddAxisValue(mBuilderPtr, axis.getOpenTypeTagValue(), axis.getStyleValue()); - } - } - return nAddFontFromAssetManager(mBuilderPtr, mgr, path, cookie, isAsset, ttcIndex, weight, - isItalic); - } - // TODO: Remove once internal user stop using private API. - private static boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex) { - return nAddFont(builderPtr, font, ttcIndex, -1, -1); + try { + ByteBuffer buffer = Font.Builder.createBuffer(mgr, path, isAsset, cookie); + return addFontFromBuffer(buffer, ttcIndex, axes, weight, isItalic); + } catch (IOException e) { + return false; + } } private static native long nInitBuilder(String langs, int variant); @@ -225,8 +221,6 @@ public class FontFamily { int weight, int isItalic); private static native boolean nAddFontWeightStyle(long builderPtr, ByteBuffer font, int ttcIndex, int weight, int isItalic); - private static native boolean nAddFontFromAssetManager(long builderPtr, AssetManager mgr, - String path, int cookie, boolean isAsset, int ttcIndex, int weight, int isItalic); // The added axis values are only valid for the next nAddFont* method call. @CriticalNative diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java index ba96a06cc852..4899fbe431cc 100644 --- a/graphics/java/android/graphics/fonts/Font.java +++ b/graphics/java/android/graphics/fonts/Font.java @@ -19,6 +19,7 @@ package android.graphics.fonts; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.res.AssetFileDescriptor; import android.content.res.AssetManager; import android.content.res.Resources; import android.os.LocaleList; @@ -35,7 +36,9 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.nio.channels.FileChannel; import java.util.Arrays; import java.util.Objects; @@ -54,10 +57,6 @@ public final class Font { * A builder class for creating new Font. */ public static final class Builder { - private static final NativeAllocationRegistry sAssetByteBufferRegistry = - NativeAllocationRegistry.createMalloced(ByteBuffer.class.getClassLoader(), - nGetReleaseNativeAssetFunc()); - private static final NativeAllocationRegistry sFontRegistry = NativeAllocationRegistry.createMalloced(Font.class.getClassLoader(), nGetReleaseNativeFont()); @@ -151,7 +150,11 @@ public final class Font { * @param path the file name of the font data in the asset directory */ public Builder(@NonNull AssetManager am, @NonNull String path) { - this(am, path, true /* is asset */, 0 /* cookie */); + try { + mBuffer = createBuffer(am, path, true /* is asset */, 0 /* cookie */); + } catch (IOException e) { + mException = e; + } } /** @@ -165,18 +168,11 @@ public final class Font { */ public Builder(@NonNull AssetManager am, @NonNull String path, boolean isAsset, int cookie) { - final long nativeAsset = nGetNativeAsset(am, path, isAsset, cookie); - if (nativeAsset == 0) { - mException = new FileNotFoundException("Unable to open " + path); - return; - } - final ByteBuffer b = nGetAssetBuffer(nativeAsset); - sAssetByteBufferRegistry.registerNativeAllocation(b, nativeAsset); - if (b == null) { - mException = new FileNotFoundException(path + " not found"); - return; + try { + mBuffer = createBuffer(am, path, isAsset, cookie); + } catch (IOException e) { + mException = e; } - mBuffer = b; } /** @@ -199,19 +195,64 @@ public final class Font { mException = new FileNotFoundException(resId + " must be font file."); return; } - final long nativeAsset = nGetNativeAsset(res.getAssets(), str, false /* is asset */, - value.assetCookie); - if (nativeAsset == 0) { - mException = new FileNotFoundException("Unable to open " + str); - return; + + try { + mBuffer = createBuffer(res.getAssets(), str, false, value.assetCookie); + } catch (IOException e) { + mException = e; } - final ByteBuffer b = nGetAssetBuffer(nativeAsset); - sAssetByteBufferRegistry.registerNativeAllocation(b, nativeAsset); - if (b == null) { - mException = new FileNotFoundException(str + " not found"); - return; + } + + /** + * Creates a buffer containing font data using the assetManager and other + * provided inputs. + * + * @param am the application's asset manager + * @param path the file name of the font data in the asset directory + * @param isAsset true if the undelying data is in asset + * @param cookie set asset cookie + * @return buffer containing the contents of the file + * + * @hide + */ + public static ByteBuffer createBuffer(@NonNull AssetManager am, @NonNull String path, + boolean isAsset, int cookie) throws IOException { + Preconditions.checkNotNull(am, "assetManager can not be null"); + Preconditions.checkNotNull(path, "path can not be null"); + + if (!isAsset) { + // Attempt to open as FD, which should work unless the asset is compressed + AssetFileDescriptor assetFD; + try { + if (cookie > 0) { + assetFD = am.openNonAssetFd(cookie, path); + } else { + assetFD = am.openNonAssetFd(path); + } + + try (FileInputStream fis = assetFD.createInputStream()) { + final FileChannel fc = fis.getChannel(); + return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); + } + } catch (IOException e) { + // failed to open as FD so now we will attempt to open as an input stream + } + } + + try (InputStream assetStream = isAsset ? am.open(path, AssetManager.ACCESS_BUFFER) + : am.openNonAsset(cookie, path, AssetManager.ACCESS_BUFFER)) { + + int capacity = assetStream.available(); + ByteBuffer buffer = ByteBuffer.allocateDirect(capacity); + buffer.order(ByteOrder.nativeOrder()); + assetStream.read(buffer.array(), buffer.arrayOffset(), assetStream.available()); + + if (assetStream.read() != -1) { + throw new IOException("Unable to access full contents of " + path); + } + + return buffer; } - mBuffer = b; } /** @@ -395,15 +436,6 @@ public final class Font { return font; } - /** - * Native methods for accessing underlying buffer in Asset - */ - private static native long nGetNativeAsset( - @NonNull AssetManager am, @NonNull String path, boolean isAsset, int cookie); - private static native ByteBuffer nGetAssetBuffer(long nativeAsset); - @CriticalNative - private static native long nGetReleaseNativeAssetFunc(); - /** * Native methods for creating Font */ -- cgit v1.2.3 From aa5f38577a9c446c35a1ac5ccfa41b7c68b02bf5 Mon Sep 17 00:00:00 2001 From: John Reck Date: Fri, 7 Feb 2020 16:19:58 -0800 Subject: Create a ParcelableColorSpace Bug: 148412652 Test: ParcelableColorSpaceTest CTS Change-Id: If0901367e501e2ecfc71b9ed29ec7d8dd4d0550f --- graphics/java/android/graphics/ColorSpace.java | 3 +- .../android/graphics/ParcelableColorSpace.java | 183 +++++++++++++++++++++ 2 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 graphics/java/android/graphics/ParcelableColorSpace.java (limited to 'graphics') diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java index 06d4fbdd85b1..ce8ff7dc38ba 100644 --- a/graphics/java/android/graphics/ColorSpace.java +++ b/graphics/java/android/graphics/ColorSpace.java @@ -867,7 +867,8 @@ public abstract class ColorSpace { } } - private ColorSpace( + /** @hide */ + ColorSpace( @NonNull String name, @NonNull Model model, @IntRange(from = MIN_ID, to = MAX_ID) int id) { diff --git a/graphics/java/android/graphics/ParcelableColorSpace.java b/graphics/java/android/graphics/ParcelableColorSpace.java new file mode 100644 index 000000000000..f9033a53d7e6 --- /dev/null +++ b/graphics/java/android/graphics/ParcelableColorSpace.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * A {@link Parcelable} {@link ColorSpace}. In order to enable parceling, the ColorSpace + * must be either a {@link ColorSpace.Named Named} ColorSpace or a {@link ColorSpace.Rgb} instance + * that has an ICC parametric transfer function as returned by {@link Rgb#getTransferParameters()}. + * TODO: Make public + * @hide + */ +public final class ParcelableColorSpace extends ColorSpace implements Parcelable { + private final ColorSpace mColorSpace; + + /** + * Checks if the given ColorSpace is able to be parceled. A ColorSpace can only be + * parceled if it is a {@link ColorSpace.Named Named} ColorSpace or a {@link ColorSpace.Rgb} + * instance that has an ICC parametric transfer function as returned by + * {@link Rgb#getTransferParameters()} + */ + public static boolean isParcelable(@NonNull ColorSpace colorSpace) { + if (colorSpace.getId() == ColorSpace.MIN_ID) { + if (!(colorSpace instanceof ColorSpace.Rgb)) { + return false; + } + ColorSpace.Rgb rgb = (ColorSpace.Rgb) colorSpace; + if (rgb.getTransferParameters() == null) { + return false; + } + } + return true; + } + + /** + * Constructs a new ParcelableColorSpace that wraps the provided ColorSpace. + * + * @param colorSpace The ColorSpace to wrap. The ColorSpace must be either named or be an + * RGB ColorSpace with an ICC parametric transfer function. + * @throws IllegalArgumentException If the provided ColorSpace does not satisfy the requirements + * to be parceled. See {@link #isParcelable(ColorSpace)}. + */ + public ParcelableColorSpace(@NonNull ColorSpace colorSpace) { + super(colorSpace.getName(), colorSpace.getModel(), colorSpace.getId()); + mColorSpace = colorSpace; + + if (mColorSpace.getId() == ColorSpace.MIN_ID) { + if (!(mColorSpace instanceof ColorSpace.Rgb)) { + throw new IllegalArgumentException( + "Unable to parcel unknown ColorSpaces that are not ColorSpace.Rgb"); + } + ColorSpace.Rgb rgb = (ColorSpace.Rgb) mColorSpace; + if (rgb.getTransferParameters() == null) { + throw new IllegalArgumentException("ColorSpace must use an ICC " + + "parametric transfer function to be parcelable"); + } + } + } + + public @NonNull ColorSpace getColorSpace() { + return mColorSpace; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + final int id = mColorSpace.getId(); + dest.writeInt(id); + if (id == ColorSpace.MIN_ID) { + // Not a named color space. We have to actually write, like, stuff. And things. Ugh. + // Cast is safe because this was asserted in the constructor + ColorSpace.Rgb rgb = (ColorSpace.Rgb) mColorSpace; + dest.writeString(rgb.getName()); + dest.writeFloatArray(rgb.getPrimaries()); + dest.writeFloatArray(rgb.getWhitePoint()); + ColorSpace.Rgb.TransferParameters transferParameters = rgb.getTransferParameters(); + dest.writeDouble(transferParameters.a); + dest.writeDouble(transferParameters.b); + dest.writeDouble(transferParameters.c); + dest.writeDouble(transferParameters.d); + dest.writeDouble(transferParameters.e); + dest.writeDouble(transferParameters.f); + dest.writeDouble(transferParameters.g); + } + } + + @NonNull + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + + public @NonNull ParcelableColorSpace createFromParcel(@NonNull Parcel in) { + final int id = in.readInt(); + if (id == ColorSpace.MIN_ID) { + String name = in.readString(); + float[] primaries = in.createFloatArray(); + float[] whitePoint = in.createFloatArray(); + double a = in.readDouble(); + double b = in.readDouble(); + double c = in.readDouble(); + double d = in.readDouble(); + double e = in.readDouble(); + double f = in.readDouble(); + double g = in.readDouble(); + ColorSpace.Rgb.TransferParameters function = + new ColorSpace.Rgb.TransferParameters(a, b, c, d, e, f, g); + return new ParcelableColorSpace( + new ColorSpace.Rgb(name, primaries, whitePoint, function)); + } else { + return new ParcelableColorSpace(ColorSpace.get(id)); + } + } + + public ParcelableColorSpace[] newArray(int size) { + return new ParcelableColorSpace[size]; + } + }; + + @Override + public boolean isWideGamut() { + return mColorSpace.isWideGamut(); + } + + @Override + public float getMinValue(int component) { + return mColorSpace.getMinValue(component); + } + + @Override + public float getMaxValue(int component) { + return mColorSpace.getMaxValue(component); + } + + @Override + public @NonNull float[] toXyz(@NonNull float[] v) { + return mColorSpace.toXyz(v); + } + + @Override + public @NonNull float[] fromXyz(@NonNull float[] v) { + return mColorSpace.fromXyz(v); + } + + @Override + public boolean equals(@Nullable Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ParcelableColorSpace other = (ParcelableColorSpace) o; + return mColorSpace.equals(other.mColorSpace); + } + + @Override + public int hashCode() { + return mColorSpace.hashCode(); + } + + /** @hide */ + @Override + long getNativeInstance() { + return mColorSpace.getNativeInstance(); + } +} -- cgit v1.2.3 From 8c2f6b6e159512d2438a0b9504a7656157fab4c5 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Tue, 11 Feb 2020 15:53:05 -0500 Subject: Move RenderNodeAnimator to android.graphics.animation package A wrapper still exists at android.view.RenderNode animator as it needs access to internals of the view that would violate the package layering if moved into android.graphics.animation. This CL also moves the Java and cpp files associated with creating a native interpolator that can be run directly on the RenderThread. Bug: 149293249 Test: CtsViewTestCases Change-Id: I5260331fedbd634cf2f6d6d392941e7284527420 --- graphics/java/android/graphics/RenderNode.java | 2 +- .../animation/FallbackLUTInterpolator.java | 80 ++++ .../graphics/animation/HasNativeInterpolator.java | 37 ++ .../graphics/animation/NativeInterpolator.java | 29 ++ .../animation/NativeInterpolatorFactory.java | 67 +++ .../graphics/animation/RenderNodeAnimator.java | 513 +++++++++++++++++++++ .../graphics/drawable/AnimatedVectorDrawable.java | 6 +- .../graphics/drawable/RippleForeground.java | 2 +- 8 files changed, 731 insertions(+), 5 deletions(-) create mode 100644 graphics/java/android/graphics/animation/FallbackLUTInterpolator.java create mode 100644 graphics/java/android/graphics/animation/HasNativeInterpolator.java create mode 100644 graphics/java/android/graphics/animation/NativeInterpolator.java create mode 100644 graphics/java/android/graphics/animation/NativeInterpolatorFactory.java create mode 100644 graphics/java/android/graphics/animation/RenderNodeAnimator.java (limited to 'graphics') diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java index 3835b2d493c5..752695fd8e52 100644 --- a/graphics/java/android/graphics/RenderNode.java +++ b/graphics/java/android/graphics/RenderNode.java @@ -22,8 +22,8 @@ import android.annotation.FloatRange; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.graphics.animation.RenderNodeAnimator; import android.view.NativeVectorDrawableAnimator; -import android.view.RenderNodeAnimator; import android.view.Surface; import android.view.View; diff --git a/graphics/java/android/graphics/animation/FallbackLUTInterpolator.java b/graphics/java/android/graphics/animation/FallbackLUTInterpolator.java new file mode 100644 index 000000000000..36062c141ed2 --- /dev/null +++ b/graphics/java/android/graphics/animation/FallbackLUTInterpolator.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics.animation; + +import android.animation.TimeInterpolator; +import android.util.TimeUtils; +import android.view.Choreographer; + +/** + * Interpolator that builds a lookup table to use. This is a fallback for + * building a native interpolator from a TimeInterpolator that is not marked + * with {@link HasNativeInterpolator} + * + * This implements TimeInterpolator to allow for easier interop with Animators + * @hide + */ +@HasNativeInterpolator +public class FallbackLUTInterpolator implements NativeInterpolator, TimeInterpolator { + + // If the duration of an animation is more than 300 frames, we cap the sample size to 300. + private static final int MAX_SAMPLE_POINTS = 300; + private TimeInterpolator mSourceInterpolator; + private final float[] mLut; + + /** + * Used to cache the float[] LUT for use across multiple native + * interpolator creation + */ + public FallbackLUTInterpolator(TimeInterpolator interpolator, long duration) { + mSourceInterpolator = interpolator; + mLut = createLUT(interpolator, duration); + } + + private static float[] createLUT(TimeInterpolator interpolator, long duration) { + long frameIntervalNanos = Choreographer.getInstance().getFrameIntervalNanos(); + int animIntervalMs = (int) (frameIntervalNanos / TimeUtils.NANOS_PER_MS); + // We need 2 frame values as the minimal. + int numAnimFrames = Math.max(2, (int) Math.ceil(((double) duration) / animIntervalMs)); + numAnimFrames = Math.min(numAnimFrames, MAX_SAMPLE_POINTS); + float[] values = new float[numAnimFrames]; + float lastFrame = numAnimFrames - 1; + for (int i = 0; i < numAnimFrames; i++) { + float inValue = i / lastFrame; + values[i] = interpolator.getInterpolation(inValue); + } + return values; + } + + @Override + public long createNativeInterpolator() { + return NativeInterpolatorFactory.createLutInterpolator(mLut); + } + + /** + * Used to create a one-shot float[] LUT & native interpolator + */ + public static long createNativeInterpolator(TimeInterpolator interpolator, long duration) { + float[] lut = createLUT(interpolator, duration); + return NativeInterpolatorFactory.createLutInterpolator(lut); + } + + @Override + public float getInterpolation(float input) { + return mSourceInterpolator.getInterpolation(input); + } +} diff --git a/graphics/java/android/graphics/animation/HasNativeInterpolator.java b/graphics/java/android/graphics/animation/HasNativeInterpolator.java new file mode 100644 index 000000000000..c53d5a42524d --- /dev/null +++ b/graphics/java/android/graphics/animation/HasNativeInterpolator.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics.animation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This is a class annotation that signals that it is safe to create + * a native interpolator counterpart via {@link NativeInterpolator} + * + * The idea here is to prevent subclasses of interpolators from being treated as a + * NativeInterpolator, and instead have them fall back to the LUT & LERP + * method like a custom interpolator. + * + * @hide + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface HasNativeInterpolator { +} diff --git a/graphics/java/android/graphics/animation/NativeInterpolator.java b/graphics/java/android/graphics/animation/NativeInterpolator.java new file mode 100644 index 000000000000..1e6fea8da466 --- /dev/null +++ b/graphics/java/android/graphics/animation/NativeInterpolator.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics.animation; + +/** + * @hide + */ +public interface NativeInterpolator { + /** + * Generates a native interpolator object that can be used by HardwareRenderer to draw + * RenderNodes. + * @return ptr to native object + */ + long createNativeInterpolator(); +} diff --git a/graphics/java/android/graphics/animation/NativeInterpolatorFactory.java b/graphics/java/android/graphics/animation/NativeInterpolatorFactory.java new file mode 100644 index 000000000000..38866145ee50 --- /dev/null +++ b/graphics/java/android/graphics/animation/NativeInterpolatorFactory.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics.animation; + +import android.animation.TimeInterpolator; + +/** + * Static utility class for constructing native interpolators to keep the + * JNI simpler + * + * @hide + */ +public final class NativeInterpolatorFactory { + private NativeInterpolatorFactory() {} + + /** + * Create a native interpolator from the provided param generating a LUT variant if a native + * implementation does not exist. + */ + public static long createNativeInterpolator(TimeInterpolator interpolator, long + duration) { + if (interpolator == null) { + return createLinearInterpolator(); + } else if (RenderNodeAnimator.isNativeInterpolator(interpolator)) { + return ((NativeInterpolator) interpolator).createNativeInterpolator(); + } else { + return FallbackLUTInterpolator.createNativeInterpolator(interpolator, duration); + } + } + + /** Creates a specialized native interpolator for Accelerate/Decelerate */ + public static native long createAccelerateDecelerateInterpolator(); + /** Creates a specialized native interpolator for Accelerate */ + public static native long createAccelerateInterpolator(float factor); + /** Creates a specialized native interpolator for Anticipate */ + public static native long createAnticipateInterpolator(float tension); + /** Creates a specialized native interpolator for Anticipate with Overshoot */ + public static native long createAnticipateOvershootInterpolator(float tension); + /** Creates a specialized native interpolator for Bounce */ + public static native long createBounceInterpolator(); + /** Creates a specialized native interpolator for Cycle */ + public static native long createCycleInterpolator(float cycles); + /** Creates a specialized native interpolator for Decelerate */ + public static native long createDecelerateInterpolator(float factor); + /** Creates a specialized native interpolator for Linear interpolation */ + public static native long createLinearInterpolator(); + /** Creates a specialized native interpolator for Overshoot */ + public static native long createOvershootInterpolator(float tension); + /** Creates a specialized native interpolator for along traveling along a Path */ + public static native long createPathInterpolator(float[] x, float[] y); + /** Creates a specialized native interpolator for LUT */ + public static native long createLutInterpolator(float[] values); +} diff --git a/graphics/java/android/graphics/animation/RenderNodeAnimator.java b/graphics/java/android/graphics/animation/RenderNodeAnimator.java new file mode 100644 index 000000000000..282b2f959fc4 --- /dev/null +++ b/graphics/java/android/graphics/animation/RenderNodeAnimator.java @@ -0,0 +1,513 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics.animation; + +import android.animation.Animator; +import android.animation.TimeInterpolator; +import android.animation.ValueAnimator; +import android.graphics.CanvasProperty; +import android.graphics.Paint; +import android.graphics.RecordingCanvas; +import android.graphics.RenderNode; +import android.os.Handler; +import android.os.Looper; +import android.view.Choreographer; + +import com.android.internal.util.VirtualRefBasePtr; + +import java.util.ArrayList; + +/** + * @hide + */ +public class RenderNodeAnimator extends Animator { + // Keep in sync with enum RenderProperty in Animator.h + public static final int TRANSLATION_X = 0; + public static final int TRANSLATION_Y = 1; + public static final int TRANSLATION_Z = 2; + public static final int SCALE_X = 3; + public static final int SCALE_Y = 4; + public static final int ROTATION = 5; + public static final int ROTATION_X = 6; + public static final int ROTATION_Y = 7; + public static final int X = 8; + public static final int Y = 9; + public static final int Z = 10; + public static final int ALPHA = 11; + // The last value in the enum, used for array size initialization + public static final int LAST_VALUE = ALPHA; + + // Keep in sync with enum PaintFields in Animator.h + public static final int PAINT_STROKE_WIDTH = 0; + + /** + * Field for the Paint alpha channel, which should be specified as a value + * between 0 and 255. + */ + public static final int PAINT_ALPHA = 1; + + private VirtualRefBasePtr mNativePtr; + + private Handler mHandler; + private RenderNode mTarget; + private ViewListener mViewListener; + private int mRenderProperty = -1; + private float mFinalValue; + private TimeInterpolator mInterpolator; + + private static final int STATE_PREPARE = 0; + private static final int STATE_DELAYED = 1; + private static final int STATE_RUNNING = 2; + private static final int STATE_FINISHED = 3; + private int mState = STATE_PREPARE; + + private long mUnscaledDuration = 300; + private long mUnscaledStartDelay = 0; + // If this is true, we will run any start delays on the UI thread. This is + // the safe default, and is necessary to ensure start listeners fire at + // the correct time. Animators created by RippleDrawable (the + // CanvasProperty<> ones) do not have this expectation, and as such will + // set this to false so that the renderthread handles the startdelay instead + private final boolean mUiThreadHandlesDelay; + private long mStartDelay = 0; + private long mStartTime; + + /** + * Interface used by the view system to update the view hierarchy in conjunction + * with this animator. + */ + public interface ViewListener { + /** notify the listener that an alpha animation has begun. */ + void onAlphaAnimationStart(float finalAlpha); + /** notify the listener that the animator has mutated a value that requires invalidation */ + void invalidateParent(boolean forceRedraw); + } + + public RenderNodeAnimator(int property, float finalValue) { + mRenderProperty = property; + mFinalValue = finalValue; + mUiThreadHandlesDelay = true; + init(nCreateAnimator(property, finalValue)); + } + + public RenderNodeAnimator(CanvasProperty property, float finalValue) { + init(nCreateCanvasPropertyFloatAnimator( + property.getNativeContainer(), finalValue)); + mUiThreadHandlesDelay = false; + } + + /** + * Creates a new render node animator for a field on a Paint property. + * + * @param property The paint property to target + * @param paintField Paint field to animate, one of {@link #PAINT_ALPHA} or + * {@link #PAINT_STROKE_WIDTH} + * @param finalValue The target value for the property + */ + public RenderNodeAnimator(CanvasProperty property, int paintField, float finalValue) { + init(nCreateCanvasPropertyPaintAnimator( + property.getNativeContainer(), paintField, finalValue)); + mUiThreadHandlesDelay = false; + } + + public RenderNodeAnimator(int x, int y, float startRadius, float endRadius) { + init(nCreateRevealAnimator(x, y, startRadius, endRadius)); + mUiThreadHandlesDelay = true; + } + + private void init(long ptr) { + mNativePtr = new VirtualRefBasePtr(ptr); + } + + private void checkMutable() { + if (mState != STATE_PREPARE) { + throw new IllegalStateException("Animator has already started, cannot change it now!"); + } + if (mNativePtr == null) { + throw new IllegalStateException("Animator's target has been destroyed " + + "(trying to modify an animation after activity destroy?)"); + } + } + + static boolean isNativeInterpolator(TimeInterpolator interpolator) { + return interpolator.getClass().isAnnotationPresent(HasNativeInterpolator.class); + } + + private void applyInterpolator() { + if (mInterpolator == null || mNativePtr == null) return; + + long ni; + if (isNativeInterpolator(mInterpolator)) { + ni = ((NativeInterpolator) mInterpolator).createNativeInterpolator(); + } else { + long duration = nGetDuration(mNativePtr.get()); + ni = FallbackLUTInterpolator.createNativeInterpolator(mInterpolator, duration); + } + nSetInterpolator(mNativePtr.get(), ni); + } + + @Override + public void start() { + if (mTarget == null) { + throw new IllegalStateException("Missing target!"); + } + + if (mState != STATE_PREPARE) { + throw new IllegalStateException("Already started!"); + } + + mState = STATE_DELAYED; + if (mHandler == null) { + mHandler = new Handler(true); + } + applyInterpolator(); + + if (mNativePtr == null) { + // It's dead, immediately cancel + cancel(); + } else if (mStartDelay <= 0 || !mUiThreadHandlesDelay) { + nSetStartDelay(mNativePtr.get(), mStartDelay); + doStart(); + } else { + getHelper().addDelayedAnimation(this); + } + } + + private void doStart() { + // Alpha is a special snowflake that has the canonical value stored + // in mTransformationInfo instead of in RenderNode, so we need to update + // it with the final value here. + if (mRenderProperty == RenderNodeAnimator.ALPHA && mViewListener != null) { + mViewListener.onAlphaAnimationStart(mFinalValue); + } + + moveToRunningState(); + + if (mViewListener != null) { + // Kick off a frame to start the process + mViewListener.invalidateParent(false); + } + } + + private void moveToRunningState() { + mState = STATE_RUNNING; + if (mNativePtr != null) { + nStart(mNativePtr.get()); + } + notifyStartListeners(); + } + + private void notifyStartListeners() { + final ArrayList listeners = cloneListeners(); + final int numListeners = listeners == null ? 0 : listeners.size(); + for (int i = 0; i < numListeners; i++) { + listeners.get(i).onAnimationStart(this); + } + } + + @Override + public void cancel() { + if (mState != STATE_PREPARE && mState != STATE_FINISHED) { + if (mState == STATE_DELAYED) { + getHelper().removeDelayedAnimation(this); + moveToRunningState(); + } + + final ArrayList listeners = cloneListeners(); + final int numListeners = listeners == null ? 0 : listeners.size(); + for (int i = 0; i < numListeners; i++) { + listeners.get(i).onAnimationCancel(this); + } + + end(); + } + } + + @Override + public void end() { + if (mState != STATE_FINISHED) { + if (mState < STATE_RUNNING) { + getHelper().removeDelayedAnimation(this); + doStart(); + } + if (mNativePtr != null) { + nEnd(mNativePtr.get()); + if (mViewListener != null) { + // Kick off a frame to flush the state change + mViewListener.invalidateParent(false); + } + } else { + // It's already dead, jump to onFinish + onFinished(); + } + } + } + + @Override + public void pause() { + throw new UnsupportedOperationException(); + } + + @Override + public void resume() { + throw new UnsupportedOperationException(); + } + + /** @hide */ + public void setViewListener(ViewListener listener) { + mViewListener = listener; + } + + /** Sets the animation target to the owning view of the RecordingCanvas */ + public final void setTarget(RecordingCanvas canvas) { + setTarget(canvas.mNode); + } + + /** Sets the node that is to be the target of this animation */ + protected void setTarget(RenderNode node) { + checkMutable(); + if (mTarget != null) { + throw new IllegalStateException("Target already set!"); + } + nSetListener(mNativePtr.get(), this); + mTarget = node; + mTarget.addAnimator(this); + } + + /** Set the start value for the animation */ + public void setStartValue(float startValue) { + checkMutable(); + nSetStartValue(mNativePtr.get(), startValue); + } + + @Override + public void setStartDelay(long startDelay) { + checkMutable(); + if (startDelay < 0) { + throw new IllegalArgumentException("startDelay must be positive; " + startDelay); + } + mUnscaledStartDelay = startDelay; + mStartDelay = (long) (ValueAnimator.getDurationScale() * startDelay); + } + + @Override + public long getStartDelay() { + return mUnscaledStartDelay; + } + + @Override + public RenderNodeAnimator setDuration(long duration) { + checkMutable(); + if (duration < 0) { + throw new IllegalArgumentException("duration must be positive; " + duration); + } + mUnscaledDuration = duration; + nSetDuration(mNativePtr.get(), (long) (duration * ValueAnimator.getDurationScale())); + return this; + } + + @Override + public long getDuration() { + return mUnscaledDuration; + } + + @Override + public long getTotalDuration() { + return mUnscaledDuration + mUnscaledStartDelay; + } + + @Override + public boolean isRunning() { + return mState == STATE_DELAYED || mState == STATE_RUNNING; + } + + @Override + public boolean isStarted() { + return mState != STATE_PREPARE; + } + + @Override + public void setInterpolator(TimeInterpolator interpolator) { + checkMutable(); + mInterpolator = interpolator; + } + + @Override + public TimeInterpolator getInterpolator() { + return mInterpolator; + } + + protected void onFinished() { + if (mState == STATE_PREPARE) { + // Unlikely but possible, the native side has been destroyed + // before we have started. + releaseNativePtr(); + return; + } + if (mState == STATE_DELAYED) { + getHelper().removeDelayedAnimation(this); + notifyStartListeners(); + } + mState = STATE_FINISHED; + + final ArrayList listeners = cloneListeners(); + final int numListeners = listeners == null ? 0 : listeners.size(); + for (int i = 0; i < numListeners; i++) { + listeners.get(i).onAnimationEnd(this); + } + + // Release the native object, as it has a global reference to us. This + // breaks the cyclic reference chain, and allows this object to be + // GC'd + releaseNativePtr(); + } + + private void releaseNativePtr() { + if (mNativePtr != null) { + mNativePtr.release(); + mNativePtr = null; + } + } + + @SuppressWarnings("unchecked") + private ArrayList cloneListeners() { + ArrayList listeners = getListeners(); + if (listeners != null) { + listeners = (ArrayList) listeners.clone(); + } + return listeners; + } + + public long getNativeAnimator() { + return mNativePtr.get(); + } + + /** + * @return true if the animator was started, false if still delayed + */ + private boolean processDelayed(long frameTimeMs) { + if (mStartTime == 0) { + mStartTime = frameTimeMs; + } else if ((frameTimeMs - mStartTime) >= mStartDelay) { + doStart(); + return true; + } + return false; + } + + private static DelayedAnimationHelper getHelper() { + DelayedAnimationHelper helper = sAnimationHelper.get(); + if (helper == null) { + helper = new DelayedAnimationHelper(); + sAnimationHelper.set(helper); + } + return helper; + } + + private static ThreadLocal sAnimationHelper = + new ThreadLocal(); + + private static class DelayedAnimationHelper implements Runnable { + + private ArrayList mDelayedAnims = new ArrayList(); + private final Choreographer mChoreographer; + private boolean mCallbackScheduled; + + DelayedAnimationHelper() { + mChoreographer = Choreographer.getInstance(); + } + + public void addDelayedAnimation(RenderNodeAnimator animator) { + mDelayedAnims.add(animator); + scheduleCallback(); + } + + public void removeDelayedAnimation(RenderNodeAnimator animator) { + mDelayedAnims.remove(animator); + } + + private void scheduleCallback() { + if (!mCallbackScheduled) { + mCallbackScheduled = true; + mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, this, null); + } + } + + @Override + public void run() { + long frameTimeMs = mChoreographer.getFrameTime(); + mCallbackScheduled = false; + + int end = 0; + for (int i = 0; i < mDelayedAnims.size(); i++) { + RenderNodeAnimator animator = mDelayedAnims.get(i); + if (!animator.processDelayed(frameTimeMs)) { + if (end != i) { + mDelayedAnims.set(end, animator); + } + end++; + } + } + while (mDelayedAnims.size() > end) { + mDelayedAnims.remove(mDelayedAnims.size() - 1); + } + + if (mDelayedAnims.size() > 0) { + scheduleCallback(); + } + } + } + + // Called by native + private static void callOnFinished(RenderNodeAnimator animator) { + if (animator.mHandler != null) { + animator.mHandler.post(animator::onFinished); + } else { + new Handler(Looper.getMainLooper(), null, true).post(animator::onFinished); + } + } + + @Override + public Animator clone() { + throw new IllegalStateException("Cannot clone this animator"); + } + + @Override + public void setAllowRunningAsynchronously(boolean mayRunAsync) { + checkMutable(); + nSetAllowRunningAsync(mNativePtr.get(), mayRunAsync); + } + + private static native long nCreateAnimator(int property, float finalValue); + private static native long nCreateCanvasPropertyFloatAnimator( + long canvasProperty, float finalValue); + private static native long nCreateCanvasPropertyPaintAnimator( + long canvasProperty, int paintField, float finalValue); + private static native long nCreateRevealAnimator( + int x, int y, float startRadius, float endRadius); + + private static native void nSetStartValue(long nativePtr, float startValue); + private static native void nSetDuration(long nativePtr, long duration); + private static native long nGetDuration(long nativePtr); + private static native void nSetStartDelay(long nativePtr, long startDelay); + private static native void nSetInterpolator(long animPtr, long interpolatorPtr); + private static native void nSetAllowRunningAsync(long animPtr, boolean mayRunAsync); + private static native void nSetListener(long animPtr, RenderNodeAnimator listener); + + private static native void nStart(long animPtr); + private static native void nEnd(long animPtr); +} diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index 1acf6c512fbd..9fb72cf08b51 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -42,6 +42,7 @@ import android.graphics.PixelFormat; import android.graphics.RecordingCanvas; import android.graphics.Rect; import android.graphics.RenderNode; +import android.graphics.animation.NativeInterpolatorFactory; import android.os.Build; import android.os.Handler; import android.util.ArrayMap; @@ -54,7 +55,6 @@ import android.util.Property; import android.util.TimeUtils; import android.view.Choreographer; import android.view.NativeVectorDrawableAnimator; -import android.view.RenderNodeAnimatorSetHelper; import android.view.View; import com.android.internal.R; @@ -1532,7 +1532,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { long startDelay = extraDelay + animator.getStartDelay(); TimeInterpolator interpolator = animator.getInterpolator(); long nativeInterpolator = - RenderNodeAnimatorSetHelper.createNativeInterpolator(interpolator, duration); + NativeInterpolatorFactory.createNativeInterpolator(interpolator, duration); startDelay *= ValueAnimator.getDurationScale(); duration *= ValueAnimator.getDurationScale(); @@ -1548,7 +1548,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { * to the last seen RenderNode target and start right away. */ protected void recordLastSeenTarget(RecordingCanvas canvas) { - final RenderNode node = RenderNodeAnimatorSetHelper.getTarget(canvas); + final RenderNode node = canvas.mNode; mLastSeenTarget = new WeakReference(node); // Add the animator to the list of animators on every draw if (mInitialized || mPendingAnimationActions.size() > 0) { diff --git a/graphics/java/android/graphics/drawable/RippleForeground.java b/graphics/java/android/graphics/drawable/RippleForeground.java index cce9ba31929f..0f376957c8ff 100644 --- a/graphics/java/android/graphics/drawable/RippleForeground.java +++ b/graphics/java/android/graphics/drawable/RippleForeground.java @@ -25,9 +25,9 @@ import android.graphics.CanvasProperty; import android.graphics.Paint; import android.graphics.RecordingCanvas; import android.graphics.Rect; +import android.graphics.animation.RenderNodeAnimator; import android.util.FloatProperty; import android.util.MathUtils; -import android.view.RenderNodeAnimator; import android.view.animation.AnimationUtils; import android.view.animation.LinearInterpolator; import android.view.animation.PathInterpolator; -- cgit v1.2.3 From 5a190b19bb2c51dac5c1ddfc78fc0b53a5ff121e Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Tue, 18 Feb 2020 13:52:18 -0500 Subject: Add Bitmap#getHardwareBuffer Bug: 148155907 Bug: 135299581 Test: TODO Hidden for now. We'd like to make it an SDK API eventually (b/148155907). Internal code is currently calling createGraphicBufferHandle. This is not something we plan to expose from the UI rendering module, so add a method to get a HardwareBuffer instead. This is something we were already planning to add. It seems that clients of createGraphicBufferHandle really wanted a Parcelable to pass the HARDWARE Bitmap to another thread. This should satisfy that use case. Change-Id: Id701f7c7eab37830cd7d2cdb929cbe6ba4eca119 --- graphics/java/android/graphics/Bitmap.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'graphics') diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 9c2e95fab455..c1e7a360fcc5 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -2243,6 +2243,19 @@ public final class Bitmap implements Parcelable { return nativeCreateGraphicBufferHandle(mNativePtr); } + /** + * @return {@link HardwareBuffer} which is internally used by hardware bitmap + * + * Note: the HardwareBuffer does *not* have an associated {@link ColorSpace}. + * To render this object the same as its rendered with this Bitmap, you + * should also call {@link getColorSpace}. + * + * @hide + */ + public HardwareBuffer getHardwareBuffer() { + return nativeGetHardwareBuffer(mNativePtr); + } + //////////// native methods private static native Bitmap nativeCreate(int[] colors, int offset, @@ -2308,6 +2321,7 @@ public final class Bitmap implements Parcelable { private static native Bitmap nativeWrapHardwareBufferBitmap(HardwareBuffer buffer, long nativeColorSpace); private static native GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap); + private static native HardwareBuffer nativeGetHardwareBuffer(long nativeBitmap); private static native ColorSpace nativeComputeColorSpace(long nativePtr); private static native void nativeSetColorSpace(long nativePtr, long nativeColorSpace); private static native boolean nativeIsSRGB(long nativePtr); -- cgit v1.2.3 From 076bbe1ceb85c8ca4a3ef3981131ab4ff1bdd717 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Thu, 20 Feb 2020 11:14:47 -0500 Subject: Add details regarding setConvexPath deprecation Bug: 149857968 Test: make docs Change-Id: I995e035fc7d73d196a50b4e515db38110baa0fe5 --- graphics/java/android/graphics/Outline.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java index c12159cfd7a4..5858e3988486 100644 --- a/graphics/java/android/graphics/Outline.java +++ b/graphics/java/android/graphics/Outline.java @@ -280,7 +280,10 @@ public final class Outline { * {@link android.os.Build.VERSION_CODES#Q}, it is no longer required to be * convex. * - * @deprecated The path is no longer required to be convex. Use {@link #setPath} instead. + * @deprecated As of {@link android.os.Build.VERSION_CODES#Q}, the restriction + * that the path must be convex is removed. However, the API is misnamed until + * {@link android.os.Build.VERSION_CODES#R}, when {@link #setPath} is + * introduced. Use {@link #setPath} instead. */ @Deprecated public void setConvexPath(@NonNull Path convexPath) { -- cgit v1.2.3 From 42c50042d1f05d92ecc57baebe3326a57aeecf77 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Tue, 18 Feb 2020 14:51:17 -0500 Subject: Remove dependence on libandroid_runtime from Bitmap.cpp The end goal is to have Bitmap.cpp use AParcel, but until that API is extended to support this use case this is an alternative way to isolate the graphics files from the libandroid_runtime. Test: CtsGraphicsTestCases Bug: 145227478 Change-Id: Ie3854fe03dec4f7b1b485295bb9a5ebba52ddb7c --- graphics/java/android/graphics/Bitmap.java | 3 +-- graphics/java/android/graphics/GraphicBuffer.java | 10 ++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index c1e7a360fcc5..f7877590869a 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -2240,7 +2240,7 @@ public final class Bitmap implements Parcelable { */ @UnsupportedAppUsage public GraphicBuffer createGraphicBufferHandle() { - return nativeCreateGraphicBufferHandle(mNativePtr); + return GraphicBuffer.createFromHardwareBuffer(getHardwareBuffer()); } /** @@ -2320,7 +2320,6 @@ public final class Bitmap implements Parcelable { private static native Bitmap nativeCopyPreserveInternalConfig(long nativeBitmap); private static native Bitmap nativeWrapHardwareBufferBitmap(HardwareBuffer buffer, long nativeColorSpace); - private static native GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap); private static native HardwareBuffer nativeGetHardwareBuffer(long nativeBitmap); private static native ColorSpace nativeComputeColorSpace(long nativePtr); private static native void nativeSetColorSpace(long nativePtr, long nativeColorSpace); diff --git a/graphics/java/android/graphics/GraphicBuffer.java b/graphics/java/android/graphics/GraphicBuffer.java index 99fa5eef7bbd..0430847857b6 100644 --- a/graphics/java/android/graphics/GraphicBuffer.java +++ b/graphics/java/android/graphics/GraphicBuffer.java @@ -17,6 +17,7 @@ package android.graphics; import android.compat.annotation.UnsupportedAppUsage; +import android.hardware.HardwareBuffer; import android.os.Parcel; import android.os.Parcelable; @@ -109,6 +110,14 @@ public class GraphicBuffer implements Parcelable { return null; } + /** + * For Bitmap until all usages are updated to AHB + * @hide + */ + public static final GraphicBuffer createFromHardwareBuffer(HardwareBuffer buffer) { + return nCreateFromHardwareBuffer(buffer); + } + /** * Returns the width of this buffer in pixels. */ @@ -305,4 +314,5 @@ public class GraphicBuffer implements Parcelable { private static native boolean nLockCanvas(long nativeObject, Canvas canvas, Rect dirty); private static native boolean nUnlockCanvasAndPost(long nativeObject, Canvas canvas); private static native long nWrapGraphicBuffer(long nativeObject); + private static native GraphicBuffer nCreateFromHardwareBuffer(HardwareBuffer buffer); } -- cgit v1.2.3 From dd03a8ef81064241943ae1788cf1c63ed3df35b7 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Fri, 21 Feb 2020 15:21:41 -0500 Subject: Do not attempt to special case uncompressed font assets. The logic to attempt to directly mmap uncompressed font assets has resulted in breakages for some applications and utilities. This CL disables this speculative optimzation until we can determine the problem with this approach and if such an optimization is required. Bug: 149780695 Test: CtsTextTestCases and androidx.appcompat.widget.AppCompatTextViewTest Change-Id: I3b10a801a5600aefe8573fab1b28cd79c848c892 --- graphics/java/android/graphics/fonts/Font.java | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java index 4899fbe431cc..853165d4cf3f 100644 --- a/graphics/java/android/graphics/fonts/Font.java +++ b/graphics/java/android/graphics/fonts/Font.java @@ -19,7 +19,6 @@ package android.graphics.fonts; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.content.res.AssetFileDescriptor; import android.content.res.AssetManager; import android.content.res.Resources; import android.os.LocaleList; @@ -220,25 +219,6 @@ public final class Font { Preconditions.checkNotNull(am, "assetManager can not be null"); Preconditions.checkNotNull(path, "path can not be null"); - if (!isAsset) { - // Attempt to open as FD, which should work unless the asset is compressed - AssetFileDescriptor assetFD; - try { - if (cookie > 0) { - assetFD = am.openNonAssetFd(cookie, path); - } else { - assetFD = am.openNonAssetFd(path); - } - - try (FileInputStream fis = assetFD.createInputStream()) { - final FileChannel fc = fis.getChannel(); - return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); - } - } catch (IOException e) { - // failed to open as FD so now we will attempt to open as an input stream - } - } - try (InputStream assetStream = isAsset ? am.open(path, AssetManager.ACCESS_BUFFER) : am.openNonAsset(cookie, path, AssetManager.ACCESS_BUFFER)) { -- cgit v1.2.3 From f8d4a6684c321e0d2b564df6600c739c9bcd5863 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Fri, 21 Feb 2020 16:38:43 -0500 Subject: Fix mmap errors when reading font files via the AssetManager. Previous attempts to do this ignored the offset that the AssetFileDescriptor may have. Bug: 149927583 Test: CtsTextTestCases and androidx.appcompat.widget.AppCompatTextViewTest Change-Id: Idcc8cb83a7f265cfa12707b7ce643b35f7f72352 --- graphics/java/android/graphics/fonts/Font.java | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'graphics') diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java index 853165d4cf3f..b09082e65ca4 100644 --- a/graphics/java/android/graphics/fonts/Font.java +++ b/graphics/java/android/graphics/fonts/Font.java @@ -19,6 +19,7 @@ package android.graphics.fonts; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.res.AssetFileDescriptor; import android.content.res.AssetManager; import android.content.res.Resources; import android.os.LocaleList; @@ -219,6 +220,27 @@ public final class Font { Preconditions.checkNotNull(am, "assetManager can not be null"); Preconditions.checkNotNull(path, "path can not be null"); + // Attempt to open as FD, which should work unless the asset is compressed + AssetFileDescriptor assetFD; + try { + if (isAsset) { + assetFD = am.openFd(path); + } else if (cookie > 0) { + assetFD = am.openNonAssetFd(cookie, path); + } else { + assetFD = am.openNonAssetFd(path); + } + + try (FileInputStream fis = assetFD.createInputStream()) { + final FileChannel fc = fis.getChannel(); + long startOffset = assetFD.getStartOffset(); + long declaredLength = assetFD.getDeclaredLength(); + return fc.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength); + } + } catch (IOException e) { + // failed to open as FD so now we will attempt to open as an input stream + } + try (InputStream assetStream = isAsset ? am.open(path, AssetManager.ACCESS_BUFFER) : am.openNonAsset(cookie, path, AssetManager.ACCESS_BUFFER)) { -- cgit v1.2.3 From 26ff673458c6b85ecfc9628cf6bd7522c8393d0f Mon Sep 17 00:00:00 2001 From: Ryan Mitchell Date: Fri, 27 Mar 2020 09:33:31 -0700 Subject: Add mSourceDrawableId to copy constructor The copy constructor of AdaptiveIconDrawable#LayerState currently does not copy mSourceDrawableId from the original layer state. This prevents drawables created from preloaded AdaptiveIconDrawables from having the correct source drawable resource id. Bug: 148488431 Test: CtsContentTestCases:android.content.pm.cts.PackageManagerTest Change-Id: I7795a337a2a364677e375776c7aec5bc9189e0da --- graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java | 1 + 1 file changed, 1 insertion(+) (limited to 'graphics') diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java index 746378e10bc7..31ad81b9c346 100644 --- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java +++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java @@ -975,6 +975,7 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback mChangingConfigurations = orig.mChangingConfigurations; mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations; + mSourceDrawableId = orig.mSourceDrawableId; for (int i = 0; i < N_CHILDREN; i++) { final ChildDrawable or = origChildDrawable[i]; -- cgit v1.2.3 From 865f0f1ec9708cb6beca7d45f285ac06a312857a Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Fri, 10 Apr 2020 15:04:22 -0400 Subject: Support Skia's gray SkColorSpaces Bug: 153410582 Test: I0a280cdfdb02766f5e415408386cce49a59504ab For gray color spaces, Skia creates a special toXYZD50 matrix which does not have any concept of primaries. Update the Java ColorSpace to recognize such a matrix and treat it specially. Instead of creating primaries, use a set of dummy values. This fixes a bug where the Java ColorSpace was invalid (NaNs in its transforms) and applying it to a new Bitmap yielded incorrect results. Fix up the @see links in getPrimaries and surrounding methods. Change-Id: I94fe232e10f56a69832d4a39a2e5909eac641264 (cherry picked from commit d82d585f283d59264c2e8459d4bda5ef69301044) Merged-In: I94fe232e10f56a69832d4a39a2e5909eac641264 --- graphics/java/android/graphics/ColorSpace.java | 59 +++++++++++++++++++++----- 1 file changed, 48 insertions(+), 11 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java index ce8ff7dc38ba..1aeafa391b41 100644 --- a/graphics/java/android/graphics/ColorSpace.java +++ b/graphics/java/android/graphics/ColorSpace.java @@ -199,6 +199,11 @@ public abstract class ColorSpace { private static final float[] SRGB_PRIMARIES = { 0.640f, 0.330f, 0.300f, 0.600f, 0.150f, 0.060f }; private static final float[] NTSC_1953_PRIMARIES = { 0.67f, 0.33f, 0.21f, 0.71f, 0.14f, 0.08f }; + /** + * A gray color space does not have meaningful primaries, so we use this arbitrary set. + */ + private static final float[] GRAY_PRIMARIES = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; + private static final float[] ILLUMINANT_D50_XYZ = { 0.964212f, 1.0f, 0.825188f }; private static final Rgb.TransferParameters SRGB_TRANSFER_PARAMETERS = @@ -1457,6 +1462,7 @@ public abstract class ColorSpace { "sRGB IEC61966-2.1", SRGB_PRIMARIES, ILLUMINANT_D65, + null, SRGB_TRANSFER_PARAMETERS, Named.SRGB.ordinal() ); @@ -1491,6 +1497,7 @@ public abstract class ColorSpace { "Rec. ITU-R BT.709-5", new float[] { 0.640f, 0.330f, 0.300f, 0.600f, 0.150f, 0.060f }, ILLUMINANT_D65, + null, new Rgb.TransferParameters(1 / 1.099, 0.099 / 1.099, 1 / 4.5, 0.081, 1 / 0.45), Named.BT709.ordinal() ); @@ -1498,6 +1505,7 @@ public abstract class ColorSpace { "Rec. ITU-R BT.2020-1", new float[] { 0.708f, 0.292f, 0.170f, 0.797f, 0.131f, 0.046f }, ILLUMINANT_D65, + null, new Rgb.TransferParameters(1 / 1.0993, 0.0993 / 1.0993, 1 / 4.5, 0.08145, 1 / 0.45), Named.BT2020.ordinal() ); @@ -1513,6 +1521,7 @@ public abstract class ColorSpace { "Display P3", new float[] { 0.680f, 0.320f, 0.265f, 0.690f, 0.150f, 0.060f }, ILLUMINANT_D65, + null, SRGB_TRANSFER_PARAMETERS, Named.DISPLAY_P3.ordinal() ); @@ -1520,6 +1529,7 @@ public abstract class ColorSpace { "NTSC (1953)", NTSC_1953_PRIMARIES, ILLUMINANT_C, + null, new Rgb.TransferParameters(1 / 1.099, 0.099 / 1.099, 1 / 4.5, 0.081, 1 / 0.45), Named.NTSC_1953.ordinal() ); @@ -1527,6 +1537,7 @@ public abstract class ColorSpace { "SMPTE-C RGB", new float[] { 0.630f, 0.340f, 0.310f, 0.595f, 0.155f, 0.070f }, ILLUMINANT_D65, + null, new Rgb.TransferParameters(1 / 1.099, 0.099 / 1.099, 1 / 4.5, 0.081, 1 / 0.45), Named.SMPTE_C.ordinal() ); @@ -1542,6 +1553,7 @@ public abstract class ColorSpace { "ROMM RGB ISO 22028-2:2013", new float[] { 0.7347f, 0.2653f, 0.1596f, 0.8404f, 0.0366f, 0.0001f }, ILLUMINANT_D50, + null, new Rgb.TransferParameters(1.0, 0.0, 1 / 16.0, 0.031248, 1.8), Named.PRO_PHOTO_RGB.ordinal() ); @@ -2471,7 +2483,11 @@ public abstract class ColorSpace { @NonNull @Size(min = 1) String name, @NonNull @Size(9) float[] toXYZ, @NonNull TransferParameters function) { - this(name, computePrimaries(toXYZ), computeWhitePoint(toXYZ), function, MIN_ID); + // Note: when isGray() returns false, this passes null for the transform for + // consistency with other constructors, which compute the transform from the primaries + // and white point. + this(name, isGray(toXYZ) ? GRAY_PRIMARIES : computePrimaries(toXYZ), + computeWhitePoint(toXYZ), isGray(toXYZ) ? toXYZ : null, function, MIN_ID); } /** @@ -2511,7 +2527,7 @@ public abstract class ColorSpace { @NonNull @Size(min = 6, max = 9) float[] primaries, @NonNull @Size(min = 2, max = 3) float[] whitePoint, @NonNull TransferParameters function) { - this(name, primaries, whitePoint, function, MIN_ID); + this(name, primaries, whitePoint, null, function, MIN_ID); } /** @@ -2534,6 +2550,8 @@ public abstract class ColorSpace { * @param name Name of the color space, cannot be null, its length must be >= 1 * @param primaries RGB primaries as an array of 6 (xy) or 9 (XYZ) floats * @param whitePoint Reference white as an array of 2 (xy) or 3 (XYZ) floats + * @param transform Computed transform matrix that converts from RGB to XYZ, or + * {@code null} to compute it from {@code primaries} and {@code whitePoint}. * @param function Parameters for the transfer functions * @param id ID of this color space as an integer between {@link #MIN_ID} and {@link #MAX_ID} * @@ -2552,9 +2570,10 @@ public abstract class ColorSpace { @NonNull @Size(min = 1) String name, @NonNull @Size(min = 6, max = 9) float[] primaries, @NonNull @Size(min = 2, max = 3) float[] whitePoint, + @Nullable @Size(9) float[] transform, @NonNull TransferParameters function, @IntRange(from = MIN_ID, to = MAX_ID) int id) { - this(name, primaries, whitePoint, null, + this(name, primaries, whitePoint, transform, function.e == 0.0 && function.f == 0.0 ? x -> rcpResponse(x, function.a, function.b, function.c, function.d, function.g) : @@ -2846,7 +2865,7 @@ public abstract class ColorSpace { * * @return The destination array passed as a parameter * - * @see #getWhitePoint(float[]) + * @see #getWhitePoint() */ @NonNull @Size(min = 2) @@ -2864,7 +2883,7 @@ public abstract class ColorSpace { * * @return A new non-null array of 2 floats * - * @see #getWhitePoint() + * @see #getWhitePoint(float[]) */ @NonNull @Size(2) @@ -2878,12 +2897,16 @@ public abstract class ColorSpace { * destination. The x and y components of the first primary are written * in the array at positions 0 and 1 respectively. * + *

Note: Some ColorSpaces represent gray profiles. The concept of + * primaries for such a ColorSpace does not make sense, so we use a special + * set of primaries that are all 1s.

+ * * @param primaries The destination array, cannot be null, its length * must be >= 6 * * @return The destination array passed as a parameter * - * @see #getPrimaries(float[]) + * @see #getPrimaries() */ @NonNull @Size(min = 6) @@ -2898,9 +2921,13 @@ public abstract class ColorSpace { * the destination. The x and y components of the first primary are * written in the array at positions 0 and 1 respectively. * + *

Note: Some ColorSpaces represent gray profiles. The concept of + * primaries for such a ColorSpace does not make sense, so we use a special + * set of primaries that are all 1s.

+ * * @return A new non-null array of 2 floats * - * @see #getWhitePoint() + * @see #getPrimaries(float[]) */ @NonNull @Size(6) @@ -2922,7 +2949,7 @@ public abstract class ColorSpace { * * @return The destination array passed as a parameter * - * @see #getInverseTransform() + * @see #getTransform() */ @NonNull @Size(min = 9) @@ -2942,7 +2969,7 @@ public abstract class ColorSpace { * * @return A new array of 9 floats * - * @see #getInverseTransform(float[]) + * @see #getTransform(float[]) */ @NonNull @Size(9) @@ -2964,7 +2991,7 @@ public abstract class ColorSpace { * * @return The destination array passed as a parameter * - * @see #getTransform() + * @see #getInverseTransform() */ @NonNull @Size(min = 9) @@ -2984,7 +3011,7 @@ public abstract class ColorSpace { * * @return A new array of 9 floats * - * @see #getTransform(float[]) + * @see #getInverseTransform(float[]) */ @NonNull @Size(9) @@ -3287,6 +3314,16 @@ public abstract class ColorSpace { return true; } + /** + * Report whether this matrix is a special gray matrix. + * @param toXYZ A XYZD50 matrix. Skia uses a special form for a gray profile. + * @return true if this is a special gray matrix. + */ + private static boolean isGray(@NonNull @Size(9) float[] toXYZ) { + return toXYZ.length == 9 && toXYZ[1] == 0 && toXYZ[2] == 0 && toXYZ[3] == 0 + && toXYZ[5] == 0 && toXYZ[6] == 0 && toXYZ[7] == 0; + } + private static boolean compare(double point, @NonNull DoubleUnaryOperator a, @NonNull DoubleUnaryOperator b) { double rA = a.applyAsDouble(point); -- cgit v1.2.3 From 62f8b4f3d604c5b056f00ecc712318f6064a23af Mon Sep 17 00:00:00 2001 From: John Reck Date: Thu, 16 Apr 2020 10:06:59 -0700 Subject: Document that getTransformMatrix can inset Bug: 152621633 Test: none, docs only change Change-Id: I4a357affdf698c8eb70ed7abbfa828586b2da0ec --- graphics/java/android/graphics/SurfaceTexture.java | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'graphics') diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index 697daa8b7b70..cd878c5a77cb 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -307,6 +307,11 @@ public class SurfaceTexture { * The matrix is stored in column-major order so that it may be passed directly to OpenGL ES via * the glLoadMatrixf or glUniformMatrix4fv functions. * + * If the underlying buffer has a crop associated with it, the transformation will also include + * a slight scale to cut off a 1-texel border around the edge of the crop. This ensures that + * when the texture is bilinear sampled that no texels outside of the buffer's valid region + * are accessed by the GPU, avoiding any sampling artifacts when scaling. + * * @param mtx the array into which the 4x4 matrix will be stored. The array must have exactly * 16 elements. */ -- cgit v1.2.3 From 67d06a9965b0e25451cb843a71c4de6ef37dbff0 Mon Sep 17 00:00:00 2001 From: Sumir Kataria Date: Mon, 20 Apr 2020 15:48:00 -0700 Subject: Update doc formatting. Add missing

tags which should make some methods more readable. Also added a few {@code} tags and a couple of missing {@link} tags. Fixes: 154547852 Test: m offline-sdk-docs Change-Id: I1b8d0212b54e902378d5d25f6d555f69af207604 --- graphics/java/android/graphics/SurfaceTexture.java | 52 +++++++++++----------- 1 file changed, 27 insertions(+), 25 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index cd878c5a77cb..228d03a1dd10 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -120,7 +120,7 @@ public class SurfaceTexture { /** * Construct a new SurfaceTexture to stream images to a given OpenGL texture. - * + *

* In single buffered mode the application is responsible for serializing access to the image * content buffer. Each time the image content is to be updated, the * {@link #releaseTexImage()} method must be called before the image content producer takes @@ -143,7 +143,7 @@ public class SurfaceTexture { /** * Construct a new SurfaceTexture to stream images to a given OpenGL texture. - * + *

* In single buffered mode the application is responsible for serializing access to the image * content buffer. Each time the image content is to be updated, the * {@link #releaseTexImage()} method must be called before the image content producer takes @@ -152,7 +152,7 @@ public class SurfaceTexture { * must be called before each ANativeWindow_lock, or that call will fail. When producing * image content with OpenGL ES, {@link #releaseTexImage()} must be called before the first * OpenGL ES function call each frame. - * + *

* Unlike {@link #SurfaceTexture(int, boolean)}, which takes an OpenGL texture object name, * this constructor creates the SurfaceTexture in detached mode. A texture name must be passed * in using {@link #attachToGLContext} before calling {@link #releaseTexImage()} and producing @@ -222,15 +222,15 @@ public class SurfaceTexture { * method. Both video and camera based image producers do override the size. This method may * be used to set the image size when producing images with {@link android.graphics.Canvas} (via * {@link android.view.Surface#lockCanvas}), or OpenGL ES (via an EGLSurface). - * + *

* The new default buffer size will take effect the next time the image producer requests a * buffer to fill. For {@link android.graphics.Canvas} this will be the next time {@link * android.view.Surface#lockCanvas} is called. For OpenGL ES, the EGLSurface should be * destroyed (via eglDestroySurface), made not-current (via eglMakeCurrent), and then recreated - * (via eglCreateWindowSurface) to ensure that the new default size has taken effect. - * + * (via {@code eglCreateWindowSurface}) to ensure that the new default size has taken effect. + *

* The width and height parameters must be no greater than the minimum of - * GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see + * {@code GL_MAX_VIEWPORT_DIMS} and {@code GL_MAX_TEXTURE_SIZE} (see * {@link javax.microedition.khronos.opengles.GL10#glGetIntegerv glGetIntegerv}). * An error due to invalid dimensions might not be reported until * updateTexImage() is called. @@ -242,7 +242,7 @@ public class SurfaceTexture { /** * Update the texture image to the most recent frame from the image stream. This may only be * called while the OpenGL ES context that owns the texture is current on the calling thread. - * It will implicitly bind its texture to the GL_TEXTURE_EXTERNAL_OES texture target. + * It will implicitly bind its texture to the {@code GL_TEXTURE_EXTERNAL_OES} texture target. */ public void updateTexImage() { nativeUpdateTexImage(); @@ -251,6 +251,7 @@ public class SurfaceTexture { /** * Releases the the texture content. This is needed in single buffered mode to allow the image * content producer to take ownership of the image buffer. + *

* For more information see {@link #SurfaceTexture(int, boolean)}. */ public void releaseTexImage() { @@ -263,7 +264,7 @@ public class SurfaceTexture { * ES texture object will be deleted as a result of this call. After calling this method all * calls to {@link #updateTexImage} will throw an {@link java.lang.IllegalStateException} until * a successful call to {@link #attachToGLContext} is made. - * + *

* This can be used to access the SurfaceTexture image contents from multiple OpenGL ES * contexts. Note, however, that the image contents are only accessible from one OpenGL ES * context at a time. @@ -279,8 +280,8 @@ public class SurfaceTexture { * Attach the SurfaceTexture to the OpenGL ES context that is current on the calling thread. A * new OpenGL ES texture object is created and populated with the SurfaceTexture image frame * that was current at the time of the last call to {@link #detachFromGLContext}. This new - * texture is bound to the GL_TEXTURE_EXTERNAL_OES texture target. - * + * texture is bound to the {@code GL_TEXTURE_EXTERNAL_OES} texture target. + *

* This can be used to access the SurfaceTexture image contents from multiple OpenGL ES * contexts. Note, however, that the image contents are only accessible from one OpenGL ES * context at a time. @@ -297,16 +298,16 @@ public class SurfaceTexture { /** * Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by - * the most recent call to updateTexImage. - * + * the most recent call to {@link #updateTexImage}. + *

* This transform matrix maps 2D homogeneous texture coordinates of the form (s, t, 0, 1) with s * and t in the inclusive range [0, 1] to the texture coordinate that should be used to sample * that location from the texture. Sampling the texture outside of the range of this transform * is undefined. - * + *

* The matrix is stored in column-major order so that it may be passed directly to OpenGL ES via - * the glLoadMatrixf or glUniformMatrix4fv functions. - * + * the {@code glLoadMatrixf} or {@code glUniformMatrix4fv} functions. + *

* If the underlying buffer has a crop associated with it, the transformation will also include * a slight scale to cut off a 1-texel border around the edge of the crop. This ensures that * when the texture is bilinear sampled that no texels outside of the buffer's valid region @@ -326,7 +327,7 @@ public class SurfaceTexture { /** * Retrieve the timestamp associated with the texture image set by the most recent call to - * updateTexImage. + * {@link #updateTexImage}. * *

This timestamp is in nanoseconds, and is normally monotonically increasing. The timestamp * should be unaffected by time-of-day adjustments. The specific meaning and zero point of the @@ -337,8 +338,8 @@ public class SurfaceTexture { * *

For camera sources, timestamps should be strictly monotonic. Timestamps from MediaPlayer * sources may be reset when the playback position is set. For EGL and Vulkan producers, the - * timestamp is the desired present time set with the EGL_ANDROID_presentation_time or - * VK_GOOGLE_display_timing extensions.

+ * timestamp is the desired present time set with the {@code EGL_ANDROID_presentation_time} or + * {@code VK_GOOGLE_display_timing} extensions.

*/ public long getTimestamp() { @@ -346,16 +347,17 @@ public class SurfaceTexture { } /** - * release() frees all the buffers and puts the SurfaceTexture into the + * {@code release()} frees all the buffers and puts the SurfaceTexture into the * 'abandoned' state. Once put in this state the SurfaceTexture can never * leave it. When in the 'abandoned' state, all methods of the - * IGraphicBufferProducer interface will fail with the NO_INIT error. - * + * {@code IGraphicBufferProducer} interface will fail with the {@code NO_INIT} + * error. + *

* Note that while calling this method causes all the buffers to be freed * from the perspective of the the SurfaceTexture, if there are additional * references on the buffers (e.g. if a buffer is referenced by a client or * by OpenGL ES as a texture) then those buffer will remain allocated. - * + *

* Always call this method when you are done with SurfaceTexture. Failing * to do so may delay resource deallocation for a significant amount of * time. @@ -367,7 +369,7 @@ public class SurfaceTexture { } /** - * Returns true if the SurfaceTexture was released. + * Returns {@code true} if the SurfaceTexture was released. * * @see #release() */ @@ -400,7 +402,7 @@ public class SurfaceTexture { } /** - * Returns true if the SurfaceTexture is single-buffered + * Returns {@code true} if the SurfaceTexture is single-buffered. * @hide */ public boolean isSingleBuffered() { -- cgit v1.2.3 From b9cf275b9bf4a5cd2f941c422ee728a4bf155601 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Wed, 22 Apr 2020 15:56:32 -0700 Subject: BLAST: Two start-up optimizations 1. Avoid a seperate IPC querying in to system-server to initialize the mUseBLAST flag. 2. Avoid calling property_get_bool with each BufferQueue creation. Instead we piggy-back both values inside addWindow return values. Bug: 152501005 Test: Existing tests pass Change-Id: If130560a8230f8d399cf7631264d551522939faa --- graphics/java/android/graphics/BLASTBufferQueue.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java index 8c6a9371d53b..4c7e960eb0a4 100644 --- a/graphics/java/android/graphics/BLASTBufferQueue.java +++ b/graphics/java/android/graphics/BLASTBufferQueue.java @@ -26,15 +26,17 @@ public final class BLASTBufferQueue { // Note: This field is accessed by native code. private long mNativeObject; // BLASTBufferQueue* - private static native long nativeCreate(long surfaceControl, long width, long height); + private static native long nativeCreate(long surfaceControl, long width, long height, + boolean tripleBufferingEnabled); private static native void nativeDestroy(long ptr); private static native Surface nativeGetSurface(long ptr); private static native void nativeSetNextTransaction(long ptr, long transactionPtr); private static native void nativeUpdate(long ptr, long surfaceControl, long width, long height); /** Create a new connection with the surface flinger. */ - public BLASTBufferQueue(SurfaceControl sc, int width, int height) { - mNativeObject = nativeCreate(sc.mNativeObject, width, height); + public BLASTBufferQueue(SurfaceControl sc, int width, int height, + boolean tripleBufferingEnabled) { + mNativeObject = nativeCreate(sc.mNativeObject, width, height, tripleBufferingEnabled); } public void destroy() { @@ -64,4 +66,3 @@ public final class BLASTBufferQueue { } } } - -- cgit v1.2.3 From 6419ebff5c553a87ff30f3e298b68519f82420e0 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Mon, 27 Apr 2020 15:31:21 -0400 Subject: Fix .equals call in ImageDecoder Bug: 154954875 Bug: 143231863 Test: I93b01cb60a8c76110ea2ff4250d0048512629d8d I9229039b752bafa9a9b85b914a62093dff1eec34 switched from "==" to ".equals", but it did not take into account that Uri#getScheme() can return null. Switch around the .equals check so that it is called on SCHEME_CONTENT, which will never be null. Change-Id: I0df5d2407a32fad0e21e597697af293fbc2fb315 Merged-In: I0df5d2407a32fad0e21e597697af293fbc2fb315 --- graphics/java/android/graphics/ImageDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java index 83432c362672..97b448aa8ff0 100644 --- a/graphics/java/android/graphics/ImageDecoder.java +++ b/graphics/java/android/graphics/ImageDecoder.java @@ -270,7 +270,7 @@ public final class ImageDecoder implements AutoCloseable { public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException { AssetFileDescriptor assetFd = null; try { - if (mUri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) { + if (ContentResolver.SCHEME_CONTENT.equals(mUri.getScheme())) { assetFd = mResolver.openTypedAssetFileDescriptor(mUri, "image/*", null); } else { -- cgit v1.2.3 From 8fe35e5f2195e416f250ba5332bce676c362b210 Mon Sep 17 00:00:00 2001 From: Andrew Sapperstein Date: Tue, 28 Apr 2020 12:29:20 -0700 Subject: Fix broken @see tags in public documentation. These were previously being suppressed by doclava but with this change, all failures are fixed and the suppression logic has been removed. To fix the issues, there were a few possible changes made: - broken reference to a public API (such as incorrect parameters): fixed - unnecessary @link inside an @see tag: fixed - @see referring to an @hide or @SystemApi: reference removed - broken references to inner class constructors - worked around by fully qualifying the constructor Bug: 6963924 Test: make doc-comment-check-docs Exempt-From-Owner-Approval: cherry-picked from master Change-Id: Ifbdce2de96cdffa560bd90f549fa7184d1f9af85 Merged-In: Ifbdce2de96cdffa560bd90f549fa7184d1f9af85 (cherry picked from commit e0624c7a40baae30cf77e948db5258b78856d0e5) --- graphics/java/android/graphics/RenderNode.java | 2 +- graphics/java/android/graphics/drawable/Drawable.java | 2 +- graphics/java/android/graphics/fonts/FontStyle.java | 2 +- graphics/java/android/graphics/text/LineBreaker.java | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java index 752695fd8e52..22f5489be3b1 100644 --- a/graphics/java/android/graphics/RenderNode.java +++ b/graphics/java/android/graphics/RenderNode.java @@ -998,7 +998,7 @@ public final class RenderNode { * Sets the rotation value for the display list around the Z axis. * * @param rotation The rotation value of the display list, in degrees - * @see View#setRotationZ(float) + * @see View#setRotation(float) * @see #getRotationZ() * @return True if the value changed, false if the new value was the same as the previous value. */ diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index e70529b6cd1a..9cf12f121e0a 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -617,7 +617,7 @@ public abstract class Drawable { * {@link #setTintList(ColorStateList) tint}. *

* - * @see {@link #setColorFilter(ColorFilter)} } + * @see #setColorFilter(ColorFilter) * @deprecated use {@link #setColorFilter(ColorFilter)} with an instance * of {@link android.graphics.BlendModeColorFilter} */ diff --git a/graphics/java/android/graphics/fonts/FontStyle.java b/graphics/java/android/graphics/fonts/FontStyle.java index af517d623b01..09799fdf5a13 100644 --- a/graphics/java/android/graphics/fonts/FontStyle.java +++ b/graphics/java/android/graphics/fonts/FontStyle.java @@ -217,7 +217,7 @@ public final class FontStyle { /** * Gets the weight value * - * @see FontStyle#setWeight(int) + * @see #FontStyle(int, int) * @return a weight value */ public @IntRange(from = 0, to = 1000) int getWeight() { diff --git a/graphics/java/android/graphics/text/LineBreaker.java b/graphics/java/android/graphics/text/LineBreaker.java index 54622c5e74df..babcfc3815f4 100644 --- a/graphics/java/android/graphics/text/LineBreaker.java +++ b/graphics/java/android/graphics/text/LineBreaker.java @@ -320,7 +320,7 @@ public class LineBreaker { /** * Returns the array of tab stops in pixels. * - * @see #setTabStops(float[], int) + * @see #setTabStops */ public @Nullable float[] getTabStops() { return mVariableTabStops; @@ -329,7 +329,7 @@ public class LineBreaker { /** * Returns the default tab stops in pixels. * - * @see #setTabStop(float[], int) + * @see #setTabStops */ public @Px @FloatRange(from = 0) float getDefaultTabStop() { return mDefaultTabStop; -- cgit v1.2.3 From e9b2cc829e1dedc35c04abb0f3cd2ad5ada459aa Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Mon, 11 May 2020 16:49:51 -0400 Subject: Update ImageDecoder docs regarding Files Bug: 139186570 Test: make docs As part of enforcing Scoped Storage for the next Android release, we're encouraging app developers to steer away from using raw file path access and, instead, use FileDescriptor or Uri to access files. Update createSource(File)'s docs to suggest why they might want to use a different method. Update the top level example to use createSource(ContentResolver, Uri) instead of createSource(File). Change-Id: Icbccdb5183edd0b6a052ec905f999f02ac4e61d3 (cherry picked from commit 405697458360779a9d7e731b4e8dbe0eeb9b3f0d) Merged-In: Icbccdb5183edd0b6a052ec905f999f02ac4e61d3 --- graphics/java/android/graphics/ImageDecoder.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java index 97b448aa8ff0..c8f065ad094c 100644 --- a/graphics/java/android/graphics/ImageDecoder.java +++ b/graphics/java/android/graphics/ImageDecoder.java @@ -70,9 +70,9 @@ import java.util.concurrent.atomic.AtomicBoolean; * {@link Bitmap} objects. * *

To use it, first create a {@link Source Source} using one of the - * {@code createSource} overloads. For example, to decode from a {@link File}, call - * {@link #createSource(File)} and pass the result to {@link #decodeDrawable(Source)} - * or {@link #decodeBitmap(Source)}: + * {@code createSource} overloads. For example, to decode from a {@link Uri}, call + * {@link #createSource(ContentResolver, Uri)} and pass the result to + * {@link #decodeDrawable(Source)} or {@link #decodeBitmap(Source)}: * *

  *  File file = new File(...);
@@ -1032,7 +1032,11 @@ public final class ImageDecoder implements AutoCloseable {
 
     /**
      * Create a new {@link Source Source} from a {@link java.io.File}.
-     *
+     * 

+ * This method should only be used for files that you have direct access to; + * if you'd like to work with files hosted outside your app, use an API like + * {@link #createSource(Callable)} or + * {@link #createSource(ContentResolver, Uri)}. * @return a new Source object, which can be passed to * {@link #decodeDrawable decodeDrawable} or * {@link #decodeBitmap decodeBitmap}. -- cgit v1.2.3 From b9001d1b8a09e96eb109238a93ed206509edbe2f Mon Sep 17 00:00:00 2001 From: Andrew Solovay Date: Mon, 18 May 2020 16:07:57 -0700 Subject: docs: Removing spurious heading from Javadoc comment There's an H3 at the top of the PorterDuff.Mode javadoc comment, and that breaks the TOC in various ways. We don't need that heading so I'm removing it. Test: make ds-docs-java Exempt-from-owner-approval: Docs-only change Change-Id: I6d5f98b5103a77a7d0245a438b6961c4a21fb059 Bug: 311897143 --- graphics/java/android/graphics/PorterDuff.java | 2 -- 1 file changed, 2 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java index 1275cb9ca4f9..eb940e2f9017 100644 --- a/graphics/java/android/graphics/PorterDuff.java +++ b/graphics/java/android/graphics/PorterDuff.java @@ -30,8 +30,6 @@ public class PorterDuff { /** * {@usesMathJax} * - *

Porter-Duff

- * *

The name of the parent class is an homage to the work of Thomas Porter and * Tom Duff, presented in their seminal 1984 paper titled "Compositing Digital Images". * In this paper, the authors describe 12 compositing operators that govern how to -- cgit v1.2.3 From 8bbf9bae6fa65822add30cbcd1901b1b0c76a686 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Tue, 26 May 2020 16:29:43 -0700 Subject: Fix small issue in PdfDocument docs Test: Doc fix only Fixes: 157396387 Change-Id: If1c7a875d8915f53726b832f51cb59fa1f12ae31 --- graphics/java/android/graphics/pdf/PdfDocument.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/pdf/PdfDocument.java b/graphics/java/android/graphics/pdf/PdfDocument.java index 1b8336f54637..58421ab5ccd9 100644 --- a/graphics/java/android/graphics/pdf/PdfDocument.java +++ b/graphics/java/android/graphics/pdf/PdfDocument.java @@ -46,8 +46,8 @@ import java.util.List; * // create a new document * PdfDocument document = new PdfDocument(); * - * // crate a page description - * PageInfo pageInfo = new PageInfo.Builder(new Rect(0, 0, 100, 100), 1).create(); + * // create a page description + * PageInfo pageInfo = new PageInfo.Builder(100, 100, 1).create(); * * // start a page * Page page = document.startPage(pageInfo); -- cgit v1.2.3 From 42bec243c0ea5df799bdea4a27ad1e6115fe66f3 Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Fri, 19 Jun 2020 14:47:41 -0700 Subject: Remove unnecessarily @System/TestApi annotations We can't expose APIs if the enclosing class is hidden, so these annotations are redundant. We need to remove them so that we can enable the check. Exempt-From-Owner-Approval:Cherry-pick from goog/master Bug: 159121253 Test: treehugger (i.e. this shouldn't trigger "API has changed" error.) Merged-in: Ie1841a670bdf6c6f4b25a1fc5deed8ec2d18cda2 Change-Id: Ie1841a670bdf6c6f4b25a1fc5deed8ec2d18cda2 --- graphics/java/android/graphics/GraphicsStatsService.java | 2 -- 1 file changed, 2 deletions(-) (limited to 'graphics') diff --git a/graphics/java/android/graphics/GraphicsStatsService.java b/graphics/java/android/graphics/GraphicsStatsService.java index 8dfd6ee92a9a..2d6848b618a1 100644 --- a/graphics/java/android/graphics/GraphicsStatsService.java +++ b/graphics/java/android/graphics/GraphicsStatsService.java @@ -16,7 +16,6 @@ package android.graphics; -import android.annotation.SystemApi; import android.app.AlarmManager; import android.app.AppOpsManager; import android.content.Context; @@ -100,7 +99,6 @@ public class GraphicsStatsService extends IGraphicsStats.Stub { private Handler mWriteOutHandler; private boolean mRotateIsScheduled = false; - @SystemApi public GraphicsStatsService(Context context) { mContext = context; mAppOps = context.getSystemService(AppOpsManager.class); -- cgit v1.2.3