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:
Heemin Seog
2020-04-06 16:38:08 +00:00
committed by Automerger Merge Worker
7 changed files with 192 additions and 7 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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>

View File

@@ -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();
}
}