Hide media details on lock screen

Media data will only be available when dozing to avoid duplication
on the notification shade.

Test: manual
Test: atest KeyguardSliceProviderTest
Bug: 111405682
Change-Id: I5e057496aa36c912293be54a4abfa62667b96db3
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index 6a0e8ad..c4c8bc7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -50,9 +50,9 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.policy.NextAlarmController;
 import com.android.systemui.statusbar.policy.NextAlarmControllerImpl;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -68,7 +68,7 @@
  */
 public class KeyguardSliceProvider extends SliceProvider implements
         NextAlarmController.NextAlarmChangeCallback, ZenModeController.Callback,
-        NotificationMediaManager.MediaListener {
+        NotificationMediaManager.MediaListener, StatusBarStateController.StateListener {
 
     private static final StyleSpan BOLD_STYLE = new StyleSpan(Typeface.BOLD);
     public static final String KEYGUARD_SLICE_URI = "content://com.android.systemui.keyguard/main";
@@ -109,7 +109,9 @@
     private AlarmManager.AlarmClockInfo mNextAlarmInfo;
     private PendingIntent mPendingIntent;
     protected NotificationMediaManager mMediaManager;
+    private StatusBarStateController mStatusBarStateController;
     protected MediaMetadata mMediaMetaData;
+    protected boolean mDozing;
 
     /**
      * Receiver responsible for time ticking and updating the date format.
@@ -167,9 +169,20 @@
         mMediaUri = Uri.parse(KEYGUARD_MEDIA_URI);
     }
 
-    public void initDependencies() {
-        mMediaManager = Dependency.get(NotificationMediaManager.class);
+    /**
+     * Initialize dependencies that don't exist during {@link android.content.ContentProvider}
+     * instantiation.
+     *
+     * @param mediaManager {@link NotificationMediaManager} singleton.
+     * @param statusBarStateController {@link StatusBarStateController} singleton.
+     */
+    public void initDependencies(
+            NotificationMediaManager mediaManager,
+            StatusBarStateController statusBarStateController) {
+        mMediaManager = mediaManager;
         mMediaManager.addCallback(this);
+        mStatusBarStateController = statusBarStateController;
+        mStatusBarStateController.addCallback(this);
     }
 
     @AnyThread
@@ -179,7 +192,7 @@
         Slice slice;
         synchronized (this) {
             ListBuilder builder = new ListBuilder(getContext(), mSliceUri, ListBuilder.INFINITY);
-            if (mMediaMetaData != null) {
+            if (needsMediaLocked()) {
                 addMediaLocked(builder);
             } else {
                 builder.addRow(new RowBuilder(mDateUri).setTitle(mLastText));
@@ -193,6 +206,10 @@
         return slice;
     }
 
+    protected boolean needsMediaLocked() {
+        return mMediaMetaData != null && mDozing;
+    }
+
     protected void addMediaLocked(ListBuilder listBuilder) {
         if (mMediaMetaData != null) {
             SpannableStringBuilder builder = new SpannableStringBuilder();
@@ -209,7 +226,7 @@
             }
 
             RowBuilder mediaBuilder = new RowBuilder(mMediaUri).setTitle(builder);
-            Icon notificationIcon = mMediaManager.getMediaIcon();
+            Icon notificationIcon = mMediaManager == null ? null : mMediaManager.getMediaIcon();
             if (notificationIcon != null) {
                 IconCompat icon = IconCompat.createFromIcon(notificationIcon);
                 mediaBuilder.addEndItem(icon, ListBuilder.ICON_IMAGE);
@@ -389,13 +406,35 @@
 
     @Override
     public void onMetadataChanged(MediaMetadata metadata) {
+        final boolean notify;
         synchronized (this) {
+            boolean neededMedia = needsMediaLocked();
             mMediaMetaData = metadata;
+            notify = neededMedia != needsMediaLocked();
         }
-        notifyChange();
+        if (notify) {
+            notifyChange();
+        }
     }
 
     protected void notifyChange() {
         mContentResolver.notifyChange(mSliceUri, null /* observer */);
     }
+
+    @Override
+    public void onDozingChanged(boolean isDozing) {
+        final boolean notify;
+        synchronized (this) {
+            boolean neededMedia = needsMediaLocked();
+            mDozing = isDozing;
+            notify = neededMedia != needsMediaLocked();
+        }
+        if (notify) {
+            notifyChange();
+        }
+    }
+
+    @Override
+    public void onStateChanged(int newState) {
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index e1a6cd3..b97e8b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -647,7 +647,7 @@
         mBubbleController.setExpandListener(mBubbleExpandListener);
         KeyguardSliceProvider sliceProvider = KeyguardSliceProvider.getAttachedInstance();
         if (sliceProvider != null) {
-            sliceProvider.initDependencies();
+            sliceProvider.initDependencies(mMediaManager, mStatusBarStateController);
         } else {
             Log.w(TAG, "Cannot init KeyguardSliceProvider dependencies");
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
index a8ff0b2..cfc19ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
@@ -44,6 +45,7 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.StatusBarStateController;
 
 import org.junit.Assert;
 import org.junit.Before;
@@ -67,6 +69,8 @@
     private AlarmManager mAlarmManager;
     @Mock
     private NotificationMediaManager mNotificationMediaManager;
+    @Mock
+    private StatusBarStateController mStatusBarStateController;
     private TestableKeyguardSliceProvider mProvider;
     private boolean mIsZenMode;
 
@@ -76,7 +80,7 @@
         mIsZenMode = false;
         mProvider = new TestableKeyguardSliceProvider();
         mProvider.attachInfo(getContext(), null);
-        mProvider.initDependencies();
+        mProvider.initDependencies(mNotificationMediaManager, mStatusBarStateController);
         SliceProvider.setSpecs(new HashSet<>(Arrays.asList(SliceSpecs.LIST)));
     }
 
@@ -98,6 +102,7 @@
     @Test
     public void onBindSlice_readsMedia() {
         MediaMetadata metadata = mock(MediaMetadata.class);
+        mProvider.onDozingChanged(true);
         mProvider.onMetadataChanged(metadata);
         mProvider.onBindSlice(mProvider.getUri());
         verify(metadata).getText(eq(MediaMetadata.METADATA_KEY_TITLE));
@@ -162,7 +167,31 @@
     @Test
     public void onMetadataChanged_updatesSlice() {
         mProvider.onMetadataChanged(mock(MediaMetadata.class));
+        mProvider.onDozingChanged(true);
         verify(mContentResolver).notifyChange(eq(mProvider.getUri()), eq(null));
+
+        // Hides after waking up
+        reset(mContentResolver);
+        mProvider.onDozingChanged(false);
+        verify(mContentResolver).notifyChange(eq(mProvider.getUri()), eq(null));
+
+        // And won't update slice if device is awake
+        reset(mContentResolver);
+        mProvider.onMetadataChanged(mock(MediaMetadata.class));
+        verify(mContentResolver, never()).notifyChange(eq(mProvider.getUri()), eq(null));
+    }
+
+    @Test
+    public void onDozingChanged_updatesSliceIfMedia() {
+        // Show media when dozing
+        mProvider.onMetadataChanged(mock(MediaMetadata.class));
+        mProvider.onDozingChanged(true);
+        verify(mContentResolver).notifyChange(eq(mProvider.getUri()), eq(null));
+
+        // Do not notify again if nothing changed
+        reset(mContentResolver);
+        mProvider.onDozingChanged(true);
+        verify(mContentResolver, never()).notifyChange(eq(mProvider.getUri()), eq(null));
     }
 
     private class TestableKeyguardSliceProvider extends KeyguardSliceProvider {
@@ -201,11 +230,6 @@
         protected String getFormattedDateLocked() {
             return super.getFormattedDateLocked() + mCounter++;
         }
-
-        @Override
-        public void initDependencies() {
-            mMediaManager = mNotificationMediaManager;
-        }
     }
 
 }