Send AGSA the dismiss intent when user dismisses the recommendation
card or the reactivated media player (during the recommendation active
session).

Fixes: 195064048
Test: Local builds & MediaDataManagerTest

Change-Id: Iaecbd80d137e28fb4f8983bf45a283e028b6c067
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index c125612..b998fb5 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -75,6 +75,8 @@
     private static final String TAG = "MediaControlPanel";
 
     private static final float DISABLED_ALPHA = 0.38f;
+    private static final String EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME = "com.google"
+            + ".android.apps.gsa.staticplugins.opa.smartspace.ExportedSmartspaceTrampolineActivity";
     private static final String EXTRAS_SMARTSPACE_INTENT =
             "com.google.android.apps.gsa.smartspace.extra.SMARTSPACE_INTENT";
     private static final int MEDIA_RECOMMENDATION_ITEMS_PER_ROW = 3;
@@ -627,6 +629,22 @@
             closeGuts();
             mMediaDataManagerLazy.get().dismissSmartspaceRecommendation(
                     data.getTargetId(), MediaViewController.GUTS_ANIMATION_DURATION + 100L);
+
+            Intent dismissIntent = data.getDismissIntent();
+            if (dismissIntent == null) {
+                Log.w(TAG, "Cannot create dismiss action click action: "
+                        + "extras missing dismiss_intent.");
+                return;
+            }
+
+            if (dismissIntent.getComponent() != null
+                    && dismissIntent.getComponent().getClassName()
+                    .equals(EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME)) {
+                // Dismiss the card Smartspace data through Smartspace trampoline activity.
+                mContext.startActivity(dismissIntent);
+            } else {
+                mContext.sendBroadcast(dismissIntent);
+            }
         });
 
         mController = null;
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
index c8deb01..79206e8 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.media
 
+import android.content.Context
 import android.os.SystemProperties
 import android.util.Log
 import com.android.internal.annotations.VisibleForTesting
@@ -32,6 +33,8 @@
 
 private const val TAG = "MediaDataFilter"
 private const val DEBUG = true
+private const val EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME = ("com.google" +
+        ".android.apps.gsa.staticplugins.opa.smartspace.ExportedSmartspaceTrampolineActivity")
 private const val RESUMABLE_MEDIA_MAX_AGE_SECONDS_KEY = "resumable_media_max_age_seconds"
 
 /**
@@ -51,6 +54,7 @@
  * background users (e.g. timeouts).
  */
 class MediaDataFilter @Inject constructor(
+    private val context: Context,
     private val broadcastDispatcher: BroadcastDispatcher,
     private val mediaResumeListener: MediaResumeListener,
     private val lockscreenUserManager: NotificationLockscreenUserManager,
@@ -229,6 +233,18 @@
             mediaDataManager.setTimedOut(it, timedOut = true, forceUpdate = true)
         }
         if (smartspaceMediaData.isActive) {
+            val dismissIntent = smartspaceMediaData.dismissIntent
+            if (dismissIntent == null) {
+                Log.w(TAG, "Cannot create dismiss action click action: " +
+                        "extras missing dismiss_intent.")
+            } else if (dismissIntent.getComponent() != null &&
+                    dismissIntent.getComponent().getClassName()
+                    == EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME) {
+                // Dismiss the card Smartspace data through Smartspace trampoline activity.
+                context.startActivity(dismissIntent)
+            } else {
+                context.sendBroadcast(dismissIntent)
+            }
             smartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA.copy(
                 targetId = smartspaceMediaData.targetId, isValid = smartspaceMediaData.isValid)
         }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index ba99f5d..eacdab6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -76,12 +76,13 @@
 
 private const val TAG = "MediaDataManager"
 private const val DEBUG = true
+private const val EXTRAS_SMARTSPACE_DISMISS_INTENT_KEY = "dismiss_intent"
 
 private val LOADING = MediaData(-1, false, 0, null, null, null, null, null,
         emptyList(), emptyList(), "INVALID", null, null, null, true, null)
 @VisibleForTesting
 internal val EMPTY_SMARTSPACE_MEDIA_DATA = SmartspaceMediaData("INVALID", false, false,
-    "INVALID", null, emptyList(), 0)
+    "INVALID", null, emptyList(), null, 0)
 
 fun isMediaNotification(sbn: StatusBarNotification): Boolean {
     if (!sbn.notification.hasMediaSession()) {
@@ -883,12 +884,22 @@
         target: SmartspaceTarget,
         isActive: Boolean
     ): SmartspaceMediaData {
+        var dismissIntent: Intent? = null
+        if (target.baseAction != null && target.baseAction.extras != null) {
+            dismissIntent = target
+                .baseAction
+                .extras
+                .getParcelable(EXTRAS_SMARTSPACE_DISMISS_INTENT_KEY) as Intent
+        }
         packageName(target)?.let {
             return SmartspaceMediaData(target.smartspaceTargetId, isActive, true, it,
-                target.baseAction, target.iconGrid, 0)
+                target.baseAction, target.iconGrid,
+                dismissIntent, 0)
         }
         return EMPTY_SMARTSPACE_MEDIA_DATA
-            .copy(targetId = target.smartspaceTargetId, isActive = isActive)
+            .copy(targetId = target.smartspaceTargetId,
+                isActive = isActive,
+                dismissIntent = dismissIntent)
     }
 
     private fun packageName(target: SmartspaceTarget): String? {
diff --git a/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt b/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt
index 9ac1289..61fdefd 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.media
 
 import android.app.smartspace.SmartspaceAction
+import android.content.Intent
 
 /** State of a Smartspace media recommendations view. */
 data class SmartspaceMediaData(
@@ -45,6 +46,10 @@
      */
     val recommendations: List<SmartspaceAction>,
     /**
+     * Intent for the user's initiated dismissal.
+     */
+    val dismissIntent: Intent?,
+    /**
      * View's background color.
      */
     val backgroundColor: Int
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
index d879186..28aed20 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
@@ -86,7 +86,7 @@
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
-        mediaDataFilter = MediaDataFilter(broadcastDispatcher, mediaResumeListener,
+        mediaDataFilter = MediaDataFilter(context, broadcastDispatcher, mediaResumeListener,
                 lockscreenUserManager, executor, clock)
         mediaDataFilter.mediaDataManager = mediaDataManager
         mediaDataFilter.addListener(listener)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
index 5c3108c..47c5545 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
@@ -4,6 +4,7 @@
 import android.app.PendingIntent
 import android.app.smartspace.SmartspaceAction
 import android.app.smartspace.SmartspaceTarget
+import android.content.Intent
 import android.graphics.Bitmap
 import android.media.MediaDescription
 import android.media.MediaMetadata
@@ -51,6 +52,7 @@
 private const val SESSION_ARTIST = "artist"
 private const val SESSION_TITLE = "title"
 private const val USER_ID = 0
+private val DISMISS_INTENT = Intent().apply { action = "dismiss" }
 
 private fun <T> anyObject(): T {
     return Mockito.anyObject<T>()
@@ -83,6 +85,7 @@
     lateinit var smartspaceMediaDataProvider: SmartspaceMediaDataProvider
     @Mock lateinit var mediaSmartspaceTarget: SmartspaceTarget
     @Mock private lateinit var mediaRecommendationItem: SmartspaceAction
+    @Mock private lateinit var mediaSmartspaceBaseAction: SmartspaceAction
     lateinit var mediaDataManager: MediaDataManager
     lateinit var mediaNotification: StatusBarNotification
     @Captor lateinit var mediaDataCaptor: ArgumentCaptor<MediaData>
@@ -146,8 +149,12 @@
         // treat mediaSessionBasedFilter as a listener for testing.
         listener = mediaSessionBasedFilter
 
-        val recommendationExtras = Bundle()
-        recommendationExtras.putString("package_name", PACKAGE_NAME)
+        val recommendationExtras = Bundle().apply {
+            putString("package_name", PACKAGE_NAME)
+            putParcelable("dismiss_intent", DISMISS_INTENT)
+        }
+        whenever(mediaSmartspaceBaseAction.extras).thenReturn(recommendationExtras)
+        whenever(mediaSmartspaceTarget.baseAction).thenReturn(mediaSmartspaceBaseAction)
         whenever(mediaRecommendationItem.extras).thenReturn(recommendationExtras)
         whenever(mediaSmartspaceTarget.smartspaceTargetId).thenReturn(KEY_MEDIA_SMARTSPACE)
         whenever(mediaSmartspaceTarget.featureType).thenReturn(SmartspaceTarget.FEATURE_MEDIA)
@@ -380,7 +387,8 @@
         verify(listener).onSmartspaceMediaDataLoaded(
             eq(KEY_MEDIA_SMARTSPACE),
             eq(SmartspaceMediaData(KEY_MEDIA_SMARTSPACE, true /* isActive */, true /*isValid */,
-            PACKAGE_NAME, null, listOf(mediaRecommendationItem), 0)),
+                PACKAGE_NAME, mediaSmartspaceBaseAction, listOf(mediaRecommendationItem),
+                DISMISS_INTENT, 0)),
             eq(false))
     }
 
@@ -391,7 +399,8 @@
         verify(listener).onSmartspaceMediaDataLoaded(
             eq(KEY_MEDIA_SMARTSPACE),
             eq(EMPTY_SMARTSPACE_MEDIA_DATA
-                .copy(targetId = KEY_MEDIA_SMARTSPACE, isActive = true, isValid = false)),
+                .copy(targetId = KEY_MEDIA_SMARTSPACE, isActive = true,
+                    isValid = false, dismissIntent = DISMISS_INTENT)),
             eq(false))
     }