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:
@@ -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",
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
88
packages/CarSystemUI/tests/Android.mk
Normal file
88
packages/CarSystemUI/tests/Android.mk
Normal 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 :=
|
||||
40
packages/CarSystemUI/tests/AndroidManifest.xml
Normal file
40
packages/CarSystemUI/tests/AndroidManifest.xml
Normal 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>
|
||||
30
packages/CarSystemUI/tests/AndroidTest.xml
Normal file
30
packages/CarSystemUI/tests/AndroidTest.xml
Normal 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>
|
||||
23
packages/CarSystemUI/tests/res/values/config.xml
Normal file
23
packages/CarSystemUI/tests/res/values/config.xml
Normal 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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user