OSDN Git Service

Keyguard transport controls: fullscreen art
authorAdam Powell <adamp@google.com>
Sat, 28 Sep 2013 00:43:53 +0000 (17:43 -0700)
committerAdam Powell <adamp@google.com>
Sat, 28 Sep 2013 01:47:52 +0000 (18:47 -0700)
When the transport controls are active, set the relevant art as a
fullscreen background for the keyguard.

Change-Id: I1e8a87f242153a2a2c5bf94dbd15f0fd3e07dde3

packages/Keyguard/res/layout/keyguard_transport_control_view.xml
packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java
packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java

index 7e36f9f..801999a 100644 (file)
     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"
index 07d4d1b..f4c16c6 100644 (file)
@@ -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);
         }
     }
 
index 3208aff..2a5f979 100644 (file)
@@ -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);
index 99062b8..734f517 100644 (file)
@@ -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;
index b0511e5..e6dddab 100644 (file)
@@ -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
+    }
 }
index b96ef88..2084a16 100644 (file)
@@ -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);
                         }
                     }
index ca698ae..ec3eb15 100644 (file)
@@ -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;