Migrate HVAC panel to use named system bars
This change updates the HVAC panel to register its drag-close listener
on specific, named system bars defined in the new
'config_registerHvacDragCloseListener' XML string-array. This allows
for more flexible and configurable behavior, as the HVAC panel is no
longer hardcoded to register on all available system bars.
Fixes: 437988309, 432799957
Test: atest CarSystemUITests
Flag: com.android.car.scalableui.enable_ext_panel_updates
Change-Id: I2c9f4658984dcf5508339aa70e38e4e7df14c301
diff --git a/res/values/config.xml b/res/values/config.xml
index b24e7e2..2c51a22 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -293,6 +293,17 @@
</string-array>
<!--
+ List of system bar names that should register HvacPanelOverlayViewController's
+ DragCloseTouchListener
+ -->
+ <string-array name="config_registerHvacDragCloseListener" translatable="false">
+ <item>TopCarSystemBar</item>
+ <item>BottomCarSystemBar</item>
+ <item>LeftCarSystemBar</item>
+ <item>RightCarSystemBar</item>
+ </string-array>
+
+ <!--
Specifies the default activities associated with different panel IDs.
This string array defines the default activity to launch for panels. Each item in the array
diff --git a/src/com/android/systemui/CarSystemUIModule.java b/src/com/android/systemui/CarSystemUIModule.java
index 2c2ea61..dcfdb0a 100644
--- a/src/com/android/systemui/CarSystemUIModule.java
+++ b/src/com/android/systemui/CarSystemUIModule.java
@@ -37,6 +37,7 @@
import com.android.systemui.car.displayconfig.ExternalDisplayController;
import com.android.systemui.car.drivemode.DriveModeModule;
import com.android.systemui.car.flags.FlagManager;
+import com.android.systemui.car.hvac.HvacModule;
import com.android.systemui.car.keyguard.CarKeyguardViewController;
import com.android.systemui.car.notification.NotificationShadeWindowControllerImpl;
import com.android.systemui.car.statusbar.DozeServiceHost;
@@ -110,6 +111,7 @@
DriveModeModule.class,
GestureModule.class,
HeadsUpEmptyImplModule.class,
+ HvacModule.class,
KeyguardDisplayModule.class,
MediaMuteAwaitConnectionCli.StartableModule.class,
NearbyMediaDevicesManager.StartableModule.class,
diff --git a/src/com/android/systemui/car/hvac/HvacModule.java b/src/com/android/systemui/car/hvac/HvacModule.java
new file mode 100644
index 0000000..45a3e8b
--- /dev/null
+++ b/src/com/android/systemui/car/hvac/HvacModule.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2025 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.
+ */
+
+package com.android.systemui.car.hvac;
+
+import android.content.Context;
+
+import com.android.systemui.R;
+
+import dagger.Module;
+import dagger.Provides;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.inject.Named;
+
+/** Dagger module for HVAC. */
+@Module
+public class HvacModule {
+ /** Dagger {@link Named} for a list of strings that listen to HVAC drag closed listener. */
+ public static final String HVAC_SYSTEM_BAR_NAMES = "HvacSystemBarNames";
+
+ /** Provides the list of system bar names that the HVAC panel should register with. */
+ @Provides
+ @Named(HVAC_SYSTEM_BAR_NAMES)
+ public List<String> provideHvacSystemBarNames(Context context) {
+ return Arrays.asList(context.getResources().getStringArray(
+ R.array.config_registerHvacDragCloseListener));
+ }
+}
diff --git a/src/com/android/systemui/car/hvac/HvacPanelOverlayViewMediator.java b/src/com/android/systemui/car/hvac/HvacPanelOverlayViewMediator.java
index 9a03cc7..33d5459 100644
--- a/src/com/android/systemui/car/hvac/HvacPanelOverlayViewMediator.java
+++ b/src/com/android/systemui/car/hvac/HvacPanelOverlayViewMediator.java
@@ -16,10 +16,7 @@
package com.android.systemui.car.hvac;
-import static com.android.systemui.car.systembar.CarSystemBarController.BOTTOM_BAR_NAME;
-import static com.android.systemui.car.systembar.CarSystemBarController.LEFT_BAR_NAME;
-import static com.android.systemui.car.systembar.CarSystemBarController.RIGHT_BAR_NAME;
-import static com.android.systemui.car.systembar.CarSystemBarController.TOP_BAR_NAME;
+import static com.android.systemui.car.hvac.HvacModule.HVAC_SYSTEM_BAR_NAMES;
import static com.android.systemui.car.window.OverlayPanelViewController.OVERLAY_FROM_BOTTOM_BAR;
import android.content.BroadcastReceiver;
@@ -36,7 +33,10 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.settings.UserTracker;
+import java.util.List;
+
import javax.inject.Inject;
+import javax.inject.Named;
@SysUISingleton
public class HvacPanelOverlayViewMediator implements OverlayViewMediator {
@@ -48,6 +48,7 @@
private final HvacPanelOverlayViewController mHvacPanelOverlayViewController;
private final BroadcastDispatcher mBroadcastDispatcher;
private final UserTracker mUserTracker;
+ private final List<String> mSystemBarNames;
@VisibleForTesting
final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -79,24 +80,20 @@
CarSystemBarController carSystemBarController,
HvacPanelOverlayViewController hvacPanelOverlayViewController,
BroadcastDispatcher broadcastDispatcher,
- UserTracker userTracker) {
+ UserTracker userTracker,
+ @Named(HVAC_SYSTEM_BAR_NAMES) List<String> systemBarNames) {
mContext = context;
mCarSystemBarController = carSystemBarController;
mHvacPanelOverlayViewController = hvacPanelOverlayViewController;
mBroadcastDispatcher = broadcastDispatcher;
mUserTracker = userTracker;
+ mSystemBarNames = systemBarNames;
}
@Override
public void registerListeners() {
- mCarSystemBarController.registerBarTouchListener(TOP_BAR_NAME,
- mHvacPanelOverlayViewController.getDragCloseTouchListener());
- mCarSystemBarController.registerBarTouchListener(BOTTOM_BAR_NAME,
- mHvacPanelOverlayViewController.getDragCloseTouchListener());
- mCarSystemBarController.registerBarTouchListener(LEFT_BAR_NAME,
- mHvacPanelOverlayViewController.getDragCloseTouchListener());
- mCarSystemBarController.registerBarTouchListener(RIGHT_BAR_NAME,
- mHvacPanelOverlayViewController.getDragCloseTouchListener());
+ mSystemBarNames.forEach(systemBarName -> mCarSystemBarController.registerBarTouchListener(
+ systemBarName, mHvacPanelOverlayViewController.getDragCloseTouchListener()));
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver,
new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), /* executor= */ null,
diff --git a/tests/src/com/android/systemui/car/hvac/HvacPanelOverlayViewMediatorTest.java b/tests/src/com/android/systemui/car/hvac/HvacPanelOverlayViewMediatorTest.java
index e717572..0d44a56 100644
--- a/tests/src/com/android/systemui/car/hvac/HvacPanelOverlayViewMediatorTest.java
+++ b/tests/src/com/android/systemui/car/hvac/HvacPanelOverlayViewMediatorTest.java
@@ -16,6 +16,7 @@
package com.android.systemui.car.hvac;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -24,6 +25,7 @@
import android.content.Intent;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.view.View;
import androidx.test.filters.SmallTest;
@@ -39,11 +41,15 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.Arrays;
+
@CarSystemUiTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@SmallTest
public class HvacPanelOverlayViewMediatorTest extends CarSysuiTestCase {
+ private static final String SYSTEM_BAR_NAME_1 = "SYSTEM_BAR_NAME_1";
+ private static final String SYSTEM_BAR_NAME_2 = "SYSTEM_BAR_NAME_2";
private HvacPanelOverlayViewMediator mHvacPanelOverlayViewMediator;
@@ -57,17 +63,33 @@
private BroadcastDispatcher mBroadcastDispatcher;
@Mock
private UserTracker mUserTracker;
+ @Mock
+ private View.OnTouchListener mOnTouchListener;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ when(mHvacPanelOverlayViewController.getDragCloseTouchListener())
+ .thenReturn(mOnTouchListener);
+
mHvacPanelOverlayViewMediator = new HvacPanelOverlayViewMediator(
mContext,
mCarSystemBarController,
mHvacPanelOverlayViewController,
mBroadcastDispatcher,
- mUserTracker);
+ mUserTracker,
+ Arrays.asList(SYSTEM_BAR_NAME_1, SYSTEM_BAR_NAME_2));
+ }
+
+ @Test
+ public void registerListeners_touchListenersRegistered() {
+ mHvacPanelOverlayViewMediator.registerListeners();
+
+ verify(mCarSystemBarController)
+ .registerBarTouchListener(eq(SYSTEM_BAR_NAME_1), eq(mOnTouchListener));
+ verify(mCarSystemBarController)
+ .registerBarTouchListener(eq(SYSTEM_BAR_NAME_2), eq(mOnTouchListener));
}
@Test