Remove references to the pdk product variable am: e1780be8cc am: abe2e5820b am: fbda8ab799 am: df396de26b am: 0cfa9cfb5b

Original change: https://android-review.googlesource.com/c/platform/packages/apps/Car/Notification/+/2693267

Change-Id: Ibca7338359339e0deefae3970b65097c72020118
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index b389d5d..08222bc 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -28,7 +28,7 @@
     <string name="toast_message_sent_success" msgid="1159956191974273064">"Se envió correctamente el mensaje."</string>
     <string name="notification_service_label" msgid="7512186049723777468">"Servicio de detección de notificaciones del vehículo"</string>
     <string name="notifications" msgid="2865534625906329283">"Centro de notificaciones"</string>
-    <string name="clear_all" msgid="1845314281571237722">"Borrar todo"</string>
+    <string name="clear_all" msgid="1845314281571237722">"Cerrar todo"</string>
     <string name="ellipsized_string" msgid="6993649229498857557">"…"</string>
     <string name="show_more" msgid="7291378544926443344">"Mostrar más"</string>
     <string name="notification_header" msgid="324550431063568049">"Notificaciones"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 0d8455f..8d1647b 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -26,7 +26,7 @@
     <string name="action_canned_reply" msgid="4045960823021872834">"\"ಡ್ರೈವ್ ಮಾಡುತ್ತಿದ್ದೇನೆ.\""</string>
     <string name="canned_reply_message" msgid="7959257272917598063">"ಡ್ರೈವ್ ಮಾಡುತ್ತಿದ್ದೇನೆ."</string>
     <string name="toast_message_sent_success" msgid="1159956191974273064">"ಸಂದೇಶವನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಕಳುಹಿಸಲಾಗಿದೆ."</string>
-    <string name="notification_service_label" msgid="7512186049723777468">"ಕಾರ್‌ ಅಧಿಸೂಚನೆ ಕೇಳುವ ಸೇವೆ"</string>
+    <string name="notification_service_label" msgid="7512186049723777468">"ಕಾರ್‌ ನೋಟಿಫಿಕೇಶನ್ ಕೇಳುವ ಸೇವೆ"</string>
     <string name="notifications" msgid="2865534625906329283">"ಅಧಿಸೂಚನೆಯ ಕೇಂದ್ರ"</string>
     <string name="clear_all" msgid="1845314281571237722">"ತೆರವುಗೊಳಿಸಿ"</string>
     <string name="ellipsized_string" msgid="6993649229498857557">"…"</string>
@@ -55,5 +55,5 @@
     <string name="hun_suppression_channel_name" msgid="8298850157350352525">"ಗಮನ ರಸ್ತೆ ಕಡೆಗೆ ಇರಲಿ ಫೀಚರ್‌ನ ನಿರ್ಬಂಧ"</string>
     <string name="hun_suppression_notification_title_park" msgid="2790860076784227523">"ಇತ್ತೀಚಿನ ಎಪಿಸೋಡ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
     <string name="hun_suppression_notification_title_drive" msgid="4403363470548899844">"ವಾಹನ ಚಾಲನೆಯ ಮೇಲೆ ಗಮನಹರಿಸಿ"</string>
-    <string name="hun_suppression_notification_description" msgid="5269238832987802104">"ಕೆಲವು ಹೊಸ ಅಧಿಸೂಚನೆಗಳನ್ನು ಅಧಿಸೂಚನೆ ಕೇಂದ್ರದಲ್ಲಿ ಉಳಿಸಲಾಗುತ್ತದೆ"</string>
+    <string name="hun_suppression_notification_description" msgid="5269238832987802104">"ಕೆಲವು ಹೊಸ ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು ನೋಟಿಫಿಕೇಶನ್‌ ಕೇಂದ್ರದಲ್ಲಿ ಉಳಿಸಲಾಗುತ್ತದೆ"</string>
 </resources>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 44f44f5..8b70c40 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -49,12 +49,9 @@
     <string name="see_more_message" msgid="6343183827924395955">"കൂടുതൽ കാണുക"</string>
     <string name="restricted_hun_message_content" msgid="631111937988857716">"പുതിയ സന്ദേശം"</string>
     <string name="manage_text" msgid="4225197445283791757">"മാനേജ് ചെയ്യുക"</string>
-    <!-- no translation found for category_navigation (4406139232918521087) -->
-    <skip />
-    <!-- no translation found for category_call (2249490790700877973) -->
-    <skip />
-    <!-- no translation found for category_message (451360226248504859) -->
-    <skip />
+    <string name="category_navigation" msgid="4406139232918521087">"നാവിഗേഷൻ"</string>
+    <string name="category_call" msgid="2249490790700877973">"കോൾ ചെയ്യുക"</string>
+    <string name="category_message" msgid="451360226248504859">"സന്ദേശം"</string>
     <string name="hun_suppression_channel_name" msgid="8298850157350352525">"മുന്നറിയിപ്പ് പ്രവർത്തനരഹിതമാക്കൽ"</string>
     <string name="hun_suppression_notification_title_park" msgid="2790860076784227523">"ഏറ്റവും പുതിയ വിവരങ്ങൾ അപ്പപ്പോൾ അറിയൂ"</string>
     <string name="hun_suppression_notification_title_drive" msgid="4403363470548899844">"ഡ്രൈവിംഗിൽ ശ്രദ്ധിക്കുക"</string>
diff --git a/src/com/android/car/notification/CarHeadsUpNotificationManager.java b/src/com/android/car/notification/CarHeadsUpNotificationManager.java
index 3294369..2d6a493 100644
--- a/src/com/android/car/notification/CarHeadsUpNotificationManager.java
+++ b/src/com/android/car/notification/CarHeadsUpNotificationManager.java
@@ -25,8 +25,6 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.app.ActivityTaskManager;
 import android.app.KeyguardManager;
 import android.app.Notification;
@@ -43,6 +41,8 @@
 import android.view.View;
 import android.view.ViewTreeObserver;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.UiThread;
 import androidx.annotation.VisibleForTesting;
 
@@ -56,6 +56,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 
 /**
@@ -108,12 +109,13 @@
     private final KeyguardManager mKeyguardManager;
     private final PreprocessingManager mPreprocessingManager;
     private final LayoutInflater mInflater;
-    private final CarHeadsUpNotificationContainer mHunContainer;
+    @VisibleForTesting
+    final CarHeadsUpNotificationContainer mHunContainer;
     private final CarHeadsUpNotificationQueue.CarHeadsUpNotificationQueueCallback
             mCarHeadsUpNotificationQueueCallback;
 
     // key for the map is the statusbarnotification key
-    private final Map<String, HeadsUpEntry> mActiveHeadsUpNotifications = new HashMap<>();
+    private final Map<String, HeadsUpEntry> mActiveHeadsUpNotifications = new ConcurrentHashMap<>();
     private final List<OnHeadsUpNotificationStateChange> mNotificationStateChangeListeners =
             new ArrayList<>();
     private final Map<HeadsUpEntry,
@@ -282,6 +284,18 @@
         mCarHeadsUpNotificationQueue.releaseQueue();
     }
 
+    /**
+     * Clears all local cached variables and gracefully removes any heads up notification views if
+     * present.
+     */
+    public void clearCache() {
+        mCarHeadsUpNotificationQueue.clearCache();
+        for (AlertEntry alertEntry : mActiveHeadsUpNotifications.values()) {
+            resetHeadsUpEntry(alertEntry);
+            removeHeadsUpEntry(alertEntry, getHeadsUpView(alertEntry));
+        }
+    }
+
     private void scheduleRemoveHeadsUp(AlertEntry alertEntry) {
         HeadsUpEntry currentActiveHeadsUpNotification = getActiveHeadsUpEntry(alertEntry);
 
@@ -477,7 +491,11 @@
         // Add swipe gesture
         View cardView = notificationView.findViewById(R.id.card_view);
         cardView.setOnTouchListener(new HeadsUpNotificationOnTouchListener(cardView,
-                isHeadsUpDismissible(alertEntry), () -> resetView(alertEntry)));
+                isHeadsUpDismissible(alertEntry), () -> {
+            resetHeadsUpEntry(alertEntry);
+            removeHeadsUpEntry(alertEntry, getHeadsUpView(alertEntry));
+            handleHeadsUpNotificationStateChanged(alertEntry, HeadsUpState.DISMISSED);
+        }));
 
         // Add dismiss button listener
         View dismissButton = notificationView.findViewById(
@@ -574,12 +592,32 @@
      */
     private void dismissHun(AlertEntry alertEntry) {
         Log.d(TAG, "clearViews for Heads Up Notification: ");
+        resetHeadsUpEntry(alertEntry);
+        boolean isTaggedToBeRemoved = isActiveHun(alertEntry)
+                && getActiveHeadsUpEntry(alertEntry).mShouldRemove;
+        View view = getHeadsUpView(alertEntry);
+
+        AnimatorSet animatorSet = mAnimationHelper.getAnimateOutAnimator(mContext, view);
+        animatorSet.setTarget(view);
+        animatorSet.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                // Remove HUN after the animation ends to prevent accidental touch on the card
+                // triggering another remove call.
+                removeHeadsUpEntry(alertEntry, view);
+
+                handleHeadsUpNotificationStateChanged(alertEntry,
+                        isTaggedToBeRemoved ? HeadsUpState.REMOVED_BY_SENDER
+                                : HeadsUpState.DISMISSED);
+            }
+        });
+        animatorSet.start();
+    }
+
+    private void resetHeadsUpEntry(@NonNull AlertEntry alertEntry) {
         if (!isActiveHun(alertEntry)) {
-            // View can also be removed when swiped away.
             return;
         }
-        // Get the current notification to perform animations and remove it immediately from the
-        // active notification maps and cancel all other call backs if any.
         HeadsUpEntry currentHeadsUpNotification = getActiveHeadsUpEntry(alertEntry);
         // view could already be in the process of being dismissed
         if (currentHeadsUpNotification.mIsDismissing) {
@@ -588,41 +626,21 @@
         currentHeadsUpNotification.mIsDismissing = true;
         currentHeadsUpNotification.getHandler().removeCallbacksAndMessages(null);
         resetViewTreeListenersEntry(currentHeadsUpNotification);
-        View view = currentHeadsUpNotification.getNotificationView();
-
-        AnimatorSet animatorSet = mAnimationHelper.getAnimateOutAnimator(mContext, view);
-        animatorSet.setTarget(view);
-        animatorSet.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mHunContainer.removeNotification(view);
-
-                // Remove HUN after the animation ends to prevent accidental touch on the card
-                // triggering another remove call.
-                mActiveHeadsUpNotifications.remove(alertEntry.getKey());
-
-                handleHeadsUpNotificationStateChanged(alertEntry,
-                        currentHeadsUpNotification.mShouldRemove ? HeadsUpState.REMOVED_BY_SENDER
-                                : HeadsUpState.DISMISSED);
-            }
-        });
-        animatorSet.start();
     }
 
-    /**
-     * Removes the view for the active heads up notification and also removes the HUN from the map
-     * of active Notifications.
-     */
-    private void resetView(AlertEntry alertEntry) {
+    @Nullable
+    private View getHeadsUpView(@NonNull AlertEntry alertEntry) {
         if (!isActiveHun(alertEntry)) {
-            return;
+            return null;
         }
-        HeadsUpEntry currentHeadsUpNotification = getActiveHeadsUpEntry(alertEntry);
-        currentHeadsUpNotification.getHandler().removeCallbacksAndMessages(null);
-        mHunContainer.removeNotification(currentHeadsUpNotification.getNotificationView());
+        return getActiveHeadsUpEntry(alertEntry).getNotificationView();
+    }
+
+    private void removeHeadsUpEntry(@NonNull AlertEntry alertEntry, @Nullable View view) {
+        if (view != null) {
+            mHunContainer.removeNotification(view);
+        }
         mActiveHeadsUpNotifications.remove(alertEntry.getKey());
-        handleHeadsUpNotificationStateChanged(alertEntry, HeadsUpState.DISMISSED);
-        resetViewTreeListenersEntry(currentHeadsUpNotification);
     }
 
     /**
@@ -774,4 +792,9 @@
     void setCarHeadsUpNotificationQueue(CarHeadsUpNotificationQueue carHeadsUpNotificationQueue) {
         mCarHeadsUpNotificationQueue = carHeadsUpNotificationQueue;
     }
+
+    @VisibleForTesting
+    void addActiveHeadsUpNotification(HeadsUpEntry headsUpEntry) {
+        mActiveHeadsUpNotifications.put(headsUpEntry.getKey(), headsUpEntry);
+    }
 }
diff --git a/src/com/android/car/notification/CarHeadsUpNotificationQueue.java b/src/com/android/car/notification/CarHeadsUpNotificationQueue.java
index 9fe4d83..dfede43 100644
--- a/src/com/android/car/notification/CarHeadsUpNotificationQueue.java
+++ b/src/com/android/car/notification/CarHeadsUpNotificationQueue.java
@@ -331,6 +331,18 @@
     }
 
     /**
+     * Clears all local cached variables and cancels scheduled executor tasks.
+     */
+    public void clearCache() {
+        mPriorityQueue.clear();
+        mKeyToAlertEntryMap.clear();
+        mThrottledDisplays.clear();
+        if (mScheduledFuture != null) {
+            mScheduledFuture.cancel(/* mayInterruptIfRunning= */ true);
+        }
+    }
+
+    /**
      * Callback to communicate status of HUN.
      */
     public interface CarHeadsUpNotificationQueueCallback {
diff --git a/src/com/android/car/notification/CarNotificationListener.java b/src/com/android/car/notification/CarNotificationListener.java
index 0cc28ed..b3db87a 100644
--- a/src/com/android/car/notification/CarNotificationListener.java
+++ b/src/com/android/car/notification/CarNotificationListener.java
@@ -261,6 +261,17 @@
     }
 
     /**
+     * Clears all local cached variables.
+     * Note: This is a blocking call so should not execute any long-running or time-consuming tasks
+     * like storing cache.
+     */
+    public void clearCache() {
+        mHeadsUpManager.clearCache();
+        mNotificationDataManager.clearAll();
+        mActiveNotifications.clear();
+    }
+
+    /**
      * Called when Notification Panel's visibility changes.
      */
     public void onVisibilityChanged(boolean isVisible) {
diff --git a/src/com/android/car/notification/HeadsUpEntry.java b/src/com/android/car/notification/HeadsUpEntry.java
index 42eb414..4a24152 100644
--- a/src/com/android/car/notification/HeadsUpEntry.java
+++ b/src/com/android/car/notification/HeadsUpEntry.java
@@ -33,9 +33,16 @@
     private View mNotificationView;
     private CarNotificationBaseViewHolder mCarNotificationBaseViewHolder;
 
+    // Signifies that this notification was NOT flagged with Notification.FLAG_ONLY_ALERT_ONCE
     boolean mIsAlertAgain;
+
+    // Signifies that this notification is to be shown as Heads Up Notification for the first time
     boolean mIsNewHeadsUp;
+
+    // Signifies that this notification is in process of being dismissed
     boolean mIsDismissing;
+
+    // Signifies that the sender marked this notification to be removed
     boolean mShouldRemove;
 
     HeadsUpEntry(StatusBarNotification statusBarNotification) {
diff --git a/tests/unit/src/com/android/car/notification/CarHeadsUpNotificationManagerTest.java b/tests/unit/src/com/android/car/notification/CarHeadsUpNotificationManagerTest.java
index dd84822..0c09c00 100644
--- a/tests/unit/src/com/android/car/notification/CarHeadsUpNotificationManagerTest.java
+++ b/tests/unit/src/com/android/car/notification/CarHeadsUpNotificationManagerTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -37,11 +38,13 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.Looper;
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
 import android.testing.TestableContext;
+import android.view.View;
 
 import androidx.annotation.Nullable;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -54,6 +57,8 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -106,7 +111,9 @@
     @Mock
     KeyguardManager mKeyguardManager;
     @Mock
-    HeadsUpEntry mHeadsUpEntry;
+    Handler mHandlerMock;
+    @Captor
+    ArgumentCaptor<View> mViewCaptor;
     private CarHeadsUpNotificationManager mManager;
     private AlertEntry mAlertEntryMessageHeadsUp;
     private AlertEntry mAlertEntryNavigationHeadsUp;
@@ -460,6 +467,22 @@
                 CarHeadsUpNotificationManager.HeadsUpState.REMOVED_FROM_QUEUE);
     }
 
+    @Test
+    public void clearCache_viewsRemovedFromCarHeadsUpNotificationContainer() {
+        CarHeadsUpNotificationContainer container = mManager.mHunContainer;
+        HeadsUpEntry notification1 = createMockHeadsUpEntry("key1");
+        HeadsUpEntry notification2 = createMockHeadsUpEntry("key2");
+        mManager.addActiveHeadsUpNotification(notification1);
+        mManager.addActiveHeadsUpNotification(notification2);
+
+        mManager.clearCache();
+
+        verify(container, times(2)).removeNotification(mViewCaptor.capture());
+        assertThat(mViewCaptor.getAllValues().containsAll(List.of(new View[]{
+                notification1.getNotificationView(), notification2.getNotificationView()})))
+                .isTrue();
+    }
+
     private void createCarHeadsUpNotificationManager() {
         createCarHeadsUpNotificationManager(mCarHeadsUpNotificationQueue);
     }
@@ -491,4 +514,13 @@
         when(mPackageManager.getPackageInfoAsUser(eq(packageName), anyInt(), anyInt())).thenReturn(
                 packageInfo);
     }
+
+    private HeadsUpEntry createMockHeadsUpEntry(String key) {
+        HeadsUpEntry headsUpEntry = mock(HeadsUpEntry.class);
+        when(headsUpEntry.getKey()).thenReturn(key);
+        when(headsUpEntry.getHandler()).thenReturn(mHandlerMock);
+        View headsUpNotificationView = mock(View.class);
+        when(headsUpEntry.getNotificationView()).thenReturn(headsUpNotificationView);
+        return headsUpEntry;
+    }
 }
\ No newline at end of file