Loading core/api/system-current.txt +12 −0 Original line number Diff line number Diff line Loading @@ -2578,6 +2578,18 @@ package android.debug { } package android.graphics.drawable { public final class BackgroundBlurDrawable extends android.graphics.drawable.Drawable { ctor @RequiresPermission(android.Manifest.permission.USE_BACKGROUND_BLUR) public BackgroundBlurDrawable(); method public void setBlurRadius(int); method public void setColor(@ColorInt int); method public void setCornerRadius(float); method public void setCornerRadius(float, float, float, float); } } package android.hardware { public final class Sensor { Loading core/java/android/view/View.java +20 −0 Original line number Diff line number Diff line Loading @@ -9802,6 +9802,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } private void notifyAttachForDrawables() { if (mBackground != null) mBackground.onAttached(this); if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) { mForegroundInfo.mDrawable.onAttached(this); } } private void notifyDetachForDrawables() { if (mBackground != null) mBackground.onDetached(this); if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) { mForegroundInfo.mDrawable.onDetached(this); } } private void setNotifiedContentCaptureAppeared() { mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED; mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED; Loading Loading @@ -20653,6 +20667,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, notifyEnterOrExitForAutoFillIfNeeded(true); notifyAppearedOrDisappearedForContentCaptureIfNeeded(true); notifyAttachForDrawables(); } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) Loading Loading @@ -20702,6 +20717,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, notifyEnterOrExitForAutoFillIfNeeded(false); notifyAppearedOrDisappearedForContentCaptureIfNeeded(false); notifyDetachForDrawables(); } /** Loading Loading @@ -23830,6 +23846,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mBackground != null) { if (isAttachedToWindow()) { mBackground.setVisible(false, false); mBackground.onDetached(this); } mBackground.setCallback(null); unscheduleDrawable(mBackground); Loading Loading @@ -23879,6 +23896,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, background.setState(getDrawableState()); } if (isAttachedToWindow()) { background.onAttached(this); background.setVisible(getWindowVisibility() == VISIBLE && isShown(), false); } Loading Loading @@ -24111,6 +24129,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mForegroundInfo.mDrawable != null) { if (isAttachedToWindow()) { mForegroundInfo.mDrawable.setVisible(false, false); mForegroundInfo.mDrawable.onDetached(this); } mForegroundInfo.mDrawable.setCallback(null); unscheduleDrawable(mForegroundInfo.mDrawable); Loading @@ -24128,6 +24147,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } applyForegroundTint(); if (isAttachedToWindow()) { foreground.onAttached(this); foreground.setVisible(getWindowVisibility() == VISIBLE && isShown(), false); } // Set callback last, since the view may still be initializing. core/java/android/view/ViewRootImpl.java +9 −8 Original line number Diff line number Diff line Loading @@ -117,6 +117,7 @@ import android.graphics.RecordingCanvas; import android.graphics.Rect; import android.graphics.Region; import android.graphics.RenderNode; import android.graphics.drawable.BackgroundBlurDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.hardware.display.DisplayManager; Loading Loading @@ -188,7 +189,6 @@ import android.window.ClientWindowFrames; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.drawable.BackgroundBlurDrawable; import com.android.internal.inputmethod.InputMethodDebug; import com.android.internal.os.IResultReceiver; import com.android.internal.os.SomeArgs; Loading Loading @@ -671,6 +671,14 @@ public final class ViewRootImpl implements ViewParent, private final BackgroundBlurDrawable.Aggregator mBlurRegionAggregator = new BackgroundBlurDrawable.Aggregator(this); /** * @return {@link BackgroundBlurDrawable.Aggregator} for this instance. */ @NonNull public BackgroundBlurDrawable.Aggregator getBlurRegionAggregator() { return mBlurRegionAggregator; } /** * @return {@link ImeFocusController} for this instance. */ Loading Loading @@ -10048,13 +10056,6 @@ public final class ViewRootImpl implements ViewParent, } } /** * Creates a background blur drawable for the backing {@link Surface}. */ public BackgroundBlurDrawable createBackgroundBlurDrawable() { return mBlurRegionAggregator.createBackgroundBlurDrawable(mContext); } @Override public void onDescendantUnbufferedRequested() { mUnbufferedInputSource = mView.mUnbufferedInputSource; Loading core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java→graphics/java/android/graphics/drawable/BackgroundBlurDrawable.java +80 −27 Original line number Diff line number Diff line Loading @@ -14,12 +14,13 @@ * limitations under the License. */ package com.android.internal.graphics.drawable; package android.graphics.drawable; import android.annotation.ColorInt; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; Loading @@ -30,59 +31,71 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RenderNode; import android.graphics.drawable.Drawable; import android.util.ArrayMap; import android.util.Log; import android.view.SurfaceControl; import android.view.View; import android.view.ViewRootImpl; import com.android.internal.R; /** * A drawable that keeps track of a blur region, pokes a hole under it, and propagates its state * to SurfaceFlinger. * * @hide */ @SystemApi public final class BackgroundBlurDrawable extends Drawable { private static final String TAG = BackgroundBlurDrawable.class.getSimpleName(); private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private final Aggregator mAggregator; private final RenderNode mRenderNode; private final Paint mPaint = new Paint(); private final Path mRectPath = new Path(); private final float[] mTmpRadii = new float[8]; private final SurfaceControl.BlurRegion mBlurRegion = new SurfaceControl.BlurRegion(); private Aggregator mAggregator; // This will be called from a thread pool. private final RenderNode.PositionUpdateListener mPositionUpdateListener = new RenderNode.PositionUpdateListener() { @Override public void positionChanged(long frameNumber, int left, int top, int right, int bottom) { if (mAggregator == null) { mBlurRegion.rect.set(left, top, right, bottom); } else { synchronized (mAggregator) { mBlurRegion.rect.set(left, top, right, bottom); mAggregator.onBlurRegionUpdated(BackgroundBlurDrawable.this, mBlurRegion); } } } @Override public void positionLost(long frameNumber) { if (mAggregator == null) { mBlurRegion.rect.setEmpty(); } else { synchronized (mAggregator) { mBlurRegion.rect.setEmpty(); mAggregator.onBlurRegionUpdated(BackgroundBlurDrawable.this, mBlurRegion); } } } }; private BackgroundBlurDrawable(Aggregator aggregator) { mAggregator = aggregator; @RequiresPermission(android.Manifest.permission.USE_BACKGROUND_BLUR) public BackgroundBlurDrawable() { mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); mPaint.setColor(Color.TRANSPARENT); mRenderNode = new RenderNode("BackgroundBlurDrawable"); mRenderNode.addPositionUpdateListener(mPositionUpdateListener); } /** * @hide */ @Override public void draw(@NonNull Canvas canvas) { if (mRectPath.isEmpty() || !isVisible() || getAlpha() == 0) { Loading @@ -100,6 +113,9 @@ public final class BackgroundBlurDrawable extends Drawable { mPaint.setColor(color); } /** * @hide */ @Override public boolean setVisible(boolean visible, boolean restart) { boolean changed = super.setVisible(visible, restart); Loading @@ -109,6 +125,9 @@ public final class BackgroundBlurDrawable extends Drawable { return changed; } /** * @hide */ @Override public void setAlpha(int alpha) { mBlurRegion.alpha = alpha / 255f; Loading Loading @@ -139,12 +158,12 @@ public final class BackgroundBlurDrawable extends Drawable { */ public void setCornerRadius(float cornerRadiusTL, float cornerRadiusTR, float cornerRadiusBL, float cornerRadiusBR) { synchronized (mAggregator) { maybeRunSynchronized(() -> { mBlurRegion.cornerRadiusTL = cornerRadiusTL; mBlurRegion.cornerRadiusTR = cornerRadiusTR; mBlurRegion.cornerRadiusBL = cornerRadiusBL; mBlurRegion.cornerRadiusBR = cornerRadiusBR; } }); updatePath(); invalidateSelf(); } Loading @@ -157,12 +176,13 @@ public final class BackgroundBlurDrawable extends Drawable { } private void updatePath() { synchronized (mAggregator) { maybeRunSynchronized(() -> { mTmpRadii[0] = mTmpRadii[1] = mBlurRegion.cornerRadiusTL; mTmpRadii[2] = mTmpRadii[3] = mBlurRegion.cornerRadiusTR; mTmpRadii[4] = mTmpRadii[5] = mBlurRegion.cornerRadiusBL; mTmpRadii[6] = mTmpRadii[7] = mBlurRegion.cornerRadiusBR; } }); mRectPath.reset(); if (getAlpha() == 0 || !isVisible()) { return; Loading @@ -172,19 +192,62 @@ public final class BackgroundBlurDrawable extends Drawable { Path.Direction.CW); } /** * @hide */ @Override public void setColorFilter(@Nullable ColorFilter colorFilter) { throw new IllegalArgumentException("not implemented"); } /** * @hide */ @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } /** * @hide */ @Override public void onAttached(@NonNull View v) { super.onAttached(v); mAggregator = v.getViewRootImpl().getBlurRegionAggregator(); } /** * @hide */ @Override public void onDetached(@NonNull View v) { super.onDetached(v); mAggregator = null; } /** * The Aggregator is called from the RenderThread to aggregate all blur regions and send them * to SurfaceFlinger. Since the BackgroundBlurDrawable could be updated at any time from the * main thread, we need to synchronize the two threads. The BackgroundBlurDrawable may be * instantiated before the ViewRootImpl is created, i.e. before the Aggregator is created. * In that case, updates are not synchronized. */ private void maybeRunSynchronized(Runnable r) { if (mAggregator == null) { r.run(); } else { synchronized (mAggregator) { r.run(); } } } /** * Responsible for keeping track of all blur regions of a {@link ViewRootImpl} and posting a * message when it's time to propagate them. * * @hide */ public static final class Aggregator { Loading @@ -198,16 +261,6 @@ public final class BackgroundBlurDrawable extends Drawable { mViewRoot = viewRoot; } /** * Creates a blur region with default radius. */ public BackgroundBlurDrawable createBackgroundBlurDrawable(Context context) { BackgroundBlurDrawable drawable = new BackgroundBlurDrawable(this); drawable.setBlurRadius(context.getResources().getDimensionPixelSize( R.dimen.default_background_blur_radius)); return drawable; } /** * Called from RenderThread only, already locked. * @param drawable Loading graphics/java/android/graphics/drawable/Drawable.java +18 −0 Original line number Diff line number Diff line Loading @@ -1464,6 +1464,24 @@ public abstract class Drawable { mVisible = attrs.getBoolean(visibleAttr, mVisible); } /** * Notifies the drawable that it has been attached. * * @param v The view that it is attached to * @hide */ public void onAttached(View v) { } /** * Notifies the drawable that it has been detached. * * @param v The view that it is detached from * @hide */ public void onDetached(View v) { } /** * Sets the source override density for this Drawable. If non-zero, this density is to be used * for any calls to {@link Resources#getDrawableForDensity(int, int, Theme)} or Loading Loading
core/api/system-current.txt +12 −0 Original line number Diff line number Diff line Loading @@ -2578,6 +2578,18 @@ package android.debug { } package android.graphics.drawable { public final class BackgroundBlurDrawable extends android.graphics.drawable.Drawable { ctor @RequiresPermission(android.Manifest.permission.USE_BACKGROUND_BLUR) public BackgroundBlurDrawable(); method public void setBlurRadius(int); method public void setColor(@ColorInt int); method public void setCornerRadius(float); method public void setCornerRadius(float, float, float, float); } } package android.hardware { public final class Sensor { Loading
core/java/android/view/View.java +20 −0 Original line number Diff line number Diff line Loading @@ -9802,6 +9802,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } private void notifyAttachForDrawables() { if (mBackground != null) mBackground.onAttached(this); if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) { mForegroundInfo.mDrawable.onAttached(this); } } private void notifyDetachForDrawables() { if (mBackground != null) mBackground.onDetached(this); if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) { mForegroundInfo.mDrawable.onDetached(this); } } private void setNotifiedContentCaptureAppeared() { mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED; mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED; Loading Loading @@ -20653,6 +20667,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, notifyEnterOrExitForAutoFillIfNeeded(true); notifyAppearedOrDisappearedForContentCaptureIfNeeded(true); notifyAttachForDrawables(); } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) Loading Loading @@ -20702,6 +20717,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, notifyEnterOrExitForAutoFillIfNeeded(false); notifyAppearedOrDisappearedForContentCaptureIfNeeded(false); notifyDetachForDrawables(); } /** Loading Loading @@ -23830,6 +23846,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mBackground != null) { if (isAttachedToWindow()) { mBackground.setVisible(false, false); mBackground.onDetached(this); } mBackground.setCallback(null); unscheduleDrawable(mBackground); Loading Loading @@ -23879,6 +23896,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, background.setState(getDrawableState()); } if (isAttachedToWindow()) { background.onAttached(this); background.setVisible(getWindowVisibility() == VISIBLE && isShown(), false); } Loading Loading @@ -24111,6 +24129,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mForegroundInfo.mDrawable != null) { if (isAttachedToWindow()) { mForegroundInfo.mDrawable.setVisible(false, false); mForegroundInfo.mDrawable.onDetached(this); } mForegroundInfo.mDrawable.setCallback(null); unscheduleDrawable(mForegroundInfo.mDrawable); Loading @@ -24128,6 +24147,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } applyForegroundTint(); if (isAttachedToWindow()) { foreground.onAttached(this); foreground.setVisible(getWindowVisibility() == VISIBLE && isShown(), false); } // Set callback last, since the view may still be initializing.
core/java/android/view/ViewRootImpl.java +9 −8 Original line number Diff line number Diff line Loading @@ -117,6 +117,7 @@ import android.graphics.RecordingCanvas; import android.graphics.Rect; import android.graphics.Region; import android.graphics.RenderNode; import android.graphics.drawable.BackgroundBlurDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.hardware.display.DisplayManager; Loading Loading @@ -188,7 +189,6 @@ import android.window.ClientWindowFrames; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.drawable.BackgroundBlurDrawable; import com.android.internal.inputmethod.InputMethodDebug; import com.android.internal.os.IResultReceiver; import com.android.internal.os.SomeArgs; Loading Loading @@ -671,6 +671,14 @@ public final class ViewRootImpl implements ViewParent, private final BackgroundBlurDrawable.Aggregator mBlurRegionAggregator = new BackgroundBlurDrawable.Aggregator(this); /** * @return {@link BackgroundBlurDrawable.Aggregator} for this instance. */ @NonNull public BackgroundBlurDrawable.Aggregator getBlurRegionAggregator() { return mBlurRegionAggregator; } /** * @return {@link ImeFocusController} for this instance. */ Loading Loading @@ -10048,13 +10056,6 @@ public final class ViewRootImpl implements ViewParent, } } /** * Creates a background blur drawable for the backing {@link Surface}. */ public BackgroundBlurDrawable createBackgroundBlurDrawable() { return mBlurRegionAggregator.createBackgroundBlurDrawable(mContext); } @Override public void onDescendantUnbufferedRequested() { mUnbufferedInputSource = mView.mUnbufferedInputSource; Loading
core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java→graphics/java/android/graphics/drawable/BackgroundBlurDrawable.java +80 −27 Original line number Diff line number Diff line Loading @@ -14,12 +14,13 @@ * limitations under the License. */ package com.android.internal.graphics.drawable; package android.graphics.drawable; import android.annotation.ColorInt; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; Loading @@ -30,59 +31,71 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RenderNode; import android.graphics.drawable.Drawable; import android.util.ArrayMap; import android.util.Log; import android.view.SurfaceControl; import android.view.View; import android.view.ViewRootImpl; import com.android.internal.R; /** * A drawable that keeps track of a blur region, pokes a hole under it, and propagates its state * to SurfaceFlinger. * * @hide */ @SystemApi public final class BackgroundBlurDrawable extends Drawable { private static final String TAG = BackgroundBlurDrawable.class.getSimpleName(); private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private final Aggregator mAggregator; private final RenderNode mRenderNode; private final Paint mPaint = new Paint(); private final Path mRectPath = new Path(); private final float[] mTmpRadii = new float[8]; private final SurfaceControl.BlurRegion mBlurRegion = new SurfaceControl.BlurRegion(); private Aggregator mAggregator; // This will be called from a thread pool. private final RenderNode.PositionUpdateListener mPositionUpdateListener = new RenderNode.PositionUpdateListener() { @Override public void positionChanged(long frameNumber, int left, int top, int right, int bottom) { if (mAggregator == null) { mBlurRegion.rect.set(left, top, right, bottom); } else { synchronized (mAggregator) { mBlurRegion.rect.set(left, top, right, bottom); mAggregator.onBlurRegionUpdated(BackgroundBlurDrawable.this, mBlurRegion); } } } @Override public void positionLost(long frameNumber) { if (mAggregator == null) { mBlurRegion.rect.setEmpty(); } else { synchronized (mAggregator) { mBlurRegion.rect.setEmpty(); mAggregator.onBlurRegionUpdated(BackgroundBlurDrawable.this, mBlurRegion); } } } }; private BackgroundBlurDrawable(Aggregator aggregator) { mAggregator = aggregator; @RequiresPermission(android.Manifest.permission.USE_BACKGROUND_BLUR) public BackgroundBlurDrawable() { mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); mPaint.setColor(Color.TRANSPARENT); mRenderNode = new RenderNode("BackgroundBlurDrawable"); mRenderNode.addPositionUpdateListener(mPositionUpdateListener); } /** * @hide */ @Override public void draw(@NonNull Canvas canvas) { if (mRectPath.isEmpty() || !isVisible() || getAlpha() == 0) { Loading @@ -100,6 +113,9 @@ public final class BackgroundBlurDrawable extends Drawable { mPaint.setColor(color); } /** * @hide */ @Override public boolean setVisible(boolean visible, boolean restart) { boolean changed = super.setVisible(visible, restart); Loading @@ -109,6 +125,9 @@ public final class BackgroundBlurDrawable extends Drawable { return changed; } /** * @hide */ @Override public void setAlpha(int alpha) { mBlurRegion.alpha = alpha / 255f; Loading Loading @@ -139,12 +158,12 @@ public final class BackgroundBlurDrawable extends Drawable { */ public void setCornerRadius(float cornerRadiusTL, float cornerRadiusTR, float cornerRadiusBL, float cornerRadiusBR) { synchronized (mAggregator) { maybeRunSynchronized(() -> { mBlurRegion.cornerRadiusTL = cornerRadiusTL; mBlurRegion.cornerRadiusTR = cornerRadiusTR; mBlurRegion.cornerRadiusBL = cornerRadiusBL; mBlurRegion.cornerRadiusBR = cornerRadiusBR; } }); updatePath(); invalidateSelf(); } Loading @@ -157,12 +176,13 @@ public final class BackgroundBlurDrawable extends Drawable { } private void updatePath() { synchronized (mAggregator) { maybeRunSynchronized(() -> { mTmpRadii[0] = mTmpRadii[1] = mBlurRegion.cornerRadiusTL; mTmpRadii[2] = mTmpRadii[3] = mBlurRegion.cornerRadiusTR; mTmpRadii[4] = mTmpRadii[5] = mBlurRegion.cornerRadiusBL; mTmpRadii[6] = mTmpRadii[7] = mBlurRegion.cornerRadiusBR; } }); mRectPath.reset(); if (getAlpha() == 0 || !isVisible()) { return; Loading @@ -172,19 +192,62 @@ public final class BackgroundBlurDrawable extends Drawable { Path.Direction.CW); } /** * @hide */ @Override public void setColorFilter(@Nullable ColorFilter colorFilter) { throw new IllegalArgumentException("not implemented"); } /** * @hide */ @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } /** * @hide */ @Override public void onAttached(@NonNull View v) { super.onAttached(v); mAggregator = v.getViewRootImpl().getBlurRegionAggregator(); } /** * @hide */ @Override public void onDetached(@NonNull View v) { super.onDetached(v); mAggregator = null; } /** * The Aggregator is called from the RenderThread to aggregate all blur regions and send them * to SurfaceFlinger. Since the BackgroundBlurDrawable could be updated at any time from the * main thread, we need to synchronize the two threads. The BackgroundBlurDrawable may be * instantiated before the ViewRootImpl is created, i.e. before the Aggregator is created. * In that case, updates are not synchronized. */ private void maybeRunSynchronized(Runnable r) { if (mAggregator == null) { r.run(); } else { synchronized (mAggregator) { r.run(); } } } /** * Responsible for keeping track of all blur regions of a {@link ViewRootImpl} and posting a * message when it's time to propagate them. * * @hide */ public static final class Aggregator { Loading @@ -198,16 +261,6 @@ public final class BackgroundBlurDrawable extends Drawable { mViewRoot = viewRoot; } /** * Creates a blur region with default radius. */ public BackgroundBlurDrawable createBackgroundBlurDrawable(Context context) { BackgroundBlurDrawable drawable = new BackgroundBlurDrawable(this); drawable.setBlurRadius(context.getResources().getDimensionPixelSize( R.dimen.default_background_blur_radius)); return drawable; } /** * Called from RenderThread only, already locked. * @param drawable Loading
graphics/java/android/graphics/drawable/Drawable.java +18 −0 Original line number Diff line number Diff line Loading @@ -1464,6 +1464,24 @@ public abstract class Drawable { mVisible = attrs.getBoolean(visibleAttr, mVisible); } /** * Notifies the drawable that it has been attached. * * @param v The view that it is attached to * @hide */ public void onAttached(View v) { } /** * Notifies the drawable that it has been detached. * * @param v The view that it is detached from * @hide */ public void onDetached(View v) { } /** * Sets the source override density for this Drawable. If non-zero, this density is to be used * for any calls to {@link Resources#getDrawableForDensity(int, int, Theme)} or Loading