Merge "Allow nav bar to consume touch events based on configuration" into rvc-dev am: e50fc87c70 am: 6749defbb5 am: ac29d8c139
Change-Id: I61c89d2b51842e0ae1364019324804d3ed7ba318
This commit is contained in:
@@ -32,6 +32,10 @@
|
|||||||
<!-- Disable normal notification rendering; we handle that ourselves -->
|
<!-- Disable normal notification rendering; we handle that ourselves -->
|
||||||
<bool name="config_renderNotifications">false</bool>
|
<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. -->
|
<!-- Whether heads-up notifications should be shown when shade is open. -->
|
||||||
<bool name="config_enableHeadsUpNotificationWhenNotificationShadeOpen">true</bool>
|
<bool name="config_enableHeadsUpNotificationWhenNotificationShadeOpen">true</bool>
|
||||||
<!-- Whether heads-up notifications should be shown on the bottom. If false, heads-up
|
<!-- Whether heads-up notifications should be shown on the bottom. If false, heads-up
|
||||||
|
|||||||
@@ -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. */
|
/** Sets the unseen count listener. */
|
||||||
public void setOnUnseenCountUpdateListener(OnUnseenCountUpdateListener listener) {
|
public void setOnUnseenCountUpdateListener(OnUnseenCountUpdateListener listener) {
|
||||||
mUnseenCountUpdateListener = listener;
|
mUnseenCountUpdateListener = listener;
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import android.car.hardware.power.CarPowerManager;
|
|||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
|
||||||
import com.android.systemui.car.CarDeviceProvisionedController;
|
import com.android.systemui.car.CarDeviceProvisionedController;
|
||||||
import com.android.systemui.car.CarServiceProvider;
|
|
||||||
import com.android.systemui.navigationbar.car.CarNavigationBarController;
|
import com.android.systemui.navigationbar.car.CarNavigationBarController;
|
||||||
import com.android.systemui.statusbar.car.PowerManagerHelper;
|
import com.android.systemui.statusbar.car.PowerManagerHelper;
|
||||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||||
@@ -36,7 +35,6 @@ public class NotificationPanelViewMediator implements OverlayViewMediator,
|
|||||||
|
|
||||||
private final CarNavigationBarController mCarNavigationBarController;
|
private final CarNavigationBarController mCarNavigationBarController;
|
||||||
private final NotificationPanelViewController mNotificationPanelViewController;
|
private final NotificationPanelViewController mNotificationPanelViewController;
|
||||||
private final CarServiceProvider mCarServiceProvider;
|
|
||||||
private final PowerManagerHelper mPowerManagerHelper;
|
private final PowerManagerHelper mPowerManagerHelper;
|
||||||
private final CarDeviceProvisionedController mCarDeviceProvisionedController;
|
private final CarDeviceProvisionedController mCarDeviceProvisionedController;
|
||||||
private final ConfigurationController mConfigurationController;
|
private final ConfigurationController mConfigurationController;
|
||||||
@@ -46,7 +44,6 @@ public class NotificationPanelViewMediator implements OverlayViewMediator,
|
|||||||
CarNavigationBarController carNavigationBarController,
|
CarNavigationBarController carNavigationBarController,
|
||||||
NotificationPanelViewController notificationPanelViewController,
|
NotificationPanelViewController notificationPanelViewController,
|
||||||
|
|
||||||
CarServiceProvider carServiceProvider,
|
|
||||||
PowerManagerHelper powerManagerHelper,
|
PowerManagerHelper powerManagerHelper,
|
||||||
|
|
||||||
CarDeviceProvisionedController carDeviceProvisionedController,
|
CarDeviceProvisionedController carDeviceProvisionedController,
|
||||||
@@ -54,7 +51,6 @@ public class NotificationPanelViewMediator implements OverlayViewMediator,
|
|||||||
) {
|
) {
|
||||||
mCarNavigationBarController = carNavigationBarController;
|
mCarNavigationBarController = carNavigationBarController;
|
||||||
mNotificationPanelViewController = notificationPanelViewController;
|
mNotificationPanelViewController = notificationPanelViewController;
|
||||||
mCarServiceProvider = carServiceProvider;
|
|
||||||
mPowerManagerHelper = powerManagerHelper;
|
mPowerManagerHelper = powerManagerHelper;
|
||||||
mCarDeviceProvisionedController = carDeviceProvisionedController;
|
mCarDeviceProvisionedController = carDeviceProvisionedController;
|
||||||
mConfigurationController = configurationController;
|
mConfigurationController = configurationController;
|
||||||
@@ -72,7 +68,17 @@ public class NotificationPanelViewMediator implements OverlayViewMediator,
|
|||||||
mNotificationPanelViewController.getNavBarNotificationTouchListener());
|
mNotificationPanelViewController.getNavBarNotificationTouchListener());
|
||||||
|
|
||||||
mCarNavigationBarController.registerNotificationController(
|
mCarNavigationBarController.registerNotificationController(
|
||||||
() -> mNotificationPanelViewController.toggle());
|
new CarNavigationBarController.NotificationsShadeController() {
|
||||||
|
@Override
|
||||||
|
public void togglePanel() {
|
||||||
|
mNotificationPanelViewController.toggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNotificationPanelOpen() {
|
||||||
|
return mNotificationPanelViewController.isPanelExpanded();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -314,6 +314,9 @@ public class CarNavigationBarController {
|
|||||||
public interface NotificationsShadeController {
|
public interface NotificationsShadeController {
|
||||||
/** Toggles the visibility of the notifications shade. */
|
/** Toggles the visibility of the notifications shade. */
|
||||||
void togglePanel();
|
void togglePanel();
|
||||||
|
|
||||||
|
/** Returns {@code true} if the panel is open. */
|
||||||
|
boolean isNotificationPanelOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAllBars(boolean isSetUp) {
|
private void checkAllBars(boolean isSetUp) {
|
||||||
|
|||||||
@@ -35,10 +35,11 @@ import com.android.systemui.statusbar.phone.StatusBarIconController;
|
|||||||
* in a linear layout.
|
* in a linear layout.
|
||||||
*/
|
*/
|
||||||
public class CarNavigationBarView extends LinearLayout {
|
public class CarNavigationBarView extends LinearLayout {
|
||||||
|
private final boolean mConsumeTouchWhenPanelOpen;
|
||||||
|
|
||||||
private View mNavButtons;
|
private View mNavButtons;
|
||||||
private CarNavigationButton mNotificationsButton;
|
private CarNavigationButton mNotificationsButton;
|
||||||
private NotificationsShadeController mNotificationsShadeController;
|
private NotificationsShadeController mNotificationsShadeController;
|
||||||
private Context mContext;
|
|
||||||
private View mLockScreenButtons;
|
private View mLockScreenButtons;
|
||||||
// used to wire in open/close gestures for notifications
|
// used to wire in open/close gestures for notifications
|
||||||
private OnTouchListener mStatusBarWindowTouchListener;
|
private OnTouchListener mStatusBarWindowTouchListener;
|
||||||
@@ -46,7 +47,8 @@ public class CarNavigationBarView extends LinearLayout {
|
|||||||
|
|
||||||
public CarNavigationBarView(Context context, AttributeSet attrs) {
|
public CarNavigationBarView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
mContext = context;
|
mConsumeTouchWhenPanelOpen = getResources().getBoolean(
|
||||||
|
R.bool.config_consumeNavigationBarTouchWhenNotificationPanelOpen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -77,9 +79,16 @@ public class CarNavigationBarView extends LinearLayout {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||||
if (mStatusBarWindowTouchListener != null) {
|
if (mStatusBarWindowTouchListener != null) {
|
||||||
|
boolean shouldConsumeEvent = mNotificationsShadeController == null ? false
|
||||||
|
: mNotificationsShadeController.isNotificationPanelOpen();
|
||||||
|
|
||||||
// Forward touch events to the status bar window so it can drag
|
// Forward touch events to the status bar window so it can drag
|
||||||
// windows if required (Notification shade)
|
// windows if required (Notification shade)
|
||||||
mStatusBarWindowTouchListener.onTouch(this, ev);
|
mStatusBarWindowTouchListener.onTouch(this, ev);
|
||||||
|
|
||||||
|
if (mConsumeTouchWhenPanelOpen && shouldConsumeEvent) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return super.onInterceptTouchEvent(ev);
|
return super.onInterceptTouchEvent(ev);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user