Change SystemUI implementation for prioritized HUNs.

This change involves:
> Migrating CarHeadsUpNotificationSystemContainer to extend instead of
implement the new implementation of CarHeadsUpNotificationContainer to
accomodate for prioritized HUNs.
> Migrating bottom HUNs resources to Notifications package.

Bug: 112155307
Test: Manual
Change-Id: I8fd2d8380d69174564b9899986e81c702b7018d1
diff --git a/packages/CarSystemUI/res/drawable/headsup_scrim_bottom.xml b/packages/CarSystemUI/res/drawable/headsup_scrim_bottom.xml
deleted file mode 100644
index 1724ef0..0000000
--- a/packages/CarSystemUI/res/drawable/headsup_scrim_bottom.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<shape
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <gradient
-        android:startColor="@android:color/black"
-        android:endColor="@android:color/transparent"
-        android:angle="90" />
-</shape>
diff --git a/packages/CarSystemUI/res/layout/headsup_container_bottom.xml b/packages/CarSystemUI/res/layout/headsup_container_bottom.xml
deleted file mode 100644
index 5aab0a1..0000000
--- a/packages/CarSystemUI/res/layout/headsup_container_bottom.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/notification_headsup"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <androidx.constraintlayout.widget.Guideline
-        android:id="@+id/gradient_edge"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        app:layout_constraintGuide_begin="@dimen/headsup_scrim_height"/>
-
-    <!-- Include a FocusParkingView at the beginning. The rotary controller "parks" the focus here
-         when the user navigates to another window. This is also used to prevent wrap-around. -->
-    <com.android.car.ui.FocusParkingView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"/>
-
-    <View
-        android:id="@+id/scrim"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:background="@drawable/headsup_scrim_bottom"
-        app:layout_constraintBottom_toBottomOf="@+id/gradient_edge"
-        app:layout_constraintTop_toTopOf="parent"/>
-
-    <FrameLayout
-        android:id="@+id/headsup_content"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="@dimen/headsup_notification_top_margin"
-        app:layout_constraintEnd_toStartOf="parent"
-        app:layout_constraintStart_toEndOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-    />
-
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml
index b6179ed..61963ac 100644
--- a/packages/CarSystemUI/res/values/config.xml
+++ b/packages/CarSystemUI/res/values/config.xml
@@ -70,13 +70,6 @@
 
     <!-- Whether heads-up notifications should be shown when shade is open. -->
     <bool name="config_enableHeadsUpNotificationWhenNotificationShadeOpen">true</bool>
-    <!-- Whether heads-up notifications should be shown on the bottom. If false, heads-up
-         notifications will be shown pushed to the top of their parent container. If true, they will
-         be shown pushed to the bottom of their parent container. If true, then should override
-         config_headsUpNotificationAnimationHelper to use a different AnimationHelper, such as
-         com.android.car.notification.headsup.animationhelper.
-         CarHeadsUpNotificationBottomAnimationHelper. -->
-    <bool name="config_showHeadsUpNotificationOnBottom">false</bool>
 
     <bool name="config_hideNavWhenKeyguardBouncerShown">true</bool>
     <bool name="config_enablePersistentDockedActivity">false</bool>
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainer.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainer.java
index 3b22a30..98b1fc4 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainer.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainer.java
@@ -17,45 +17,41 @@
 package com.android.systemui.car.notification;
 
 import android.content.Context;
-import android.content.res.Resources;
 import android.graphics.PixelFormat;
 import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
 
-import com.android.car.notification.R;
 import com.android.car.notification.headsup.CarHeadsUpNotificationContainer;
 import com.android.systemui.car.CarDeviceProvisionedController;
 import com.android.systemui.car.window.OverlayViewGlobalStateController;
 import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
 
 import javax.inject.Inject;
 
 /**
  * A controller for SysUI's HUN display.
+ *
+ * Used to attach HUNs views to window and determine whether to show HUN panel.
  */
 @SysUISingleton
-public class CarHeadsUpNotificationSystemContainer implements CarHeadsUpNotificationContainer {
+public class CarHeadsUpNotificationSystemContainer extends CarHeadsUpNotificationContainer {
+    private static final String WINDOW_TITLE = "HeadsUpNotification";
     private final CarDeviceProvisionedController mCarDeviceProvisionedController;
     private final OverlayViewGlobalStateController mOverlayViewGlobalStateController;
 
-    private final ViewGroup mWindow;
-    private final ViewGroup mHeadsUpContentFrame;
-
     @Inject
     CarHeadsUpNotificationSystemContainer(Context context,
-            @Main Resources resources,
             CarDeviceProvisionedController deviceProvisionedController,
             WindowManager windowManager,
             OverlayViewGlobalStateController overlayViewGlobalStateController) {
+        super(context, windowManager);
         mCarDeviceProvisionedController = deviceProvisionedController;
         mOverlayViewGlobalStateController = overlayViewGlobalStateController;
+    }
 
-        boolean showOnBottom = resources.getBoolean(R.bool.config_showHeadsUpNotificationOnBottom);
-
+    @Override
+    protected WindowManager.LayoutParams getWindowManagerLayoutParams() {
         // Use TYPE_STATUS_BAR_SUB_PANEL window type since we need to find a window that is above
         // status bar but below navigation bar.
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
@@ -66,45 +62,15 @@
                         | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
                 PixelFormat.TRANSLUCENT);
 
-        lp.gravity = showOnBottom ? Gravity.BOTTOM : Gravity.TOP;
-        lp.setTitle("HeadsUpNotification");
+        lp.gravity = getShowHunOnBottom() ? Gravity.BOTTOM : Gravity.TOP;
+        lp.setTitle(WINDOW_TITLE);
 
-        int layoutId = showOnBottom
-                ? R.layout.headsup_container_bottom
-                : R.layout.headsup_container;
-        mWindow = (ViewGroup) LayoutInflater.from(context).inflate(layoutId, null, false);
-        windowManager.addView(mWindow, lp);
-        mWindow.setVisibility(View.INVISIBLE);
-        mHeadsUpContentFrame = mWindow.findViewById(R.id.headsup_content);
-    }
-
-    private void animateShow() {
-        if (mCarDeviceProvisionedController.isCurrentUserFullySetup()
-                && mOverlayViewGlobalStateController.shouldShowHUN()) {
-            mWindow.setVisibility(View.VISIBLE);
-        }
-    }
-
-    private void animateHide() {
-        mWindow.setVisibility(View.INVISIBLE);
+        return lp;
     }
 
     @Override
-    public void displayNotification(View notificationView) {
-        mHeadsUpContentFrame.addView(notificationView);
-        animateShow();
-    }
-
-    @Override
-    public void removeNotification(View notificationView) {
-        mHeadsUpContentFrame.removeView(notificationView);
-        if (mHeadsUpContentFrame.getChildCount() == 0) {
-            animateHide();
-        }
-    }
-
-    @Override
-    public boolean isVisible() {
-        return mWindow.getVisibility() == View.VISIBLE;
+    public boolean shouldShowHunPanel() {
+        return mCarDeviceProvisionedController.isCurrentUserFullySetup()
+                && mOverlayViewGlobalStateController.shouldShowHUN();
     }
 }
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainerTest.java
index 384888a..19b7f7b 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainerTest.java
@@ -22,12 +22,12 @@
 
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
-import android.testing.TestableResources;
 import android.view.View;
 import android.view.WindowManager;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.car.notification.CarNotificationTypeItem;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.car.CarDeviceProvisionedController;
 import com.android.systemui.car.CarSystemUiTest;
@@ -64,37 +64,41 @@
         when(mOverlayViewGlobalStateController.shouldShowHUN()).thenReturn(true);
         when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(true);
 
-        TestableResources testableResources = mContext.getOrCreateTestableResources();
+        mContext.ensureTestableResources();
 
         mCarHeadsUpNotificationSystemContainer = new CarHeadsUpNotificationSystemContainer(mContext,
-                testableResources.getResources(), mCarDeviceProvisionedController, mWindowManager,
-                mOverlayViewGlobalStateController);
+                mCarDeviceProvisionedController, mWindowManager, mOverlayViewGlobalStateController);
     }
 
     @Test
     public void testDisplayNotification_firstNotification_isVisible() {
-        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
+        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView,
+                CarNotificationTypeItem.INBOX);
         assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
     }
 
     @Test
     public void testRemoveNotification_lastNotification_isInvisible() {
-        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
+        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView,
+                CarNotificationTypeItem.INBOX);
         mCarHeadsUpNotificationSystemContainer.removeNotification(mNotificationView);
         assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isFalse();
     }
 
     @Test
     public void testRemoveNotification_nonLastNotification_isVisible() {
-        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
-        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView2);
+        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView,
+                CarNotificationTypeItem.INBOX);
+        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView2,
+                CarNotificationTypeItem.INBOX);
         mCarHeadsUpNotificationSystemContainer.removeNotification(mNotificationView);
         assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
     }
 
     @Test
     public void testDisplayNotification_userFullySetupTrue_isInvisible() {
-        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
+        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView,
+                CarNotificationTypeItem.INBOX);
         assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
 
     }
@@ -102,20 +106,23 @@
     @Test
     public void testDisplayNotification_userFullySetupFalse_isInvisible() {
         when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(false);
-        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
+        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView,
+                CarNotificationTypeItem.INBOX);
         assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isFalse();
     }
 
     @Test
     public void testDisplayNotification_overlayWindowStateShouldShowHUNFalse_isInvisible() {
         when(mOverlayViewGlobalStateController.shouldShowHUN()).thenReturn(false);
-        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
+        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView,
+                CarNotificationTypeItem.INBOX);
         assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isFalse();
     }
 
     @Test
     public void testDisplayNotification_overlayWindowStateShouldShowHUNTrue_isVisible() {
-        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
+        mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView,
+                CarNotificationTypeItem.INBOX);
         assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
     }
 }