From fe7a18eeada1bf2553ca00afb71b372bd79666dd Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Tue, 19 Aug 2014 17:44:20 -0700 Subject: [PATCH 1/3] Make getOutline account for gravity BitmapDrawable bug:17112454 Also cleans up several subtle bugs in updating gravity/tile mode/insets. Change-Id: Idbd2c52e5f572d11b651f5e93d000535880f5708 --- .../graphics/drawable/BitmapDrawable.java | 78 +++++++++---------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index e52d778b11879..715da7eb0bf1c 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -81,14 +81,14 @@ public class BitmapDrawable extends Drawable { private static final int TILE_MODE_REPEAT = 1; private static final int TILE_MODE_MIRROR = 2; - private final Rect mDstRect = new Rect(); // Gravity.apply() sets this + private final Rect mDstRect = new Rect(); // #updateDstRectAndInsetsIfDirty() sets this private BitmapState mBitmapState; private PorterDuffColorFilter mTintFilter; private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT; - private boolean mApplyGravity; + private boolean mDstRectAndInsetsDirty = true; private boolean mMutated; // These are scaled to match the target density. @@ -96,7 +96,7 @@ public class BitmapDrawable extends Drawable { private int mBitmapHeight; /** Optical insets due to gravity. */ - private Insets mOpticalInsets = null; + private Insets mOpticalInsets = Insets.NONE; // Mirroring matrix for using with Shaders private Matrix mMirrorMatrix; @@ -285,7 +285,7 @@ public class BitmapDrawable extends Drawable { public void setGravity(int gravity) { if (mBitmapState.mGravity != gravity) { mBitmapState.mGravity = gravity; - mApplyGravity = true; + mDstRectAndInsetsDirty = true; invalidateSelf(); } } @@ -428,6 +428,7 @@ public class BitmapDrawable extends Drawable { state.mTileModeX = xmode; state.mTileModeY = ymode; state.mRebuildShader = true; + mDstRectAndInsetsDirty = true; invalidateSelf(); } } @@ -464,7 +465,7 @@ public class BitmapDrawable extends Drawable { @Override protected void onBoundsChange(Rect bounds) { - mApplyGravity = true; + mDstRectAndInsetsDirty = true; final Shader shader = mBitmapState.mPaint.getShader(); if (shader != null) { @@ -503,7 +504,6 @@ public class BitmapDrawable extends Drawable { } state.mRebuildShader = false; - copyBounds(mDstRect); } final int restoreAlpha; @@ -523,14 +523,10 @@ public class BitmapDrawable extends Drawable { clearColorFilter = false; } + updateDstRectAndInsetsIfDirty(); final Shader shader = paint.getShader(); final boolean needMirroring = needMirroring(); if (shader == null) { - if (mApplyGravity) { - applyGravity(); - mApplyGravity = false; - } - if (needMirroring) { canvas.save(); // Mirror the bitmap @@ -544,11 +540,6 @@ public class BitmapDrawable extends Drawable { canvas.restore(); } } else { - if (mApplyGravity) { - copyBounds(mDstRect); - mApplyGravity = false; - } - if (needMirroring) { // Mirror the bitmap updateMirrorMatrix(mDstRect.right - mDstRect.left); @@ -574,39 +565,46 @@ public class BitmapDrawable extends Drawable { } } + private void updateDstRectAndInsetsIfDirty() { + if (mDstRectAndInsetsDirty) { + if (mBitmapState.mTileModeX == null && mBitmapState.mTileModeY == null) { + final Rect bounds = getBounds(); + final int layoutDirection = getLayoutDirection(); + Gravity.apply(mBitmapState.mGravity, mBitmapWidth, mBitmapHeight, + bounds, mDstRect, layoutDirection); + + final int left = mDstRect.left - bounds.left; + final int top = mDstRect.top - bounds.top; + final int right = bounds.right - mDstRect.right; + final int bottom = bounds.bottom - mDstRect.bottom; + mOpticalInsets = Insets.of(left, top, right, bottom); + } else { + copyBounds(mDstRect); + mOpticalInsets = Insets.NONE; + } + } + mDstRectAndInsetsDirty = false; + } + /** * @hide */ @Override public Insets getOpticalInsets() { - if (mApplyGravity && mBitmapState.mPaint.getShader() == null) { - applyGravity(); - mApplyGravity = false; - } - return mOpticalInsets == null ? Insets.NONE : mOpticalInsets; - } - - private void applyGravity() { - final Rect bounds = getBounds(); - final int layoutDirection = getLayoutDirection(); - Gravity.apply(mBitmapState.mGravity, mBitmapWidth, mBitmapHeight, - bounds, mDstRect, layoutDirection); - - final int left = mDstRect.left - bounds.left; - final int top = mDstRect.top - bounds.top; - final int right = bounds.right - mDstRect.right; - final int bottom = bounds.bottom - mDstRect.bottom; - mOpticalInsets = Insets.of(left, top, right, bottom); + updateDstRectAndInsetsIfDirty(); + return mOpticalInsets; } @Override public void getOutline(@NonNull Outline outline) { - super.getOutline(outline); - if (mBitmapState.mBitmap == null || mBitmapState.mBitmap.hasAlpha()) { - // Only opaque Bitmaps can report a non-0 alpha, - // since only they are guaranteed to fill their bounds - outline.setAlpha(0.0f); - } + updateDstRectAndInsetsIfDirty(); + outline.setRect(mDstRect); + + // Only opaque Bitmaps can report a non-0 alpha, + // since only they are guaranteed to fill their bounds + boolean opaqueOverShape = mBitmapState.mBitmap != null + && !mBitmapState.mBitmap.hasAlpha(); + outline.setAlpha(opaqueOverShape ? getAlpha() / 255.0f : 0.0f); } @Override From f56885d413b9910a414716c4652c26f888dac316 Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Fri, 8 Aug 2014 10:46:03 -0700 Subject: [PATCH 2/3] Add outlineProvider attribute bug:16871683 Change-Id: Iae9326c41872ac03d40ebeec6257522a34cbe1ff --- api/current.txt | 3 ++ core/java/android/view/View.java | 34 ++++++++++++++----- .../android/view/ViewOutlineProvider.java | 29 ++++++++++++++++ core/res/res/values/attrs.xml | 13 +++++++ core/res/res/values/public.xml | 1 + 5 files changed, 72 insertions(+), 8 deletions(-) diff --git a/api/current.txt b/api/current.txt index b2106d24b4b39..3faf5b91041bc 100644 --- a/api/current.txt +++ b/api/current.txt @@ -930,6 +930,7 @@ package android { field public static final int orderingFromXml = 16843239; // 0x10101e7 field public static final int orientation = 16842948; // 0x10100c4 field public static final int outAnimation = 16843128; // 0x1010178 + field public static final int outlineProvider = 16843961; // 0x10104b9 field public static final int overScrollFooter = 16843459; // 0x10102c3 field public static final int overScrollHeader = 16843458; // 0x10102c2 field public static final int overScrollMode = 16843457; // 0x10102c1 @@ -35193,6 +35194,8 @@ package android.view { ctor public ViewOutlineProvider(); method public abstract void getOutline(android.view.View, android.graphics.Outline); field public static final android.view.ViewOutlineProvider BACKGROUND; + field public static final android.view.ViewOutlineProvider BOUNDS; + field public static final android.view.ViewOutlineProvider PADDED_BOUNDS; } public class ViewOverlay { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 3adc41a0e86d5..f17daafca6078 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -4047,6 +4047,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mBackgroundTintMode = Drawable.parseTintMode(a.getInt( R.styleable.View_backgroundTintMode, -1), mBackgroundTintMode); break; + case R.styleable.View_outlineProvider: + setOutlineProviderFromAttribute(a.getInt(R.styleable.View_outlineProvider, + PROVIDER_BACKGROUND)); + break; } } @@ -10823,14 +10827,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } - /** - * Deprecated, pending removal - * - * @hide - */ - @Deprecated - public void setOutline(@Nullable Outline outline) {} - /** * Returns whether the Outline should be used to clip the contents of the View. *

@@ -10860,6 +10856,28 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } + // correspond to the enum values of View_outlineProvider + private static final int PROVIDER_BACKGROUND = 0; + private static final int PROVIDER_NONE = 1; + private static final int PROVIDER_BOUNDS = 2; + private static final int PROVIDER_PADDED_BOUNDS = 3; + private void setOutlineProviderFromAttribute(int providerInt) { + switch (providerInt) { + case PROVIDER_BACKGROUND: + setOutlineProvider(ViewOutlineProvider.BACKGROUND); + break; + case PROVIDER_NONE: + setOutlineProvider(null); + break; + case PROVIDER_BOUNDS: + setOutlineProvider(ViewOutlineProvider.BOUNDS); + break; + case PROVIDER_PADDED_BOUNDS: + setOutlineProvider(ViewOutlineProvider.PADDED_BOUNDS); + break; + } + } + /** * Sets the {@link ViewOutlineProvider} of the view, which generates the Outline that defines * the shape of the shadow it casts, and enables outline clipping. diff --git a/core/java/android/view/ViewOutlineProvider.java b/core/java/android/view/ViewOutlineProvider.java index 170c5d8149cc1..a1a02f67ff5bc 100644 --- a/core/java/android/view/ViewOutlineProvider.java +++ b/core/java/android/view/ViewOutlineProvider.java @@ -43,6 +43,35 @@ public abstract class ViewOutlineProvider { } }; + /** + * Maintains the outline of the View to match its rectangular bounds, + * at 1.0f alpha. + * + * This can be used to enable Views that are opaque but lacking a background cast a shadow. + */ + public static final ViewOutlineProvider BOUNDS = new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRect(0, 0, view.getWidth(), view.getHeight()); + } + }; + + /** + * Maintains the outline of the View to match its rectangular padded bounds, + * at 1.0f alpha. + * + * This can be used to enable Views that are opaque but lacking a background cast a shadow. + */ + public static final ViewOutlineProvider PADDED_BOUNDS = new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRect(view.getPaddingLeft(), + view.getPaddingTop(), + view.getWidth() - view.getPaddingRight(), + view.getHeight() - view.getPaddingBottom()); + } + }; + /** * Called to get the provider to populate the Outline. * diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index f9ea5d8a0cfbf..08aaa6aee8212 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2513,6 +2513,19 @@ result to valid color values. Saturate(S + D) --> + + + + + + + + + + + + + diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 7ade51d9c1ad2..ed66c652bb742 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2272,6 +2272,7 @@ + From 4b9e324b6f59f49a8ca4bc4cd8b38a5ea005a6b2 Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Wed, 20 Aug 2014 23:36:25 +0200 Subject: [PATCH 3/3] Only run TrustAgentServices for users with secure keyguards Bug: 17107213 Change-Id: Ic9e93862c722ebc529f5b2010b9cea941f569ce7 --- .../java/com/android/internal/widget/LockPatternUtils.java | 7 +++++++ .../java/com/android/server/trust/TrustManagerService.java | 2 ++ 2 files changed, 9 insertions(+) diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index ece3e9d5e503b..97b5a38fcd3f4 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -479,6 +479,7 @@ public class LockPatternUtils { saveLockPattern(null); setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED); setLong(PASSWORD_TYPE_ALTERNATE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED); + onAfterChangingPassword(); } /** @@ -565,6 +566,7 @@ public class LockPatternUtils { dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0, userId); } + onAfterChangingPassword(); } catch (RemoteException re) { Log.e(TAG, "Couldn't save lock pattern " + re); } @@ -844,6 +846,7 @@ public class LockPatternUtils { DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0, userHandle); } + onAfterChangingPassword(); } catch (RemoteException re) { // Cant do much Log.e(TAG, "Unable to save lock password " + re); @@ -1542,4 +1545,8 @@ public class LockPatternUtils { public void requireCredentialEntry(int userId) { getTrustManager().reportRequireCredentialEntry(userId); } + + private void onAfterChangingPassword() { + getTrustManager().reportEnabledTrustAgentsChanged(getCurrentOrCallingUserId()); + } } diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 490536e6e8c33..98c3381f27fff 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -168,6 +168,8 @@ public class TrustManagerService extends SystemService { obsoleteAgents.addAll(mActiveAgents); for (UserInfo userInfo : userInfos) { + if (lockPatternUtils.getKeyguardStoredPasswordQuality() + == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) continue; DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager(); int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id); final boolean disableTrustAgents =