Setup on device testing for sys ui

This borrows on the testing infrastructure set up by the phone sys ui
team and provides an examples via test for CarNavigationBarController.

Bug: 143227120
Test: atest CarNavigationBarControllerTest
Change-Id: I10fd4e2e51f2faf75ade5b40e47441a9e948f075
This commit is contained in:
Heemin Seog
2019-10-23 16:52:31 -07:00
parent ec2b60ef29
commit d0cfab0964
8 changed files with 784 additions and 4 deletions

View File

@@ -63,6 +63,64 @@ android_library {
}
android_library {
name: "CarSystemUI-tests",
manifest: "tests/AndroidManifest.xml",
resource_dirs: [
"tests/res",
"res-keyguard",
"res",
],
srcs: [
"tests/src/**/*.java",
"src/**/*.java",
"src/**/I*.aidl",
],
static_libs: [
"SystemUI-tests",
"CarNotificationLib",
"SystemUIPluginLib",
"SystemUISharedLib",
"SettingsLib",
"android.car.userlib",
"androidx.legacy_legacy-support-v4",
"androidx.recyclerview_recyclerview",
"androidx.preference_preference",
"androidx.appcompat_appcompat",
"androidx.mediarouter_mediarouter",
"androidx.palette_palette",
"androidx.legacy_legacy-preference-v14",
"androidx.leanback_leanback",
"androidx.slice_slice-core",
"androidx.slice_slice-view",
"androidx.slice_slice-builders",
"androidx.arch.core_core-runtime",
"androidx.lifecycle_lifecycle-extensions",
"SystemUI-tags",
"SystemUI-proto",
"metrics-helper-lib",
"androidx.test.rules", "hamcrest-library",
"mockito-target-inline-minus-junit4",
"testables",
"truth-prebuilt",
"dagger2-2.19",
"//external/kotlinc:kotlin-annotations",
],
libs: [
"android.test.runner",
"telephony-common",
"android.test.base",
"android.car",
],
aaptflags: [
"--extra-packages",
"com.android.systemui",
],
plugins: ["dagger2-compiler-2.19"],
}
android_app {
name: "CarSystemUI",

View File

@@ -24,6 +24,7 @@ import android.widget.LinearLayout;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.navigationbar.car.CarNavigationBarController.NotificationsShadeController;
import com.android.systemui.statusbar.phone.StatusBarIconController;
/**
@@ -35,7 +36,7 @@ import com.android.systemui.statusbar.phone.StatusBarIconController;
public class CarNavigationBarView extends LinearLayout {
private View mNavButtons;
private CarNavigationButton mNotificationsButton;
private CarNavigationBarController.NotificationsShadeController mNotificationsShadeController;
private NotificationsShadeController mNotificationsShadeController;
private Context mContext;
private View mLockScreenButtons;
// used to wire in open/close gestures for notifications
@@ -81,13 +82,18 @@ public class CarNavigationBarView extends LinearLayout {
return super.onInterceptTouchEvent(ev);
}
public void setNotificationsPanelController(
CarNavigationBarController.NotificationsShadeController controller) {
/** Sets the notifications panel controller. */
public void setNotificationsPanelController(NotificationsShadeController controller) {
mNotificationsShadeController = controller;
}
/** Gets the notifications panel controller. */
public NotificationsShadeController getNotificationsPanelController() {
return mNotificationsShadeController;
}
/**
* Set a touch listener that will be called from onInterceptTouchEvent and onTouchEvent
* Sets a touch listener that will be called from onInterceptTouchEvent and onTouchEvent
*
* @param statusBarWindowTouchListener The listener to call from touch and intercept touch
*/
@@ -95,6 +101,11 @@ public class CarNavigationBarView extends LinearLayout {
mStatusBarWindowTouchListener = statusBarWindowTouchListener;
}
/** Gets the touch listener that will be called from onInterceptTouchEvent and onTouchEvent. */
public OnTouchListener getStatusBarWindowTouchListener() {
return mStatusBarWindowTouchListener;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mStatusBarWindowTouchListener != null) {

View File

@@ -0,0 +1,88 @@
# Copyright (C) 2019 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.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_USE_AAPT2 := true
LOCAL_MODULE_TAGS := tests
LOCAL_JACK_FLAGS := --multi-dex native
LOCAL_DX_FLAGS := --multi-dex
LOCAL_PACKAGE_NAME := CarSystemUITests
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_STATIC_ANDROID_LIBRARIES := \
CarSystemUI-tests
LOCAL_MULTILIB := both
LOCAL_JNI_SHARED_LIBRARIES := \
libdexmakerjvmtiagent \
libmultiplejvmtiagentsinterferenceagent
LOCAL_JAVA_LIBRARIES := \
android.test.runner \
telephony-common \
android.test.base \
LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui
# sign this with platform cert, so this test is allowed to inject key events into
# UI it doesn't own. This is necessary to allow screenshots to be taken
LOCAL_CERTIFICATE := platform
# Provide jack a list of classes to exclude from code coverage.
# This is needed because the CarSystemUITests compile CarSystemUI source directly, rather than using
# LOCAL_INSTRUMENTATION_FOR := CarSystemUI.
#
# We want to exclude the test classes from code coverage measurements, but they share the same
# package as the rest of SystemUI so they can't be easily filtered by package name.
#
# Generate a comma separated list of patterns based on the test source files under src/
# SystemUI classes are in ../src/ so they won't be excluded.
# Example:
# Input files: src/com/android/systemui/Test.java src/com/android/systemui/AnotherTest.java
# Generated exclude list: com.android.systemui.Test*,com.android.systemui.AnotherTest*
# Filter all src files under src/ to just java files
local_java_files := $(filter %.java,$(call all-java-files-under, src))
# Transform java file names into full class names.
# This only works if the class name matches the file name and the directory structure
# matches the package.
local_classes := $(subst /,.,$(patsubst src/%.java,%,$(local_java_files)))
local_comma := ,
local_empty :=
local_space := $(local_empty) $(local_empty)
# Convert class name list to jacoco exclude list
# This appends a * to all classes and replace the space separators with commas.
jacoco_exclude := $(subst $(space),$(comma),$(patsubst %,%*,$(local_classes)))
LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.systemui.*,com.android.keyguard.*
LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := $(jacoco_exclude)
ifeq ($(EXCLUDE_SYSTEMUI_TESTS),)
include $(BUILD_PACKAGE)
endif
# Reset variables
local_java_files :=
local_classes :=
local_comma :=
local_space :=
jacoco_exclude :=

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2019 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:sharedUserId="android.uid.system"
package="com.android.systemui.tests">
<application android:debuggable="true" android:largeHeap="true">
<uses-library android:name="android.test.runner" />
<provider
android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
tools:replace="android:authorities"
android:authorities="${applicationId}.lifecycle-tests"
android:exported="false"
android:enabled="false"
android:multiprocess="true" />
</application>
<instrumentation android:name="android.testing.TestableInstrumentation"
android:targetPackage="com.android.systemui.tests"
android:label="Tests for CarSystemUI">
</instrumentation>
</manifest>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2019 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.
-->
<configuration description="Runs Tests for CarSystemUI.">
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="CarSystemUITests.apk" />
</target_preparer>
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="framework-base-presubmit" />
<option name="test-tag" value="CarSystemUITests" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.systemui.tests" />
<option name="runner" value="android.testing.TestableInstrumentation" />
<option name="hidden-api-checks" value="false"/>
</test>
</configuration>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2019 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.
-->
<resources>
<!-- Configure which system ui bars should be displayed.
These can be overwritten within the tests. -->
<bool name="config_enableLeftNavigationBar">false</bool>
<bool name="config_enableRightNavigationBar">false</bool>
<bool name="config_enableBottomNavigationBar">false</bool>
</resources>

View File

@@ -0,0 +1,214 @@
/*
* Copyright (C) 2019 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;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import android.testing.AndroidTestingRunner;
import android.text.TextUtils;
import android.util.Log;
import androidx.test.filters.LargeTest;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
import androidx.test.internal.runner.ClassPathScanner;
import androidx.test.internal.runner.ClassPathScanner.ChainedClassNameFilter;
import androidx.test.internal.runner.ClassPathScanner.ExternalClassNameFilter;
import com.android.systemui.SysuiBaseFragmentTest;
import com.android.systemui.SysuiTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
/**
* This is named AAAPlusPlusVerifySysuiRequiredTestPropertiesTest for two reasons.
* a) Its so awesome it deserves an AAA++
* b) It should run first to draw attention to itself.
*
* For trues though: this test verifies that all the sysui tests extend the right classes.
* This matters because including tests with different context implementations in the same
* test suite causes errors, such as the incorrect settings provider being cached.
* For an example, see {@link com.android.systemui.DependencyTest}.
*/
@RunWith(AndroidTestingRunner.class)
@SmallTest
public class AAAPlusPlusVerifySysuiRequiredTestPropertiesTest extends SysuiTestCase {
private static final String TAG = "AAA++VerifyTest";
private static final Class[] BASE_CLS_WHITELIST = {
SysuiTestCase.class,
SysuiBaseFragmentTest.class,
};
private static final Class[] SUPPORTED_SIZES = {
SmallTest.class,
MediumTest.class,
LargeTest.class,
android.test.suitebuilder.annotation.SmallTest.class,
android.test.suitebuilder.annotation.MediumTest.class,
android.test.suitebuilder.annotation.LargeTest.class,
};
@Test
public void testAllClassInheritance() throws Throwable {
ArrayList<String> fails = new ArrayList<>();
for (String className : getClassNamesFromClassPath()) {
Class<?> cls = Class.forName(className, false, this.getClass().getClassLoader());
if (!isTestClass(cls)) continue;
boolean hasParent = false;
for (Class<?> parent : BASE_CLS_WHITELIST) {
if (parent.isAssignableFrom(cls)) {
hasParent = true;
break;
}
}
boolean hasSize = hasSize(cls);
if (!hasSize) {
fails.add(cls.getName() + " does not have size annotation, such as @SmallTest");
}
if (!hasParent) {
fails.add(cls.getName() + " does not extend any of " + getClsStr());
}
}
assertThat("All sysui test classes must have size and extend one of " + getClsStr(),
fails, is(empty()));
}
private boolean hasSize(Class<?> cls) {
for (int i = 0; i < SUPPORTED_SIZES.length; i++) {
if (cls.getDeclaredAnnotation(SUPPORTED_SIZES[i]) != null) return true;
}
return false;
}
private Collection<String> getClassNamesFromClassPath() {
ClassPathScanner scanner = new ClassPathScanner(mContext.getPackageCodePath());
ChainedClassNameFilter filter = new ChainedClassNameFilter();
filter.add(new ExternalClassNameFilter());
filter.add(s -> s.startsWith("com.android.systemui")
|| s.startsWith("com.android.keyguard"));
try {
return scanner.getClassPathEntries(filter);
} catch (IOException e) {
Log.e(TAG, "Failed to scan classes", e);
}
return Collections.emptyList();
}
private String getClsStr() {
return TextUtils.join(",", Arrays.asList(BASE_CLS_WHITELIST)
.stream().map(cls -> cls.getSimpleName()).toArray());
}
/**
* Determines if given class is a valid test class.
*
* @return <code>true</code> if loadedClass is a test
*/
private boolean isTestClass(Class<?> loadedClass) {
try {
if (Modifier.isAbstract(loadedClass.getModifiers())) {
logDebug(String.format("Skipping abstract class %s: not a test",
loadedClass.getName()));
return false;
}
// TODO: try to find upstream junit calls to replace these checks
if (junit.framework.Test.class.isAssignableFrom(loadedClass)) {
// ensure that if a TestCase, it has at least one test method otherwise
// TestSuite will throw error
if (junit.framework.TestCase.class.isAssignableFrom(loadedClass)) {
return hasJUnit3TestMethod(loadedClass);
}
return true;
}
// TODO: look for a 'suite' method?
if (loadedClass.isAnnotationPresent(RunWith.class)) {
return true;
}
for (Method testMethod : loadedClass.getMethods()) {
if (testMethod.isAnnotationPresent(Test.class)) {
return true;
}
}
logDebug(String.format("Skipping class %s: not a test", loadedClass.getName()));
return false;
} catch (Exception e) {
// Defensively catch exceptions - Will throw runtime exception if it cannot load
// methods.
// For earlier versions of Android (Pre-ICS), Dalvik might try to initialize a class
// during getMethods(), fail to do so, hide the error and throw a NoSuchMethodException.
// Since the java.lang.Class.getMethods does not declare such an exception, resort to a
// generic catch all.
// For ICS+, Dalvik will throw a NoClassDefFoundException.
Log.w(TAG, String.format("%s in isTestClass for %s", e.toString(),
loadedClass.getName()));
return false;
} catch (Error e) {
// defensively catch Errors too
Log.w(TAG, String.format("%s in isTestClass for %s", e.toString(),
loadedClass.getName()));
return false;
}
}
private boolean hasJUnit3TestMethod(Class<?> loadedClass) {
for (Method testMethod : loadedClass.getMethods()) {
if (isPublicTestMethod(testMethod)) {
return true;
}
}
return false;
}
// copied from junit.framework.TestSuite
private boolean isPublicTestMethod(Method m) {
return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
}
// copied from junit.framework.TestSuite
private boolean isTestMethod(Method m) {
return m.getParameterTypes().length == 0 && m.getName().startsWith("test")
&& m.getReturnType().equals(Void.TYPE);
}
/**
* Utility method for logging debug messages. Only actually logs a message if TAG is marked
* as loggable to limit log spam during normal use.
*/
private void logDebug(String msg) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, msg);
}
}
}

View File

@@ -0,0 +1,316 @@
/*
* Copyright (C) 2019 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.mock;
import static org.mockito.Mockito.verify;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableResources;
import android.view.View;
import android.view.ViewGroup;
import androidx.test.filters.SmallTest;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.car.hvac.HvacController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import dagger.Lazy;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@SmallTest
public class CarNavigationBarControllerTest extends SysuiTestCase {
private CarNavigationBarController mCarNavigationBar;
private NavigationBarViewFactory mNavigationBarViewFactory;
private Lazy<HvacController> mHvacControllerLazy;
private TestableResources mTestableResources;
@Mock
private HvacController mHvacController;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mNavigationBarViewFactory = new NavigationBarViewFactory(mContext);
mHvacControllerLazy = () -> mHvacController;
mTestableResources = mContext.getOrCreateTestableResources();
}
@Test
public void testConnectToHvac_callsConnect() {
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
mCarNavigationBar.connectToHvac();
verify(mHvacController).connectToCarService();
}
@Test
public void testRemoveAllFromHvac_callsRemoveAll() {
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
mCarNavigationBar.removeAllFromHvac();
verify(mHvacController).removeAllComponents();
}
@Test
public void testGetBottomWindow_bottomDisabled_returnsNull() {
mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, false);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window = mCarNavigationBar.getBottomWindow();
assertThat(window).isNull();
}
@Test
public void testGetBottomWindow_bottomEnabled_returnsWindow() {
mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window = mCarNavigationBar.getBottomWindow();
assertThat(window).isNotNull();
}
@Test
public void testGetBottomWindow_bottomEnabled_calledTwice_returnsSameWindow() {
mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window1 = mCarNavigationBar.getBottomWindow();
ViewGroup window2 = mCarNavigationBar.getBottomWindow();
assertThat(window1).isEqualTo(window2);
}
@Test
public void testGetLeftWindow_leftDisabled_returnsNull() {
mTestableResources.addOverride(R.bool.config_enableLeftNavigationBar, false);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window = mCarNavigationBar.getLeftWindow();
assertThat(window).isNull();
}
@Test
public void testGetLeftWindow_leftEnabled_returnsWindow() {
mTestableResources.addOverride(R.bool.config_enableLeftNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window = mCarNavigationBar.getLeftWindow();
assertThat(window).isNotNull();
}
@Test
public void testGetLeftWindow_leftEnabled_calledTwice_returnsSameWindow() {
mTestableResources.addOverride(R.bool.config_enableLeftNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window1 = mCarNavigationBar.getLeftWindow();
ViewGroup window2 = mCarNavigationBar.getLeftWindow();
assertThat(window1).isEqualTo(window2);
}
@Test
public void testGetRightWindow_rightDisabled_returnsNull() {
mTestableResources.addOverride(R.bool.config_enableRightNavigationBar, false);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window = mCarNavigationBar.getRightWindow();
assertThat(window).isNull();
}
@Test
public void testGetRightWindow_rightEnabled_returnsWindow() {
mTestableResources.addOverride(R.bool.config_enableRightNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window = mCarNavigationBar.getRightWindow();
assertThat(window).isNotNull();
}
@Test
public void testGetRightWindow_rightEnabled_calledTwice_returnsSameWindow() {
mTestableResources.addOverride(R.bool.config_enableRightNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window1 = mCarNavigationBar.getRightWindow();
ViewGroup window2 = mCarNavigationBar.getRightWindow();
assertThat(window1).isEqualTo(window2);
}
@Test
public void testSetBottomWindowVisibility_setTrue_isVisible() {
mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window = mCarNavigationBar.getBottomWindow();
mCarNavigationBar.setBottomWindowVisibility(true);
assertThat(window.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void testSetBottomWindowVisibility_setFalse_isGone() {
mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window = mCarNavigationBar.getBottomWindow();
mCarNavigationBar.setBottomWindowVisibility(false);
assertThat(window.getVisibility()).isEqualTo(View.GONE);
}
@Test
public void testSetLeftWindowVisibility_setTrue_isVisible() {
mTestableResources.addOverride(R.bool.config_enableLeftNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window = mCarNavigationBar.getLeftWindow();
mCarNavigationBar.setLeftWindowVisibility(true);
assertThat(window.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void testSetLeftWindowVisibility_setFalse_isGone() {
mTestableResources.addOverride(R.bool.config_enableLeftNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window = mCarNavigationBar.getLeftWindow();
mCarNavigationBar.setLeftWindowVisibility(false);
assertThat(window.getVisibility()).isEqualTo(View.GONE);
}
@Test
public void testSetRightWindowVisibility_setTrue_isVisible() {
mTestableResources.addOverride(R.bool.config_enableRightNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window = mCarNavigationBar.getRightWindow();
mCarNavigationBar.setRightWindowVisibility(true);
assertThat(window.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void testSetRightWindowVisibility_setFalse_isGone() {
mTestableResources.addOverride(R.bool.config_enableRightNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
ViewGroup window = mCarNavigationBar.getRightWindow();
mCarNavigationBar.setRightWindowVisibility(false);
assertThat(window.getVisibility()).isEqualTo(View.GONE);
}
@Test
public void testRegisterBottomBarTouchListener_createViewFirst_registrationSuccessful() {
mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
CarNavigationBarView bottomBar = mCarNavigationBar.getBottomBar(/* isSetUp= */ true);
View.OnTouchListener controller = bottomBar.getStatusBarWindowTouchListener();
assertThat(controller).isNull();
mCarNavigationBar.registerBottomBarTouchListener(mock(View.OnTouchListener.class));
controller = bottomBar.getStatusBarWindowTouchListener();
assertThat(controller).isNotNull();
}
@Test
public void testRegisterBottomBarTouchListener_registerFirst_registrationSuccessful() {
mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
mCarNavigationBar.registerBottomBarTouchListener(mock(View.OnTouchListener.class));
CarNavigationBarView bottomBar = mCarNavigationBar.getBottomBar(/* isSetUp= */ true);
View.OnTouchListener controller = bottomBar.getStatusBarWindowTouchListener();
assertThat(controller).isNotNull();
}
@Test
public void testRegisterNotificationController_createViewFirst_registrationSuccessful() {
mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
CarNavigationBarView bottomBar = mCarNavigationBar.getBottomBar(/* isSetUp= */ true);
CarNavigationBarController.NotificationsShadeController controller =
bottomBar.getNotificationsPanelController();
assertThat(controller).isNull();
mCarNavigationBar.registerNotificationController(
mock(CarNavigationBarController.NotificationsShadeController.class));
controller = bottomBar.getNotificationsPanelController();
assertThat(controller).isNotNull();
}
@Test
public void testRegisterNotificationController_registerFirst_registrationSuccessful() {
mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mHvacControllerLazy);
mCarNavigationBar.registerNotificationController(
mock(CarNavigationBarController.NotificationsShadeController.class));
CarNavigationBarView bottomBar = mCarNavigationBar.getBottomBar(/* isSetUp= */ true);
CarNavigationBarController.NotificationsShadeController controller =
bottomBar.getNotificationsPanelController();
assertThat(controller).isNotNull();
}
}