diff options
7 files changed, 192 insertions, 7 deletions
diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml index 43e2918bd98d..0b56d05cc66f 100644 --- a/packages/CarSystemUI/res/values/config.xml +++ b/packages/CarSystemUI/res/values/config.xml @@ -32,6 +32,10 @@ <!-- Disable normal notification rendering; we handle that ourselves --> <bool name="config_renderNotifications">false</bool> + <!-- Whether navigationBar touch events should be consumed before reaching the CarFacetButton \ + when the notification panel is open. --> + <bool name="config_consumeNavigationBarTouchWhenNotificationPanelOpen">false</bool> + <!-- 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 diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java index 9d98479dfeff..1901a2db879d 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java @@ -599,6 +599,11 @@ public class NotificationPanelViewController extends OverlayViewController { } } + /** Returns {@code true} if the notification panel is expanded. */ + public boolean isPanelExpanded() { + return mPanelExpanded; + } + /** Sets the unseen count listener. */ public void setOnUnseenCountUpdateListener(OnUnseenCountUpdateListener listener) { mUnseenCountUpdateListener = listener; diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java index 1cfc83293acb..110c2ee8854b 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java @@ -20,7 +20,6 @@ import android.car.hardware.power.CarPowerManager; import android.content.res.Configuration; import com.android.systemui.car.CarDeviceProvisionedController; -import com.android.systemui.car.CarServiceProvider; import com.android.systemui.navigationbar.car.CarNavigationBarController; import com.android.systemui.statusbar.car.PowerManagerHelper; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -36,7 +35,6 @@ public class NotificationPanelViewMediator implements OverlayViewMediator, private final CarNavigationBarController mCarNavigationBarController; private final NotificationPanelViewController mNotificationPanelViewController; - private final CarServiceProvider mCarServiceProvider; private final PowerManagerHelper mPowerManagerHelper; private final CarDeviceProvisionedController mCarDeviceProvisionedController; private final ConfigurationController mConfigurationController; @@ -46,7 +44,6 @@ public class NotificationPanelViewMediator implements OverlayViewMediator, CarNavigationBarController carNavigationBarController, NotificationPanelViewController notificationPanelViewController, - CarServiceProvider carServiceProvider, PowerManagerHelper powerManagerHelper, CarDeviceProvisionedController carDeviceProvisionedController, @@ -54,7 +51,6 @@ public class NotificationPanelViewMediator implements OverlayViewMediator, ) { mCarNavigationBarController = carNavigationBarController; mNotificationPanelViewController = notificationPanelViewController; - mCarServiceProvider = carServiceProvider; mPowerManagerHelper = powerManagerHelper; mCarDeviceProvisionedController = carDeviceProvisionedController; mConfigurationController = configurationController; @@ -72,7 +68,17 @@ public class NotificationPanelViewMediator implements OverlayViewMediator, mNotificationPanelViewController.getNavBarNotificationTouchListener()); mCarNavigationBarController.registerNotificationController( - () -> mNotificationPanelViewController.toggle()); + new CarNavigationBarController.NotificationsShadeController() { + @Override + public void togglePanel() { + mNotificationPanelViewController.toggle(); + } + + @Override + public boolean isNotificationPanelOpen() { + return mNotificationPanelViewController.isPanelExpanded(); + } + }); } @Override diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java index 67e9da429c36..fbcd8787135d 100644 --- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java +++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java @@ -314,6 +314,9 @@ public class CarNavigationBarController { public interface NotificationsShadeController { /** Toggles the visibility of the notifications shade. */ void togglePanel(); + + /** Returns {@code true} if the panel is open. */ + boolean isNotificationPanelOpen(); } private void checkAllBars(boolean isSetUp) { diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java index 28da16932fc4..5b99f53af9f9 100644 --- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java +++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java @@ -35,10 +35,11 @@ import com.android.systemui.statusbar.phone.StatusBarIconController; * in a linear layout. */ public class CarNavigationBarView extends LinearLayout { + private final boolean mConsumeTouchWhenPanelOpen; + private View mNavButtons; private CarNavigationButton mNotificationsButton; private NotificationsShadeController mNotificationsShadeController; - private Context mContext; private View mLockScreenButtons; // used to wire in open/close gestures for notifications private OnTouchListener mStatusBarWindowTouchListener; @@ -46,7 +47,8 @@ public class CarNavigationBarView extends LinearLayout { public CarNavigationBarView(Context context, AttributeSet attrs) { super(context, attrs); - mContext = context; + mConsumeTouchWhenPanelOpen = getResources().getBoolean( + R.bool.config_consumeNavigationBarTouchWhenNotificationPanelOpen); } @Override @@ -77,9 +79,16 @@ public class CarNavigationBarView extends LinearLayout { @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (mStatusBarWindowTouchListener != null) { + boolean shouldConsumeEvent = mNotificationsShadeController == null ? false + : mNotificationsShadeController.isNotificationPanelOpen(); + // Forward touch events to the status bar window so it can drag // windows if required (Notification shade) mStatusBarWindowTouchListener.onTouch(this, ev); + + if (mConsumeTouchWhenPanelOpen && shouldConsumeEvent) { + return true; + } } return super.onInterceptTouchEvent(ev); } diff --git a/packages/CarSystemUI/tests/res/layout/car_navigation_bar_view_test.xml b/packages/CarSystemUI/tests/res/layout/car_navigation_bar_view_test.xml new file mode 100644 index 000000000000..b0ca8dc4cd34 --- /dev/null +++ b/packages/CarSystemUI/tests/res/layout/car_navigation_bar_view_test.xml @@ -0,0 +1,58 @@ +<!-- + ~ 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. + --> + +<com.android.systemui.navigationbar.car.CarNavigationBarView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:systemui="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/system_bar_background" + android:orientation="vertical"> + <!--The 20dp padding is the difference between the background selected icon size and the ripple + that was chosen, thus it's a hack to make it look pretty and not an official margin value--> + <LinearLayout + android:id="@id/nav_buttons" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_weight="1" + android:paddingStart="20dp" + android:paddingEnd="20dp" + android:gravity="center"> + + <com.android.systemui.navigationbar.car.CarNavigationButton + android:id="@+id/home" + style="@style/NavigationBarButton" + systemui:componentNames="com.android.car.carlauncher/.CarLauncher" + systemui:icon="@drawable/car_ic_overview" + systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end" + systemui:selectedIcon="@drawable/car_ic_overview_selected" + systemui:highlightWhenSelected="true" + /> + + </LinearLayout> + + <LinearLayout + android:id="@+id/lock_screen_nav_buttons" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_weight="1" + android:paddingStart="@dimen/car_keyline_1" + android:paddingEnd="@dimen/car_keyline_1" + android:gravity="center" + android:visibility="gone" + /> + +</com.android.systemui.navigationbar.car.CarNavigationBarView> diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarViewTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarViewTest.java new file mode 100644 index 000000000000..9e2131c9ccfb --- /dev/null +++ b/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarViewTest.java @@ -0,0 +1,100 @@ +/* + * 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. + */ + +package com.android.systemui.navigationbar.car; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.when; + +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.R; +import com.android.systemui.SysuiTestCase; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +@SmallTest +public class CarNavigationBarViewTest extends SysuiTestCase { + + private CarNavigationBarView mNavBarView; + + @Mock + private CarNavigationBarController.NotificationsShadeController mNotificationsShadeController; + + @Mock + private View.OnTouchListener mNavBarTouchListener; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @After + public void tearDown() { + getContext().getOrCreateTestableResources().addOverride( + R.bool.config_consumeNavigationBarTouchWhenNotificationPanelOpen, false); + } + + @Test + public void dispatchTouch_shadeOpen_flagOff_doesNotConsumeTouch() { + getContext().getOrCreateTestableResources().addOverride( + R.bool.config_consumeNavigationBarTouchWhenNotificationPanelOpen, false); + when(mNotificationsShadeController.isNotificationPanelOpen()).thenReturn(true); + mNavBarView = (CarNavigationBarView) LayoutInflater.from(getContext()).inflate( + R.layout.car_navigation_bar_view_test, /* root= */ null); + mNavBarView.setNotificationsPanelController(mNotificationsShadeController); + mNavBarView.setStatusBarWindowTouchListener(mNavBarTouchListener); + + boolean consume = mNavBarView.onInterceptTouchEvent( + MotionEvent.obtain(/* downTime= */ 200, /* eventTime= */ 300, + MotionEvent.ACTION_MOVE, mNavBarView.getX(), + mNavBarView.getY(), /* metaState= */ 0)); + + assertThat(consume).isFalse(); + } + + @Test + public void dispatchTouch_shadeOpen_flagOn_consumesTouch() { + getContext().getOrCreateTestableResources().addOverride( + R.bool.config_consumeNavigationBarTouchWhenNotificationPanelOpen, true); + when(mNotificationsShadeController.isNotificationPanelOpen()).thenReturn(true); + mNavBarView = (CarNavigationBarView) LayoutInflater.from(getContext()).inflate( + R.layout.car_navigation_bar_view_test, /* root= */ null); + mNavBarView.setNotificationsPanelController(mNotificationsShadeController); + mNavBarView.setStatusBarWindowTouchListener(mNavBarTouchListener); + + boolean consume = mNavBarView.onInterceptTouchEvent( + MotionEvent.obtain(/* downTime= */ 200, /* eventTime= */ 300, + MotionEvent.ACTION_MOVE, mNavBarView.getX(), + mNavBarView.getY(), /* metaState= */ 0)); + + assertThat(consume).isTrue(); + } +} |