diff options
7 files changed, 101 insertions, 21 deletions
diff --git a/packages/Keyguard/res/layout/keyguard_transport_control_view.xml b/packages/Keyguard/res/layout/keyguard_transport_control_view.xml index 7e36f9f..801999a 100644 --- a/packages/Keyguard/res/layout/keyguard_transport_control_view.xml +++ b/packages/Keyguard/res/layout/keyguard_transport_control_view.xml @@ -22,22 +22,16 @@ android:gravity="center_horizontal" android:id="@+id/keyguard_transport_control"> - <!-- FrameLayout used as scrim to show between album art and buttons --> - <FrameLayout + <!-- Use ImageView for its cropping features; otherwise could be android:background --> + <ImageView + android:id="@+id/albumart" android:layout_width="match_parent" android:layout_height="match_parent" - android:foreground="@drawable/ic_lockscreen_player_background" - android:contentDescription="@string/keygaurd_accessibility_media_controls"> - <!-- Use ImageView for its cropping features; otherwise could be android:background --> - <ImageView - android:id="@+id/albumart" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="fill" - android:scaleType="centerCrop" - android:adjustViewBounds="false" - /> - </FrameLayout> + android:layout_gravity="fill" + android:scaleType="centerCrop" + android:adjustViewBounds="false" + android:contentDescription="@string/keygaurd_accessibility_media_controls" /> + <LinearLayout android:orientation="vertical" diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java index 07d4d1b..f4c16c6 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java @@ -1483,6 +1483,7 @@ public class KeyguardHostView extends KeyguardViewBase { if (DEBUGXPORT) Log.v(TAG, "remove transport"); mAppWidgetContainer.removeWidget(getOrCreateTransportControl()); mTransportControl = null; + KeyguardUpdateMonitor.getInstance(getContext()).dispatchSetBackground(null); } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java index 3208aff..2a5f979 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java @@ -36,6 +36,7 @@ import android.text.Spannable; import android.text.TextUtils; import android.text.style.ForegroundColorSpan; import android.util.AttributeSet; +import android.util.DisplayMetrics; import android.util.Log; import android.view.KeyEvent; import android.view.View; @@ -98,11 +99,9 @@ public class KeyguardTransportControlView extends FrameLayout implements OnClick case MSG_SET_ARTWORK: if (mClientGeneration == msg.arg1) { - if (mMetadata.bitmap != null) { - mMetadata.bitmap.recycle(); - } mMetadata.bitmap = (Bitmap) msg.obj; - mAlbumArt.setImageBitmap(mMetadata.bitmap); + KeyguardUpdateMonitor.getInstance(getContext()).dispatchSetBackground( + mMetadata.bitmap); } break; @@ -223,7 +222,8 @@ public class KeyguardTransportControlView extends FrameLayout implements OnClick @Override protected void onSizeChanged (int w, int h, int oldw, int oldh) { if (mAttached) { - int dim = Math.min(512, Math.max(w, h)); + final DisplayMetrics dm = getContext().getResources().getDisplayMetrics(); + int dim = Math.max(dm.widthPixels, dm.heightPixels); if (DEBUG) Log.v(TAG, "TCV uses bitmap size=" + dim); mAudioManager.remoteControlDisplayUsesBitmapSize(mIRCD, dim, dim); } @@ -300,7 +300,8 @@ public class KeyguardTransportControlView extends FrameLayout implements OnClick Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } - mAlbumArt.setImageBitmap(mMetadata.bitmap); + KeyguardUpdateMonitor.getInstance(getContext()).dispatchSetBackground( + mMetadata.bitmap); final int flags = mTransportControlFlags; setVisibilityBasedOnFlag(mBtnPrev, flags, RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS); setVisibilityBasedOnFlag(mBtnNext, flags, RemoteControlClient.FLAG_KEY_MEDIA_NEXT); diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java index 99062b8..734f517 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -407,6 +407,20 @@ public class KeyguardUpdateMonitor { return sInstance; } + /** + * IMPORTANT: Must be called from UI thread. + */ + public void dispatchSetBackground(Bitmap bmp) { + if (DEBUG) Log.d(TAG, "dispatchSetBackground"); + final int count = mCallbacks.size(); + for (int i = 0; i < count; i++) { + KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); + if (cb != null) { + cb.onSetBackground(bmp); + } + } + } + protected void handleSetGenerationId(int clientGeneration, boolean clearing, PendingIntent p) { mDisplayClientState.clientGeneration = clientGeneration; mDisplayClientState.clearing = clearing; diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java index b0511e5..e6dddab 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java @@ -17,6 +17,7 @@ package com.android.keyguard; import android.app.PendingIntent; import android.app.admin.DevicePolicyManager; +import android.graphics.Bitmap; import android.media.AudioManager; import com.android.internal.telephony.IccCardConstants; @@ -135,4 +136,8 @@ class KeyguardUpdateMonitorCallback { * Called when the emergency call button is pressed. */ void onEmergencyCallAction() { } + + public void onSetBackground(Bitmap bitmap) { + // THIS SPACE FOR RENT + } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java index b96ef88..2084a16 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java @@ -16,6 +16,9 @@ package com.android.keyguard; +import android.app.PendingIntent; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; import com.android.internal.policy.IKeyguardShowCallback; import com.android.internal.widget.LockPatternUtils; @@ -77,6 +80,14 @@ public class KeyguardViewManager { private boolean mScreenOn = false; private LockPatternUtils mLockPatternUtils; + private KeyguardUpdateMonitorCallback mBackgroundChanger = new KeyguardUpdateMonitorCallback() { + @Override + public void onSetBackground(Bitmap bmp) { + mKeyguardHost.setCustomBackground(bmp != null ? + new BitmapDrawable(mContext.getResources(), bmp) : null); + } + }; + public interface ShowListener { void onShown(IBinder windowToken); }; @@ -140,11 +151,25 @@ public class KeyguardViewManager { class ViewManagerHost extends FrameLayout { private static final int BACKGROUND_COLOR = 0x70000000; + private Drawable mCustomBackground; + // This is a faster way to draw the background on devices without hardware acceleration private final Drawable mBackgroundDrawable = new Drawable() { @Override public void draw(Canvas canvas) { - canvas.drawColor(BACKGROUND_COLOR, PorterDuff.Mode.SRC); + if (mCustomBackground != null) { + final Rect bounds = mCustomBackground.getBounds(); + final int vWidth = getWidth(); + final int vHeight = getHeight(); + + final int restore = canvas.save(); + canvas.translate(-(bounds.width() - vWidth) / 2, + -(bounds.height() - vHeight) / 2); + mCustomBackground.draw(canvas); + canvas.restoreToCount(restore); + } else { + canvas.drawColor(BACKGROUND_COLOR, PorterDuff.Mode.SRC); + } } @Override @@ -166,6 +191,40 @@ public class KeyguardViewManager { setBackground(mBackgroundDrawable); } + public void setCustomBackground(Drawable d) { + mCustomBackground = d; + if (d != null) { + d.setColorFilter(BACKGROUND_COLOR, PorterDuff.Mode.SRC_OVER); + } + computeCustomBackgroundBounds(); + invalidate(); + } + + private void computeCustomBackgroundBounds() { + if (mCustomBackground == null) return; // Nothing to do + if (!isLaidOut()) return; // We'll do this later + + final int bgWidth = mCustomBackground.getIntrinsicWidth(); + final int bgHeight = mCustomBackground.getIntrinsicHeight(); + final int vWidth = getWidth(); + final int vHeight = getHeight(); + + final float bgAspect = (float) bgWidth / bgHeight; + final float vAspect = (float) vWidth / vHeight; + + if (bgAspect > vAspect) { + mCustomBackground.setBounds(0, 0, (int) (vHeight * bgAspect), vHeight); + } else { + mCustomBackground.setBounds(0, 0, vWidth, (int) (vWidth / bgAspect)); + } + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + computeCustomBackgroundBounds(); + } + @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); @@ -239,9 +298,12 @@ public class KeyguardViewManager { lp.setTitle("Keyguard"); mWindowLayoutParams = lp; mViewManager.addView(mKeyguardHost, lp); + + KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mBackgroundChanger); } if (force || mKeyguardView == null) { + mKeyguardHost.setCustomBackground(null); mKeyguardHost.removeAllViews(); inflateKeyguardView(options); mKeyguardView.requestFocus(); @@ -428,6 +490,8 @@ public class KeyguardViewManager { public void run() { synchronized (KeyguardViewManager.this) { lastView.cleanUp(); + // Let go of any large bitmaps. + mKeyguardHost.setCustomBackground(null); mKeyguardHost.removeView(lastView); } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java index ca698ae..ec3eb15 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java @@ -16,6 +16,7 @@ package com.android.keyguard; +import android.graphics.Bitmap; import com.android.internal.policy.IKeyguardExitCallback; import com.android.internal.policy.IKeyguardShowCallback; import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; |