From f7fed3c20b67de91de1b4db32a6ae9b7897a5746 Mon Sep 17 00:00:00 2001 From: Jordan Demeulenaere Date: Thu, 28 Jul 2022 18:06:49 +0200 Subject: Move SystemUI test utils to SystemUI/tests/utils/ (1/2) This CL moves all the SystemUI-test-utils files to a separate SystemUI/tests/utils/ directory. This paves the way towards making this filegroup a reusable library instead. The files have been move using a small bash script [1]. [1] https://paste.googleplex.com/5565628199993344 Bug: 240431193 Test: m SystemUI-tests SystemUIGoogleTests SystemUIGoogleScreenshotTests ArcSystemUI-test Change-Id: I43ff578be211f1ef3f9c5bffd5c65771ef1492dc --- packages/SystemUI/Android.bp | 26 +- .../android/systemui/SysuiBaseFragmentTest.java | 104 ------ .../src/com/android/systemui/SysuiTestCase.java | 254 --------------- .../com/android/systemui/SysuiTestableContext.java | 149 --------- .../com/android/systemui/TestableDependency.java | 62 ---- .../systemui/broadcast/FakeBroadcastDispatcher.kt | 81 ----- .../systemui/classifier/FalsingManagerFake.java | 175 ---------- .../screenshot/FakeScrollCaptureConnection.java | 142 --------- .../android/systemui/screenshot/FakeSession.java | 196 ------------ .../android/systemui/statusbar/RankingBuilder.java | 254 --------------- .../com/android/systemui/statusbar/SbnBuilder.java | 191 ----------- .../collection/NotificationEntryBuilder.java | 353 --------------------- .../policy/FakeConfigurationController.kt | 35 -- .../systemui/util/DeviceConfigProxyFake.java | 154 --------- .../systemui/util/concurrency/FakeExecutor.java | 223 ------------- .../util/concurrency/FakeRepeatableExecutor.java | 34 -- .../util/concurrency/FakeThreadFactory.java | 73 ----- .../systemui/util/condition/FakeCondition.java | 33 -- .../systemui/util/io/FakeBasicFileAttributes.java | 126 -------- .../systemui/util/sensors/FakeProximitySensor.java | 67 ---- .../systemui/util/sensors/FakeSensorManager.java | 293 ----------------- .../systemui/util/sensors/FakeThresholdSensor.java | 91 ------ .../systemui/util/settings/FakeSettings.java | 152 --------- .../systemui/util/time/FakeSystemClock.java | 128 -------- .../systemui/util/wakelock/WakeLockFake.java | 73 ----- .../systemui/utils/leaks/BaseLeakChecker.java | 51 --- .../utils/leaks/FakeBatteryController.java | 77 ----- .../utils/leaks/FakeBluetoothController.java | 113 ------- .../systemui/utils/leaks/FakeCastController.java | 54 ---- .../utils/leaks/FakeConfigurationController.java | 41 --- .../utils/leaks/FakeDataSaverController.java | 37 --- .../utils/leaks/FakeExtensionController.java | 130 -------- .../utils/leaks/FakeFlashlightController.java | 47 --- .../utils/leaks/FakeHotspotController.java | 52 --- .../utils/leaks/FakeKeyguardStateController.java | 140 -------- .../utils/leaks/FakeLocationController.java | 42 --- .../utils/leaks/FakeManagedProfileController.java | 42 --- .../utils/leaks/FakeNetworkController.java | 107 ------- .../utils/leaks/FakeNextAlarmController.java | 28 -- .../systemui/utils/leaks/FakePluginManager.java | 68 ---- .../utils/leaks/FakeRotationLockController.java | 62 ---- .../utils/leaks/FakeSecurityController.java | 150 --------- .../utils/leaks/FakeStatusBarIconController.java | 96 ------ .../systemui/utils/leaks/FakeTunerService.java | 91 ------ .../utils/leaks/FakeUserInfoController.java | 32 -- .../utils/leaks/FakeZenModeController.java | 91 ------ .../systemui/utils/leaks/LeakCheckedTest.java | 147 --------- .../com/android/systemui/utils/os/FakeHandler.java | 71 ----- packages/SystemUI/tests/utils/AndroidManifest.xml | 23 ++ .../android/systemui/SysuiBaseFragmentTest.java | 104 ++++++ .../src/com/android/systemui/SysuiTestCase.java | 254 +++++++++++++++ .../com/android/systemui/SysuiTestableContext.java | 149 +++++++++ .../com/android/systemui/TestableDependency.java | 62 ++++ .../systemui/broadcast/FakeBroadcastDispatcher.kt | 81 +++++ .../systemui/classifier/FalsingManagerFake.java | 175 ++++++++++ .../systemui/people/FakePeopleTileRepository.kt | 30 ++ .../systemui/people/FakePeopleWidgetRepository.kt | 29 ++ .../screenshot/FakeScrollCaptureConnection.java | 142 +++++++++ .../android/systemui/screenshot/FakeSession.java | 196 ++++++++++++ .../android/systemui/statusbar/RankingBuilder.java | 254 +++++++++++++++ .../com/android/systemui/statusbar/SbnBuilder.java | 191 +++++++++++ .../collection/NotificationEntryBuilder.java | 353 +++++++++++++++++++++ .../policy/FakeConfigurationController.kt | 35 ++ .../systemui/util/DeviceConfigProxyFake.java | 154 +++++++++ .../systemui/util/concurrency/FakeExecutor.java | 223 +++++++++++++ .../util/concurrency/FakeRepeatableExecutor.java | 34 ++ .../util/concurrency/FakeThreadFactory.java | 73 +++++ .../systemui/util/condition/FakeCondition.java | 33 ++ .../systemui/util/io/FakeBasicFileAttributes.java | 126 ++++++++ .../systemui/util/sensors/FakeProximitySensor.java | 67 ++++ .../systemui/util/sensors/FakeSensorManager.java | 293 +++++++++++++++++ .../systemui/util/sensors/FakeThresholdSensor.java | 91 ++++++ .../systemui/util/settings/FakeSettings.java | 152 +++++++++ .../systemui/util/time/FakeSystemClock.java | 128 ++++++++ .../systemui/util/wakelock/WakeLockFake.java | 73 +++++ .../systemui/utils/leaks/BaseLeakChecker.java | 51 +++ .../utils/leaks/FakeBatteryController.java | 77 +++++ .../utils/leaks/FakeBluetoothController.java | 113 +++++++ .../systemui/utils/leaks/FakeCastController.java | 54 ++++ .../utils/leaks/FakeConfigurationController.java | 41 +++ .../utils/leaks/FakeDataSaverController.java | 37 +++ .../utils/leaks/FakeExtensionController.java | 130 ++++++++ .../utils/leaks/FakeFlashlightController.java | 47 +++ .../utils/leaks/FakeHotspotController.java | 52 +++ .../utils/leaks/FakeKeyguardStateController.java | 140 ++++++++ .../utils/leaks/FakeLocationController.java | 42 +++ .../utils/leaks/FakeManagedProfileController.java | 42 +++ .../utils/leaks/FakeNetworkController.java | 107 +++++++ .../utils/leaks/FakeNextAlarmController.java | 28 ++ .../systemui/utils/leaks/FakePluginManager.java | 68 ++++ .../utils/leaks/FakeRotationLockController.java | 62 ++++ .../utils/leaks/FakeSecurityController.java | 150 +++++++++ .../utils/leaks/FakeStatusBarIconController.java | 96 ++++++ .../systemui/utils/leaks/FakeTunerService.java | 91 ++++++ .../utils/leaks/FakeUserInfoController.java | 32 ++ .../utils/leaks/FakeZenModeController.java | 91 ++++++ .../systemui/utils/leaks/LeakCheckedTest.java | 147 +++++++++ .../com/android/systemui/utils/os/FakeHandler.java | 71 +++++ 98 files changed, 5300 insertions(+), 5232 deletions(-) delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerFake.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeScrollCaptureConnection.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSession.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/SbnBuilder.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/util/DeviceConfigProxyFake.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutor.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeRepeatableExecutor.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeThreadFactory.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/util/condition/FakeCondition.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/util/io/FakeBasicFileAttributes.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeSensorManager.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeThresholdSensor.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/util/settings/FakeSettings.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockFake.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/BaseLeakChecker.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBluetoothController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeCastController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeDataSaverController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeExtensionController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeFlashlightController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeHotspotController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeLocationController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeManagedProfileController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNextAlarmController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeRotationLockController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeTunerService.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeUserInfoController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeZenModeController.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/utils/os/FakeHandler.java create mode 100644 packages/SystemUI/tests/utils/AndroidManifest.xml create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/SysuiBaseFragmentTest.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/TestableDependency.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingManagerFake.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/people/FakePeopleTileRepository.kt create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/people/FakePeopleWidgetRepository.kt create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/screenshot/FakeScrollCaptureConnection.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/screenshot/FakeSession.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/RankingBuilder.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SbnBuilder.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/util/DeviceConfigProxyFake.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeExecutor.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeRepeatableExecutor.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeThreadFactory.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/util/condition/FakeCondition.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/util/io/FakeBasicFileAttributes.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/util/sensors/FakeProximitySensor.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/util/sensors/FakeSensorManager.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/util/sensors/FakeThresholdSensor.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClock.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/util/wakelock/WakeLockFake.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/BaseLeakChecker.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeBatteryController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeBluetoothController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeCastController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeConfigurationController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeDataSaverController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeExtensionController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeFlashlightController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeHotspotController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeLocationController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeManagedProfileController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeNetworkController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeNextAlarmController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakePluginManager.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeRotationLockController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeSecurityController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeTunerService.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeUserInfoController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeZenModeController.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckedTest.java create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/utils/os/FakeHandler.java (limited to 'packages/SystemUI') diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index ffd6b522e394..9a261bf0da55 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -145,25 +145,10 @@ filegroup { filegroup { name: "SystemUI-tests-utils", srcs: [ - "tests/src/com/android/systemui/SysuiBaseFragmentTest.java", - "tests/src/com/android/systemui/SysuiTestCase.java", - "tests/src/com/android/systemui/TestableDependency.java", - "tests/src/com/android/systemui/classifier/FalsingManagerFake.java", - "tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java", - "tests/src/com/android/systemui/statusbar/RankingBuilder.java", - "tests/src/com/android/systemui/statusbar/SbnBuilder.java", - "tests/src/com/android/systemui/SysuiTestableContext.java", - "tests/src/com/android/systemui/util/**/*Fake.java", - "tests/src/com/android/systemui/utils/leaks/BaseLeakChecker.java", - "tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java", - "tests/src/com/android/systemui/**/Fake*.java", - "tests/src/com/android/systemui/**/Fake*.kt", + "tests/utils/src/**/*.java", + "tests/utils/src/**/*.kt", ], - exclude_srcs: [ - "tests/src/com/android/systemui/**/*Test.java", - "tests/src/com/android/systemui/**/*Test.kt", - ], - path: "tests/src", + path: "tests/utils/src", } java_library { @@ -171,8 +156,8 @@ java_library { srcs: [ "src/com/android/systemui/util/concurrency/DelayableExecutor.java", "src/com/android/systemui/util/time/SystemClock.java", - "tests/src/com/android/systemui/util/concurrency/FakeExecutor.java", - "tests/src/com/android/systemui/util/time/FakeSystemClock.java", + "tests/utils/src/com/android/systemui/util/concurrency/FakeExecutor.java", + "tests/utils/src/com/android/systemui/util/time/FakeSystemClock.java", ], jarjar_rules: ":jarjar-rules-shared", } @@ -195,6 +180,7 @@ android_library { "src/**/*.java", "src/**/I*.aidl", ":ReleaseJavaFiles", + ":SystemUI-tests-utils", ], static_libs: [ "WifiTrackerLib", diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java deleted file mode 100644 index 9179efc9f39f..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2017 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; - -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import android.app.Fragment; -import android.app.Instrumentation; -import android.testing.BaseFragmentTest; -import android.testing.DexmakerShareClassLoaderRule; - -import androidx.test.InstrumentationRegistry; - -import com.android.systemui.assist.AssistManager; -import com.android.systemui.utils.leaks.LeakCheckedTest; -import com.android.systemui.utils.leaks.LeakCheckedTest.SysuiLeakCheck; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.Rule; -import org.mockito.Mockito; - -import java.util.concurrent.ExecutionException; - -public abstract class SysuiBaseFragmentTest extends BaseFragmentTest { - - public static final Class[] ALL_SUPPORTED_CLASSES = LeakCheckedTest.ALL_SUPPORTED_CLASSES; - - @Rule - public final SysuiLeakCheck mLeakCheck = new SysuiLeakCheck(); - - @Rule - public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule = - new DexmakerShareClassLoaderRule(); - - protected TestableDependency mDependency; - protected SysuiTestableContext mSysuiContext; - private Instrumentation mRealInstrumentation; - - public SysuiBaseFragmentTest(Class cls) { - super(cls); - } - - @Before - public void sysuiSetup() throws ExecutionException, InterruptedException { - SystemUIInitializer initializer = - SystemUIInitializerFactory.createFromConfigNoAssert(mContext); - initializer.init(true); - mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency()); - Dependency.setInstance(mDependency); - - // TODO: Figure out another way to give reference to a SysuiTestableContext. - mSysuiContext = (SysuiTestableContext) mContext; - - mRealInstrumentation = InstrumentationRegistry.getInstrumentation(); - Instrumentation inst = spy(mRealInstrumentation); - when(inst.getContext()).thenThrow(new RuntimeException( - "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext")); - when(inst.getTargetContext()).thenThrow(new RuntimeException( - "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext")); - InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments()); - mDependency.injectMockDependency(AssistManager.class); - } - - @After - public void SysuiTeardown() { - InstrumentationRegistry.registerInstance(mRealInstrumentation, - InstrumentationRegistry.getArguments()); - } - - @AfterClass - public static void mockitoTeardown() { - Mockito.framework().clearInlineMocks(); - } - - @Override - protected SysuiTestableContext getContext() { - return new SysuiTestableContext(InstrumentationRegistry.getContext(), mLeakCheck); - } - - public void injectLeakCheckedDependencies(Class... cls) { - for (Class c : cls) { - injectLeakCheckedDependency(c); - } - } - - public void injectLeakCheckedDependency(Class c) { - mDependency.injectTestDependency(c, mLeakCheck.getLeakChecker(c)); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java deleted file mode 100644 index c52ea60f0bfc..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (C) 2014 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; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import android.app.Instrumentation; -import android.os.Handler; -import android.os.Looper; -import android.os.MessageQueue; -import android.os.ParcelFileDescriptor; -import android.testing.DexmakerShareClassLoaderRule; -import android.testing.LeakCheck; -import android.testing.TestableLooper; -import android.util.Log; - -import androidx.test.InstrumentationRegistry; -import androidx.test.uiautomator.UiDevice; - -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.settingslib.bluetooth.LocalBluetoothManager; -import com.android.systemui.broadcast.BroadcastDispatcher; -import com.android.systemui.broadcast.FakeBroadcastDispatcher; -import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger; -import com.android.systemui.classifier.FalsingManagerFake; -import com.android.systemui.dump.DumpManager; -import com.android.systemui.plugins.FalsingManager; -import com.android.systemui.settings.UserTracker; -import com.android.systemui.statusbar.SmartReplyController; -import com.android.systemui.statusbar.phone.SystemUIDialogManager; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.Rule; -import org.mockito.Mockito; - -import java.io.FileInputStream; -import java.io.IOException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; -import java.util.concurrent.Future; - -/** - * Base class that does System UI specific setup. - */ -public abstract class SysuiTestCase { - - private static final String TAG = "SysuiTestCase"; - - private Handler mHandler; - @Rule - public SysuiTestableContext mContext = new SysuiTestableContext( - InstrumentationRegistry.getContext(), getLeakCheck()); - @Rule - public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule = - new DexmakerShareClassLoaderRule(); - public TestableDependency mDependency; - private Instrumentation mRealInstrumentation; - private FakeBroadcastDispatcher mFakeBroadcastDispatcher; - - @Before - public void SysuiSetup() throws Exception { - SystemUIInitializer initializer = - SystemUIInitializerFactory.createFromConfigNoAssert(mContext); - initializer.init(true); - mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency()); - Dependency.setInstance(mDependency); - mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Looper.class), - mock(Executor.class), mock(DumpManager.class), - mock(BroadcastDispatcherLogger.class), mock(UserTracker.class)); - - mRealInstrumentation = InstrumentationRegistry.getInstrumentation(); - Instrumentation inst = spy(mRealInstrumentation); - when(inst.getContext()).thenAnswer(invocation -> { - throw new RuntimeException( - "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"); - }); - when(inst.getTargetContext()).thenAnswer(invocation -> { - throw new RuntimeException( - "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"); - }); - InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments()); - // Many tests end up creating a BroadcastDispatcher. Instead, give them a fake that will - // record receivers registered. They are not actually leaked as they are kept just as a weak - // reference and are never sent to the Context. This will also prevent a real - // BroadcastDispatcher from actually registering receivers. - mDependency.injectTestDependency(BroadcastDispatcher.class, mFakeBroadcastDispatcher); - // A lot of tests get the FalsingManager, often via several layers of indirection. - // None of them actually need it. - mDependency.injectTestDependency(FalsingManager.class, new FalsingManagerFake()); - mDependency.injectMockDependency(KeyguardUpdateMonitor.class); - - // A lot of tests get the LocalBluetoothManager, often via several layers of indirection. - // None of them actually need it. - mDependency.injectMockDependency(LocalBluetoothManager.class); - - // Notifications tests are injecting one of these, causing many classes (including - // KeyguardUpdateMonitor to be created (injected). - // TODO(b/1531701009) Clean up NotificationContentView creation to prevent this - mDependency.injectMockDependency(SmartReplyController.class); - - // Make sure that all tests on any SystemUIDialog does not crash because this dependency - // is missing (constructing the actual one would throw). - // TODO(b/219008720): Remove this. - mDependency.injectMockDependency(SystemUIDialogManager.class); - } - - @After - public void SysuiTeardown() { - InstrumentationRegistry.registerInstance(mRealInstrumentation, - InstrumentationRegistry.getArguments()); - if (TestableLooper.get(this) != null) { - TestableLooper.get(this).processAllMessages(); - } - disallowTestableLooperAsMainThread(); - mContext.cleanUpReceivers(this.getClass().getSimpleName()); - mFakeBroadcastDispatcher.cleanUpReceivers(this.getClass().getSimpleName()); - } - - @AfterClass - public static void mockitoTearDown() { - Mockito.framework().clearInlineMocks(); - } - - /** - * Tests are run on the TestableLooper; however, there are parts of SystemUI that assert that - * the code is run from the main looper. Therefore, we allow the TestableLooper to pass these - * assertions since in a test, the TestableLooper is essentially the MainLooper. - */ - protected void allowTestableLooperAsMainThread() { - com.android.systemui.util.Assert.setTestableLooper(TestableLooper.get(this).getLooper()); - } - - protected void disallowTestableLooperAsMainThread() { - com.android.systemui.util.Assert.setTestableLooper(null); - } - - protected LeakCheck getLeakCheck() { - return null; - } - - protected FakeBroadcastDispatcher getFakeBroadcastDispatcher() { - return mFakeBroadcastDispatcher; - } - - public SysuiTestableContext getContext() { - return mContext; - } - - protected UiDevice getUiDevice() { - return UiDevice.getInstance(mRealInstrumentation); - } - - protected void runShellCommand(String command) throws IOException { - ParcelFileDescriptor pfd = mRealInstrumentation.getUiAutomation() - .executeShellCommand(command); - - // Read the input stream fully. - FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd); - while (fis.read() != -1); - fis.close(); - } - - protected void waitForIdleSync() { - if (mHandler == null) { - mHandler = new Handler(Looper.getMainLooper()); - } - waitForIdleSync(mHandler); - } - - protected void waitForUiOffloadThread() { - Future future = Dependency.get(UiOffloadThread.class).execute(() -> { }); - try { - future.get(); - } catch (InterruptedException | ExecutionException e) { - Log.e(TAG, "Failed to wait for ui offload thread.", e); - } - } - - public static void waitForIdleSync(Handler h) { - validateThread(h.getLooper()); - Idler idler = new Idler(null); - h.getLooper().getQueue().addIdleHandler(idler); - // Ensure we are non-idle, so the idle handler can run. - h.post(new EmptyRunnable()); - idler.waitForIdle(); - } - - private static final void validateThread(Looper l) { - if (Looper.myLooper() == l) { - throw new RuntimeException( - "This method can not be called from the looper being synced"); - } - } - - /** Delegates to {@link android.testing.TestableResources#addOverride(int, Object)}. */ - protected void overrideResource(int resourceId, Object value) { - mContext.getOrCreateTestableResources().addOverride(resourceId, value); - } - - public static final class EmptyRunnable implements Runnable { - public void run() { - } - } - - public static final class Idler implements MessageQueue.IdleHandler { - private final Runnable mCallback; - private boolean mIdle; - - public Idler(Runnable callback) { - mCallback = callback; - mIdle = false; - } - - @Override - public boolean queueIdle() { - if (mCallback != null) { - mCallback.run(); - } - synchronized (this) { - mIdle = true; - notifyAll(); - } - return false; - } - - public void waitForIdle() { - synchronized (this) { - while (!mIdle) { - try { - wait(); - } catch (InterruptedException e) { - } - } - } - } - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java deleted file mode 100644 index 0674ea855d7f..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2017 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; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Handler; -import android.os.UserHandle; -import android.testing.LeakCheck; -import android.testing.TestableContext; -import android.util.ArraySet; -import android.util.Log; -import android.view.Display; - -import com.android.internal.annotations.GuardedBy; - -import java.util.Set; - -public class SysuiTestableContext extends TestableContext { - - @GuardedBy("mRegisteredReceivers") - private final Set mRegisteredReceivers = new ArraySet<>(); - - public SysuiTestableContext(Context base) { - super(base); - setTheme(R.style.Theme_SystemUI); - } - - public SysuiTestableContext(Context base, LeakCheck check) { - super(base, check); - setTheme(R.style.Theme_SystemUI); - } - - @Override - public Context createDisplayContext(Display display) { - if (display == null) { - throw new IllegalArgumentException("display must not be null"); - } - - SysuiTestableContext context = - new SysuiTestableContext(getBaseContext().createDisplayContext(display)); - return context; - } - - public void cleanUpReceivers(String testName) { - Set copy; - synchronized (mRegisteredReceivers) { - copy = new ArraySet<>(mRegisteredReceivers); - mRegisteredReceivers.clear(); - } - for (BroadcastReceiver r : copy) { - try { - unregisterReceiver(r); - Log.w(testName, "Receiver not unregistered from Context: " + r); - } catch (IllegalArgumentException e) { - // Nothing to do here. Somehow it got unregistered. - } - } - } - - @Override - public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { - if (receiver != null) { - synchronized (mRegisteredReceivers) { - mRegisteredReceivers.add(receiver); - } - } - return super.registerReceiver(receiver, filter); - } - - @Override - public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) { - if (receiver != null) { - synchronized (mRegisteredReceivers) { - mRegisteredReceivers.add(receiver); - } - } - return super.registerReceiver(receiver, filter, flags); - } - - @Override - public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, - String broadcastPermission, Handler scheduler) { - if (receiver != null) { - synchronized (mRegisteredReceivers) { - mRegisteredReceivers.add(receiver); - } - } - return super.registerReceiver(receiver, filter, broadcastPermission, scheduler); - } - - @Override - public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, - String broadcastPermission, Handler scheduler, int flags) { - if (receiver != null) { - synchronized (mRegisteredReceivers) { - mRegisteredReceivers.add(receiver); - } - } - return super.registerReceiver(receiver, filter, broadcastPermission, scheduler, flags); - } - - @Override - public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, - IntentFilter filter, String broadcastPermission, Handler scheduler) { - if (receiver != null) { - synchronized (mRegisteredReceivers) { - mRegisteredReceivers.add(receiver); - } - } - return super.registerReceiverAsUser(receiver, user, filter, broadcastPermission, scheduler); - } - - @Override - public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, - IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) { - if (receiver != null) { - synchronized (mRegisteredReceivers) { - mRegisteredReceivers.add(receiver); - } - } - return super.registerReceiverAsUser(receiver, user, filter, broadcastPermission, scheduler, - flags); - } - - @Override - public void unregisterReceiver(BroadcastReceiver receiver) { - if (receiver != null) { - synchronized (mRegisteredReceivers) { - mRegisteredReceivers.remove(receiver); - } - } - super.unregisterReceiver(receiver); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java b/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java deleted file mode 100644 index 0751475c2fb0..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2017 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; - -import static org.mockito.Mockito.mock; - -import android.util.ArrayMap; -import android.util.ArraySet; -import android.util.Log; - -public class TestableDependency extends Dependency { - private static final String TAG = "TestableDependency"; - - private final ArrayMap mObjs = new ArrayMap<>(); - private final ArraySet mInstantiatedObjects = new ArraySet<>(); - private final Dependency mParent; - - public TestableDependency(Dependency parent) { - mParent = parent; - } - - public T injectMockDependency(Class cls) { - final T mock = mock(cls); - injectTestDependency(cls, mock); - return mock; - } - - public void injectTestDependency(DependencyKey key, T obj) { - mObjs.put(key, obj); - } - - public void injectTestDependency(Class key, T obj) { - if (mInstantiatedObjects.contains(key)) { - Log.d(TAG, key + " was already initialized but overriding with testDependency."); - } - mObjs.put(key, obj); - } - - @Override - public T createDependency(Object key) { - if (mObjs.containsKey(key)) return (T) mObjs.get(key); - - mInstantiatedObjects.add(key); - return mParent.createDependency(key); - } - - public boolean hasInstantiatedDependency(Class key) { - return mObjs.containsKey(key) || mInstantiatedObjects.contains(key); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt deleted file mode 100644 index 53dcc8d269c9..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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.broadcast - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.IntentFilter -import android.os.Handler -import android.os.Looper -import android.os.UserHandle -import android.util.ArraySet -import android.util.Log -import com.android.systemui.SysuiTestableContext -import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger -import com.android.systemui.dump.DumpManager -import com.android.systemui.settings.UserTracker -import java.util.concurrent.Executor - -class FakeBroadcastDispatcher( - context: SysuiTestableContext, - looper: Looper, - executor: Executor, - dumpManager: DumpManager, - logger: BroadcastDispatcherLogger, - userTracker: UserTracker -) : BroadcastDispatcher( - context, looper, executor, dumpManager, logger, userTracker, PendingRemovalStore(logger)) { - - private val registeredReceivers = ArraySet() - - override fun registerReceiverWithHandler( - receiver: BroadcastReceiver, - filter: IntentFilter, - handler: Handler, - user: UserHandle, - @Context.RegisterReceiverFlags flags: Int, - permission: String? - ) { - registeredReceivers.add(receiver) - } - - override fun registerReceiver( - receiver: BroadcastReceiver, - filter: IntentFilter, - executor: Executor?, - user: UserHandle?, - @Context.RegisterReceiverFlags flags: Int, - permission: String? - ) { - registeredReceivers.add(receiver) - } - - override fun unregisterReceiver(receiver: BroadcastReceiver) { - registeredReceivers.remove(receiver) - } - - override fun unregisterReceiverForUser(receiver: BroadcastReceiver, user: UserHandle) { - registeredReceivers.remove(receiver) - } - - fun cleanUpReceivers(testName: String) { - registeredReceivers.forEach { - Log.i(testName, "Receiver not unregistered from dispatcher: $it") - } - registeredReceivers.clear() - } -} \ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerFake.java deleted file mode 100644 index 48b5c62da38f..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerFake.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2021 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.classifier; - -import static com.google.common.truth.Truth.assertWithMessage; - -import android.net.Uri; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.plugins.FalsingManager; - -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; - -/** - * Simple Fake for testing where {@link FalsingManager} is required. - */ -public class FalsingManagerFake implements FalsingManager { - private boolean mIsFalseTouch; - private boolean mIsSimpleTap; - private boolean mIsFalseDoubleTap; - private boolean mIsUnlockingDisabled; - private boolean mIsClassifierEnabled; - private boolean mShouldEnforceBouncer; - private boolean mIsReportingEnabled; - private boolean mIsFalseRobustTap; - private boolean mDestroyed; - - private final List mFalsingBeliefListeners = new ArrayList<>(); - private final List mTapListeners = new ArrayList<>(); - - @Override - public void onSuccessfulUnlock() { - - } - - @VisibleForTesting - public void setIsUnlockingDisabled(boolean isUnlockingDisabled) { - mIsUnlockingDisabled = isUnlockingDisabled; - } - - @Override - public boolean isUnlockingDisabled() { - return mIsUnlockingDisabled; - } - - @VisibleForTesting - public void setIsFalseTouch(boolean isFalseTouch) { - mIsFalseTouch = isFalseTouch; - } - - @Override - public boolean isFalseTouch(@Classifier.InteractionType int interactionType) { - checkDestroyed(); - return mIsFalseTouch; - } - - public void setFalseTap(boolean falseRobustTap) { - mIsFalseRobustTap = falseRobustTap; - } - - public void setSimpleTap(boolean isSimpleTape) { - mIsSimpleTap = isSimpleTape; - } - - public void setFalseDoubleTap(boolean falseDoubleTap) { - mIsFalseDoubleTap = falseDoubleTap; - } - - @Override - public boolean isSimpleTap() { - checkDestroyed(); - return mIsSimpleTap; - } - - @Override - public boolean isFalseTap(@Penalty int penalty) { - checkDestroyed(); - return mIsFalseRobustTap; - } - - @Override - public boolean isFalseDoubleTap() { - checkDestroyed(); - return mIsFalseDoubleTap; - } - - @VisibleForTesting - public void setIsClassifierEnabled(boolean isClassifierEnabled) { - mIsClassifierEnabled = isClassifierEnabled; - } - - @Override - public boolean isClassifierEnabled() { - return mIsClassifierEnabled; - } - - @Override - public boolean shouldEnforceBouncer() { - return mShouldEnforceBouncer; - } - - @Override - public Uri reportRejectedTouch() { - return null; - } - - @VisibleForTesting - public void setIsReportingEnabled(boolean isReportingEnabled) { - mIsReportingEnabled = isReportingEnabled; - } - - @Override - public boolean isReportingEnabled() { - return mIsReportingEnabled; - } - - @Override - public void dump(PrintWriter pw, String[] args) { - } - - @Override - public void cleanupInternal() { - mDestroyed = true; - } - - private void checkDestroyed() { - assertWithMessage("FakeFasingManager has been destroyed") - .that(mDestroyed).isFalse(); - } - - @Override - public void onProximityEvent(ProximityEvent proximityEvent) { - - } - - @Override - public void addFalsingBeliefListener(FalsingBeliefListener listener) { - mFalsingBeliefListeners.add(listener); - } - - @Override - public void removeFalsingBeliefListener(FalsingBeliefListener listener) { - mFalsingBeliefListeners.remove(listener); - } - - @Override - public void addTapListener(FalsingTapListener falsingTapListener) { - mTapListeners.add(falsingTapListener); - } - - @Override - public void removeTapListener(FalsingTapListener falsingTapListener) { - mTapListeners.remove(falsingTapListener); - } - - public List getTapListeners() { - return mTapListeners; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeScrollCaptureConnection.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeScrollCaptureConnection.java deleted file mode 100644 index 63f7c9755782..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeScrollCaptureConnection.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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.screenshot; - -import android.content.pm.ActivityInfo; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.HardwareRenderer; -import android.graphics.Paint; -import android.graphics.RecordingCanvas; -import android.graphics.Rect; -import android.graphics.RenderNode; -import android.os.CancellationSignal; -import android.os.ICancellationSignal; -import android.os.RemoteException; -import android.view.IScrollCaptureCallbacks; -import android.view.IScrollCaptureConnection; -import android.view.Surface; - -/** - * An IScrollCaptureConnection which returns a sequence of solid filled rectangles in the - * locations requested, in alternating colors. - */ -class FakeScrollCaptureConnection extends IScrollCaptureConnection.Stub { - private final int[] mColors = {Color.RED, Color.GREEN, Color.BLUE}; - private IScrollCaptureCallbacks mCallbacks; - private Paint mPaint; - private int mNextColor; - private HwuiContext mHwuiContext; - private CancellationSignal mCancellationSignal; - - @Override - public ICancellationSignal startCapture(Surface surface, IScrollCaptureCallbacks callbacks) { - mCallbacks = callbacks; - mHwuiContext = new HwuiContext(surface); - mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - mPaint.setStyle(Paint.Style.FILL); - try { - mCallbacks.onCaptureStarted(); - } catch (RemoteException e) { - e.rethrowAsRuntimeException(); - } - ICancellationSignal signal = CancellationSignal.createTransport(); - mCancellationSignal = CancellationSignal.fromTransport(signal); - return signal; - } - - @Override - public ICancellationSignal requestImage(Rect rect) { - Canvas canvas = mHwuiContext.lockCanvas(rect.width(), rect.height()); - mPaint.setColor(mColors[mNextColor]); - canvas.drawRect(rect, mPaint); - mNextColor = (mNextColor++) % mColors.length; - mHwuiContext.unlockAndPost(canvas); - try { - mCallbacks.onImageRequestCompleted(0, rect); - } catch (RemoteException e) { - e.rethrowAsRuntimeException(); - } - ICancellationSignal signal = CancellationSignal.createTransport(); - mCancellationSignal = CancellationSignal.fromTransport(signal); - return signal; - } - - @Override - public ICancellationSignal endCapture() { - try { - mCallbacks.onCaptureEnded(); - } catch (RemoteException e) { - e.rethrowAsRuntimeException(); - } finally { - mHwuiContext.destroy(); - mCallbacks = null; - } - ICancellationSignal signal = CancellationSignal.createTransport(); - mCancellationSignal = CancellationSignal.fromTransport(signal); - return signal; - } - - @Override - public void close() throws RemoteException { - } - - // From android.view.Surface, but issues render requests synchronously with waitForPresent(true) - private static final class HwuiContext { - private final RenderNode mRenderNode; - private final HardwareRenderer mHardwareRenderer; - private RecordingCanvas mCanvas; - - HwuiContext(Surface surface) { - mRenderNode = RenderNode.create("HwuiCanvas", null); - mRenderNode.setClipToBounds(false); - mRenderNode.setForceDarkAllowed(false); - - mHardwareRenderer = new HardwareRenderer(); - mHardwareRenderer.setContentRoot(mRenderNode); - mHardwareRenderer.setSurface(surface, true); - mHardwareRenderer.setColorMode(ActivityInfo.COLOR_MODE_DEFAULT); - mHardwareRenderer.setLightSourceAlpha(0.0f, 0.0f); - mHardwareRenderer.setLightSourceGeometry(0.0f, 0.0f, 0.0f, 0.0f); - } - - Canvas lockCanvas(int width, int height) { - if (mCanvas != null) { - throw new IllegalStateException("Surface was already locked!"); - } - mCanvas = mRenderNode.beginRecording(width, height); - return mCanvas; - } - - void unlockAndPost(Canvas canvas) { - if (canvas != mCanvas) { - throw new IllegalArgumentException("canvas object must be the same instance that " - + "was previously returned by lockCanvas"); - } - mRenderNode.endRecording(); - mCanvas = null; - mHardwareRenderer.createRenderRequest() - .setVsyncTime(System.nanoTime()) - .setWaitForPresent(true) // sync! - .syncAndDraw(); - } - - void destroy() { - mHardwareRenderer.destroy(); - } - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSession.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSession.java deleted file mode 100644 index 478658eb232d..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSession.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2021 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.screenshot; - -import static android.util.MathUtils.constrain; - -import static com.google.common.util.concurrent.Futures.immediateFuture; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import static java.lang.Math.abs; -import static java.lang.Math.max; -import static java.lang.Math.min; - -import android.graphics.Rect; -import android.hardware.HardwareBuffer; -import android.media.Image; -import android.util.Log; - -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -/** - * A flexible test double for {@link ScrollCaptureClient.Session}. - *

- * FakeSession provides the ability to emulate both the available scrollable content range as well - * as the current visible bounds. Visible bounds may vary because the target view itself may be - * slid vertically during capture, with portions may become clipped by parent views. This scenario - * frequently occurs with UIs constructed from nested scrolling views or collapsing headers. - */ -class FakeSession implements ScrollCaptureClient.Session { - private static final String TAG = "FakeSession"; - // Available range of content - private final Rect mAvailable; - - /** bounds for scrollDelta (y), range with bottom adjusted to account for page height. */ - private final Rect mAvailableTop; - - private final Rect mVisiblePage; - private final int mTileHeight; - private final int mMaxTiles; - - private int mScrollDelta; - private int mPageHeight; - private int mTargetHeight; - - FakeSession(int pageHeight, float maxPages, int tileHeight, int visiblePageTop, - int visiblePageBottom, int availableTop, int availableBottom, - int maxTiles) { - mPageHeight = pageHeight; - mTileHeight = tileHeight; - mAvailable = new Rect(0, availableTop, getPageWidth(), availableBottom); - mAvailableTop = new Rect(mAvailable); - mAvailableTop.inset(0, 0, 0, pageHeight); - mVisiblePage = new Rect(0, visiblePageTop, getPageWidth(), visiblePageBottom); - mTargetHeight = (int) (pageHeight * maxPages); - mMaxTiles = maxTiles; - } - - private static Image mockImage() { - Image image = mock(Image.class); - when(image.getHardwareBuffer()).thenReturn(mock(HardwareBuffer.class)); - return image; - } - - public int getScrollDelta() { - return mScrollDelta; - } - - @Override - public ListenableFuture requestTile(int requestedTop) { - Rect requested = new Rect(0, requestedTop, getPageWidth(), requestedTop + getTileHeight()); - Log.d(TAG, "requested: " + requested); - Rect page = new Rect(0, 0, getPageWidth(), mPageHeight); - page.offset(0, mScrollDelta); - Log.d(TAG, "page: " + page); - // Simulate behavior from lower levels by replicating 'requestChildRectangleOnScreen' - if (!page.contains(requested)) { - Log.d(TAG, "requested not within page, scrolling"); - // distance+direction needed to scroll to align each edge of request with - // corresponding edge of the page - int distTop = requested.top - page.top; // positive means already visible - int distBottom = requested.bottom - page.bottom; // negative means already visible - Log.d(TAG, "distTop = " + distTop); - Log.d(TAG, "distBottom = " + distBottom); - - boolean scrollUp = false; - if (distTop < 0 && distBottom > 0) { - scrollUp = abs(distTop) < distBottom; - } else if (distTop < 0) { - scrollUp = true; - } - - // determine which edges are currently clipped - if (scrollUp) { - Log.d(TAG, "trying to scroll up by " + -distTop + " px"); - // need to scroll up to align top edge to visible-top - mScrollDelta += distTop; - Log.d(TAG, "new scrollDelta = " + mScrollDelta); - } else { - Log.d(TAG, "trying to scroll down by " + distBottom + " px"); - // scroll down to align bottom edge with visible bottom, but keep top visible - int topEdgeDistance = max(0, requestedTop - page.top); - mScrollDelta += min(distBottom, topEdgeDistance); - Log.d(TAG, "new scrollDelta = " + mScrollDelta); - } - - // Clamp to available content - mScrollDelta = constrain(mScrollDelta, mAvailableTop.top, mAvailableTop.bottom); - Log.d(TAG, "scrollDelta, adjusted to available range = " + mScrollDelta); - - // Reset to apply a changed scroll delta possibly. - page.offsetTo(0, 0); - page.offset(0, mScrollDelta); - - Log.d(TAG, "page (after scroll): " + page); - Log.d(TAG, "requested (after scroll): " + requested); - } - Log.d(TAG, "mVisiblePage = " + mVisiblePage); - Log.d(TAG, "scrollDelta = " + mScrollDelta); - - Rect target = new Rect(requested); - Rect visible = new Rect(mVisiblePage); - visible.offset(0, mScrollDelta); - - Log.d(TAG, "target: " + target); - Log.d(TAG, "visible: " + visible); - - // if any of the requested rect is available to scroll into the view: - if (target.intersect(page) && target.intersect(visible)) { - Log.d(TAG, "returning captured = " + target); - ScrollCaptureClient.CaptureResult result = - new ScrollCaptureClient.CaptureResult(mockImage(), requested, target); - return immediateFuture(result); - } - Log.d(TAG, "no part of requested rect is within page, returning empty"); - ScrollCaptureClient.CaptureResult result = - new ScrollCaptureClient.CaptureResult(null, requested, new Rect()); - return immediateFuture(result); - } - - - @Override - public int getMaxTiles() { - return mMaxTiles; - } - - @Override - public int getTargetHeight() { - return mTargetHeight; - } - - @Override - public int getTileHeight() { - return mTileHeight; - } - - @Override - public int getPageWidth() { - return 100; - } - - @Override - public int getPageHeight() { - return mPageHeight; - } - - @Override - public Rect getWindowBounds() { - throw new IllegalStateException("Not implemented"); - } - - @Override - public ListenableFuture end() { - return Futures.immediateVoidFuture(); - } - - @Override - public void release() { - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java deleted file mode 100644 index 045e6f19c667..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * 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.statusbar; - -import android.annotation.NonNull; -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager.Importance; -import android.content.pm.ShortcutInfo; -import android.service.notification.NotificationListenerService.Ranking; -import android.service.notification.SnoozeCriterion; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Standard builder class for Ranking objects. For use in tests that need to craft the underlying - * Ranking object of a NotificationEntry. - */ -public class RankingBuilder { - private String mKey = "test_key"; - private int mRank = 0; - private boolean mMatchesInterruptionFilter = false; - private int mVisibilityOverride = 0; - private int mSuppressedVisualEffects = 0; - @Importance private int mImportance = 0; - private CharSequence mExplanation = "test_explanation"; - private String mOverrideGroupKey = null; - private NotificationChannel mChannel = null; - private ArrayList mAdditionalPeople = null; - private ArrayList mSnoozeCriteria = null; - private boolean mCanShowBadge = false; - private int mUserSentiment = 0; - private boolean mIsSuspended = false; - private long mLastAudiblyAlertedMs = 0; - private boolean mNoisy = false; - private ArrayList mSmartActions = new ArrayList<>(); - private ArrayList mSmartReplies = new ArrayList<>(); - private boolean mCanBubble = false; - private boolean mIsTextChanged = false; - private boolean mIsConversation = false; - private ShortcutInfo mShortcutInfo = null; - private int mRankingAdjustment = 0; - private boolean mIsBubble = false; - - public RankingBuilder() { - } - - public RankingBuilder(Ranking ranking) { - mKey = ranking.getKey(); - mRank = ranking.getRank(); - mMatchesInterruptionFilter = ranking.matchesInterruptionFilter(); - mVisibilityOverride = ranking.getLockscreenVisibilityOverride(); - mSuppressedVisualEffects = ranking.getSuppressedVisualEffects(); - mImportance = ranking.getImportance(); - mExplanation = ranking.getImportanceExplanation(); - mOverrideGroupKey = ranking.getOverrideGroupKey(); - mChannel = ranking.getChannel(); - mAdditionalPeople = copyList(ranking.getAdditionalPeople()); - mSnoozeCriteria = copyList(ranking.getSnoozeCriteria()); - mCanShowBadge = ranking.canShowBadge(); - mUserSentiment = ranking.getUserSentiment(); - mIsSuspended = ranking.isSuspended(); - mLastAudiblyAlertedMs = ranking.getLastAudiblyAlertedMillis(); - mNoisy = ranking.isNoisy(); - mSmartActions = copyList(ranking.getSmartActions()); - mSmartReplies = copyList(ranking.getSmartReplies()); - mCanBubble = ranking.canBubble(); - mIsTextChanged = ranking.isTextChanged(); - mIsConversation = ranking.isConversation(); - mShortcutInfo = ranking.getConversationShortcutInfo(); - mRankingAdjustment = ranking.getRankingAdjustment(); - mIsBubble = ranking.isBubble(); - } - - public Ranking build() { - final Ranking ranking = new Ranking(); - ranking.populate( - mKey, - mRank, - mMatchesInterruptionFilter, - mVisibilityOverride, - mSuppressedVisualEffects, - mImportance, - mExplanation, - mOverrideGroupKey, - mChannel, - mAdditionalPeople, - mSnoozeCriteria, - mCanShowBadge, - mUserSentiment, - mIsSuspended, - mLastAudiblyAlertedMs, - mNoisy, - mSmartActions, - mSmartReplies, - mCanBubble, - mIsTextChanged, - mIsConversation, - mShortcutInfo, - mRankingAdjustment, - mIsBubble); - return ranking; - } - - public RankingBuilder setKey(String key) { - mKey = key; - return this; - } - - public RankingBuilder setRank(int rank) { - mRank = rank; - return this; - } - - public RankingBuilder setMatchesInterruptionFilter(boolean matchesInterruptionFilter) { - mMatchesInterruptionFilter = matchesInterruptionFilter; - return this; - } - - public RankingBuilder setVisibilityOverride(int visibilityOverride) { - mVisibilityOverride = visibilityOverride; - return this; - } - - public RankingBuilder setSuppressedVisualEffects(int suppressedVisualEffects) { - mSuppressedVisualEffects = suppressedVisualEffects; - return this; - } - - public RankingBuilder setExplanation(CharSequence explanation) { - mExplanation = explanation; - return this; - } - - public RankingBuilder setOverrideGroupKey(String overrideGroupKey) { - mOverrideGroupKey = overrideGroupKey; - return this; - } - - public RankingBuilder setAdditionalPeople(ArrayList additionalPeople) { - mAdditionalPeople = additionalPeople; - return this; - } - - public RankingBuilder setSnoozeCriteria( - ArrayList snoozeCriteria) { - mSnoozeCriteria = snoozeCriteria; - return this; - } - - public RankingBuilder setCanShowBadge(boolean canShowBadge) { - mCanShowBadge = canShowBadge; - return this; - } - - public RankingBuilder setSuspended(boolean suspended) { - mIsSuspended = suspended; - return this; - } - - public RankingBuilder setLastAudiblyAlertedMs(long lastAudiblyAlertedMs) { - mLastAudiblyAlertedMs = lastAudiblyAlertedMs; - return this; - } - - public RankingBuilder setNoisy(boolean noisy) { - mNoisy = noisy; - return this; - } - - public RankingBuilder setCanBubble(boolean canBubble) { - mCanBubble = canBubble; - return this; - } - - public RankingBuilder setTextChanged(boolean textChanged) { - mIsTextChanged = textChanged; - return this; - } - - public RankingBuilder setIsConversation(boolean isConversation) { - mIsConversation = isConversation; - return this; - } - - public RankingBuilder setShortcutInfo(ShortcutInfo shortcutInfo) { - mShortcutInfo = shortcutInfo; - return this; - } - - public RankingBuilder setRankingAdjustment(int rankingAdjustment) { - mRankingAdjustment = rankingAdjustment; - return this; - } - - public RankingBuilder setImportance(@Importance int importance) { - mImportance = importance; - return this; - } - - public RankingBuilder setUserSentiment(int userSentiment) { - mUserSentiment = userSentiment; - return this; - } - - public RankingBuilder setChannel(NotificationChannel channel) { - mChannel = channel; - return this; - } - - public RankingBuilder setSmartActions(@NonNull ArrayList smartActions) { - mSmartActions = smartActions; - return this; - } - - public RankingBuilder setSmartActions(Notification.Action... smartActions) { - mSmartActions = new ArrayList<>(Arrays.asList(smartActions)); - return this; - } - - public RankingBuilder setSmartReplies(@NonNull ArrayList smartReplies) { - mSmartReplies = smartReplies; - return this; - } - - public RankingBuilder setSmartReplies(CharSequence... smartReplies) { - mSmartReplies = new ArrayList<>(Arrays.asList(smartReplies)); - return this; - } - - private static ArrayList copyList(List list) { - if (list == null) { - return null; - } else { - return new ArrayList<>(list); - } - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SbnBuilder.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SbnBuilder.java deleted file mode 100644 index 1b0ed112cea1..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SbnBuilder.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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.statusbar; - -import android.annotation.Nullable; -import android.app.Notification; -import android.content.Context; -import android.os.UserHandle; -import android.service.notification.StatusBarNotification; - -import com.android.internal.logging.InstanceId; - -/** - * Convenience builder for {@link StatusBarNotification} since its constructor is terrifying. - * - * Only for use in tests. - */ -public class SbnBuilder { - private String mPkg = "test_pkg"; - private String mOpPkg; - private int mId; - private String mTag; - private int mUid; - private int mInitialPid; - @Nullable private Notification mNotification; - @Nullable private Notification.Builder mNotificationBuilder; - private Notification.BubbleMetadata mBubbleMetadata; - private UserHandle mUser = UserHandle.of(0); - private String mOverrideGroupKey; - private long mPostTime; - private InstanceId mInstanceId; - - public SbnBuilder() { - } - - public SbnBuilder(StatusBarNotification source) { - mPkg = source.getPackageName(); - mOpPkg = source.getOpPkg(); - mId = source.getId(); - mTag = source.getTag(); - mUid = source.getUid(); - mInitialPid = source.getInitialPid(); - mNotification = source.getNotification(); - mUser = source.getUser(); - mOverrideGroupKey = source.getOverrideGroupKey(); - mPostTime = source.getPostTime(); - mInstanceId = source.getInstanceId(); - } - - public StatusBarNotification build() { - Notification notification; - if (mNotificationBuilder != null) { - notification = mNotificationBuilder.build(); - } else if (mNotification != null) { - notification = mNotification; - } else { - notification = new Notification(); - } - - if (mBubbleMetadata != null) { - notification.setBubbleMetadata(mBubbleMetadata); - } - - StatusBarNotification result = new StatusBarNotification( - mPkg, - mOpPkg, - mId, - mTag, - mUid, - mInitialPid, - notification, - mUser, - mOverrideGroupKey, - mPostTime); - if (mInstanceId != null) { - result.setInstanceId(mInstanceId); - } - return result; - } - - public SbnBuilder setPkg(String pkg) { - mPkg = pkg; - return this; - } - - public SbnBuilder setOpPkg(String opPkg) { - mOpPkg = opPkg; - return this; - } - - public SbnBuilder setId(int id) { - mId = id; - return this; - } - - public SbnBuilder setTag(String tag) { - mTag = tag; - return this; - } - - public SbnBuilder setUid(int uid) { - mUid = uid; - return this; - } - - public SbnBuilder setInitialPid(int initialPid) { - mInitialPid = initialPid; - return this; - } - - public SbnBuilder setNotification(Notification notification) { - mNotification = notification; - mNotificationBuilder = null; - return this; - } - - public SbnBuilder setContentTitle(Context context, String contentTitle) { - modifyNotification(context).setContentTitle(contentTitle); - return this; - } - - public SbnBuilder setContentText(Context context, String contentText) { - modifyNotification(context).setContentText(contentText); - return this; - } - - public SbnBuilder setGroup(Context context, String groupKey) { - modifyNotification(context).setGroup(groupKey); - return this; - } - - public SbnBuilder setGroupSummary(Context context, boolean isGroupSummary) { - modifyNotification(context).setGroupSummary(isGroupSummary); - return this; - } - - public SbnBuilder setFlag(Context context, int mask, boolean value) { - modifyNotification(context).setFlag(mask, value); - return this; - } - - public Notification.Builder modifyNotification(Context context) { - if (mNotification != null) { - mNotificationBuilder = new Notification.Builder(context, mNotification); - mNotification = null; - } else if (mNotificationBuilder == null) { - mNotificationBuilder = new Notification.Builder(context); - } - - return mNotificationBuilder; - } - - public SbnBuilder setUser(UserHandle user) { - mUser = user; - return this; - } - - public SbnBuilder setOverrideGroupKey(String overrideGroupKey) { - mOverrideGroupKey = overrideGroupKey; - return this; - } - - public SbnBuilder setPostTime(long postTime) { - mPostTime = postTime; - return this; - } - - public SbnBuilder setBubbleMetadata(Notification.BubbleMetadata data) { - mBubbleMetadata = data; - return this; - } - - public SbnBuilder setInstanceId(InstanceId instanceId) { - mInstanceId = instanceId; - return this; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java deleted file mode 100644 index b91f7e6b6169..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java +++ /dev/null @@ -1,353 +0,0 @@ -/* - * 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.statusbar.notification.collection; - -import android.annotation.Nullable; -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.content.Context; -import android.content.pm.ShortcutInfo; -import android.os.UserHandle; -import android.service.notification.NotificationListenerService.Ranking; -import android.service.notification.SnoozeCriterion; -import android.service.notification.StatusBarNotification; - -import com.android.internal.logging.InstanceId; -import com.android.systemui.statusbar.RankingBuilder; -import com.android.systemui.statusbar.SbnBuilder; -import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection; -import com.android.systemui.util.time.FakeSystemClock; - -import java.util.ArrayList; - -import kotlin.Unit; - -/** - * Combined builder for constructing a NotificationEntry and its associated StatusBarNotification - * and Ranking. Is largely a proxy for the SBN and Ranking builders, but does a little extra magic - * to make sure the keys match between the two, etc. - * - * Has the ability to set ListEntry properties as well. - * - * Only for use in tests. - */ -public class NotificationEntryBuilder { - private final SbnBuilder mSbnBuilder; - private final RankingBuilder mRankingBuilder; - private final FakeSystemClock mClock = new FakeSystemClock(); - private StatusBarNotification mSbn = null; - - /* ListEntry properties */ - private GroupEntry mParent; - private NotifSection mNotifSection; - - /* If set, use this creation time instead of mClock.uptimeMillis */ - private long mCreationTime = -1; - private int mStableIndex = -1; - - public NotificationEntryBuilder() { - mSbnBuilder = new SbnBuilder(); - mRankingBuilder = new RankingBuilder(); - } - - public NotificationEntryBuilder(NotificationEntry source) { - mSbnBuilder = new SbnBuilder(source.getSbn()); - mRankingBuilder = new RankingBuilder(source.getRanking()); - - mParent = source.getParent(); - mCreationTime = source.getCreationTime(); - } - - /** Update an the parent on an existing entry */ - public static void setNewParent(NotificationEntry entry, GroupEntry parent) { - entry.setParent(parent); - } - - /** Build a new instance of NotificationEntry */ - public NotificationEntry build() { - return buildOrApply(null); - } - - /** Modifies [target] to match the contents of this builder */ - public void apply(NotificationEntry target) { - buildOrApply(target); - } - - /** Convenience method for Kotlin callbacks that are passed a builder and need to return Unit */ - public Unit done() { - return Unit.INSTANCE; - } - - private NotificationEntry buildOrApply(NotificationEntry target) { - final StatusBarNotification sbn = mSbn != null ? mSbn : mSbnBuilder.build(); - final Ranking ranking = mRankingBuilder.setKey(sbn.getKey()).build(); - final long creationTime = mCreationTime != -1 ? mCreationTime : mClock.uptimeMillis(); - - final NotificationEntry entry; - if (target == null) { - entry = new NotificationEntry(sbn, ranking, creationTime); - } else { - entry = target; - entry.setSbn(sbn); - entry.setRanking(ranking); - // Note: we can't modify the creation time as it's immutable - } - - /* ListEntry properties */ - entry.setParent(mParent); - entry.getAttachState().setSection(mNotifSection); - entry.getAttachState().setStableIndex(mStableIndex); - return entry; - } - - /** - * Sets the parent. - */ - public NotificationEntryBuilder setParent(@Nullable GroupEntry parent) { - mParent = parent; - return this; - } - - /** - * Sets the parent. - */ - public NotificationEntryBuilder setSection(@Nullable NotifSection section) { - mNotifSection = section; - return this; - } - - /** - * Sets the SBN directly. If set, causes all calls to delegated SbnBuilder methods to be - * ignored. - */ - public NotificationEntryBuilder setSbn(@Nullable StatusBarNotification sbn) { - mSbn = sbn; - return this; - } - - public NotificationEntryBuilder setStableIndex(int index) { - mStableIndex = index; - return this; - } - - /** - * Set the creation time - */ - public NotificationEntryBuilder setCreationTime(long creationTime) { - mCreationTime = creationTime; - return this; - } - - /* Delegated to SbnBuilder */ - - public NotificationEntryBuilder setPkg(String pkg) { - mSbnBuilder.setPkg(pkg); - return this; - } - - public NotificationEntryBuilder setOpPkg(String opPkg) { - mSbnBuilder.setOpPkg(opPkg); - return this; - } - - public NotificationEntryBuilder setId(int id) { - mSbnBuilder.setId(id); - return this; - } - - public NotificationEntryBuilder setTag(String tag) { - mSbnBuilder.setTag(tag); - return this; - } - - public NotificationEntryBuilder setUid(int uid) { - mSbnBuilder.setUid(uid); - return this; - } - - public NotificationEntryBuilder setInitialPid(int initialPid) { - mSbnBuilder.setInitialPid(initialPid); - return this; - } - - public NotificationEntryBuilder setNotification(Notification notification) { - mSbnBuilder.setNotification(notification); - return this; - } - - public Notification.Builder modifyNotification(Context context) { - return mSbnBuilder.modifyNotification(context); - } - - public NotificationEntryBuilder setUser(UserHandle user) { - mSbnBuilder.setUser(user); - return this; - } - - public NotificationEntryBuilder setOverrideGroupKey(String overrideGroupKey) { - mSbnBuilder.setOverrideGroupKey(overrideGroupKey); - return this; - } - - public NotificationEntryBuilder setPostTime(long postTime) { - mSbnBuilder.setPostTime(postTime); - return this; - } - - public NotificationEntryBuilder setInstanceId(InstanceId instanceId) { - mSbnBuilder.setInstanceId(instanceId); - return this; - } - - /* Delegated to Notification.Builder (via SbnBuilder) */ - - public NotificationEntryBuilder setContentTitle(Context context, String contentTitle) { - mSbnBuilder.setContentTitle(context, contentTitle); - return this; - } - - public NotificationEntryBuilder setContentText(Context context, String contentText) { - mSbnBuilder.setContentText(context, contentText); - return this; - } - - public NotificationEntryBuilder setGroup(Context context, String groupKey) { - mSbnBuilder.setGroup(context, groupKey); - return this; - } - - public NotificationEntryBuilder setGroupSummary(Context context, boolean isGroupSummary) { - mSbnBuilder.setGroupSummary(context, isGroupSummary); - return this; - } - - public NotificationEntryBuilder setFlag(Context context, int mask, boolean value) { - mSbnBuilder.setFlag(context, mask, value); - return this; - } - - /* Delegated to RankingBuilder */ - - public NotificationEntryBuilder setRank(int rank) { - mRankingBuilder.setRank(rank); - return this; - } - - public NotificationEntryBuilder setMatchesInterruptionFilter( - boolean matchesInterruptionFilter) { - mRankingBuilder.setMatchesInterruptionFilter(matchesInterruptionFilter); - return this; - } - - public NotificationEntryBuilder setVisibilityOverride(int visibilityOverride) { - mRankingBuilder.setVisibilityOverride(visibilityOverride); - return this; - } - - public NotificationEntryBuilder setSuppressedVisualEffects(int suppressedVisualEffects) { - mRankingBuilder.setSuppressedVisualEffects(suppressedVisualEffects); - return this; - } - - public NotificationEntryBuilder setExplanation(CharSequence explanation) { - mRankingBuilder.setExplanation(explanation); - return this; - } - - public NotificationEntryBuilder setAdditionalPeople(ArrayList additionalPeople) { - mRankingBuilder.setAdditionalPeople(additionalPeople); - return this; - } - - public NotificationEntryBuilder setSnoozeCriteria( - ArrayList snoozeCriteria) { - mRankingBuilder.setSnoozeCriteria(snoozeCriteria); - return this; - } - - public NotificationEntryBuilder setCanShowBadge(boolean canShowBadge) { - mRankingBuilder.setCanShowBadge(canShowBadge); - return this; - } - - public NotificationEntryBuilder setSuspended(boolean suspended) { - mRankingBuilder.setSuspended(suspended); - return this; - } - - public NotificationEntryBuilder setLastAudiblyAlertedMs(long lastAudiblyAlertedMs) { - mRankingBuilder.setLastAudiblyAlertedMs(lastAudiblyAlertedMs); - return this; - } - - public NotificationEntryBuilder setNoisy(boolean noisy) { - mRankingBuilder.setNoisy(noisy); - return this; - } - - public NotificationEntryBuilder setCanBubble(boolean canBubble) { - mRankingBuilder.setCanBubble(canBubble); - return this; - } - - public NotificationEntryBuilder setImportance(@NotificationManager.Importance int importance) { - mRankingBuilder.setImportance(importance); - return this; - } - - public NotificationEntryBuilder setUserSentiment(int userSentiment) { - mRankingBuilder.setUserSentiment(userSentiment); - return this; - } - - public NotificationEntryBuilder setChannel(NotificationChannel channel) { - mRankingBuilder.setChannel(channel); - return this; - } - - public NotificationEntryBuilder setSmartActions( - ArrayList smartActions) { - mRankingBuilder.setSmartActions(smartActions); - return this; - } - - public NotificationEntryBuilder setSmartActions(Notification.Action... smartActions) { - mRankingBuilder.setSmartActions(smartActions); - return this; - } - - public NotificationEntryBuilder setSmartReplies(ArrayList smartReplies) { - mRankingBuilder.setSmartReplies(smartReplies); - return this; - } - - public NotificationEntryBuilder setSmartReplies(CharSequence... smartReplies) { - mRankingBuilder.setSmartReplies(smartReplies); - return this; - } - - public NotificationEntryBuilder setShortcutInfo(ShortcutInfo shortcutInfo) { - mRankingBuilder.setShortcutInfo(shortcutInfo); - return this; - } - - public NotificationEntryBuilder setRankingAdjustment(int rankingAdjustment) { - mRankingBuilder.setRankingAdjustment(rankingAdjustment); - return this; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt deleted file mode 100644 index 16a326869562..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.android.systemui.statusbar.policy - -import android.content.res.Configuration - -/** Fake implementation of [ConfigurationController] for tests. */ -class FakeConfigurationController : ConfigurationController { - - private var listeners = mutableListOf() - - override fun addCallback(listener: ConfigurationController.ConfigurationListener) { - listeners += listener - } - - override fun removeCallback(listener: ConfigurationController.ConfigurationListener) { - listeners -= listener - } - - override fun onConfigurationChanged(newConfiguration: Configuration?) { - listeners.forEach { it.onConfigChanged(newConfiguration) } - } - - override fun notifyThemeChanged() { - listeners.forEach { it.onThemeChanged() } - } - - fun notifyDensityOrFontScaleChanged() { - listeners.forEach { it.onDensityOrFontScaleChanged() } - } - - fun notifyConfigurationChanged() { - onConfigurationChanged(newConfiguration = null) - } - - override fun isLayoutRtl(): Boolean = false -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/DeviceConfigProxyFake.java b/packages/SystemUI/tests/src/com/android/systemui/util/DeviceConfigProxyFake.java deleted file mode 100644 index 33ece0084906..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/util/DeviceConfigProxyFake.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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.util; - -import android.content.Context; -import android.provider.DeviceConfig; -import android.provider.DeviceConfig.OnPropertiesChangedListener; -import android.provider.DeviceConfig.Properties; -import android.util.Pair; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Executor; - -/** - * A Fake of {@link DeviceConfigProxy} useful for testing. - * - * No properties are set by default. No calls to {@link DeviceConfig} are made. Be sure to set any - * properties you rely on ahead of time in your test. - */ -public class DeviceConfigProxyFake extends DeviceConfigProxy { - - private List> mListeners = new ArrayList<>(); - private Map> mDefaultProperties = new HashMap<>(); - private Map> mProperties = new HashMap<>(); - - public DeviceConfigProxyFake() { - } - - @Override - public void addOnPropertiesChangedListener( - String namespace, Executor executor, - OnPropertiesChangedListener onPropertiesChangedListener) { - mListeners.add(Pair.create(executor, onPropertiesChangedListener)); - } - - @Override - public void removeOnPropertiesChangedListener( - OnPropertiesChangedListener onPropertiesChangedListener) { - mListeners.removeIf(listener -> { - if (listener == null) { - return false; - } - return listener.second.equals(onPropertiesChangedListener); - }); - } - - @Override - public boolean setProperty(String namespace, String name, String value, boolean makeDefault) { - setPropertyInternal(namespace, name, value, mProperties); - if (makeDefault) { - setPropertyInternal(namespace, name, value, mDefaultProperties); - } - - for (Pair listener : mListeners) { - Properties.Builder propBuilder = new Properties.Builder(namespace); - propBuilder.setString(name, value); - listener.first.execute(() -> listener.second.onPropertiesChanged(propBuilder.build())); - } - return true; - } - - private void setPropertyInternal(String namespace, String name, String value, - Map> properties) { - properties.putIfAbsent(namespace, new HashMap<>()); - properties.get(namespace).put(name, value); - } - - @Override - public void enforceReadPermission(Context context, String namespace) { - // no-op - } - - private Properties propsForNamespaceAndName(String namespace, String name) { - if (mProperties.containsKey(namespace) && mProperties.get(namespace).containsKey(name)) { - return new Properties.Builder(namespace) - .setString(name, mProperties.get(namespace).get(name)).build(); - } - if (mDefaultProperties.containsKey(namespace)) { - return new Properties.Builder(namespace) - .setString(name, mDefaultProperties.get(namespace).get(name)).build(); - } - - return null; - } - - @Override - public boolean getBoolean(String namespace, String name, boolean defaultValue) { - Properties props = propsForNamespaceAndName(namespace, name); - if (props != null) { - return props.getBoolean(name, defaultValue); - } - - return defaultValue; - } - - @Override - public int getInt(String namespace, String name, int defaultValue) { - Properties props = propsForNamespaceAndName(namespace, name); - if (props != null) { - return props.getInt(name, defaultValue); - } - - return defaultValue; - } - - @Override - public long getLong(String namespace, String name, long defaultValue) { - Properties props = propsForNamespaceAndName(namespace, name); - if (props != null) { - return props.getLong(name, defaultValue); - } - - return defaultValue; - } - - @Override - public String getProperty(String namespace, String name) { - return getString(namespace, name, null); - } - - @Override - public String getString(String namespace, String name, String defaultValue) { - Properties props = propsForNamespaceAndName(namespace, name); - if (props != null) { - return props.getString(name, defaultValue); - } - - return defaultValue; - } - - @Override - public void resetToDefaults(int resetMode, String namespace) { - if (mProperties.containsKey(namespace)) { - mProperties.get(namespace).clear(); - } - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutor.java b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutor.java deleted file mode 100644 index d3d30f242dcf..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutor.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 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.util.concurrency; - -import com.android.systemui.util.time.FakeSystemClock; - -import java.util.Collections; -import java.util.PriorityQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -public class FakeExecutor implements DelayableExecutor { - private final FakeSystemClock mClock; - private PriorityQueue mQueuedRunnables = new PriorityQueue<>(); - private boolean mIgnoreClockUpdates; - private boolean mExecuting; - - /** - * Initializes a fake executor. - * - * @param clock FakeSystemClock allowing control over delayed runnables. It is strongly - * recommended that this clock have its auto-increment setting set to false to - * prevent unexpected advancement of the time. - */ - public FakeExecutor(FakeSystemClock clock) { - mClock = clock; - mClock.addListener(() -> { - if (!mIgnoreClockUpdates) { - runAllReady(); - } - }); - } - - /** - * Runs a single runnable if it's scheduled to run according to the internal clock. - * - * If constructed to advance the clock automatically, this will advance the clock enough to - * run the next pending item. - * - * This method does not advance the clock past the item that was run. - * - * @return Returns true if an item was run. - */ - public boolean runNextReady() { - if (!mQueuedRunnables.isEmpty() && mQueuedRunnables.peek().mWhen <= mClock.uptimeMillis()) { - mExecuting = true; - mQueuedRunnables.poll().mRunnable.run(); - mExecuting = false; - return true; - } - - return false; - } - - /** - * Runs all Runnables that are scheduled to run according to the internal clock. - * - * If constructed to advance the clock automatically, this will advance the clock enough to - * run all the pending items. This method does not advance the clock past items that were - * run. It is equivalent to calling {@link #runNextReady()} in a loop. - * - * @return Returns the number of items that ran. - */ - public int runAllReady() { - int num = 0; - while (runNextReady()) { - num++; - } - - return num; - } - - /** - * Advances the internal clock to the next item to run. - * - * The clock will only move forward. If the next item is set to run in the past or there is no - * next item, the clock does not change. - * - * Note that this will cause one or more items to actually run. - * - * @return The delta in uptimeMillis that the clock advanced, or 0 if the clock did not advance. - */ - public long advanceClockToNext() { - if (mQueuedRunnables.isEmpty()) { - return 0; - } - - long startTime = mClock.uptimeMillis(); - long nextTime = mQueuedRunnables.peek().mWhen; - if (nextTime <= startTime) { - return 0; - } - updateClock(nextTime); - - return nextTime - startTime; - } - - - /** - * Advances the internal clock to the last item to run. - * - * The clock will only move forward. If the last item is set to run in the past or there is no - * next item, the clock does not change. - * - * @return The delta in uptimeMillis that the clock advanced, or 0 if the clock did not advance. - */ - public long advanceClockToLast() { - if (mQueuedRunnables.isEmpty()) { - return 0; - } - - long startTime = mClock.uptimeMillis(); - long nextTime = Collections.max(mQueuedRunnables).mWhen; - if (nextTime <= startTime) { - return 0; - } - - updateClock(nextTime); - - return nextTime - startTime; - } - - /** - * Returns the number of un-executed runnables waiting to run. - */ - public int numPending() { - return mQueuedRunnables.size(); - } - - @Override - public Runnable executeDelayed(Runnable r, long delay, TimeUnit unit) { - if (delay < 0) { - delay = 0; - } - return executeAtTime(r, mClock.uptimeMillis() + unit.toMillis(delay)); - } - - @Override - public Runnable executeAtTime(Runnable r, long uptime, TimeUnit unit) { - long uptimeMillis = unit.toMillis(uptime); - - QueuedRunnable container = new QueuedRunnable(r, uptimeMillis); - - mQueuedRunnables.offer(container); - - return () -> mQueuedRunnables.remove(container); - } - - @Override - public void execute(Runnable command) { - executeDelayed(command, 0); - } - - public boolean isExecuting() { - return mExecuting; - } - - /** - * Run all Executors in a loop until they all report they have no ready work to do. - * - * Useful if you have Executors the post work to other Executors, and you simply want to - * run them all until they stop posting work. - */ - public static void exhaustExecutors(FakeExecutor ...executors) { - boolean didAnything; - do { - didAnything = false; - for (FakeExecutor executor : executors) { - didAnything = didAnything || executor.runAllReady() != 0; - } - } while (didAnything); - } - - private void updateClock(long nextTime) { - mIgnoreClockUpdates = true; - mClock.setUptimeMillis(nextTime); - mIgnoreClockUpdates = false; - } - - private static class QueuedRunnable implements Comparable { - private static AtomicInteger sCounter = new AtomicInteger(); - - Runnable mRunnable; - long mWhen; - private int mCounter; - - private QueuedRunnable(Runnable r, long when) { - mRunnable = r; - mWhen = when; - - // PrioirityQueue orders items arbitrarily when equal. We want to ensure that - // otherwise-equal elements are ordered according to their insertion order. Because this - // class only is constructed right before insertion, we use a static counter to track - // insertion order of otherwise equal elements. - mCounter = sCounter.incrementAndGet(); - } - - @Override - public int compareTo(QueuedRunnable other) { - long diff = mWhen - other.mWhen; - - if (diff == 0) { - return mCounter - other.mCounter; - } - - return diff > 0 ? 1 : -1; - } - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeRepeatableExecutor.java b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeRepeatableExecutor.java deleted file mode 100644 index 477f615faf2b..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeRepeatableExecutor.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.util.concurrency; - -/** - * A fake to use in tests. - */ -public class FakeRepeatableExecutor extends RepeatableExecutorImpl { - - /** - * Initializes a fake RepeatableExecutor from a fake executor. - * - * Use the fake executor to actually process tasks. - * - * @param executor fake executor. - */ - public FakeRepeatableExecutor(FakeExecutor executor) { - super(executor); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeThreadFactory.java b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeThreadFactory.java deleted file mode 100644 index 301a157bd42e..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeThreadFactory.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.util.concurrency; - -import android.os.Handler; -import android.os.Looper; - -import java.util.concurrent.Executor; - -/** - * Implementation of {@link ThreadFactory} that returns {@link FakeExecutor} where it can. - */ -public class FakeThreadFactory implements ThreadFactory { - private final FakeExecutor mFakeExecutor; - private Handler mHandler; - private Looper mLooper; - - public FakeThreadFactory(FakeExecutor fakeExecutor) { - mFakeExecutor = fakeExecutor; - } - - public void setHandler(Handler handler) { - mHandler = handler; - } - - public void setLooper(Looper looper) { - mLooper = looper; - } - - @Override - public Looper buildLooperOnNewThread(String threadName) { - return mLooper; - } - - @Override - public Handler buildHandlerOnNewThread(String threadName) { - return mHandler; - } - - @Override - public Executor buildExecutorOnNewThread(String threadName) { - return mFakeExecutor; - } - - @Override - public DelayableExecutor buildDelayableExecutorOnNewThread(String threadName) { - return mFakeExecutor; - } - - @Override - public DelayableExecutor buildDelayableExecutorOnHandler(Handler handler) { - return mFakeExecutor; - } - - @Override - public DelayableExecutor buildDelayableExecutorOnLooper(Looper looper) { - return mFakeExecutor; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/condition/FakeCondition.java b/packages/SystemUI/tests/src/com/android/systemui/util/condition/FakeCondition.java deleted file mode 100644 index 9d5ccbec87ea..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/util/condition/FakeCondition.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2021 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.util.condition; - -/** - * Fake implementation of {@link Condition}, and provides a way for tests to update - * condition fulfillment. - */ -public class FakeCondition extends Condition { - @Override - public void start() {} - - @Override - public void stop() {} - - public void fakeUpdateCondition(boolean isConditionMet) { - updateCondition(isConditionMet); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/io/FakeBasicFileAttributes.java b/packages/SystemUI/tests/src/com/android/systemui/util/io/FakeBasicFileAttributes.java deleted file mode 100644 index f7a04dcdbbd8..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/util/io/FakeBasicFileAttributes.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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.util.io; - -import java.nio.file.attribute.BasicFileAttributes; -import java.nio.file.attribute.FileTime; -import java.util.concurrent.TimeUnit; - -/** - * Fake implementation of {@link BasicFileAttributes} (for use in tests) - */ -public class FakeBasicFileAttributes implements BasicFileAttributes { - private FileTime mLastModifiedTime = FileTime.from(0, TimeUnit.MILLISECONDS); - private FileTime mLastAccessTime = FileTime.from(0, TimeUnit.MILLISECONDS); - private FileTime mCreationTime = FileTime.from(0, TimeUnit.MILLISECONDS); - private boolean mIsRegularFile = true; - private boolean mIsDirectory = false; - private boolean mIsSymbolicLink = false; - private boolean mIsOther = false; - private long mSize = 0; - private Object mFileKey = null; - - @Override - public FileTime lastModifiedTime() { - return mLastModifiedTime; - } - - @Override - public FileTime lastAccessTime() { - return mLastAccessTime; - } - - @Override - public FileTime creationTime() { - return mCreationTime; - } - - @Override - public boolean isRegularFile() { - return mIsRegularFile; - } - - @Override - public boolean isDirectory() { - return mIsDirectory; - } - - @Override - public boolean isSymbolicLink() { - return mIsSymbolicLink; - } - - @Override - public boolean isOther() { - return mIsOther; - } - - @Override - public long size() { - return mSize; - } - - @Override - public Object fileKey() { - return mFileKey; - } - - public FakeBasicFileAttributes setLastModifiedTime(long millis) { - mLastModifiedTime = FileTime.from(millis, TimeUnit.MILLISECONDS); - return this; - } - - public FakeBasicFileAttributes setLastAccessTime(long millis) { - mLastAccessTime = FileTime.from(millis, TimeUnit.MILLISECONDS); - return this; - } - - public FakeBasicFileAttributes setCreationTime(long millis) { - mCreationTime = FileTime.from(millis, TimeUnit.MILLISECONDS); - return this; - } - - public FakeBasicFileAttributes setRegularFile(boolean regularFile) { - mIsRegularFile = regularFile; - return this; - } - - public FakeBasicFileAttributes setDirectory(boolean directory) { - mIsDirectory = directory; - return this; - } - - public FakeBasicFileAttributes setSymbolicLink(boolean symbolicLink) { - mIsSymbolicLink = symbolicLink; - return this; - } - - public FakeBasicFileAttributes setOther(boolean other) { - mIsOther = other; - return this; - } - - public FakeBasicFileAttributes setSize(long size) { - mSize = size; - return this; - } - - public FakeBasicFileAttributes setFileKey(Object fileKey) { - mFileKey = fileKey; - return this; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java deleted file mode 100644 index 22cf744c726b..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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.util.sensors; - -import com.android.systemui.util.concurrency.DelayableExecutor; -import com.android.systemui.util.concurrency.FakeExecution; - -public class FakeProximitySensor extends ProximitySensorImpl { - private boolean mAvailable; - private boolean mRegistered; - - public FakeProximitySensor( - ThresholdSensor primary, - ThresholdSensor secondary, - DelayableExecutor delayableExecutor - ) { - super( - primary, - secondary == null ? new FakeThresholdSensor() : secondary, - delayableExecutor, - new FakeExecution() - ); - mAvailable = true; - } - - public void setSensorAvailable(boolean available) { - mAvailable = available; - } - - public void setLastEvent(ThresholdSensorEvent event) { - mLastEvent = event; - } - - @Override - public boolean isRegistered() { - return mRegistered; - } - - @Override - public boolean isLoaded() { - return mAvailable; - } - - @Override - protected void registerInternal() { - mRegistered = !mPaused; - } - - @Override - protected void unregisterInternal() { - mRegistered = false; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeSensorManager.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeSensorManager.java deleted file mode 100644 index 197873f15d0d..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeSensorManager.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (C) 2017 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.util.sensors; - -import android.content.Context; -import android.hardware.HardwareBuffer; -import android.hardware.Sensor; -import android.hardware.SensorAdditionalInfo; -import android.hardware.SensorDirectChannel; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; -import android.hardware.TriggerEventListener; -import android.os.Handler; -import android.os.MemoryFile; -import android.os.SystemClock; -import android.util.ArraySet; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -import javax.annotation.Nullable; - -/** - * Rudimentary fake for SensorManager - * - * Currently only supports proximity, light and tap sensors. - * - * Note that this class ignores the "Handler" argument, so the test is responsible for calling the - * listener on the right thread. - */ -public class FakeSensorManager extends SensorManager { - - public static final String TAP_SENSOR_TYPE = "tapSensorType"; - - private final FakeProximitySensor mFakeProximitySensor; - private final FakeGenericSensor mFakeLightSensor; - private final FakeGenericSensor mFakeLightSensor2; - private final FakeGenericSensor mFakeTapSensor; - private final FakeGenericSensor[] mSensors; - - public FakeSensorManager(Context context) throws Exception { - Sensor proxSensor = context.getSystemService(SensorManager.class) - .getDefaultSensor(Sensor.TYPE_PROXIMITY, true); - if (proxSensor == null) { - // No prox? Let's create a fake one! - proxSensor = - createSensor(Sensor.TYPE_PROXIMITY, null, 1 /* SENSOR_FLAG_WAKE_UP_SENSOR */); - } - - mSensors = new FakeGenericSensor[]{ - mFakeProximitySensor = new FakeProximitySensor(proxSensor), - mFakeLightSensor = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT, null)), - mFakeTapSensor = new FakeGenericSensor(createSensor(99, TAP_SENSOR_TYPE)), - mFakeLightSensor2 = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT, null)) - }; - } - - public FakeProximitySensor getFakeProximitySensor() { - return mFakeProximitySensor; - } - - public FakeGenericSensor getFakeLightSensor() { - return mFakeLightSensor; - } - - public FakeGenericSensor getFakeLightSensor2() { - return mFakeLightSensor2; - } - - public FakeGenericSensor getFakeTapSensor() { - return mFakeTapSensor; - } - - @Override - public Sensor getDefaultSensor(int type) { - Sensor s = super.getDefaultSensor(type); - if (s != null) { - return s; - } - // Our mock sensors aren't wakeup, and it's a pain to create them that way. Instead, just - // return non-wakeup sensors if we can't find a wakeup sensor. - return getDefaultSensor(type, false /* wakeup */); - } - - @Override - protected List getFullSensorList() { - return Arrays - .stream(mSensors) - .map(i -> i.mSensor) - .collect(Collectors.toList()); - } - - @Override - protected List getFullDynamicSensorList() { - return new ArrayList<>(); - } - - @Override - protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) { - Objects.requireNonNull(listener); - for (FakeGenericSensor s : mSensors) { - if (sensor == null || s.mSensor == sensor) { - s.mListeners.remove(listener); - } - } - } - - @Override - protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, - int delayUs, - Handler handler, int maxReportLatencyUs, int reservedFlags) { - Objects.requireNonNull(sensor); - Objects.requireNonNull(listener); - for (FakeGenericSensor s : mSensors) { - if (s.mSensor == sensor) { - s.mListeners.add(listener); - return true; - } - } - return false; - } - - @Override - protected boolean flushImpl(SensorEventListener listener) { - return false; - } - - @Override - protected SensorDirectChannel createDirectChannelImpl(MemoryFile memoryFile, - HardwareBuffer hardwareBuffer) { - return null; - } - - @Override - protected void destroyDirectChannelImpl(SensorDirectChannel channel) { - - } - - @Override - protected int configureDirectChannelImpl(SensorDirectChannel channel, Sensor s, int rate) { - return 0; - } - - @Override - protected void registerDynamicSensorCallbackImpl(DynamicSensorCallback callback, - Handler handler) { - - } - - @Override - protected void unregisterDynamicSensorCallbackImpl( - DynamicSensorCallback callback) { - - } - - @Override - protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) { - return true; - } - - @Override - protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor, - boolean disable) { - return true; - } - - @Override - protected boolean initDataInjectionImpl(boolean enable) { - return false; - } - - @Override - protected boolean injectSensorDataImpl(Sensor sensor, float[] values, int accuracy, - long timestamp) { - return false; - } - - @Override - protected boolean setOperationParameterImpl(SensorAdditionalInfo parameter) { - return false; - } - - private Sensor createSensor(int type, @Nullable String stringType) throws Exception { - return createSensor(type, stringType, 0 /* flags */); - } - - private Sensor createSensor(int type, @Nullable String stringType, int flags) throws Exception { - Constructor constr = Sensor.class.getDeclaredConstructor(); - constr.setAccessible(true); - Sensor sensor = constr.newInstance(); - - setSensorType(sensor, type); - if (stringType != null) { - setSensorField(sensor, "mStringType", stringType); - } - setSensorField(sensor, "mName", "Mock " + sensor.getStringType() + "/" + type); - setSensorField(sensor, "mVendor", "Mock Vendor"); - setSensorField(sensor, "mVersion", 1); - setSensorField(sensor, "mHandle", -1); - setSensorField(sensor, "mMaxRange", 10); - setSensorField(sensor, "mResolution", 1); - setSensorField(sensor, "mPower", 1); - setSensorField(sensor, "mMinDelay", 1000); - setSensorField(sensor, "mMaxDelay", 1000000000); - setSensorField(sensor, "mFlags", flags); - setSensorField(sensor, "mId", -1); - - return sensor; - } - - private void setSensorField(Sensor sensor, String fieldName, Object value) throws Exception { - Field field = Sensor.class.getDeclaredField(fieldName); - field.setAccessible(true); - field.set(sensor, value); - } - - private void setSensorType(Sensor sensor, int type) throws Exception { - Method setter = Sensor.class.getDeclaredMethod("setType", Integer.TYPE); - setter.setAccessible(true); - setter.invoke(sensor, type); - } - - public class FakeProximitySensor extends FakeGenericSensor { - - private FakeProximitySensor(Sensor sensor) { - super(sensor); - } - - public void sendProximityResult(boolean far) { - sendSensorEvent(far ? getSensor().getMaximumRange() : 0); - } - } - - public class FakeGenericSensor { - - private final Sensor mSensor; - private final ArraySet mListeners = new ArraySet<>(); - - public FakeGenericSensor( - Sensor sensor) { - this.mSensor = sensor; - } - - public Sensor getSensor() { - return mSensor; - } - - public void sendSensorEvent(float... values) { - SensorEvent event = createSensorEvent(values.length); - System.arraycopy(values, 0, event.values, 0, values.length); - for (SensorEventListener listener : mListeners) { - listener.onSensorChanged(event); - } - } - - private SensorEvent createSensorEvent(int valuesSize) { - SensorEvent event; - try { - Constructor constr = - SensorEvent.class.getDeclaredConstructor(Integer.TYPE); - constr.setAccessible(true); - event = constr.newInstance(valuesSize); - } catch (Exception e) { - throw new RuntimeException(e); - } - event.sensor = mSensor; - event.timestamp = SystemClock.elapsedRealtimeNanos(); - - return event; - } - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeThresholdSensor.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeThresholdSensor.java deleted file mode 100644 index 0d4a6c7023fb..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeThresholdSensor.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.util.sensors; - -import java.util.ArrayList; -import java.util.List; - -public class FakeThresholdSensor implements ThresholdSensor { - private boolean mIsLoaded; - private boolean mPaused; - private List mListeners = new ArrayList<>(); - - public FakeThresholdSensor() { - } - - public void setTag(String tag) { - } - - @Override - public void setDelay(int delay) { - } - - @Override - public boolean isLoaded() { - return mIsLoaded; - } - - @Override - public void pause() { - mPaused = true; - } - - @Override - public void resume() { - mPaused = false; - } - - @Override - public void register(ThresholdSensor.Listener listener) { - mListeners.add(listener); - } - - @Override - public void unregister(ThresholdSensor.Listener listener) { - mListeners.remove(listener); - } - - @Override - public String getName() { - return "FakeThresholdSensorName"; - } - - @Override - public String getType() { - return "FakeThresholdSensorType"; - } - - public void setLoaded(boolean loaded) { - mIsLoaded = loaded; - } - - void triggerEvent(boolean below, long timestampNs) { - if (!mPaused) { - for (Listener listener : mListeners) { - listener.onThresholdCrossed(new ThresholdSensorEvent(below, timestampNs)); - } - } - } - - boolean isPaused() { - return mPaused; - } - - int getNumListeners() { - return mListeners.size(); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/settings/FakeSettings.java b/packages/SystemUI/tests/src/com/android/systemui/util/settings/FakeSettings.java deleted file mode 100644 index e660e1f2d845..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/util/settings/FakeSettings.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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.util.settings; - -import android.annotation.UserIdInt; -import android.content.ContentResolver; -import android.database.ContentObserver; -import android.net.Uri; -import android.os.UserHandle; -import android.util.Pair; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class FakeSettings implements SecureSettings, GlobalSettings, SystemSettings { - private final Map mValues = new HashMap<>(); - private final Map> mContentObservers = - new HashMap<>(); - private final Map> mContentObserversAllUsers = new HashMap<>(); - - public static final Uri CONTENT_URI = Uri.parse("content://settings/fake"); - @UserIdInt - private int mUserId = UserHandle.USER_CURRENT; - - public FakeSettings() { - } - - public FakeSettings(String initialKey, String initialValue) { - putString(initialKey, initialValue); - } - - public FakeSettings(Map initialValues) { - for (Map.Entry kv : initialValues.entrySet()) { - putString(kv.getKey(), kv.getValue()); - } - } - - @Override - public ContentResolver getContentResolver() { - return null; - } - - @Override - public void registerContentObserverForUser(Uri uri, boolean notifyDescendents, - ContentObserver settingsObserver, int userHandle) { - List observers; - if (userHandle == UserHandle.USER_ALL) { - mContentObserversAllUsers.putIfAbsent(uri.toString(), new ArrayList<>()); - observers = mContentObserversAllUsers.get(uri.toString()); - } else { - SettingsKey key = new SettingsKey(userHandle, uri.toString()); - mContentObservers.putIfAbsent(key, new ArrayList<>()); - observers = mContentObservers.get(key); - } - observers.add(settingsObserver); - } - - @Override - public void unregisterContentObserver(ContentObserver settingsObserver) { - for (SettingsKey key : mContentObservers.keySet()) { - List observers = mContentObservers.get(key); - observers.remove(settingsObserver); - } - for (String key : mContentObserversAllUsers.keySet()) { - List observers = mContentObserversAllUsers.get(key); - observers.remove(settingsObserver); - } - } - - @Override - public Uri getUriFor(String name) { - return Uri.withAppendedPath(CONTENT_URI, name); - } - - public void setUserId(@UserIdInt int userId) { - mUserId = userId; - } - - @Override - public int getUserId() { - return mUserId; - } - - @Override - public String getString(String name) { - return getStringForUser(name, getUserId()); - } - - @Override - public String getStringForUser(String name, int userHandle) { - return mValues.get(new SettingsKey(userHandle, getUriFor(name).toString())); - } - - @Override - public boolean putString(String name, String value, boolean overrideableByRestore) { - return putStringForUser(name, value, null, false, getUserId(), overrideableByRestore); - } - - @Override - public boolean putString(String name, String value) { - return putString(name, value, false); - } - - @Override - public boolean putStringForUser(String name, String value, int userHandle) { - return putStringForUser(name, value, null, false, userHandle, false); - } - - @Override - public boolean putStringForUser(String name, String value, String tag, boolean makeDefault, - int userHandle, boolean overrideableByRestore) { - SettingsKey key = new SettingsKey(userHandle, getUriFor(name).toString()); - mValues.put(key, value); - - Uri uri = getUriFor(name); - for (ContentObserver observer : mContentObservers.getOrDefault(key, new ArrayList<>())) { - observer.dispatchChange(false, List.of(uri), 0, userHandle); - } - for (ContentObserver observer : - mContentObserversAllUsers.getOrDefault(uri.toString(), new ArrayList<>())) { - observer.dispatchChange(false, List.of(uri), 0, userHandle); - } - return true; - } - - @Override - public boolean putString(String name, String value, String tag, boolean makeDefault) { - return putString(name, value); - } - - private static class SettingsKey extends Pair { - SettingsKey(Integer first, String second) { - super(first, second); - } - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java b/packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java deleted file mode 100644 index db6164dcf8f9..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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.util.time; - -import com.android.systemui.util.concurrency.FakeExecutor; - -import java.util.ArrayList; -import java.util.List; - -/** - * A fake {@link SystemClock} for use with {@link FakeExecutor}. - * - * Attempts to simulate the behavior of a real system clock. Time can be moved forward but not - * backwards. uptimeMillis, elapsedRealtime, and currentThreadTimeMillis are all kept in sync. - * - * Unless otherwise specified, uptimeMillis and elapsedRealtime will advance the same amount with - * every call to {@link #advanceTime}. Thread time always lags by 50% of the uptime - * advancement to simulate time loss due to scheduling. - */ -public class FakeSystemClock implements SystemClock { - private long mUptimeMillis = 10000; - private long mElapsedRealtime = 10000; - private long mCurrentThreadTimeMillis = 10000; - private long mCurrentTimeMillis = 1555555500000L; - private final List mListeners = new ArrayList<>(); - - @Override - public long uptimeMillis() { - return mUptimeMillis; - } - - @Override - public long elapsedRealtime() { - return mElapsedRealtime; - } - - @Override - public long elapsedRealtimeNanos() { - return mElapsedRealtime * 1000000 + 447; - } - - @Override - public long currentThreadTimeMillis() { - return mCurrentThreadTimeMillis; - } - - @Override - public long currentTimeMillis() { - return mCurrentTimeMillis; - } - - public void setUptimeMillis(long uptime) { - advanceTime(uptime - mUptimeMillis); - } - - public void setCurrentTimeMillis(long millis) { - mCurrentTimeMillis = millis; - } - - public void setElapsedRealtime(long millis) { - mElapsedRealtime = millis; - } - - /** - * Advances the time tracked by the fake clock and notifies any listeners that the time has - * changed (for example, an attached {@link FakeExecutor} may fire its pending runnables). - * - * All tracked times increment by [millis], with the exception of currentThreadTimeMillis, - * which advances by [millis] * 0.5 - */ - public void advanceTime(long millis) { - advanceTime(millis, 0); - } - - /** - * Advances the time tracked by the fake clock and notifies any listeners that the time has - * changed (for example, an attached {@link FakeExecutor} may fire its pending runnables). - * - * The tracked times change as follows: - * - uptimeMillis increments by [awakeMillis] - * - currentThreadTimeMillis increments by [awakeMillis] * 0.5 - * - elapsedRealtime increments by [awakeMillis] + [sleepMillis] - * - currentTimeMillis increments by [awakeMillis] + [sleepMillis] - */ - public void advanceTime(long awakeMillis, long sleepMillis) { - if (awakeMillis < 0 || sleepMillis < 0) { - throw new IllegalArgumentException("Time cannot go backwards"); - } - - if (awakeMillis > 0 || sleepMillis > 0) { - mUptimeMillis += awakeMillis; - mElapsedRealtime += awakeMillis + sleepMillis; - mCurrentTimeMillis += awakeMillis + sleepMillis; - - mCurrentThreadTimeMillis += Math.ceil(awakeMillis * 0.5); - - for (ClockTickListener listener : mListeners) { - listener.onClockTick(); - } - } - } - - public void addListener(ClockTickListener listener) { - mListeners.add(listener); - } - - public void removeListener(ClockTickListener listener) { - mListeners.remove(listener); - } - - public interface ClockTickListener { - void onClockTick(); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockFake.java b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockFake.java deleted file mode 100644 index 553b8a42edc8..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockFake.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2017 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.util.wakelock; - -import android.content.Context; - -import com.android.internal.util.Preconditions; - -public class WakeLockFake implements WakeLock { - - private int mAcquired = 0; - - @Override - public void acquire(String why) { - mAcquired++; - } - - @Override - public void release(String why) { - Preconditions.checkState(mAcquired > 0); - mAcquired--; - } - - @Override - public Runnable wrap(Runnable runnable) { - acquire(WakeLockFake.class.getSimpleName()); - return () -> { - try { - runnable.run(); - } finally { - release(WakeLockFake.class.getSimpleName()); - } - }; - } - - public boolean isHeld() { - return mAcquired > 0; - } - - public static class Builder extends WakeLock.Builder { - private WakeLock mWakeLock; - - public Builder(Context context) { - super(context); - } - - public void setWakeLock(WakeLock wakeLock) { - mWakeLock = wakeLock; - } - - public WakeLock build() { - if (mWakeLock != null) { - return mWakeLock; - } - - return super.build(); - } - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/BaseLeakChecker.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/BaseLeakChecker.java deleted file mode 100644 index 8fe7f59bca67..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/BaseLeakChecker.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2017 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.utils.leaks; - -import android.testing.LeakCheck; -import android.testing.LeakCheck.Tracker; - -import com.android.systemui.Dumpable; -import com.android.systemui.statusbar.policy.CallbackController; - -import java.io.PrintWriter; - -public class BaseLeakChecker implements CallbackController, Dumpable { - - private final Tracker mTracker; - - public BaseLeakChecker(LeakCheck test, String tag) { - mTracker = test.getTracker(tag); - } - - protected final Tracker getTracker() { - return mTracker; - } - - @Override - public void addCallback(T listener) { - mTracker.getLeakInfo(listener).addAllocation(new Throwable()); - } - - @Override - public void removeCallback(T listener) { - mTracker.getLeakInfo(listener).clearAllocations(); - } - - @Override - public void dump(PrintWriter pw, String[] args) { - - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java deleted file mode 100644 index eaa109d672f8..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.os.Bundle; -import android.testing.LeakCheck; -import android.view.View; - -import com.android.systemui.statusbar.policy.BatteryController; -import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback; - -import java.io.PrintWriter; - -public class FakeBatteryController extends BaseLeakChecker - implements BatteryController { - private boolean mWirelessCharging; - - public FakeBatteryController(LeakCheck test) { - super(test, "battery"); - } - - @Override - public void dispatchDemoCommand(String command, Bundle args) { - - } - - @Override - public void dump(PrintWriter pw, String[] args) { - - } - - @Override - public void setPowerSaveMode(boolean powerSave) { - - } - - @Override - public void setPowerSaveMode(boolean powerSave, View view) { - - } - - @Override - public boolean isPluggedIn() { - return false; - } - - @Override - public boolean isPowerSave() { - return false; - } - - @Override - public boolean isAodPowerSave() { - return false; - } - - @Override - public boolean isWirelessCharging() { - return mWirelessCharging; - } - - public void setWirelessCharging(boolean wirelessCharging) { - mWirelessCharging = wirelessCharging; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBluetoothController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBluetoothController.java deleted file mode 100644 index 6cbd175c1084..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBluetoothController.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.testing.LeakCheck; - -import com.android.settingslib.bluetooth.CachedBluetoothDevice; -import com.android.systemui.statusbar.policy.BluetoothController; -import com.android.systemui.statusbar.policy.BluetoothController.Callback; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public class FakeBluetoothController extends BaseLeakChecker implements - BluetoothController { - - public FakeBluetoothController(LeakCheck test) { - super(test, "bluetooth"); - } - - @Override - public boolean isBluetoothSupported() { - return false; - } - - @Override - public boolean isBluetoothEnabled() { - return false; - } - - @Override - public int getBluetoothState() { - return 0; - } - - @Override - public boolean isBluetoothConnected() { - return false; - } - - @Override - public boolean isBluetoothConnecting() { - return false; - } - - @Override - public boolean isBluetoothAudioProfileOnly() { - return false; - } - - @Override - public boolean isBluetoothAudioActive() { - return false; - } - - @Override - public String getConnectedDeviceName() { - return null; - } - - @Override - public void setBluetoothEnabled(boolean enabled) { - - } - - @Override - public Collection getDevices() { - return null; - } - - @Override - public void connect(CachedBluetoothDevice device) { - - } - - @Override - public void disconnect(CachedBluetoothDevice device) { - - } - - @Override - public boolean canConfigBluetooth() { - return false; - } - - @Override - public int getMaxConnectionState(CachedBluetoothDevice device) { - return 0; - } - - @Override - public int getBondState(CachedBluetoothDevice device) { - return 0; - } - - @Override - public List getConnectedDevices() { - return Collections.emptyList(); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeCastController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeCastController.java deleted file mode 100644 index f6b24da9b821..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeCastController.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.testing.LeakCheck; - -import com.android.systemui.statusbar.policy.CastController; -import com.android.systemui.statusbar.policy.CastController.Callback; - -import java.util.ArrayList; -import java.util.List; - -public class FakeCastController extends BaseLeakChecker implements CastController { - public FakeCastController(LeakCheck test) { - super(test, "cast"); - } - - @Override - public void setDiscovering(boolean request) { - - } - - @Override - public void setCurrentUserId(int currentUserId) { - - } - - @Override - public List getCastDevices() { - return new ArrayList<>(); - } - - @Override - public void startCasting(CastDevice device) { - - } - - @Override - public void stopCasting(CastDevice device) { - - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java deleted file mode 100644 index 516eb6e6dffd..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2017 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.utils.leaks; - -import android.content.res.Configuration; - -import com.android.systemui.statusbar.policy.ConfigurationController; - -public class FakeConfigurationController - extends BaseLeakChecker - implements ConfigurationController { - - public FakeConfigurationController(LeakCheckedTest.SysuiLeakCheck sysuiLeakCheck) { - super(sysuiLeakCheck, "config"); - } - - @Override - public void onConfigurationChanged(Configuration newConfiguration) { - } - - @Override - public void notifyThemeChanged() { - } - - @Override - public boolean isLayoutRtl() { - return false; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeDataSaverController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeDataSaverController.java deleted file mode 100644 index 886722e46376..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeDataSaverController.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.testing.LeakCheck; - -import com.android.systemui.statusbar.policy.DataSaverController; -import com.android.systemui.statusbar.policy.DataSaverController.Listener; - -public class FakeDataSaverController extends BaseLeakChecker implements DataSaverController { - - public FakeDataSaverController(LeakCheck test) { - super(test, "datasaver"); - } - - @Override - public boolean isDataSaverEnabled() { - return false; - } - - @Override - public void setDataSaverEnabled(boolean enabled) { - - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeExtensionController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeExtensionController.java deleted file mode 100644 index ab16e3bd163e..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeExtensionController.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2017 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.utils.leaks; - -import android.content.Context; -import android.testing.LeakCheck; -import android.testing.LeakCheck.Tracker; - -import com.android.systemui.statusbar.policy.ExtensionController; - -import java.util.function.Consumer; -import java.util.function.Supplier; - -public class FakeExtensionController implements ExtensionController { - - private final Tracker mTracker; - - public FakeExtensionController(LeakCheck test) { - mTracker = test.getTracker("extension"); - } - - @Override - public ExtensionBuilder newExtension(Class cls) { - final Object o = new Object(); - mTracker.getLeakInfo(o).addAllocation(new Throwable()); - return new FakeExtensionBuilder(o); - } - - private class FakeExtensionBuilder implements ExtensionBuilder { - private final Object mAllocation; - - public FakeExtensionBuilder(Object o) { - mAllocation = o; - } - - @Override - public ExtensionBuilder withTunerFactory(TunerFactory factory) { - return this; - } - - @Override - public

ExtensionBuilder withPlugin(Class

cls) { - return this; - } - - @Override - public

ExtensionBuilder withPlugin(Class

cls, String action) { - return this; - } - - @Override - public

ExtensionBuilder withPlugin(Class

cls, String action, PluginConverter converter) { - return this; - } - - @Override - public ExtensionBuilder withDefault(Supplier def) { - return this; - } - - @Override - public ExtensionBuilder withCallback(Consumer callback) { - return this; - } - - @Override - public ExtensionBuilder withUiMode(int mode, Supplier def) { - return null; - } - - @Override - public ExtensionBuilder withFeature(String feature, Supplier def) { - return null; - } - - @Override - public Extension build() { - return new FakeExtension(mAllocation); - } - } - - private class FakeExtension implements Extension { - private final Object mAllocation; - - public FakeExtension(Object allocation) { - mAllocation = allocation; - } - - @Override - public T get() { - // TODO: Support defaults or things. - return null; - } - - @Override - public void clearItem(boolean isDestroyed) { - - } - - @Override - public Context getContext() { - return null; - } - - @Override - public void destroy() { - mTracker.getLeakInfo(mAllocation).clearAllocations(); - } - - @Override - public void addCallback(Consumer callback) { - } - - public T reload() { - return null; - } - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeFlashlightController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeFlashlightController.java deleted file mode 100644 index f6fd2cb8f3b1..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeFlashlightController.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.testing.LeakCheck; - -import com.android.systemui.statusbar.policy.FlashlightController; -import com.android.systemui.statusbar.policy.FlashlightController.FlashlightListener; - -public class FakeFlashlightController extends BaseLeakChecker - implements FlashlightController { - public FakeFlashlightController(LeakCheck test) { - super(test, "flashlight"); - } - - @Override - public boolean hasFlashlight() { - return false; - } - - @Override - public void setFlashlight(boolean newState) { - - } - - @Override - public boolean isAvailable() { - return false; - } - - @Override - public boolean isEnabled() { - return false; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeHotspotController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeHotspotController.java deleted file mode 100644 index 016160aea433..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeHotspotController.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.testing.LeakCheck; - -import com.android.systemui.statusbar.policy.HotspotController; -import com.android.systemui.statusbar.policy.HotspotController.Callback; - -public class FakeHotspotController extends BaseLeakChecker implements HotspotController { - - public FakeHotspotController(LeakCheck test) { - super(test, "hotspot"); - } - - @Override - public boolean isHotspotEnabled() { - return false; - } - - @Override - public boolean isHotspotTransient() { - return false; - } - - @Override - public void setHotspotEnabled(boolean enabled) { - - } - - @Override - public boolean isHotspotSupported() { - return false; - } - - @Override - public int getNumConnectedDevices() { - return 0; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java deleted file mode 100644 index 95b62a12c621..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.testing.LeakCheck; - -import com.android.systemui.statusbar.policy.KeyguardStateController; - -public class FakeKeyguardStateController implements KeyguardStateController { - - private final BaseLeakChecker mCallbackController; - - public FakeKeyguardStateController(LeakCheck test) { - mCallbackController = new BaseLeakChecker(test, "keyguard"); - } - - @Override - public void addCallback(Callback callback) { - mCallbackController.addCallback(callback); - } - - @Override - public void removeCallback(Callback callback) { - mCallbackController.removeCallback(callback); - } - - @Override - public boolean isMethodSecure() { - return false; - } - - @Override - public boolean isShowing() { - return false; - } - - @Override - public boolean isBouncerShowing() { - return false; - } - - @Override - public boolean canDismissLockScreen() { - return false; - } - - @Override - public boolean isOccluded() { - return false; - } - - @Override - public boolean isTrusted() { - return false; - } - - @Override - public boolean isKeyguardFadingAway() { - return false; - } - - @Override - public boolean isKeyguardGoingAway() { - return false; - } - - @Override - public boolean isLaunchTransitionFadingAway() { - return false; - } - - @Override - public long getKeyguardFadingAwayDuration() { - return 0; - } - - @Override - public long getKeyguardFadingAwayDelay() { - return 0; - } - - @Override - public long calculateGoingToFullShadeDelay() { - return 0; - } - - @Override - public float getDismissAmount() { - return 0; - } - - @Override - public boolean isDismissingFromSwipe() { - return false; - } - - @Override - public boolean isFlingingToDismissKeyguard() { - return false; - } - - @Override - public boolean isFlingingToDismissKeyguardDuringSwipeGesture() { - return false; - } - - @Override - public boolean isSnappingKeyguardBackAfterSwipe() { - return false; - } - - @Override - public void notifyPanelFlingStart(boolean dismiss) { - - } - - @Override - public void notifyPanelFlingEnd() { - - } - - @Override - public boolean isKeyguardScreenRotationAllowed() { - return false; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeLocationController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeLocationController.java deleted file mode 100644 index 838a2739f0b0..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeLocationController.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.testing.LeakCheck; - -import com.android.systemui.statusbar.policy.LocationController; -import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback; - -public class FakeLocationController extends BaseLeakChecker - implements LocationController { - public FakeLocationController(LeakCheck test) { - super(test, "location"); - } - - @Override - public boolean isLocationActive() { - return false; - } - - @Override - public boolean isLocationEnabled() { - return false; - } - - @Override - public boolean setLocationEnabled(boolean enabled) { - return false; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeManagedProfileController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeManagedProfileController.java deleted file mode 100644 index 18b07cf25fbc..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeManagedProfileController.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.testing.LeakCheck; - -import com.android.systemui.statusbar.phone.ManagedProfileController; -import com.android.systemui.statusbar.phone.ManagedProfileController.Callback; - -public class FakeManagedProfileController extends BaseLeakChecker implements - ManagedProfileController { - public FakeManagedProfileController(LeakCheck test) { - super(test, "profile"); - } - - @Override - public void setWorkModeEnabled(boolean enabled) { - - } - - @Override - public boolean hasActiveProfile() { - return false; - } - - @Override - public boolean isWorkModeEnabled() { - return false; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java deleted file mode 100644 index 33ef9cf7a9c5..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.os.Bundle; -import android.testing.LeakCheck; - -import com.android.settingslib.net.DataUsageController; -import com.android.systemui.statusbar.connectivity.AccessPointController; -import com.android.systemui.statusbar.connectivity.NetworkController; -import com.android.systemui.statusbar.connectivity.SignalCallback; -import com.android.systemui.statusbar.policy.DataSaverController; - -public class FakeNetworkController extends BaseLeakChecker - implements NetworkController { - - private final FakeDataSaverController mDataSaverController; - private final BaseLeakChecker mEmergencyChecker; - - public FakeNetworkController(LeakCheck test) { - super(test, "network"); - mDataSaverController = new FakeDataSaverController(test); - mEmergencyChecker = new BaseLeakChecker<>(test, "emergency"); - } - - @Override - public void addEmergencyListener(EmergencyListener listener) { - mEmergencyChecker.addCallback(listener); - } - - @Override - public void removeEmergencyListener(EmergencyListener listener) { - mEmergencyChecker.removeCallback(listener); - } - - @Override - public boolean hasEmergencyCryptKeeperText() { - return false; - } - - @Override - public boolean isRadioOn() { - return false; - } - - @Override - public DataSaverController getDataSaverController() { - return mDataSaverController; - } - - @Override - public boolean hasMobileDataFeature() { - return false; - } - - @Override - public void setWifiEnabled(boolean enabled) { - - } - - @Override - public AccessPointController getAccessPointController() { - return null; - } - - @Override - public DataUsageController getMobileDataController() { - return null; - } - - @Override - public boolean hasVoiceCallingFeature() { - return false; - } - - @Override - public void dispatchDemoCommand(String command, Bundle args) { - - } - - @Override - public String getMobileDataNetworkName() { - return ""; - } - - @Override - public boolean isMobileDataNetworkInService() { - return false; - } - - @Override - public int getNumberSubscriptions() { - return 0; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNextAlarmController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNextAlarmController.java deleted file mode 100644 index 5ae8e22c06ee..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNextAlarmController.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.testing.LeakCheck; - -import com.android.systemui.statusbar.policy.NextAlarmController; -import com.android.systemui.statusbar.policy.NextAlarmController.NextAlarmChangeCallback; - -public class FakeNextAlarmController extends BaseLeakChecker - implements NextAlarmController { - - public FakeNextAlarmController(LeakCheck test) { - super(test, "alarm"); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java deleted file mode 100644 index d245c727dcf8..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2017 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.utils.leaks; - -import android.testing.LeakCheck; - -import com.android.systemui.plugins.Plugin; -import com.android.systemui.plugins.PluginListener; -import com.android.systemui.shared.plugins.PluginManager; - -public class FakePluginManager implements PluginManager { - - private final BaseLeakChecker> mLeakChecker; - - public FakePluginManager(LeakCheck test) { - mLeakChecker = new BaseLeakChecker<>(test, "Plugin"); - } - - @Override - public void addPluginListener(String action, PluginListener listener, - Class cls, boolean allowMultiple) { - mLeakChecker.addCallback(listener); - } - - @Override - public void addPluginListener(PluginListener listener, Class cls) { - mLeakChecker.addCallback(listener); - } - - @Override - public void addPluginListener(PluginListener listener, Class cls, - boolean allowMultiple) { - mLeakChecker.addCallback(listener); - } - - @Override - public void addPluginListener(String action, PluginListener listener, - Class cls) { - mLeakChecker.addCallback(listener); - } - - @Override - public void removePluginListener(PluginListener listener) { - mLeakChecker.removeCallback(listener); - } - - @Override - public boolean dependsOn(Plugin p, Class cls) { - return false; - } - - @Override - public String[] getPrivilegedPlugins() { - return new String[0]; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeRotationLockController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeRotationLockController.java deleted file mode 100644 index 4f9cb35db1a3..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeRotationLockController.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.testing.LeakCheck; - -import com.android.systemui.statusbar.policy.RotationLockController; -import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback; - -public class FakeRotationLockController extends BaseLeakChecker - implements RotationLockController { - public FakeRotationLockController(LeakCheck test) { - super(test, "rotation"); - } - - @Override - public void setListening(boolean listening) { - - } - - @Override - public int getRotationLockOrientation() { - return 0; - } - - @Override - public boolean isRotationLockAffordanceVisible() { - return false; - } - - @Override - public boolean isRotationLocked() { - return false; - } - - @Override - public void setRotationLocked(boolean locked) { - - } - - @Override - public boolean isCameraRotationEnabled() { - return false; - } - - @Override - public void setRotationLockedAtAngle(boolean locked, int rotation) { - - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java deleted file mode 100644 index d5348dc39832..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.app.admin.DeviceAdminInfo; -import android.content.ComponentName; -import android.graphics.drawable.Drawable; -import android.testing.LeakCheck; - -import com.android.systemui.statusbar.policy.SecurityController; -import com.android.systemui.statusbar.policy.SecurityController.SecurityControllerCallback; - -public class FakeSecurityController extends BaseLeakChecker - implements SecurityController { - public FakeSecurityController(LeakCheck test) { - super(test, "security"); - } - - @Override - public boolean isDeviceManaged() { - return false; - } - - @Override - public boolean hasProfileOwner() { - return false; - } - - @Override - public boolean hasWorkProfile() { - return false; - } - - @Override - public boolean isWorkProfileOn() { - return false; - } - - @Override - public boolean isProfileOwnerOfOrganizationOwnedDevice() { - return false; - } - - @Override - public String getDeviceOwnerName() { - return null; - } - - @Override - public String getProfileOwnerName() { - return null; - } - - @Override - public CharSequence getDeviceOwnerOrganizationName() { - return null; - } - - @Override - public CharSequence getWorkProfileOrganizationName() { - return null; - } - - @Override - public ComponentName getDeviceOwnerComponentOnAnyUser() { - return null; - } - - @Override - public int getDeviceOwnerType(ComponentName admin) { - return 0; - } - - @Override - public boolean isNetworkLoggingEnabled() { - return false; - } - - @Override - public boolean isVpnEnabled() { - return false; - } - - @Override - public boolean isVpnRestricted() { - return false; - } - - @Override - public boolean isVpnBranded() { - return false; - } - - @Override - public String getPrimaryVpnName() { - return null; - } - - @Override - public String getWorkProfileVpnName() { - return null; - } - - @Override - public boolean hasCACertInCurrentUser() { - return false; - } - - @Override - public boolean hasCACertInWorkProfile() { - return false; - } - - @Override - public void onUserSwitched(int newUserId) { - - } - - @Override - public boolean isParentalControlsEnabled() { - return false; - } - - @Override - public DeviceAdminInfo getDeviceAdminInfo() { - return null; - } - - @Override - public Drawable getIcon(DeviceAdminInfo info) { - return null; - } - - @Override - public CharSequence getLabel(DeviceAdminInfo info) { - return null; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java deleted file mode 100644 index 2be67edfc946..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2017 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.utils.leaks; - -import android.testing.LeakCheck; - -import com.android.internal.statusbar.StatusBarIcon; -import com.android.systemui.statusbar.phone.StatusBarIconController; -import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager; -import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.CallIndicatorIconState; -import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; -import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; - -import java.util.List; - -public class FakeStatusBarIconController extends BaseLeakChecker - implements StatusBarIconController { - - public FakeStatusBarIconController(LeakCheck test) { - super(test, "StatusBarGroup"); - } - - @Override - public void addIconGroup(IconManager iconManager) { - addCallback(iconManager); - } - - @Override - public void removeIconGroup(IconManager iconManager) { - removeCallback(iconManager); - } - - @Override - public void refreshIconGroup(IconManager iconManager) { - } - - @Override - public void setExternalIcon(String slot) { - - } - - @Override - public void setIcon(String slot, int resourceId, CharSequence contentDescription) { - - } - - @Override - public void setIcon(String slot, StatusBarIcon icon) { - - } - - @Override - public void setSignalIcon(String slot, WifiIconState state) { - } - - @Override - public void setMobileIcons(String slot, List states) { - } - - @Override - public void setCallStrengthIcons(String slot, List states) { - } - - @Override - public void setNoCallingIcons(String slot, List states) { - } - - @Override - public void setIconVisibility(String slotTty, boolean b) { - } - - @Override - public void removeIcon(String slot, int tag) { - } - - @Override - public void removeAllIconsForSlot(String slot) { - } - - @Override - public void setIconAccessibilityLiveRegion(String slot, int mode) { - } - -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeTunerService.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeTunerService.java deleted file mode 100644 index 7d8a28812fde..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeTunerService.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2017 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.utils.leaks; - -import android.testing.LeakCheck; - -import com.android.systemui.tuner.TunerService; - -public class FakeTunerService extends TunerService { - - private final BaseLeakChecker mBaseLeakChecker; - private boolean mEnabled; - - public FakeTunerService(LeakCheck test) { - super(null); - mBaseLeakChecker = new BaseLeakChecker<>(test, "tunable"); - } - - @Override - public void addTunable(Tunable tunable, String... keys) { - for (String key : keys) { - tunable.onTuningChanged(key, null); - } - mBaseLeakChecker.addCallback(tunable); - } - - @Override - public void removeTunable(Tunable tunable) { - mBaseLeakChecker.removeCallback(tunable); - } - - @Override - public void clearAll() { - - } - - @Override - public void destroy() { - - } - - @Override - public String getValue(String setting) { - return null; - } - - @Override - public int getValue(String setting, int def) { - return def; - } - - @Override - public String getValue(String setting, String def) { - return def; - } - - @Override - public void setValue(String setting, String value) { - - } - - @Override - public void setValue(String setting, int value) { - - } - - @Override - public void setTunerEnabled(boolean enabled) { - mEnabled = enabled; - } - - @Override - public boolean isTunerEnabled() { - return mEnabled; - } - - @Override - public void showResetRequest(Runnable onDisabled) {} -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeUserInfoController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeUserInfoController.java deleted file mode 100644 index f7ef653aebf2..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeUserInfoController.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.testing.LeakCheck; - -import com.android.systemui.statusbar.policy.UserInfoController; -import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener; - -public class FakeUserInfoController extends BaseLeakChecker - implements UserInfoController { - public FakeUserInfoController(LeakCheck test) { - super(test, "user_info"); - } - - @Override - public void reloadUserInfo() { - - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeZenModeController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeZenModeController.java deleted file mode 100644 index 75df4e67db23..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeZenModeController.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.app.NotificationManager; -import android.content.ComponentName; -import android.net.Uri; -import android.service.notification.ZenModeConfig; -import android.service.notification.ZenModeConfig.ZenRule; -import android.testing.LeakCheck; - -import com.android.systemui.statusbar.policy.ZenModeController; -import com.android.systemui.statusbar.policy.ZenModeController.Callback; - -public class FakeZenModeController extends BaseLeakChecker implements ZenModeController { - public FakeZenModeController(LeakCheck test) { - super(test, "zen"); - } - - @Override - public void setZen(int zen, Uri conditionId, String reason) { - - } - - @Override - public int getZen() { - return 0; - } - - @Override - public ZenRule getManualRule() { - return null; - } - - @Override - public ZenModeConfig getConfig() { - return null; - } - - @Override - public NotificationManager.Policy getConsolidatedPolicy() { - return null; - } - - @Override - public long getNextAlarm() { - return 0; - } - - @Override - public boolean isZenAvailable() { - return false; - } - - @Override - public ComponentName getEffectsSuppressor() { - return null; - } - - @Override - public boolean isCountdownConditionSupported() { - return false; - } - - @Override - public int getCurrentUser() { - return 0; - } - - @Override - public boolean isVolumeRestricted() { - return false; - } - - @Override - public boolean areNotificationsHiddenInShade() { - return false; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java deleted file mode 100644 index dc6a8fb9a4c4..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2016 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.utils.leaks; - -import android.testing.LeakCheck; -import android.util.ArrayMap; - -import com.android.systemui.SysuiTestCase; -import com.android.systemui.shared.plugins.PluginManager; -import com.android.systemui.statusbar.connectivity.NetworkController; -import com.android.systemui.statusbar.phone.ManagedProfileController; -import com.android.systemui.statusbar.phone.StatusBarIconController; -import com.android.systemui.statusbar.policy.BatteryController; -import com.android.systemui.statusbar.policy.BluetoothController; -import com.android.systemui.statusbar.policy.CastController; -import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.statusbar.policy.FlashlightController; -import com.android.systemui.statusbar.policy.HotspotController; -import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.statusbar.policy.LocationController; -import com.android.systemui.statusbar.policy.NextAlarmController; -import com.android.systemui.statusbar.policy.RotationLockController; -import com.android.systemui.statusbar.policy.SecurityController; -import com.android.systemui.statusbar.policy.UserInfoController; -import com.android.systemui.statusbar.policy.ZenModeController; -import com.android.systemui.tuner.TunerService; - -import org.junit.Assert; -import org.junit.Rule; - -import java.util.Map; - -/** - * Base class for tests to check if receivers are left registered, services bound, or other - * listeners listening. - */ -public abstract class LeakCheckedTest extends SysuiTestCase { - private static final String TAG = "LeakCheckedTest"; - - public static final Class[] ALL_SUPPORTED_CLASSES = new Class[]{ - BluetoothController.class, - LocationController.class, - RotationLockController.class, - ZenModeController.class, - CastController.class, - HotspotController.class, - FlashlightController.class, - UserInfoController.class, - KeyguardStateController.class, - BatteryController.class, - SecurityController.class, - ManagedProfileController.class, - NextAlarmController.class, - NetworkController.class, - PluginManager.class, - TunerService.class, - StatusBarIconController.class, - ConfigurationController.class, - }; - - @Rule - public SysuiLeakCheck mLeakCheck = new SysuiLeakCheck(); - - @Override - public LeakCheck getLeakCheck() { - return mLeakCheck; - } - - public void injectLeakCheckedDependencies(Class... cls) { - for (Class c : cls) { - injectLeakCheckedDependency(c); - } - } - - public void injectLeakCheckedDependency(Class c) { - mDependency.injectTestDependency(c, mLeakCheck.getLeakChecker(c)); - } - - public static class SysuiLeakCheck extends LeakCheck { - - private final Map mLeakCheckers = new ArrayMap<>(); - - public SysuiLeakCheck() { - super(); - } - - public T getLeakChecker(Class cls) { - Object obj = mLeakCheckers.get(cls); - if (obj == null) { - // Lazy create checkers so we only have the ones we need. - if (cls == BluetoothController.class) { - obj = new FakeBluetoothController(this); - } else if (cls == LocationController.class) { - obj = new FakeLocationController(this); - } else if (cls == RotationLockController.class) { - obj = new FakeRotationLockController(this); - } else if (cls == ZenModeController.class) { - obj = new FakeZenModeController(this); - } else if (cls == CastController.class) { - obj = new FakeCastController(this); - } else if (cls == HotspotController.class) { - obj = new FakeHotspotController(this); - } else if (cls == FlashlightController.class) { - obj = new FakeFlashlightController(this); - } else if (cls == UserInfoController.class) { - obj = new FakeUserInfoController(this); - } else if (cls == KeyguardStateController.class) { - obj = new FakeKeyguardStateController(this); - } else if (cls == BatteryController.class) { - obj = new FakeBatteryController(this); - } else if (cls == SecurityController.class) { - obj = new FakeSecurityController(this); - } else if (cls == ManagedProfileController.class) { - obj = new FakeManagedProfileController(this); - } else if (cls == NextAlarmController.class) { - obj = new FakeNextAlarmController(this); - } else if (cls == NetworkController.class) { - obj = new FakeNetworkController(this); - } else if (cls == PluginManager.class) { - obj = new FakePluginManager(this); - } else if (cls == TunerService.class) { - obj = new FakeTunerService(this); - } else if (cls == StatusBarIconController.class) { - obj = new FakeStatusBarIconController(this); - } else if (cls == ConfigurationController.class) { - obj = new FakeConfigurationController(this); - } else { - Assert.fail(cls.getName() + " is not supported by LeakCheckedTest yet"); - } - mLeakCheckers.put(cls, obj); - } - return (T) obj; - } - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/os/FakeHandler.java b/packages/SystemUI/tests/src/com/android/systemui/utils/os/FakeHandler.java deleted file mode 100644 index 5a7d4b5e54b3..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/os/FakeHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2017 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.utils.os; - -import android.os.Handler; -import android.os.Looper; -import android.os.Message; - -import java.util.ArrayList; - -/** - * A handler that allows control over when to dispatch messages and callbacks. - * - * WARNING: Because most Handler methods are final, the only thing this handler can intercept - * are sending messages and posting runnables, but *NOT* removing messages nor runnables. - * It also *CANNOT* intercept messages posted to the front of queue. - */ -public class FakeHandler extends Handler { - - private Mode mMode = Mode.IMMEDIATE; - private ArrayList mQueuedMessages = new ArrayList<>(); - - public FakeHandler(Looper looper) { - super(looper); - } - - @Override - public boolean sendMessageAtTime(Message msg, long uptimeMillis) { - mQueuedMessages.add(msg); - if (mMode == Mode.IMMEDIATE) { - dispatchQueuedMessages(); - } - return true; - } - - public void setMode(Mode mode) { - mMode = mode; - } - - /** - * Dispatch any messages that have been queued on the calling thread. - */ - public void dispatchQueuedMessages() { - ArrayList messages = new ArrayList<>(mQueuedMessages); - mQueuedMessages.clear(); - for (Message msg : messages) { - dispatchMessage(msg); - } - } - - public enum Mode { - /** Messages are dispatched immediately on the calling thread. */ - IMMEDIATE, - /** Messages are queued until {@link #dispatchQueuedMessages()} is called. */ - QUEUEING, - } -} diff --git a/packages/SystemUI/tests/utils/AndroidManifest.xml b/packages/SystemUI/tests/utils/AndroidManifest.xml new file mode 100644 index 000000000000..cbef5f6036ab --- /dev/null +++ b/packages/SystemUI/tests/utils/AndroidManifest.xml @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiBaseFragmentTest.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiBaseFragmentTest.java new file mode 100644 index 000000000000..9179efc9f39f --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiBaseFragmentTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2017 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; + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.app.Fragment; +import android.app.Instrumentation; +import android.testing.BaseFragmentTest; +import android.testing.DexmakerShareClassLoaderRule; + +import androidx.test.InstrumentationRegistry; + +import com.android.systemui.assist.AssistManager; +import com.android.systemui.utils.leaks.LeakCheckedTest; +import com.android.systemui.utils.leaks.LeakCheckedTest.SysuiLeakCheck; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Rule; +import org.mockito.Mockito; + +import java.util.concurrent.ExecutionException; + +public abstract class SysuiBaseFragmentTest extends BaseFragmentTest { + + public static final Class[] ALL_SUPPORTED_CLASSES = LeakCheckedTest.ALL_SUPPORTED_CLASSES; + + @Rule + public final SysuiLeakCheck mLeakCheck = new SysuiLeakCheck(); + + @Rule + public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule = + new DexmakerShareClassLoaderRule(); + + protected TestableDependency mDependency; + protected SysuiTestableContext mSysuiContext; + private Instrumentation mRealInstrumentation; + + public SysuiBaseFragmentTest(Class cls) { + super(cls); + } + + @Before + public void sysuiSetup() throws ExecutionException, InterruptedException { + SystemUIInitializer initializer = + SystemUIInitializerFactory.createFromConfigNoAssert(mContext); + initializer.init(true); + mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency()); + Dependency.setInstance(mDependency); + + // TODO: Figure out another way to give reference to a SysuiTestableContext. + mSysuiContext = (SysuiTestableContext) mContext; + + mRealInstrumentation = InstrumentationRegistry.getInstrumentation(); + Instrumentation inst = spy(mRealInstrumentation); + when(inst.getContext()).thenThrow(new RuntimeException( + "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext")); + when(inst.getTargetContext()).thenThrow(new RuntimeException( + "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext")); + InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments()); + mDependency.injectMockDependency(AssistManager.class); + } + + @After + public void SysuiTeardown() { + InstrumentationRegistry.registerInstance(mRealInstrumentation, + InstrumentationRegistry.getArguments()); + } + + @AfterClass + public static void mockitoTeardown() { + Mockito.framework().clearInlineMocks(); + } + + @Override + protected SysuiTestableContext getContext() { + return new SysuiTestableContext(InstrumentationRegistry.getContext(), mLeakCheck); + } + + public void injectLeakCheckedDependencies(Class... cls) { + for (Class c : cls) { + injectLeakCheckedDependency(c); + } + } + + public void injectLeakCheckedDependency(Class c) { + mDependency.injectTestDependency(c, mLeakCheck.getLeakChecker(c)); + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java new file mode 100644 index 000000000000..c52ea60f0bfc --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2014 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; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.app.Instrumentation; +import android.os.Handler; +import android.os.Looper; +import android.os.MessageQueue; +import android.os.ParcelFileDescriptor; +import android.testing.DexmakerShareClassLoaderRule; +import android.testing.LeakCheck; +import android.testing.TestableLooper; +import android.util.Log; + +import androidx.test.InstrumentationRegistry; +import androidx.test.uiautomator.UiDevice; + +import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.settingslib.bluetooth.LocalBluetoothManager; +import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.broadcast.FakeBroadcastDispatcher; +import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger; +import com.android.systemui.classifier.FalsingManagerFake; +import com.android.systemui.dump.DumpManager; +import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.settings.UserTracker; +import com.android.systemui.statusbar.SmartReplyController; +import com.android.systemui.statusbar.phone.SystemUIDialogManager; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Rule; +import org.mockito.Mockito; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.Future; + +/** + * Base class that does System UI specific setup. + */ +public abstract class SysuiTestCase { + + private static final String TAG = "SysuiTestCase"; + + private Handler mHandler; + @Rule + public SysuiTestableContext mContext = new SysuiTestableContext( + InstrumentationRegistry.getContext(), getLeakCheck()); + @Rule + public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule = + new DexmakerShareClassLoaderRule(); + public TestableDependency mDependency; + private Instrumentation mRealInstrumentation; + private FakeBroadcastDispatcher mFakeBroadcastDispatcher; + + @Before + public void SysuiSetup() throws Exception { + SystemUIInitializer initializer = + SystemUIInitializerFactory.createFromConfigNoAssert(mContext); + initializer.init(true); + mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency()); + Dependency.setInstance(mDependency); + mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Looper.class), + mock(Executor.class), mock(DumpManager.class), + mock(BroadcastDispatcherLogger.class), mock(UserTracker.class)); + + mRealInstrumentation = InstrumentationRegistry.getInstrumentation(); + Instrumentation inst = spy(mRealInstrumentation); + when(inst.getContext()).thenAnswer(invocation -> { + throw new RuntimeException( + "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"); + }); + when(inst.getTargetContext()).thenAnswer(invocation -> { + throw new RuntimeException( + "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"); + }); + InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments()); + // Many tests end up creating a BroadcastDispatcher. Instead, give them a fake that will + // record receivers registered. They are not actually leaked as they are kept just as a weak + // reference and are never sent to the Context. This will also prevent a real + // BroadcastDispatcher from actually registering receivers. + mDependency.injectTestDependency(BroadcastDispatcher.class, mFakeBroadcastDispatcher); + // A lot of tests get the FalsingManager, often via several layers of indirection. + // None of them actually need it. + mDependency.injectTestDependency(FalsingManager.class, new FalsingManagerFake()); + mDependency.injectMockDependency(KeyguardUpdateMonitor.class); + + // A lot of tests get the LocalBluetoothManager, often via several layers of indirection. + // None of them actually need it. + mDependency.injectMockDependency(LocalBluetoothManager.class); + + // Notifications tests are injecting one of these, causing many classes (including + // KeyguardUpdateMonitor to be created (injected). + // TODO(b/1531701009) Clean up NotificationContentView creation to prevent this + mDependency.injectMockDependency(SmartReplyController.class); + + // Make sure that all tests on any SystemUIDialog does not crash because this dependency + // is missing (constructing the actual one would throw). + // TODO(b/219008720): Remove this. + mDependency.injectMockDependency(SystemUIDialogManager.class); + } + + @After + public void SysuiTeardown() { + InstrumentationRegistry.registerInstance(mRealInstrumentation, + InstrumentationRegistry.getArguments()); + if (TestableLooper.get(this) != null) { + TestableLooper.get(this).processAllMessages(); + } + disallowTestableLooperAsMainThread(); + mContext.cleanUpReceivers(this.getClass().getSimpleName()); + mFakeBroadcastDispatcher.cleanUpReceivers(this.getClass().getSimpleName()); + } + + @AfterClass + public static void mockitoTearDown() { + Mockito.framework().clearInlineMocks(); + } + + /** + * Tests are run on the TestableLooper; however, there are parts of SystemUI that assert that + * the code is run from the main looper. Therefore, we allow the TestableLooper to pass these + * assertions since in a test, the TestableLooper is essentially the MainLooper. + */ + protected void allowTestableLooperAsMainThread() { + com.android.systemui.util.Assert.setTestableLooper(TestableLooper.get(this).getLooper()); + } + + protected void disallowTestableLooperAsMainThread() { + com.android.systemui.util.Assert.setTestableLooper(null); + } + + protected LeakCheck getLeakCheck() { + return null; + } + + protected FakeBroadcastDispatcher getFakeBroadcastDispatcher() { + return mFakeBroadcastDispatcher; + } + + public SysuiTestableContext getContext() { + return mContext; + } + + protected UiDevice getUiDevice() { + return UiDevice.getInstance(mRealInstrumentation); + } + + protected void runShellCommand(String command) throws IOException { + ParcelFileDescriptor pfd = mRealInstrumentation.getUiAutomation() + .executeShellCommand(command); + + // Read the input stream fully. + FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd); + while (fis.read() != -1); + fis.close(); + } + + protected void waitForIdleSync() { + if (mHandler == null) { + mHandler = new Handler(Looper.getMainLooper()); + } + waitForIdleSync(mHandler); + } + + protected void waitForUiOffloadThread() { + Future future = Dependency.get(UiOffloadThread.class).execute(() -> { }); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + Log.e(TAG, "Failed to wait for ui offload thread.", e); + } + } + + public static void waitForIdleSync(Handler h) { + validateThread(h.getLooper()); + Idler idler = new Idler(null); + h.getLooper().getQueue().addIdleHandler(idler); + // Ensure we are non-idle, so the idle handler can run. + h.post(new EmptyRunnable()); + idler.waitForIdle(); + } + + private static final void validateThread(Looper l) { + if (Looper.myLooper() == l) { + throw new RuntimeException( + "This method can not be called from the looper being synced"); + } + } + + /** Delegates to {@link android.testing.TestableResources#addOverride(int, Object)}. */ + protected void overrideResource(int resourceId, Object value) { + mContext.getOrCreateTestableResources().addOverride(resourceId, value); + } + + public static final class EmptyRunnable implements Runnable { + public void run() { + } + } + + public static final class Idler implements MessageQueue.IdleHandler { + private final Runnable mCallback; + private boolean mIdle; + + public Idler(Runnable callback) { + mCallback = callback; + mIdle = false; + } + + @Override + public boolean queueIdle() { + if (mCallback != null) { + mCallback.run(); + } + synchronized (this) { + mIdle = true; + notifyAll(); + } + return false; + } + + public void waitForIdle() { + synchronized (this) { + while (!mIdle) { + try { + wait(); + } catch (InterruptedException e) { + } + } + } + } + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java new file mode 100644 index 000000000000..0674ea855d7f --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2017 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; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Handler; +import android.os.UserHandle; +import android.testing.LeakCheck; +import android.testing.TestableContext; +import android.util.ArraySet; +import android.util.Log; +import android.view.Display; + +import com.android.internal.annotations.GuardedBy; + +import java.util.Set; + +public class SysuiTestableContext extends TestableContext { + + @GuardedBy("mRegisteredReceivers") + private final Set mRegisteredReceivers = new ArraySet<>(); + + public SysuiTestableContext(Context base) { + super(base); + setTheme(R.style.Theme_SystemUI); + } + + public SysuiTestableContext(Context base, LeakCheck check) { + super(base, check); + setTheme(R.style.Theme_SystemUI); + } + + @Override + public Context createDisplayContext(Display display) { + if (display == null) { + throw new IllegalArgumentException("display must not be null"); + } + + SysuiTestableContext context = + new SysuiTestableContext(getBaseContext().createDisplayContext(display)); + return context; + } + + public void cleanUpReceivers(String testName) { + Set copy; + synchronized (mRegisteredReceivers) { + copy = new ArraySet<>(mRegisteredReceivers); + mRegisteredReceivers.clear(); + } + for (BroadcastReceiver r : copy) { + try { + unregisterReceiver(r); + Log.w(testName, "Receiver not unregistered from Context: " + r); + } catch (IllegalArgumentException e) { + // Nothing to do here. Somehow it got unregistered. + } + } + } + + @Override + public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { + if (receiver != null) { + synchronized (mRegisteredReceivers) { + mRegisteredReceivers.add(receiver); + } + } + return super.registerReceiver(receiver, filter); + } + + @Override + public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) { + if (receiver != null) { + synchronized (mRegisteredReceivers) { + mRegisteredReceivers.add(receiver); + } + } + return super.registerReceiver(receiver, filter, flags); + } + + @Override + public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, + String broadcastPermission, Handler scheduler) { + if (receiver != null) { + synchronized (mRegisteredReceivers) { + mRegisteredReceivers.add(receiver); + } + } + return super.registerReceiver(receiver, filter, broadcastPermission, scheduler); + } + + @Override + public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, + String broadcastPermission, Handler scheduler, int flags) { + if (receiver != null) { + synchronized (mRegisteredReceivers) { + mRegisteredReceivers.add(receiver); + } + } + return super.registerReceiver(receiver, filter, broadcastPermission, scheduler, flags); + } + + @Override + public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, + IntentFilter filter, String broadcastPermission, Handler scheduler) { + if (receiver != null) { + synchronized (mRegisteredReceivers) { + mRegisteredReceivers.add(receiver); + } + } + return super.registerReceiverAsUser(receiver, user, filter, broadcastPermission, scheduler); + } + + @Override + public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, + IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) { + if (receiver != null) { + synchronized (mRegisteredReceivers) { + mRegisteredReceivers.add(receiver); + } + } + return super.registerReceiverAsUser(receiver, user, filter, broadcastPermission, scheduler, + flags); + } + + @Override + public void unregisterReceiver(BroadcastReceiver receiver) { + if (receiver != null) { + synchronized (mRegisteredReceivers) { + mRegisteredReceivers.remove(receiver); + } + } + super.unregisterReceiver(receiver); + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/TestableDependency.java b/packages/SystemUI/tests/utils/src/com/android/systemui/TestableDependency.java new file mode 100644 index 000000000000..0751475c2fb0 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/TestableDependency.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2017 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; + +import static org.mockito.Mockito.mock; + +import android.util.ArrayMap; +import android.util.ArraySet; +import android.util.Log; + +public class TestableDependency extends Dependency { + private static final String TAG = "TestableDependency"; + + private final ArrayMap mObjs = new ArrayMap<>(); + private final ArraySet mInstantiatedObjects = new ArraySet<>(); + private final Dependency mParent; + + public TestableDependency(Dependency parent) { + mParent = parent; + } + + public T injectMockDependency(Class cls) { + final T mock = mock(cls); + injectTestDependency(cls, mock); + return mock; + } + + public void injectTestDependency(DependencyKey key, T obj) { + mObjs.put(key, obj); + } + + public void injectTestDependency(Class key, T obj) { + if (mInstantiatedObjects.contains(key)) { + Log.d(TAG, key + " was already initialized but overriding with testDependency."); + } + mObjs.put(key, obj); + } + + @Override + public T createDependency(Object key) { + if (mObjs.containsKey(key)) return (T) mObjs.get(key); + + mInstantiatedObjects.add(key); + return mParent.createDependency(key); + } + + public boolean hasInstantiatedDependency(Class key) { + return mObjs.containsKey(key) || mInstantiatedObjects.contains(key); + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt new file mode 100644 index 000000000000..53dcc8d269c9 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt @@ -0,0 +1,81 @@ +/* + * 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.broadcast + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.IntentFilter +import android.os.Handler +import android.os.Looper +import android.os.UserHandle +import android.util.ArraySet +import android.util.Log +import com.android.systemui.SysuiTestableContext +import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger +import com.android.systemui.dump.DumpManager +import com.android.systemui.settings.UserTracker +import java.util.concurrent.Executor + +class FakeBroadcastDispatcher( + context: SysuiTestableContext, + looper: Looper, + executor: Executor, + dumpManager: DumpManager, + logger: BroadcastDispatcherLogger, + userTracker: UserTracker +) : BroadcastDispatcher( + context, looper, executor, dumpManager, logger, userTracker, PendingRemovalStore(logger)) { + + private val registeredReceivers = ArraySet() + + override fun registerReceiverWithHandler( + receiver: BroadcastReceiver, + filter: IntentFilter, + handler: Handler, + user: UserHandle, + @Context.RegisterReceiverFlags flags: Int, + permission: String? + ) { + registeredReceivers.add(receiver) + } + + override fun registerReceiver( + receiver: BroadcastReceiver, + filter: IntentFilter, + executor: Executor?, + user: UserHandle?, + @Context.RegisterReceiverFlags flags: Int, + permission: String? + ) { + registeredReceivers.add(receiver) + } + + override fun unregisterReceiver(receiver: BroadcastReceiver) { + registeredReceivers.remove(receiver) + } + + override fun unregisterReceiverForUser(receiver: BroadcastReceiver, user: UserHandle) { + registeredReceivers.remove(receiver) + } + + fun cleanUpReceivers(testName: String) { + registeredReceivers.forEach { + Log.i(testName, "Receiver not unregistered from dispatcher: $it") + } + registeredReceivers.clear() + } +} \ No newline at end of file diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingManagerFake.java new file mode 100644 index 000000000000..48b5c62da38f --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingManagerFake.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2021 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.classifier; + +import static com.google.common.truth.Truth.assertWithMessage; + +import android.net.Uri; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.plugins.FalsingManager; + +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; + +/** + * Simple Fake for testing where {@link FalsingManager} is required. + */ +public class FalsingManagerFake implements FalsingManager { + private boolean mIsFalseTouch; + private boolean mIsSimpleTap; + private boolean mIsFalseDoubleTap; + private boolean mIsUnlockingDisabled; + private boolean mIsClassifierEnabled; + private boolean mShouldEnforceBouncer; + private boolean mIsReportingEnabled; + private boolean mIsFalseRobustTap; + private boolean mDestroyed; + + private final List mFalsingBeliefListeners = new ArrayList<>(); + private final List mTapListeners = new ArrayList<>(); + + @Override + public void onSuccessfulUnlock() { + + } + + @VisibleForTesting + public void setIsUnlockingDisabled(boolean isUnlockingDisabled) { + mIsUnlockingDisabled = isUnlockingDisabled; + } + + @Override + public boolean isUnlockingDisabled() { + return mIsUnlockingDisabled; + } + + @VisibleForTesting + public void setIsFalseTouch(boolean isFalseTouch) { + mIsFalseTouch = isFalseTouch; + } + + @Override + public boolean isFalseTouch(@Classifier.InteractionType int interactionType) { + checkDestroyed(); + return mIsFalseTouch; + } + + public void setFalseTap(boolean falseRobustTap) { + mIsFalseRobustTap = falseRobustTap; + } + + public void setSimpleTap(boolean isSimpleTape) { + mIsSimpleTap = isSimpleTape; + } + + public void setFalseDoubleTap(boolean falseDoubleTap) { + mIsFalseDoubleTap = falseDoubleTap; + } + + @Override + public boolean isSimpleTap() { + checkDestroyed(); + return mIsSimpleTap; + } + + @Override + public boolean isFalseTap(@Penalty int penalty) { + checkDestroyed(); + return mIsFalseRobustTap; + } + + @Override + public boolean isFalseDoubleTap() { + checkDestroyed(); + return mIsFalseDoubleTap; + } + + @VisibleForTesting + public void setIsClassifierEnabled(boolean isClassifierEnabled) { + mIsClassifierEnabled = isClassifierEnabled; + } + + @Override + public boolean isClassifierEnabled() { + return mIsClassifierEnabled; + } + + @Override + public boolean shouldEnforceBouncer() { + return mShouldEnforceBouncer; + } + + @Override + public Uri reportRejectedTouch() { + return null; + } + + @VisibleForTesting + public void setIsReportingEnabled(boolean isReportingEnabled) { + mIsReportingEnabled = isReportingEnabled; + } + + @Override + public boolean isReportingEnabled() { + return mIsReportingEnabled; + } + + @Override + public void dump(PrintWriter pw, String[] args) { + } + + @Override + public void cleanupInternal() { + mDestroyed = true; + } + + private void checkDestroyed() { + assertWithMessage("FakeFasingManager has been destroyed") + .that(mDestroyed).isFalse(); + } + + @Override + public void onProximityEvent(ProximityEvent proximityEvent) { + + } + + @Override + public void addFalsingBeliefListener(FalsingBeliefListener listener) { + mFalsingBeliefListeners.add(listener); + } + + @Override + public void removeFalsingBeliefListener(FalsingBeliefListener listener) { + mFalsingBeliefListeners.remove(listener); + } + + @Override + public void addTapListener(FalsingTapListener falsingTapListener) { + mTapListeners.add(falsingTapListener); + } + + @Override + public void removeTapListener(FalsingTapListener falsingTapListener) { + mTapListeners.remove(falsingTapListener); + } + + public List getTapListeners() { + return mTapListeners; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/people/FakePeopleTileRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/people/FakePeopleTileRepository.kt new file mode 100644 index 000000000000..0bde5d21d32f --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/people/FakePeopleTileRepository.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2022 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.people + +import com.android.systemui.people.data.model.PeopleTileModel +import com.android.systemui.people.data.repository.PeopleTileRepository + +/** A fake [PeopleTileRepository] to be used in tests. */ +class FakePeopleTileRepository( + private val priorityTiles: List, + private val recentTiles: List, +) : PeopleTileRepository { + override fun priorityTiles(): List = priorityTiles + + override fun recentTiles(): List = recentTiles +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/people/FakePeopleWidgetRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/people/FakePeopleWidgetRepository.kt new file mode 100644 index 000000000000..2f814091f3e5 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/people/FakePeopleWidgetRepository.kt @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2022 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.people + +import com.android.systemui.people.data.repository.PeopleWidgetRepository +import com.android.systemui.people.widget.PeopleTileKey + +/** A fake [PeopleWidgetRepository] to be used in tests. */ +class FakePeopleWidgetRepository( + private val onSetWidgetTile: (widgetId: Int, tileKey: PeopleTileKey) -> Unit = { _, _ -> }, +) : PeopleWidgetRepository { + override fun setWidgetTile(widgetId: Int, tileKey: PeopleTileKey) { + onSetWidgetTile(widgetId, tileKey) + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/screenshot/FakeScrollCaptureConnection.java b/packages/SystemUI/tests/utils/src/com/android/systemui/screenshot/FakeScrollCaptureConnection.java new file mode 100644 index 000000000000..63f7c9755782 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/screenshot/FakeScrollCaptureConnection.java @@ -0,0 +1,142 @@ +/* + * 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.screenshot; + +import android.content.pm.ActivityInfo; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.HardwareRenderer; +import android.graphics.Paint; +import android.graphics.RecordingCanvas; +import android.graphics.Rect; +import android.graphics.RenderNode; +import android.os.CancellationSignal; +import android.os.ICancellationSignal; +import android.os.RemoteException; +import android.view.IScrollCaptureCallbacks; +import android.view.IScrollCaptureConnection; +import android.view.Surface; + +/** + * An IScrollCaptureConnection which returns a sequence of solid filled rectangles in the + * locations requested, in alternating colors. + */ +class FakeScrollCaptureConnection extends IScrollCaptureConnection.Stub { + private final int[] mColors = {Color.RED, Color.GREEN, Color.BLUE}; + private IScrollCaptureCallbacks mCallbacks; + private Paint mPaint; + private int mNextColor; + private HwuiContext mHwuiContext; + private CancellationSignal mCancellationSignal; + + @Override + public ICancellationSignal startCapture(Surface surface, IScrollCaptureCallbacks callbacks) { + mCallbacks = callbacks; + mHwuiContext = new HwuiContext(surface); + mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mPaint.setStyle(Paint.Style.FILL); + try { + mCallbacks.onCaptureStarted(); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + ICancellationSignal signal = CancellationSignal.createTransport(); + mCancellationSignal = CancellationSignal.fromTransport(signal); + return signal; + } + + @Override + public ICancellationSignal requestImage(Rect rect) { + Canvas canvas = mHwuiContext.lockCanvas(rect.width(), rect.height()); + mPaint.setColor(mColors[mNextColor]); + canvas.drawRect(rect, mPaint); + mNextColor = (mNextColor++) % mColors.length; + mHwuiContext.unlockAndPost(canvas); + try { + mCallbacks.onImageRequestCompleted(0, rect); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + ICancellationSignal signal = CancellationSignal.createTransport(); + mCancellationSignal = CancellationSignal.fromTransport(signal); + return signal; + } + + @Override + public ICancellationSignal endCapture() { + try { + mCallbacks.onCaptureEnded(); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } finally { + mHwuiContext.destroy(); + mCallbacks = null; + } + ICancellationSignal signal = CancellationSignal.createTransport(); + mCancellationSignal = CancellationSignal.fromTransport(signal); + return signal; + } + + @Override + public void close() throws RemoteException { + } + + // From android.view.Surface, but issues render requests synchronously with waitForPresent(true) + private static final class HwuiContext { + private final RenderNode mRenderNode; + private final HardwareRenderer mHardwareRenderer; + private RecordingCanvas mCanvas; + + HwuiContext(Surface surface) { + mRenderNode = RenderNode.create("HwuiCanvas", null); + mRenderNode.setClipToBounds(false); + mRenderNode.setForceDarkAllowed(false); + + mHardwareRenderer = new HardwareRenderer(); + mHardwareRenderer.setContentRoot(mRenderNode); + mHardwareRenderer.setSurface(surface, true); + mHardwareRenderer.setColorMode(ActivityInfo.COLOR_MODE_DEFAULT); + mHardwareRenderer.setLightSourceAlpha(0.0f, 0.0f); + mHardwareRenderer.setLightSourceGeometry(0.0f, 0.0f, 0.0f, 0.0f); + } + + Canvas lockCanvas(int width, int height) { + if (mCanvas != null) { + throw new IllegalStateException("Surface was already locked!"); + } + mCanvas = mRenderNode.beginRecording(width, height); + return mCanvas; + } + + void unlockAndPost(Canvas canvas) { + if (canvas != mCanvas) { + throw new IllegalArgumentException("canvas object must be the same instance that " + + "was previously returned by lockCanvas"); + } + mRenderNode.endRecording(); + mCanvas = null; + mHardwareRenderer.createRenderRequest() + .setVsyncTime(System.nanoTime()) + .setWaitForPresent(true) // sync! + .syncAndDraw(); + } + + void destroy() { + mHardwareRenderer.destroy(); + } + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/screenshot/FakeSession.java b/packages/SystemUI/tests/utils/src/com/android/systemui/screenshot/FakeSession.java new file mode 100644 index 000000000000..478658eb232d --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/screenshot/FakeSession.java @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2021 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.screenshot; + +import static android.util.MathUtils.constrain; + +import static com.google.common.util.concurrent.Futures.immediateFuture; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import static java.lang.Math.abs; +import static java.lang.Math.max; +import static java.lang.Math.min; + +import android.graphics.Rect; +import android.hardware.HardwareBuffer; +import android.media.Image; +import android.util.Log; + +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + +/** + * A flexible test double for {@link ScrollCaptureClient.Session}. + *

+ * FakeSession provides the ability to emulate both the available scrollable content range as well + * as the current visible bounds. Visible bounds may vary because the target view itself may be + * slid vertically during capture, with portions may become clipped by parent views. This scenario + * frequently occurs with UIs constructed from nested scrolling views or collapsing headers. + */ +class FakeSession implements ScrollCaptureClient.Session { + private static final String TAG = "FakeSession"; + // Available range of content + private final Rect mAvailable; + + /** bounds for scrollDelta (y), range with bottom adjusted to account for page height. */ + private final Rect mAvailableTop; + + private final Rect mVisiblePage; + private final int mTileHeight; + private final int mMaxTiles; + + private int mScrollDelta; + private int mPageHeight; + private int mTargetHeight; + + FakeSession(int pageHeight, float maxPages, int tileHeight, int visiblePageTop, + int visiblePageBottom, int availableTop, int availableBottom, + int maxTiles) { + mPageHeight = pageHeight; + mTileHeight = tileHeight; + mAvailable = new Rect(0, availableTop, getPageWidth(), availableBottom); + mAvailableTop = new Rect(mAvailable); + mAvailableTop.inset(0, 0, 0, pageHeight); + mVisiblePage = new Rect(0, visiblePageTop, getPageWidth(), visiblePageBottom); + mTargetHeight = (int) (pageHeight * maxPages); + mMaxTiles = maxTiles; + } + + private static Image mockImage() { + Image image = mock(Image.class); + when(image.getHardwareBuffer()).thenReturn(mock(HardwareBuffer.class)); + return image; + } + + public int getScrollDelta() { + return mScrollDelta; + } + + @Override + public ListenableFuture requestTile(int requestedTop) { + Rect requested = new Rect(0, requestedTop, getPageWidth(), requestedTop + getTileHeight()); + Log.d(TAG, "requested: " + requested); + Rect page = new Rect(0, 0, getPageWidth(), mPageHeight); + page.offset(0, mScrollDelta); + Log.d(TAG, "page: " + page); + // Simulate behavior from lower levels by replicating 'requestChildRectangleOnScreen' + if (!page.contains(requested)) { + Log.d(TAG, "requested not within page, scrolling"); + // distance+direction needed to scroll to align each edge of request with + // corresponding edge of the page + int distTop = requested.top - page.top; // positive means already visible + int distBottom = requested.bottom - page.bottom; // negative means already visible + Log.d(TAG, "distTop = " + distTop); + Log.d(TAG, "distBottom = " + distBottom); + + boolean scrollUp = false; + if (distTop < 0 && distBottom > 0) { + scrollUp = abs(distTop) < distBottom; + } else if (distTop < 0) { + scrollUp = true; + } + + // determine which edges are currently clipped + if (scrollUp) { + Log.d(TAG, "trying to scroll up by " + -distTop + " px"); + // need to scroll up to align top edge to visible-top + mScrollDelta += distTop; + Log.d(TAG, "new scrollDelta = " + mScrollDelta); + } else { + Log.d(TAG, "trying to scroll down by " + distBottom + " px"); + // scroll down to align bottom edge with visible bottom, but keep top visible + int topEdgeDistance = max(0, requestedTop - page.top); + mScrollDelta += min(distBottom, topEdgeDistance); + Log.d(TAG, "new scrollDelta = " + mScrollDelta); + } + + // Clamp to available content + mScrollDelta = constrain(mScrollDelta, mAvailableTop.top, mAvailableTop.bottom); + Log.d(TAG, "scrollDelta, adjusted to available range = " + mScrollDelta); + + // Reset to apply a changed scroll delta possibly. + page.offsetTo(0, 0); + page.offset(0, mScrollDelta); + + Log.d(TAG, "page (after scroll): " + page); + Log.d(TAG, "requested (after scroll): " + requested); + } + Log.d(TAG, "mVisiblePage = " + mVisiblePage); + Log.d(TAG, "scrollDelta = " + mScrollDelta); + + Rect target = new Rect(requested); + Rect visible = new Rect(mVisiblePage); + visible.offset(0, mScrollDelta); + + Log.d(TAG, "target: " + target); + Log.d(TAG, "visible: " + visible); + + // if any of the requested rect is available to scroll into the view: + if (target.intersect(page) && target.intersect(visible)) { + Log.d(TAG, "returning captured = " + target); + ScrollCaptureClient.CaptureResult result = + new ScrollCaptureClient.CaptureResult(mockImage(), requested, target); + return immediateFuture(result); + } + Log.d(TAG, "no part of requested rect is within page, returning empty"); + ScrollCaptureClient.CaptureResult result = + new ScrollCaptureClient.CaptureResult(null, requested, new Rect()); + return immediateFuture(result); + } + + + @Override + public int getMaxTiles() { + return mMaxTiles; + } + + @Override + public int getTargetHeight() { + return mTargetHeight; + } + + @Override + public int getTileHeight() { + return mTileHeight; + } + + @Override + public int getPageWidth() { + return 100; + } + + @Override + public int getPageHeight() { + return mPageHeight; + } + + @Override + public Rect getWindowBounds() { + throw new IllegalStateException("Not implemented"); + } + + @Override + public ListenableFuture end() { + return Futures.immediateVoidFuture(); + } + + @Override + public void release() { + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/RankingBuilder.java b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/RankingBuilder.java new file mode 100644 index 000000000000..045e6f19c667 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/RankingBuilder.java @@ -0,0 +1,254 @@ +/* + * 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.statusbar; + +import android.annotation.NonNull; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager.Importance; +import android.content.pm.ShortcutInfo; +import android.service.notification.NotificationListenerService.Ranking; +import android.service.notification.SnoozeCriterion; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Standard builder class for Ranking objects. For use in tests that need to craft the underlying + * Ranking object of a NotificationEntry. + */ +public class RankingBuilder { + private String mKey = "test_key"; + private int mRank = 0; + private boolean mMatchesInterruptionFilter = false; + private int mVisibilityOverride = 0; + private int mSuppressedVisualEffects = 0; + @Importance private int mImportance = 0; + private CharSequence mExplanation = "test_explanation"; + private String mOverrideGroupKey = null; + private NotificationChannel mChannel = null; + private ArrayList mAdditionalPeople = null; + private ArrayList mSnoozeCriteria = null; + private boolean mCanShowBadge = false; + private int mUserSentiment = 0; + private boolean mIsSuspended = false; + private long mLastAudiblyAlertedMs = 0; + private boolean mNoisy = false; + private ArrayList mSmartActions = new ArrayList<>(); + private ArrayList mSmartReplies = new ArrayList<>(); + private boolean mCanBubble = false; + private boolean mIsTextChanged = false; + private boolean mIsConversation = false; + private ShortcutInfo mShortcutInfo = null; + private int mRankingAdjustment = 0; + private boolean mIsBubble = false; + + public RankingBuilder() { + } + + public RankingBuilder(Ranking ranking) { + mKey = ranking.getKey(); + mRank = ranking.getRank(); + mMatchesInterruptionFilter = ranking.matchesInterruptionFilter(); + mVisibilityOverride = ranking.getLockscreenVisibilityOverride(); + mSuppressedVisualEffects = ranking.getSuppressedVisualEffects(); + mImportance = ranking.getImportance(); + mExplanation = ranking.getImportanceExplanation(); + mOverrideGroupKey = ranking.getOverrideGroupKey(); + mChannel = ranking.getChannel(); + mAdditionalPeople = copyList(ranking.getAdditionalPeople()); + mSnoozeCriteria = copyList(ranking.getSnoozeCriteria()); + mCanShowBadge = ranking.canShowBadge(); + mUserSentiment = ranking.getUserSentiment(); + mIsSuspended = ranking.isSuspended(); + mLastAudiblyAlertedMs = ranking.getLastAudiblyAlertedMillis(); + mNoisy = ranking.isNoisy(); + mSmartActions = copyList(ranking.getSmartActions()); + mSmartReplies = copyList(ranking.getSmartReplies()); + mCanBubble = ranking.canBubble(); + mIsTextChanged = ranking.isTextChanged(); + mIsConversation = ranking.isConversation(); + mShortcutInfo = ranking.getConversationShortcutInfo(); + mRankingAdjustment = ranking.getRankingAdjustment(); + mIsBubble = ranking.isBubble(); + } + + public Ranking build() { + final Ranking ranking = new Ranking(); + ranking.populate( + mKey, + mRank, + mMatchesInterruptionFilter, + mVisibilityOverride, + mSuppressedVisualEffects, + mImportance, + mExplanation, + mOverrideGroupKey, + mChannel, + mAdditionalPeople, + mSnoozeCriteria, + mCanShowBadge, + mUserSentiment, + mIsSuspended, + mLastAudiblyAlertedMs, + mNoisy, + mSmartActions, + mSmartReplies, + mCanBubble, + mIsTextChanged, + mIsConversation, + mShortcutInfo, + mRankingAdjustment, + mIsBubble); + return ranking; + } + + public RankingBuilder setKey(String key) { + mKey = key; + return this; + } + + public RankingBuilder setRank(int rank) { + mRank = rank; + return this; + } + + public RankingBuilder setMatchesInterruptionFilter(boolean matchesInterruptionFilter) { + mMatchesInterruptionFilter = matchesInterruptionFilter; + return this; + } + + public RankingBuilder setVisibilityOverride(int visibilityOverride) { + mVisibilityOverride = visibilityOverride; + return this; + } + + public RankingBuilder setSuppressedVisualEffects(int suppressedVisualEffects) { + mSuppressedVisualEffects = suppressedVisualEffects; + return this; + } + + public RankingBuilder setExplanation(CharSequence explanation) { + mExplanation = explanation; + return this; + } + + public RankingBuilder setOverrideGroupKey(String overrideGroupKey) { + mOverrideGroupKey = overrideGroupKey; + return this; + } + + public RankingBuilder setAdditionalPeople(ArrayList additionalPeople) { + mAdditionalPeople = additionalPeople; + return this; + } + + public RankingBuilder setSnoozeCriteria( + ArrayList snoozeCriteria) { + mSnoozeCriteria = snoozeCriteria; + return this; + } + + public RankingBuilder setCanShowBadge(boolean canShowBadge) { + mCanShowBadge = canShowBadge; + return this; + } + + public RankingBuilder setSuspended(boolean suspended) { + mIsSuspended = suspended; + return this; + } + + public RankingBuilder setLastAudiblyAlertedMs(long lastAudiblyAlertedMs) { + mLastAudiblyAlertedMs = lastAudiblyAlertedMs; + return this; + } + + public RankingBuilder setNoisy(boolean noisy) { + mNoisy = noisy; + return this; + } + + public RankingBuilder setCanBubble(boolean canBubble) { + mCanBubble = canBubble; + return this; + } + + public RankingBuilder setTextChanged(boolean textChanged) { + mIsTextChanged = textChanged; + return this; + } + + public RankingBuilder setIsConversation(boolean isConversation) { + mIsConversation = isConversation; + return this; + } + + public RankingBuilder setShortcutInfo(ShortcutInfo shortcutInfo) { + mShortcutInfo = shortcutInfo; + return this; + } + + public RankingBuilder setRankingAdjustment(int rankingAdjustment) { + mRankingAdjustment = rankingAdjustment; + return this; + } + + public RankingBuilder setImportance(@Importance int importance) { + mImportance = importance; + return this; + } + + public RankingBuilder setUserSentiment(int userSentiment) { + mUserSentiment = userSentiment; + return this; + } + + public RankingBuilder setChannel(NotificationChannel channel) { + mChannel = channel; + return this; + } + + public RankingBuilder setSmartActions(@NonNull ArrayList smartActions) { + mSmartActions = smartActions; + return this; + } + + public RankingBuilder setSmartActions(Notification.Action... smartActions) { + mSmartActions = new ArrayList<>(Arrays.asList(smartActions)); + return this; + } + + public RankingBuilder setSmartReplies(@NonNull ArrayList smartReplies) { + mSmartReplies = smartReplies; + return this; + } + + public RankingBuilder setSmartReplies(CharSequence... smartReplies) { + mSmartReplies = new ArrayList<>(Arrays.asList(smartReplies)); + return this; + } + + private static ArrayList copyList(List list) { + if (list == null) { + return null; + } else { + return new ArrayList<>(list); + } + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SbnBuilder.java b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SbnBuilder.java new file mode 100644 index 000000000000..1b0ed112cea1 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SbnBuilder.java @@ -0,0 +1,191 @@ +/* + * 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.statusbar; + +import android.annotation.Nullable; +import android.app.Notification; +import android.content.Context; +import android.os.UserHandle; +import android.service.notification.StatusBarNotification; + +import com.android.internal.logging.InstanceId; + +/** + * Convenience builder for {@link StatusBarNotification} since its constructor is terrifying. + * + * Only for use in tests. + */ +public class SbnBuilder { + private String mPkg = "test_pkg"; + private String mOpPkg; + private int mId; + private String mTag; + private int mUid; + private int mInitialPid; + @Nullable private Notification mNotification; + @Nullable private Notification.Builder mNotificationBuilder; + private Notification.BubbleMetadata mBubbleMetadata; + private UserHandle mUser = UserHandle.of(0); + private String mOverrideGroupKey; + private long mPostTime; + private InstanceId mInstanceId; + + public SbnBuilder() { + } + + public SbnBuilder(StatusBarNotification source) { + mPkg = source.getPackageName(); + mOpPkg = source.getOpPkg(); + mId = source.getId(); + mTag = source.getTag(); + mUid = source.getUid(); + mInitialPid = source.getInitialPid(); + mNotification = source.getNotification(); + mUser = source.getUser(); + mOverrideGroupKey = source.getOverrideGroupKey(); + mPostTime = source.getPostTime(); + mInstanceId = source.getInstanceId(); + } + + public StatusBarNotification build() { + Notification notification; + if (mNotificationBuilder != null) { + notification = mNotificationBuilder.build(); + } else if (mNotification != null) { + notification = mNotification; + } else { + notification = new Notification(); + } + + if (mBubbleMetadata != null) { + notification.setBubbleMetadata(mBubbleMetadata); + } + + StatusBarNotification result = new StatusBarNotification( + mPkg, + mOpPkg, + mId, + mTag, + mUid, + mInitialPid, + notification, + mUser, + mOverrideGroupKey, + mPostTime); + if (mInstanceId != null) { + result.setInstanceId(mInstanceId); + } + return result; + } + + public SbnBuilder setPkg(String pkg) { + mPkg = pkg; + return this; + } + + public SbnBuilder setOpPkg(String opPkg) { + mOpPkg = opPkg; + return this; + } + + public SbnBuilder setId(int id) { + mId = id; + return this; + } + + public SbnBuilder setTag(String tag) { + mTag = tag; + return this; + } + + public SbnBuilder setUid(int uid) { + mUid = uid; + return this; + } + + public SbnBuilder setInitialPid(int initialPid) { + mInitialPid = initialPid; + return this; + } + + public SbnBuilder setNotification(Notification notification) { + mNotification = notification; + mNotificationBuilder = null; + return this; + } + + public SbnBuilder setContentTitle(Context context, String contentTitle) { + modifyNotification(context).setContentTitle(contentTitle); + return this; + } + + public SbnBuilder setContentText(Context context, String contentText) { + modifyNotification(context).setContentText(contentText); + return this; + } + + public SbnBuilder setGroup(Context context, String groupKey) { + modifyNotification(context).setGroup(groupKey); + return this; + } + + public SbnBuilder setGroupSummary(Context context, boolean isGroupSummary) { + modifyNotification(context).setGroupSummary(isGroupSummary); + return this; + } + + public SbnBuilder setFlag(Context context, int mask, boolean value) { + modifyNotification(context).setFlag(mask, value); + return this; + } + + public Notification.Builder modifyNotification(Context context) { + if (mNotification != null) { + mNotificationBuilder = new Notification.Builder(context, mNotification); + mNotification = null; + } else if (mNotificationBuilder == null) { + mNotificationBuilder = new Notification.Builder(context); + } + + return mNotificationBuilder; + } + + public SbnBuilder setUser(UserHandle user) { + mUser = user; + return this; + } + + public SbnBuilder setOverrideGroupKey(String overrideGroupKey) { + mOverrideGroupKey = overrideGroupKey; + return this; + } + + public SbnBuilder setPostTime(long postTime) { + mPostTime = postTime; + return this; + } + + public SbnBuilder setBubbleMetadata(Notification.BubbleMetadata data) { + mBubbleMetadata = data; + return this; + } + + public SbnBuilder setInstanceId(InstanceId instanceId) { + mInstanceId = instanceId; + return this; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java new file mode 100644 index 000000000000..b91f7e6b6169 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java @@ -0,0 +1,353 @@ +/* + * 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.statusbar.notification.collection; + +import android.annotation.Nullable; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.Context; +import android.content.pm.ShortcutInfo; +import android.os.UserHandle; +import android.service.notification.NotificationListenerService.Ranking; +import android.service.notification.SnoozeCriterion; +import android.service.notification.StatusBarNotification; + +import com.android.internal.logging.InstanceId; +import com.android.systemui.statusbar.RankingBuilder; +import com.android.systemui.statusbar.SbnBuilder; +import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection; +import com.android.systemui.util.time.FakeSystemClock; + +import java.util.ArrayList; + +import kotlin.Unit; + +/** + * Combined builder for constructing a NotificationEntry and its associated StatusBarNotification + * and Ranking. Is largely a proxy for the SBN and Ranking builders, but does a little extra magic + * to make sure the keys match between the two, etc. + * + * Has the ability to set ListEntry properties as well. + * + * Only for use in tests. + */ +public class NotificationEntryBuilder { + private final SbnBuilder mSbnBuilder; + private final RankingBuilder mRankingBuilder; + private final FakeSystemClock mClock = new FakeSystemClock(); + private StatusBarNotification mSbn = null; + + /* ListEntry properties */ + private GroupEntry mParent; + private NotifSection mNotifSection; + + /* If set, use this creation time instead of mClock.uptimeMillis */ + private long mCreationTime = -1; + private int mStableIndex = -1; + + public NotificationEntryBuilder() { + mSbnBuilder = new SbnBuilder(); + mRankingBuilder = new RankingBuilder(); + } + + public NotificationEntryBuilder(NotificationEntry source) { + mSbnBuilder = new SbnBuilder(source.getSbn()); + mRankingBuilder = new RankingBuilder(source.getRanking()); + + mParent = source.getParent(); + mCreationTime = source.getCreationTime(); + } + + /** Update an the parent on an existing entry */ + public static void setNewParent(NotificationEntry entry, GroupEntry parent) { + entry.setParent(parent); + } + + /** Build a new instance of NotificationEntry */ + public NotificationEntry build() { + return buildOrApply(null); + } + + /** Modifies [target] to match the contents of this builder */ + public void apply(NotificationEntry target) { + buildOrApply(target); + } + + /** Convenience method for Kotlin callbacks that are passed a builder and need to return Unit */ + public Unit done() { + return Unit.INSTANCE; + } + + private NotificationEntry buildOrApply(NotificationEntry target) { + final StatusBarNotification sbn = mSbn != null ? mSbn : mSbnBuilder.build(); + final Ranking ranking = mRankingBuilder.setKey(sbn.getKey()).build(); + final long creationTime = mCreationTime != -1 ? mCreationTime : mClock.uptimeMillis(); + + final NotificationEntry entry; + if (target == null) { + entry = new NotificationEntry(sbn, ranking, creationTime); + } else { + entry = target; + entry.setSbn(sbn); + entry.setRanking(ranking); + // Note: we can't modify the creation time as it's immutable + } + + /* ListEntry properties */ + entry.setParent(mParent); + entry.getAttachState().setSection(mNotifSection); + entry.getAttachState().setStableIndex(mStableIndex); + return entry; + } + + /** + * Sets the parent. + */ + public NotificationEntryBuilder setParent(@Nullable GroupEntry parent) { + mParent = parent; + return this; + } + + /** + * Sets the parent. + */ + public NotificationEntryBuilder setSection(@Nullable NotifSection section) { + mNotifSection = section; + return this; + } + + /** + * Sets the SBN directly. If set, causes all calls to delegated SbnBuilder methods to be + * ignored. + */ + public NotificationEntryBuilder setSbn(@Nullable StatusBarNotification sbn) { + mSbn = sbn; + return this; + } + + public NotificationEntryBuilder setStableIndex(int index) { + mStableIndex = index; + return this; + } + + /** + * Set the creation time + */ + public NotificationEntryBuilder setCreationTime(long creationTime) { + mCreationTime = creationTime; + return this; + } + + /* Delegated to SbnBuilder */ + + public NotificationEntryBuilder setPkg(String pkg) { + mSbnBuilder.setPkg(pkg); + return this; + } + + public NotificationEntryBuilder setOpPkg(String opPkg) { + mSbnBuilder.setOpPkg(opPkg); + return this; + } + + public NotificationEntryBuilder setId(int id) { + mSbnBuilder.setId(id); + return this; + } + + public NotificationEntryBuilder setTag(String tag) { + mSbnBuilder.setTag(tag); + return this; + } + + public NotificationEntryBuilder setUid(int uid) { + mSbnBuilder.setUid(uid); + return this; + } + + public NotificationEntryBuilder setInitialPid(int initialPid) { + mSbnBuilder.setInitialPid(initialPid); + return this; + } + + public NotificationEntryBuilder setNotification(Notification notification) { + mSbnBuilder.setNotification(notification); + return this; + } + + public Notification.Builder modifyNotification(Context context) { + return mSbnBuilder.modifyNotification(context); + } + + public NotificationEntryBuilder setUser(UserHandle user) { + mSbnBuilder.setUser(user); + return this; + } + + public NotificationEntryBuilder setOverrideGroupKey(String overrideGroupKey) { + mSbnBuilder.setOverrideGroupKey(overrideGroupKey); + return this; + } + + public NotificationEntryBuilder setPostTime(long postTime) { + mSbnBuilder.setPostTime(postTime); + return this; + } + + public NotificationEntryBuilder setInstanceId(InstanceId instanceId) { + mSbnBuilder.setInstanceId(instanceId); + return this; + } + + /* Delegated to Notification.Builder (via SbnBuilder) */ + + public NotificationEntryBuilder setContentTitle(Context context, String contentTitle) { + mSbnBuilder.setContentTitle(context, contentTitle); + return this; + } + + public NotificationEntryBuilder setContentText(Context context, String contentText) { + mSbnBuilder.setContentText(context, contentText); + return this; + } + + public NotificationEntryBuilder setGroup(Context context, String groupKey) { + mSbnBuilder.setGroup(context, groupKey); + return this; + } + + public NotificationEntryBuilder setGroupSummary(Context context, boolean isGroupSummary) { + mSbnBuilder.setGroupSummary(context, isGroupSummary); + return this; + } + + public NotificationEntryBuilder setFlag(Context context, int mask, boolean value) { + mSbnBuilder.setFlag(context, mask, value); + return this; + } + + /* Delegated to RankingBuilder */ + + public NotificationEntryBuilder setRank(int rank) { + mRankingBuilder.setRank(rank); + return this; + } + + public NotificationEntryBuilder setMatchesInterruptionFilter( + boolean matchesInterruptionFilter) { + mRankingBuilder.setMatchesInterruptionFilter(matchesInterruptionFilter); + return this; + } + + public NotificationEntryBuilder setVisibilityOverride(int visibilityOverride) { + mRankingBuilder.setVisibilityOverride(visibilityOverride); + return this; + } + + public NotificationEntryBuilder setSuppressedVisualEffects(int suppressedVisualEffects) { + mRankingBuilder.setSuppressedVisualEffects(suppressedVisualEffects); + return this; + } + + public NotificationEntryBuilder setExplanation(CharSequence explanation) { + mRankingBuilder.setExplanation(explanation); + return this; + } + + public NotificationEntryBuilder setAdditionalPeople(ArrayList additionalPeople) { + mRankingBuilder.setAdditionalPeople(additionalPeople); + return this; + } + + public NotificationEntryBuilder setSnoozeCriteria( + ArrayList snoozeCriteria) { + mRankingBuilder.setSnoozeCriteria(snoozeCriteria); + return this; + } + + public NotificationEntryBuilder setCanShowBadge(boolean canShowBadge) { + mRankingBuilder.setCanShowBadge(canShowBadge); + return this; + } + + public NotificationEntryBuilder setSuspended(boolean suspended) { + mRankingBuilder.setSuspended(suspended); + return this; + } + + public NotificationEntryBuilder setLastAudiblyAlertedMs(long lastAudiblyAlertedMs) { + mRankingBuilder.setLastAudiblyAlertedMs(lastAudiblyAlertedMs); + return this; + } + + public NotificationEntryBuilder setNoisy(boolean noisy) { + mRankingBuilder.setNoisy(noisy); + return this; + } + + public NotificationEntryBuilder setCanBubble(boolean canBubble) { + mRankingBuilder.setCanBubble(canBubble); + return this; + } + + public NotificationEntryBuilder setImportance(@NotificationManager.Importance int importance) { + mRankingBuilder.setImportance(importance); + return this; + } + + public NotificationEntryBuilder setUserSentiment(int userSentiment) { + mRankingBuilder.setUserSentiment(userSentiment); + return this; + } + + public NotificationEntryBuilder setChannel(NotificationChannel channel) { + mRankingBuilder.setChannel(channel); + return this; + } + + public NotificationEntryBuilder setSmartActions( + ArrayList smartActions) { + mRankingBuilder.setSmartActions(smartActions); + return this; + } + + public NotificationEntryBuilder setSmartActions(Notification.Action... smartActions) { + mRankingBuilder.setSmartActions(smartActions); + return this; + } + + public NotificationEntryBuilder setSmartReplies(ArrayList smartReplies) { + mRankingBuilder.setSmartReplies(smartReplies); + return this; + } + + public NotificationEntryBuilder setSmartReplies(CharSequence... smartReplies) { + mRankingBuilder.setSmartReplies(smartReplies); + return this; + } + + public NotificationEntryBuilder setShortcutInfo(ShortcutInfo shortcutInfo) { + mRankingBuilder.setShortcutInfo(shortcutInfo); + return this; + } + + public NotificationEntryBuilder setRankingAdjustment(int rankingAdjustment) { + mRankingBuilder.setRankingAdjustment(rankingAdjustment); + return this; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt new file mode 100644 index 000000000000..16a326869562 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt @@ -0,0 +1,35 @@ +package com.android.systemui.statusbar.policy + +import android.content.res.Configuration + +/** Fake implementation of [ConfigurationController] for tests. */ +class FakeConfigurationController : ConfigurationController { + + private var listeners = mutableListOf() + + override fun addCallback(listener: ConfigurationController.ConfigurationListener) { + listeners += listener + } + + override fun removeCallback(listener: ConfigurationController.ConfigurationListener) { + listeners -= listener + } + + override fun onConfigurationChanged(newConfiguration: Configuration?) { + listeners.forEach { it.onConfigChanged(newConfiguration) } + } + + override fun notifyThemeChanged() { + listeners.forEach { it.onThemeChanged() } + } + + fun notifyDensityOrFontScaleChanged() { + listeners.forEach { it.onDensityOrFontScaleChanged() } + } + + fun notifyConfigurationChanged() { + onConfigurationChanged(newConfiguration = null) + } + + override fun isLayoutRtl(): Boolean = false +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/DeviceConfigProxyFake.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/DeviceConfigProxyFake.java new file mode 100644 index 000000000000..33ece0084906 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/DeviceConfigProxyFake.java @@ -0,0 +1,154 @@ +/* + * 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.util; + +import android.content.Context; +import android.provider.DeviceConfig; +import android.provider.DeviceConfig.OnPropertiesChangedListener; +import android.provider.DeviceConfig.Properties; +import android.util.Pair; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; + +/** + * A Fake of {@link DeviceConfigProxy} useful for testing. + * + * No properties are set by default. No calls to {@link DeviceConfig} are made. Be sure to set any + * properties you rely on ahead of time in your test. + */ +public class DeviceConfigProxyFake extends DeviceConfigProxy { + + private List> mListeners = new ArrayList<>(); + private Map> mDefaultProperties = new HashMap<>(); + private Map> mProperties = new HashMap<>(); + + public DeviceConfigProxyFake() { + } + + @Override + public void addOnPropertiesChangedListener( + String namespace, Executor executor, + OnPropertiesChangedListener onPropertiesChangedListener) { + mListeners.add(Pair.create(executor, onPropertiesChangedListener)); + } + + @Override + public void removeOnPropertiesChangedListener( + OnPropertiesChangedListener onPropertiesChangedListener) { + mListeners.removeIf(listener -> { + if (listener == null) { + return false; + } + return listener.second.equals(onPropertiesChangedListener); + }); + } + + @Override + public boolean setProperty(String namespace, String name, String value, boolean makeDefault) { + setPropertyInternal(namespace, name, value, mProperties); + if (makeDefault) { + setPropertyInternal(namespace, name, value, mDefaultProperties); + } + + for (Pair listener : mListeners) { + Properties.Builder propBuilder = new Properties.Builder(namespace); + propBuilder.setString(name, value); + listener.first.execute(() -> listener.second.onPropertiesChanged(propBuilder.build())); + } + return true; + } + + private void setPropertyInternal(String namespace, String name, String value, + Map> properties) { + properties.putIfAbsent(namespace, new HashMap<>()); + properties.get(namespace).put(name, value); + } + + @Override + public void enforceReadPermission(Context context, String namespace) { + // no-op + } + + private Properties propsForNamespaceAndName(String namespace, String name) { + if (mProperties.containsKey(namespace) && mProperties.get(namespace).containsKey(name)) { + return new Properties.Builder(namespace) + .setString(name, mProperties.get(namespace).get(name)).build(); + } + if (mDefaultProperties.containsKey(namespace)) { + return new Properties.Builder(namespace) + .setString(name, mDefaultProperties.get(namespace).get(name)).build(); + } + + return null; + } + + @Override + public boolean getBoolean(String namespace, String name, boolean defaultValue) { + Properties props = propsForNamespaceAndName(namespace, name); + if (props != null) { + return props.getBoolean(name, defaultValue); + } + + return defaultValue; + } + + @Override + public int getInt(String namespace, String name, int defaultValue) { + Properties props = propsForNamespaceAndName(namespace, name); + if (props != null) { + return props.getInt(name, defaultValue); + } + + return defaultValue; + } + + @Override + public long getLong(String namespace, String name, long defaultValue) { + Properties props = propsForNamespaceAndName(namespace, name); + if (props != null) { + return props.getLong(name, defaultValue); + } + + return defaultValue; + } + + @Override + public String getProperty(String namespace, String name) { + return getString(namespace, name, null); + } + + @Override + public String getString(String namespace, String name, String defaultValue) { + Properties props = propsForNamespaceAndName(namespace, name); + if (props != null) { + return props.getString(name, defaultValue); + } + + return defaultValue; + } + + @Override + public void resetToDefaults(int resetMode, String namespace) { + if (mProperties.containsKey(namespace)) { + mProperties.get(namespace).clear(); + } + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeExecutor.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeExecutor.java new file mode 100644 index 000000000000..d3d30f242dcf --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeExecutor.java @@ -0,0 +1,223 @@ +/* + * 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.util.concurrency; + +import com.android.systemui.util.time.FakeSystemClock; + +import java.util.Collections; +import java.util.PriorityQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +public class FakeExecutor implements DelayableExecutor { + private final FakeSystemClock mClock; + private PriorityQueue mQueuedRunnables = new PriorityQueue<>(); + private boolean mIgnoreClockUpdates; + private boolean mExecuting; + + /** + * Initializes a fake executor. + * + * @param clock FakeSystemClock allowing control over delayed runnables. It is strongly + * recommended that this clock have its auto-increment setting set to false to + * prevent unexpected advancement of the time. + */ + public FakeExecutor(FakeSystemClock clock) { + mClock = clock; + mClock.addListener(() -> { + if (!mIgnoreClockUpdates) { + runAllReady(); + } + }); + } + + /** + * Runs a single runnable if it's scheduled to run according to the internal clock. + * + * If constructed to advance the clock automatically, this will advance the clock enough to + * run the next pending item. + * + * This method does not advance the clock past the item that was run. + * + * @return Returns true if an item was run. + */ + public boolean runNextReady() { + if (!mQueuedRunnables.isEmpty() && mQueuedRunnables.peek().mWhen <= mClock.uptimeMillis()) { + mExecuting = true; + mQueuedRunnables.poll().mRunnable.run(); + mExecuting = false; + return true; + } + + return false; + } + + /** + * Runs all Runnables that are scheduled to run according to the internal clock. + * + * If constructed to advance the clock automatically, this will advance the clock enough to + * run all the pending items. This method does not advance the clock past items that were + * run. It is equivalent to calling {@link #runNextReady()} in a loop. + * + * @return Returns the number of items that ran. + */ + public int runAllReady() { + int num = 0; + while (runNextReady()) { + num++; + } + + return num; + } + + /** + * Advances the internal clock to the next item to run. + * + * The clock will only move forward. If the next item is set to run in the past or there is no + * next item, the clock does not change. + * + * Note that this will cause one or more items to actually run. + * + * @return The delta in uptimeMillis that the clock advanced, or 0 if the clock did not advance. + */ + public long advanceClockToNext() { + if (mQueuedRunnables.isEmpty()) { + return 0; + } + + long startTime = mClock.uptimeMillis(); + long nextTime = mQueuedRunnables.peek().mWhen; + if (nextTime <= startTime) { + return 0; + } + updateClock(nextTime); + + return nextTime - startTime; + } + + + /** + * Advances the internal clock to the last item to run. + * + * The clock will only move forward. If the last item is set to run in the past or there is no + * next item, the clock does not change. + * + * @return The delta in uptimeMillis that the clock advanced, or 0 if the clock did not advance. + */ + public long advanceClockToLast() { + if (mQueuedRunnables.isEmpty()) { + return 0; + } + + long startTime = mClock.uptimeMillis(); + long nextTime = Collections.max(mQueuedRunnables).mWhen; + if (nextTime <= startTime) { + return 0; + } + + updateClock(nextTime); + + return nextTime - startTime; + } + + /** + * Returns the number of un-executed runnables waiting to run. + */ + public int numPending() { + return mQueuedRunnables.size(); + } + + @Override + public Runnable executeDelayed(Runnable r, long delay, TimeUnit unit) { + if (delay < 0) { + delay = 0; + } + return executeAtTime(r, mClock.uptimeMillis() + unit.toMillis(delay)); + } + + @Override + public Runnable executeAtTime(Runnable r, long uptime, TimeUnit unit) { + long uptimeMillis = unit.toMillis(uptime); + + QueuedRunnable container = new QueuedRunnable(r, uptimeMillis); + + mQueuedRunnables.offer(container); + + return () -> mQueuedRunnables.remove(container); + } + + @Override + public void execute(Runnable command) { + executeDelayed(command, 0); + } + + public boolean isExecuting() { + return mExecuting; + } + + /** + * Run all Executors in a loop until they all report they have no ready work to do. + * + * Useful if you have Executors the post work to other Executors, and you simply want to + * run them all until they stop posting work. + */ + public static void exhaustExecutors(FakeExecutor ...executors) { + boolean didAnything; + do { + didAnything = false; + for (FakeExecutor executor : executors) { + didAnything = didAnything || executor.runAllReady() != 0; + } + } while (didAnything); + } + + private void updateClock(long nextTime) { + mIgnoreClockUpdates = true; + mClock.setUptimeMillis(nextTime); + mIgnoreClockUpdates = false; + } + + private static class QueuedRunnable implements Comparable { + private static AtomicInteger sCounter = new AtomicInteger(); + + Runnable mRunnable; + long mWhen; + private int mCounter; + + private QueuedRunnable(Runnable r, long when) { + mRunnable = r; + mWhen = when; + + // PrioirityQueue orders items arbitrarily when equal. We want to ensure that + // otherwise-equal elements are ordered according to their insertion order. Because this + // class only is constructed right before insertion, we use a static counter to track + // insertion order of otherwise equal elements. + mCounter = sCounter.incrementAndGet(); + } + + @Override + public int compareTo(QueuedRunnable other) { + long diff = mWhen - other.mWhen; + + if (diff == 0) { + return mCounter - other.mCounter; + } + + return diff > 0 ? 1 : -1; + } + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeRepeatableExecutor.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeRepeatableExecutor.java new file mode 100644 index 000000000000..477f615faf2b --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeRepeatableExecutor.java @@ -0,0 +1,34 @@ +/* + * 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.util.concurrency; + +/** + * A fake to use in tests. + */ +public class FakeRepeatableExecutor extends RepeatableExecutorImpl { + + /** + * Initializes a fake RepeatableExecutor from a fake executor. + * + * Use the fake executor to actually process tasks. + * + * @param executor fake executor. + */ + public FakeRepeatableExecutor(FakeExecutor executor) { + super(executor); + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeThreadFactory.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeThreadFactory.java new file mode 100644 index 000000000000..301a157bd42e --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeThreadFactory.java @@ -0,0 +1,73 @@ +/* + * 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.util.concurrency; + +import android.os.Handler; +import android.os.Looper; + +import java.util.concurrent.Executor; + +/** + * Implementation of {@link ThreadFactory} that returns {@link FakeExecutor} where it can. + */ +public class FakeThreadFactory implements ThreadFactory { + private final FakeExecutor mFakeExecutor; + private Handler mHandler; + private Looper mLooper; + + public FakeThreadFactory(FakeExecutor fakeExecutor) { + mFakeExecutor = fakeExecutor; + } + + public void setHandler(Handler handler) { + mHandler = handler; + } + + public void setLooper(Looper looper) { + mLooper = looper; + } + + @Override + public Looper buildLooperOnNewThread(String threadName) { + return mLooper; + } + + @Override + public Handler buildHandlerOnNewThread(String threadName) { + return mHandler; + } + + @Override + public Executor buildExecutorOnNewThread(String threadName) { + return mFakeExecutor; + } + + @Override + public DelayableExecutor buildDelayableExecutorOnNewThread(String threadName) { + return mFakeExecutor; + } + + @Override + public DelayableExecutor buildDelayableExecutorOnHandler(Handler handler) { + return mFakeExecutor; + } + + @Override + public DelayableExecutor buildDelayableExecutorOnLooper(Looper looper) { + return mFakeExecutor; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/condition/FakeCondition.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/condition/FakeCondition.java new file mode 100644 index 000000000000..9d5ccbec87ea --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/condition/FakeCondition.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2021 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.util.condition; + +/** + * Fake implementation of {@link Condition}, and provides a way for tests to update + * condition fulfillment. + */ +public class FakeCondition extends Condition { + @Override + public void start() {} + + @Override + public void stop() {} + + public void fakeUpdateCondition(boolean isConditionMet) { + updateCondition(isConditionMet); + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/io/FakeBasicFileAttributes.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/io/FakeBasicFileAttributes.java new file mode 100644 index 000000000000..f7a04dcdbbd8 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/io/FakeBasicFileAttributes.java @@ -0,0 +1,126 @@ +/* + * 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.util.io; + +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; +import java.util.concurrent.TimeUnit; + +/** + * Fake implementation of {@link BasicFileAttributes} (for use in tests) + */ +public class FakeBasicFileAttributes implements BasicFileAttributes { + private FileTime mLastModifiedTime = FileTime.from(0, TimeUnit.MILLISECONDS); + private FileTime mLastAccessTime = FileTime.from(0, TimeUnit.MILLISECONDS); + private FileTime mCreationTime = FileTime.from(0, TimeUnit.MILLISECONDS); + private boolean mIsRegularFile = true; + private boolean mIsDirectory = false; + private boolean mIsSymbolicLink = false; + private boolean mIsOther = false; + private long mSize = 0; + private Object mFileKey = null; + + @Override + public FileTime lastModifiedTime() { + return mLastModifiedTime; + } + + @Override + public FileTime lastAccessTime() { + return mLastAccessTime; + } + + @Override + public FileTime creationTime() { + return mCreationTime; + } + + @Override + public boolean isRegularFile() { + return mIsRegularFile; + } + + @Override + public boolean isDirectory() { + return mIsDirectory; + } + + @Override + public boolean isSymbolicLink() { + return mIsSymbolicLink; + } + + @Override + public boolean isOther() { + return mIsOther; + } + + @Override + public long size() { + return mSize; + } + + @Override + public Object fileKey() { + return mFileKey; + } + + public FakeBasicFileAttributes setLastModifiedTime(long millis) { + mLastModifiedTime = FileTime.from(millis, TimeUnit.MILLISECONDS); + return this; + } + + public FakeBasicFileAttributes setLastAccessTime(long millis) { + mLastAccessTime = FileTime.from(millis, TimeUnit.MILLISECONDS); + return this; + } + + public FakeBasicFileAttributes setCreationTime(long millis) { + mCreationTime = FileTime.from(millis, TimeUnit.MILLISECONDS); + return this; + } + + public FakeBasicFileAttributes setRegularFile(boolean regularFile) { + mIsRegularFile = regularFile; + return this; + } + + public FakeBasicFileAttributes setDirectory(boolean directory) { + mIsDirectory = directory; + return this; + } + + public FakeBasicFileAttributes setSymbolicLink(boolean symbolicLink) { + mIsSymbolicLink = symbolicLink; + return this; + } + + public FakeBasicFileAttributes setOther(boolean other) { + mIsOther = other; + return this; + } + + public FakeBasicFileAttributes setSize(long size) { + mSize = size; + return this; + } + + public FakeBasicFileAttributes setFileKey(Object fileKey) { + mFileKey = fileKey; + return this; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/sensors/FakeProximitySensor.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/sensors/FakeProximitySensor.java new file mode 100644 index 000000000000..22cf744c726b --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/sensors/FakeProximitySensor.java @@ -0,0 +1,67 @@ +/* + * 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.util.sensors; + +import com.android.systemui.util.concurrency.DelayableExecutor; +import com.android.systemui.util.concurrency.FakeExecution; + +public class FakeProximitySensor extends ProximitySensorImpl { + private boolean mAvailable; + private boolean mRegistered; + + public FakeProximitySensor( + ThresholdSensor primary, + ThresholdSensor secondary, + DelayableExecutor delayableExecutor + ) { + super( + primary, + secondary == null ? new FakeThresholdSensor() : secondary, + delayableExecutor, + new FakeExecution() + ); + mAvailable = true; + } + + public void setSensorAvailable(boolean available) { + mAvailable = available; + } + + public void setLastEvent(ThresholdSensorEvent event) { + mLastEvent = event; + } + + @Override + public boolean isRegistered() { + return mRegistered; + } + + @Override + public boolean isLoaded() { + return mAvailable; + } + + @Override + protected void registerInternal() { + mRegistered = !mPaused; + } + + @Override + protected void unregisterInternal() { + mRegistered = false; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/sensors/FakeSensorManager.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/sensors/FakeSensorManager.java new file mode 100644 index 000000000000..197873f15d0d --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/sensors/FakeSensorManager.java @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2017 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.util.sensors; + +import android.content.Context; +import android.hardware.HardwareBuffer; +import android.hardware.Sensor; +import android.hardware.SensorAdditionalInfo; +import android.hardware.SensorDirectChannel; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.hardware.TriggerEventListener; +import android.os.Handler; +import android.os.MemoryFile; +import android.os.SystemClock; +import android.util.ArraySet; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import javax.annotation.Nullable; + +/** + * Rudimentary fake for SensorManager + * + * Currently only supports proximity, light and tap sensors. + * + * Note that this class ignores the "Handler" argument, so the test is responsible for calling the + * listener on the right thread. + */ +public class FakeSensorManager extends SensorManager { + + public static final String TAP_SENSOR_TYPE = "tapSensorType"; + + private final FakeProximitySensor mFakeProximitySensor; + private final FakeGenericSensor mFakeLightSensor; + private final FakeGenericSensor mFakeLightSensor2; + private final FakeGenericSensor mFakeTapSensor; + private final FakeGenericSensor[] mSensors; + + public FakeSensorManager(Context context) throws Exception { + Sensor proxSensor = context.getSystemService(SensorManager.class) + .getDefaultSensor(Sensor.TYPE_PROXIMITY, true); + if (proxSensor == null) { + // No prox? Let's create a fake one! + proxSensor = + createSensor(Sensor.TYPE_PROXIMITY, null, 1 /* SENSOR_FLAG_WAKE_UP_SENSOR */); + } + + mSensors = new FakeGenericSensor[]{ + mFakeProximitySensor = new FakeProximitySensor(proxSensor), + mFakeLightSensor = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT, null)), + mFakeTapSensor = new FakeGenericSensor(createSensor(99, TAP_SENSOR_TYPE)), + mFakeLightSensor2 = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT, null)) + }; + } + + public FakeProximitySensor getFakeProximitySensor() { + return mFakeProximitySensor; + } + + public FakeGenericSensor getFakeLightSensor() { + return mFakeLightSensor; + } + + public FakeGenericSensor getFakeLightSensor2() { + return mFakeLightSensor2; + } + + public FakeGenericSensor getFakeTapSensor() { + return mFakeTapSensor; + } + + @Override + public Sensor getDefaultSensor(int type) { + Sensor s = super.getDefaultSensor(type); + if (s != null) { + return s; + } + // Our mock sensors aren't wakeup, and it's a pain to create them that way. Instead, just + // return non-wakeup sensors if we can't find a wakeup sensor. + return getDefaultSensor(type, false /* wakeup */); + } + + @Override + protected List getFullSensorList() { + return Arrays + .stream(mSensors) + .map(i -> i.mSensor) + .collect(Collectors.toList()); + } + + @Override + protected List getFullDynamicSensorList() { + return new ArrayList<>(); + } + + @Override + protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) { + Objects.requireNonNull(listener); + for (FakeGenericSensor s : mSensors) { + if (sensor == null || s.mSensor == sensor) { + s.mListeners.remove(listener); + } + } + } + + @Override + protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, + int delayUs, + Handler handler, int maxReportLatencyUs, int reservedFlags) { + Objects.requireNonNull(sensor); + Objects.requireNonNull(listener); + for (FakeGenericSensor s : mSensors) { + if (s.mSensor == sensor) { + s.mListeners.add(listener); + return true; + } + } + return false; + } + + @Override + protected boolean flushImpl(SensorEventListener listener) { + return false; + } + + @Override + protected SensorDirectChannel createDirectChannelImpl(MemoryFile memoryFile, + HardwareBuffer hardwareBuffer) { + return null; + } + + @Override + protected void destroyDirectChannelImpl(SensorDirectChannel channel) { + + } + + @Override + protected int configureDirectChannelImpl(SensorDirectChannel channel, Sensor s, int rate) { + return 0; + } + + @Override + protected void registerDynamicSensorCallbackImpl(DynamicSensorCallback callback, + Handler handler) { + + } + + @Override + protected void unregisterDynamicSensorCallbackImpl( + DynamicSensorCallback callback) { + + } + + @Override + protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) { + return true; + } + + @Override + protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor, + boolean disable) { + return true; + } + + @Override + protected boolean initDataInjectionImpl(boolean enable) { + return false; + } + + @Override + protected boolean injectSensorDataImpl(Sensor sensor, float[] values, int accuracy, + long timestamp) { + return false; + } + + @Override + protected boolean setOperationParameterImpl(SensorAdditionalInfo parameter) { + return false; + } + + private Sensor createSensor(int type, @Nullable String stringType) throws Exception { + return createSensor(type, stringType, 0 /* flags */); + } + + private Sensor createSensor(int type, @Nullable String stringType, int flags) throws Exception { + Constructor constr = Sensor.class.getDeclaredConstructor(); + constr.setAccessible(true); + Sensor sensor = constr.newInstance(); + + setSensorType(sensor, type); + if (stringType != null) { + setSensorField(sensor, "mStringType", stringType); + } + setSensorField(sensor, "mName", "Mock " + sensor.getStringType() + "/" + type); + setSensorField(sensor, "mVendor", "Mock Vendor"); + setSensorField(sensor, "mVersion", 1); + setSensorField(sensor, "mHandle", -1); + setSensorField(sensor, "mMaxRange", 10); + setSensorField(sensor, "mResolution", 1); + setSensorField(sensor, "mPower", 1); + setSensorField(sensor, "mMinDelay", 1000); + setSensorField(sensor, "mMaxDelay", 1000000000); + setSensorField(sensor, "mFlags", flags); + setSensorField(sensor, "mId", -1); + + return sensor; + } + + private void setSensorField(Sensor sensor, String fieldName, Object value) throws Exception { + Field field = Sensor.class.getDeclaredField(fieldName); + field.setAccessible(true); + field.set(sensor, value); + } + + private void setSensorType(Sensor sensor, int type) throws Exception { + Method setter = Sensor.class.getDeclaredMethod("setType", Integer.TYPE); + setter.setAccessible(true); + setter.invoke(sensor, type); + } + + public class FakeProximitySensor extends FakeGenericSensor { + + private FakeProximitySensor(Sensor sensor) { + super(sensor); + } + + public void sendProximityResult(boolean far) { + sendSensorEvent(far ? getSensor().getMaximumRange() : 0); + } + } + + public class FakeGenericSensor { + + private final Sensor mSensor; + private final ArraySet mListeners = new ArraySet<>(); + + public FakeGenericSensor( + Sensor sensor) { + this.mSensor = sensor; + } + + public Sensor getSensor() { + return mSensor; + } + + public void sendSensorEvent(float... values) { + SensorEvent event = createSensorEvent(values.length); + System.arraycopy(values, 0, event.values, 0, values.length); + for (SensorEventListener listener : mListeners) { + listener.onSensorChanged(event); + } + } + + private SensorEvent createSensorEvent(int valuesSize) { + SensorEvent event; + try { + Constructor constr = + SensorEvent.class.getDeclaredConstructor(Integer.TYPE); + constr.setAccessible(true); + event = constr.newInstance(valuesSize); + } catch (Exception e) { + throw new RuntimeException(e); + } + event.sensor = mSensor; + event.timestamp = SystemClock.elapsedRealtimeNanos(); + + return event; + } + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/sensors/FakeThresholdSensor.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/sensors/FakeThresholdSensor.java new file mode 100644 index 000000000000..0d4a6c7023fb --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/sensors/FakeThresholdSensor.java @@ -0,0 +1,91 @@ +/* + * 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.util.sensors; + +import java.util.ArrayList; +import java.util.List; + +public class FakeThresholdSensor implements ThresholdSensor { + private boolean mIsLoaded; + private boolean mPaused; + private List mListeners = new ArrayList<>(); + + public FakeThresholdSensor() { + } + + public void setTag(String tag) { + } + + @Override + public void setDelay(int delay) { + } + + @Override + public boolean isLoaded() { + return mIsLoaded; + } + + @Override + public void pause() { + mPaused = true; + } + + @Override + public void resume() { + mPaused = false; + } + + @Override + public void register(ThresholdSensor.Listener listener) { + mListeners.add(listener); + } + + @Override + public void unregister(ThresholdSensor.Listener listener) { + mListeners.remove(listener); + } + + @Override + public String getName() { + return "FakeThresholdSensorName"; + } + + @Override + public String getType() { + return "FakeThresholdSensorType"; + } + + public void setLoaded(boolean loaded) { + mIsLoaded = loaded; + } + + void triggerEvent(boolean below, long timestampNs) { + if (!mPaused) { + for (Listener listener : mListeners) { + listener.onThresholdCrossed(new ThresholdSensorEvent(below, timestampNs)); + } + } + } + + boolean isPaused() { + return mPaused; + } + + int getNumListeners() { + return mListeners.size(); + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java new file mode 100644 index 000000000000..e660e1f2d845 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java @@ -0,0 +1,152 @@ +/* + * 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.util.settings; + +import android.annotation.UserIdInt; +import android.content.ContentResolver; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.UserHandle; +import android.util.Pair; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class FakeSettings implements SecureSettings, GlobalSettings, SystemSettings { + private final Map mValues = new HashMap<>(); + private final Map> mContentObservers = + new HashMap<>(); + private final Map> mContentObserversAllUsers = new HashMap<>(); + + public static final Uri CONTENT_URI = Uri.parse("content://settings/fake"); + @UserIdInt + private int mUserId = UserHandle.USER_CURRENT; + + public FakeSettings() { + } + + public FakeSettings(String initialKey, String initialValue) { + putString(initialKey, initialValue); + } + + public FakeSettings(Map initialValues) { + for (Map.Entry kv : initialValues.entrySet()) { + putString(kv.getKey(), kv.getValue()); + } + } + + @Override + public ContentResolver getContentResolver() { + return null; + } + + @Override + public void registerContentObserverForUser(Uri uri, boolean notifyDescendents, + ContentObserver settingsObserver, int userHandle) { + List observers; + if (userHandle == UserHandle.USER_ALL) { + mContentObserversAllUsers.putIfAbsent(uri.toString(), new ArrayList<>()); + observers = mContentObserversAllUsers.get(uri.toString()); + } else { + SettingsKey key = new SettingsKey(userHandle, uri.toString()); + mContentObservers.putIfAbsent(key, new ArrayList<>()); + observers = mContentObservers.get(key); + } + observers.add(settingsObserver); + } + + @Override + public void unregisterContentObserver(ContentObserver settingsObserver) { + for (SettingsKey key : mContentObservers.keySet()) { + List observers = mContentObservers.get(key); + observers.remove(settingsObserver); + } + for (String key : mContentObserversAllUsers.keySet()) { + List observers = mContentObserversAllUsers.get(key); + observers.remove(settingsObserver); + } + } + + @Override + public Uri getUriFor(String name) { + return Uri.withAppendedPath(CONTENT_URI, name); + } + + public void setUserId(@UserIdInt int userId) { + mUserId = userId; + } + + @Override + public int getUserId() { + return mUserId; + } + + @Override + public String getString(String name) { + return getStringForUser(name, getUserId()); + } + + @Override + public String getStringForUser(String name, int userHandle) { + return mValues.get(new SettingsKey(userHandle, getUriFor(name).toString())); + } + + @Override + public boolean putString(String name, String value, boolean overrideableByRestore) { + return putStringForUser(name, value, null, false, getUserId(), overrideableByRestore); + } + + @Override + public boolean putString(String name, String value) { + return putString(name, value, false); + } + + @Override + public boolean putStringForUser(String name, String value, int userHandle) { + return putStringForUser(name, value, null, false, userHandle, false); + } + + @Override + public boolean putStringForUser(String name, String value, String tag, boolean makeDefault, + int userHandle, boolean overrideableByRestore) { + SettingsKey key = new SettingsKey(userHandle, getUriFor(name).toString()); + mValues.put(key, value); + + Uri uri = getUriFor(name); + for (ContentObserver observer : mContentObservers.getOrDefault(key, new ArrayList<>())) { + observer.dispatchChange(false, List.of(uri), 0, userHandle); + } + for (ContentObserver observer : + mContentObserversAllUsers.getOrDefault(uri.toString(), new ArrayList<>())) { + observer.dispatchChange(false, List.of(uri), 0, userHandle); + } + return true; + } + + @Override + public boolean putString(String name, String value, String tag, boolean makeDefault) { + return putString(name, value); + } + + private static class SettingsKey extends Pair { + SettingsKey(Integer first, String second) { + super(first, second); + } + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClock.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClock.java new file mode 100644 index 000000000000..db6164dcf8f9 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClock.java @@ -0,0 +1,128 @@ +/* + * 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.util.time; + +import com.android.systemui.util.concurrency.FakeExecutor; + +import java.util.ArrayList; +import java.util.List; + +/** + * A fake {@link SystemClock} for use with {@link FakeExecutor}. + * + * Attempts to simulate the behavior of a real system clock. Time can be moved forward but not + * backwards. uptimeMillis, elapsedRealtime, and currentThreadTimeMillis are all kept in sync. + * + * Unless otherwise specified, uptimeMillis and elapsedRealtime will advance the same amount with + * every call to {@link #advanceTime}. Thread time always lags by 50% of the uptime + * advancement to simulate time loss due to scheduling. + */ +public class FakeSystemClock implements SystemClock { + private long mUptimeMillis = 10000; + private long mElapsedRealtime = 10000; + private long mCurrentThreadTimeMillis = 10000; + private long mCurrentTimeMillis = 1555555500000L; + private final List mListeners = new ArrayList<>(); + + @Override + public long uptimeMillis() { + return mUptimeMillis; + } + + @Override + public long elapsedRealtime() { + return mElapsedRealtime; + } + + @Override + public long elapsedRealtimeNanos() { + return mElapsedRealtime * 1000000 + 447; + } + + @Override + public long currentThreadTimeMillis() { + return mCurrentThreadTimeMillis; + } + + @Override + public long currentTimeMillis() { + return mCurrentTimeMillis; + } + + public void setUptimeMillis(long uptime) { + advanceTime(uptime - mUptimeMillis); + } + + public void setCurrentTimeMillis(long millis) { + mCurrentTimeMillis = millis; + } + + public void setElapsedRealtime(long millis) { + mElapsedRealtime = millis; + } + + /** + * Advances the time tracked by the fake clock and notifies any listeners that the time has + * changed (for example, an attached {@link FakeExecutor} may fire its pending runnables). + * + * All tracked times increment by [millis], with the exception of currentThreadTimeMillis, + * which advances by [millis] * 0.5 + */ + public void advanceTime(long millis) { + advanceTime(millis, 0); + } + + /** + * Advances the time tracked by the fake clock and notifies any listeners that the time has + * changed (for example, an attached {@link FakeExecutor} may fire its pending runnables). + * + * The tracked times change as follows: + * - uptimeMillis increments by [awakeMillis] + * - currentThreadTimeMillis increments by [awakeMillis] * 0.5 + * - elapsedRealtime increments by [awakeMillis] + [sleepMillis] + * - currentTimeMillis increments by [awakeMillis] + [sleepMillis] + */ + public void advanceTime(long awakeMillis, long sleepMillis) { + if (awakeMillis < 0 || sleepMillis < 0) { + throw new IllegalArgumentException("Time cannot go backwards"); + } + + if (awakeMillis > 0 || sleepMillis > 0) { + mUptimeMillis += awakeMillis; + mElapsedRealtime += awakeMillis + sleepMillis; + mCurrentTimeMillis += awakeMillis + sleepMillis; + + mCurrentThreadTimeMillis += Math.ceil(awakeMillis * 0.5); + + for (ClockTickListener listener : mListeners) { + listener.onClockTick(); + } + } + } + + public void addListener(ClockTickListener listener) { + mListeners.add(listener); + } + + public void removeListener(ClockTickListener listener) { + mListeners.remove(listener); + } + + public interface ClockTickListener { + void onClockTick(); + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/wakelock/WakeLockFake.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/wakelock/WakeLockFake.java new file mode 100644 index 000000000000..553b8a42edc8 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/wakelock/WakeLockFake.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2017 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.util.wakelock; + +import android.content.Context; + +import com.android.internal.util.Preconditions; + +public class WakeLockFake implements WakeLock { + + private int mAcquired = 0; + + @Override + public void acquire(String why) { + mAcquired++; + } + + @Override + public void release(String why) { + Preconditions.checkState(mAcquired > 0); + mAcquired--; + } + + @Override + public Runnable wrap(Runnable runnable) { + acquire(WakeLockFake.class.getSimpleName()); + return () -> { + try { + runnable.run(); + } finally { + release(WakeLockFake.class.getSimpleName()); + } + }; + } + + public boolean isHeld() { + return mAcquired > 0; + } + + public static class Builder extends WakeLock.Builder { + private WakeLock mWakeLock; + + public Builder(Context context) { + super(context); + } + + public void setWakeLock(WakeLock wakeLock) { + mWakeLock = wakeLock; + } + + public WakeLock build() { + if (mWakeLock != null) { + return mWakeLock; + } + + return super.build(); + } + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/BaseLeakChecker.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/BaseLeakChecker.java new file mode 100644 index 000000000000..8fe7f59bca67 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/BaseLeakChecker.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2017 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.utils.leaks; + +import android.testing.LeakCheck; +import android.testing.LeakCheck.Tracker; + +import com.android.systemui.Dumpable; +import com.android.systemui.statusbar.policy.CallbackController; + +import java.io.PrintWriter; + +public class BaseLeakChecker implements CallbackController, Dumpable { + + private final Tracker mTracker; + + public BaseLeakChecker(LeakCheck test, String tag) { + mTracker = test.getTracker(tag); + } + + protected final Tracker getTracker() { + return mTracker; + } + + @Override + public void addCallback(T listener) { + mTracker.getLeakInfo(listener).addAllocation(new Throwable()); + } + + @Override + public void removeCallback(T listener) { + mTracker.getLeakInfo(listener).clearAllocations(); + } + + @Override + public void dump(PrintWriter pw, String[] args) { + + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeBatteryController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeBatteryController.java new file mode 100644 index 000000000000..eaa109d672f8 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeBatteryController.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.os.Bundle; +import android.testing.LeakCheck; +import android.view.View; + +import com.android.systemui.statusbar.policy.BatteryController; +import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback; + +import java.io.PrintWriter; + +public class FakeBatteryController extends BaseLeakChecker + implements BatteryController { + private boolean mWirelessCharging; + + public FakeBatteryController(LeakCheck test) { + super(test, "battery"); + } + + @Override + public void dispatchDemoCommand(String command, Bundle args) { + + } + + @Override + public void dump(PrintWriter pw, String[] args) { + + } + + @Override + public void setPowerSaveMode(boolean powerSave) { + + } + + @Override + public void setPowerSaveMode(boolean powerSave, View view) { + + } + + @Override + public boolean isPluggedIn() { + return false; + } + + @Override + public boolean isPowerSave() { + return false; + } + + @Override + public boolean isAodPowerSave() { + return false; + } + + @Override + public boolean isWirelessCharging() { + return mWirelessCharging; + } + + public void setWirelessCharging(boolean wirelessCharging) { + mWirelessCharging = wirelessCharging; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeBluetoothController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeBluetoothController.java new file mode 100644 index 000000000000..6cbd175c1084 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeBluetoothController.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.testing.LeakCheck; + +import com.android.settingslib.bluetooth.CachedBluetoothDevice; +import com.android.systemui.statusbar.policy.BluetoothController; +import com.android.systemui.statusbar.policy.BluetoothController.Callback; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class FakeBluetoothController extends BaseLeakChecker implements + BluetoothController { + + public FakeBluetoothController(LeakCheck test) { + super(test, "bluetooth"); + } + + @Override + public boolean isBluetoothSupported() { + return false; + } + + @Override + public boolean isBluetoothEnabled() { + return false; + } + + @Override + public int getBluetoothState() { + return 0; + } + + @Override + public boolean isBluetoothConnected() { + return false; + } + + @Override + public boolean isBluetoothConnecting() { + return false; + } + + @Override + public boolean isBluetoothAudioProfileOnly() { + return false; + } + + @Override + public boolean isBluetoothAudioActive() { + return false; + } + + @Override + public String getConnectedDeviceName() { + return null; + } + + @Override + public void setBluetoothEnabled(boolean enabled) { + + } + + @Override + public Collection getDevices() { + return null; + } + + @Override + public void connect(CachedBluetoothDevice device) { + + } + + @Override + public void disconnect(CachedBluetoothDevice device) { + + } + + @Override + public boolean canConfigBluetooth() { + return false; + } + + @Override + public int getMaxConnectionState(CachedBluetoothDevice device) { + return 0; + } + + @Override + public int getBondState(CachedBluetoothDevice device) { + return 0; + } + + @Override + public List getConnectedDevices() { + return Collections.emptyList(); + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeCastController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeCastController.java new file mode 100644 index 000000000000..f6b24da9b821 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeCastController.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.testing.LeakCheck; + +import com.android.systemui.statusbar.policy.CastController; +import com.android.systemui.statusbar.policy.CastController.Callback; + +import java.util.ArrayList; +import java.util.List; + +public class FakeCastController extends BaseLeakChecker implements CastController { + public FakeCastController(LeakCheck test) { + super(test, "cast"); + } + + @Override + public void setDiscovering(boolean request) { + + } + + @Override + public void setCurrentUserId(int currentUserId) { + + } + + @Override + public List getCastDevices() { + return new ArrayList<>(); + } + + @Override + public void startCasting(CastDevice device) { + + } + + @Override + public void stopCasting(CastDevice device) { + + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeConfigurationController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeConfigurationController.java new file mode 100644 index 000000000000..516eb6e6dffd --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeConfigurationController.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2017 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.utils.leaks; + +import android.content.res.Configuration; + +import com.android.systemui.statusbar.policy.ConfigurationController; + +public class FakeConfigurationController + extends BaseLeakChecker + implements ConfigurationController { + + public FakeConfigurationController(LeakCheckedTest.SysuiLeakCheck sysuiLeakCheck) { + super(sysuiLeakCheck, "config"); + } + + @Override + public void onConfigurationChanged(Configuration newConfiguration) { + } + + @Override + public void notifyThemeChanged() { + } + + @Override + public boolean isLayoutRtl() { + return false; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeDataSaverController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeDataSaverController.java new file mode 100644 index 000000000000..886722e46376 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeDataSaverController.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.testing.LeakCheck; + +import com.android.systemui.statusbar.policy.DataSaverController; +import com.android.systemui.statusbar.policy.DataSaverController.Listener; + +public class FakeDataSaverController extends BaseLeakChecker implements DataSaverController { + + public FakeDataSaverController(LeakCheck test) { + super(test, "datasaver"); + } + + @Override + public boolean isDataSaverEnabled() { + return false; + } + + @Override + public void setDataSaverEnabled(boolean enabled) { + + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeExtensionController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeExtensionController.java new file mode 100644 index 000000000000..ab16e3bd163e --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeExtensionController.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2017 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.utils.leaks; + +import android.content.Context; +import android.testing.LeakCheck; +import android.testing.LeakCheck.Tracker; + +import com.android.systemui.statusbar.policy.ExtensionController; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class FakeExtensionController implements ExtensionController { + + private final Tracker mTracker; + + public FakeExtensionController(LeakCheck test) { + mTracker = test.getTracker("extension"); + } + + @Override + public ExtensionBuilder newExtension(Class cls) { + final Object o = new Object(); + mTracker.getLeakInfo(o).addAllocation(new Throwable()); + return new FakeExtensionBuilder(o); + } + + private class FakeExtensionBuilder implements ExtensionBuilder { + private final Object mAllocation; + + public FakeExtensionBuilder(Object o) { + mAllocation = o; + } + + @Override + public ExtensionBuilder withTunerFactory(TunerFactory factory) { + return this; + } + + @Override + public

ExtensionBuilder withPlugin(Class

cls) { + return this; + } + + @Override + public

ExtensionBuilder withPlugin(Class

cls, String action) { + return this; + } + + @Override + public

ExtensionBuilder withPlugin(Class

cls, String action, PluginConverter converter) { + return this; + } + + @Override + public ExtensionBuilder withDefault(Supplier def) { + return this; + } + + @Override + public ExtensionBuilder withCallback(Consumer callback) { + return this; + } + + @Override + public ExtensionBuilder withUiMode(int mode, Supplier def) { + return null; + } + + @Override + public ExtensionBuilder withFeature(String feature, Supplier def) { + return null; + } + + @Override + public Extension build() { + return new FakeExtension(mAllocation); + } + } + + private class FakeExtension implements Extension { + private final Object mAllocation; + + public FakeExtension(Object allocation) { + mAllocation = allocation; + } + + @Override + public T get() { + // TODO: Support defaults or things. + return null; + } + + @Override + public void clearItem(boolean isDestroyed) { + + } + + @Override + public Context getContext() { + return null; + } + + @Override + public void destroy() { + mTracker.getLeakInfo(mAllocation).clearAllocations(); + } + + @Override + public void addCallback(Consumer callback) { + } + + public T reload() { + return null; + } + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeFlashlightController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeFlashlightController.java new file mode 100644 index 000000000000..f6fd2cb8f3b1 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeFlashlightController.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.testing.LeakCheck; + +import com.android.systemui.statusbar.policy.FlashlightController; +import com.android.systemui.statusbar.policy.FlashlightController.FlashlightListener; + +public class FakeFlashlightController extends BaseLeakChecker + implements FlashlightController { + public FakeFlashlightController(LeakCheck test) { + super(test, "flashlight"); + } + + @Override + public boolean hasFlashlight() { + return false; + } + + @Override + public void setFlashlight(boolean newState) { + + } + + @Override + public boolean isAvailable() { + return false; + } + + @Override + public boolean isEnabled() { + return false; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeHotspotController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeHotspotController.java new file mode 100644 index 000000000000..016160aea433 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeHotspotController.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.testing.LeakCheck; + +import com.android.systemui.statusbar.policy.HotspotController; +import com.android.systemui.statusbar.policy.HotspotController.Callback; + +public class FakeHotspotController extends BaseLeakChecker implements HotspotController { + + public FakeHotspotController(LeakCheck test) { + super(test, "hotspot"); + } + + @Override + public boolean isHotspotEnabled() { + return false; + } + + @Override + public boolean isHotspotTransient() { + return false; + } + + @Override + public void setHotspotEnabled(boolean enabled) { + + } + + @Override + public boolean isHotspotSupported() { + return false; + } + + @Override + public int getNumConnectedDevices() { + return 0; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java new file mode 100644 index 000000000000..95b62a12c621 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.testing.LeakCheck; + +import com.android.systemui.statusbar.policy.KeyguardStateController; + +public class FakeKeyguardStateController implements KeyguardStateController { + + private final BaseLeakChecker mCallbackController; + + public FakeKeyguardStateController(LeakCheck test) { + mCallbackController = new BaseLeakChecker(test, "keyguard"); + } + + @Override + public void addCallback(Callback callback) { + mCallbackController.addCallback(callback); + } + + @Override + public void removeCallback(Callback callback) { + mCallbackController.removeCallback(callback); + } + + @Override + public boolean isMethodSecure() { + return false; + } + + @Override + public boolean isShowing() { + return false; + } + + @Override + public boolean isBouncerShowing() { + return false; + } + + @Override + public boolean canDismissLockScreen() { + return false; + } + + @Override + public boolean isOccluded() { + return false; + } + + @Override + public boolean isTrusted() { + return false; + } + + @Override + public boolean isKeyguardFadingAway() { + return false; + } + + @Override + public boolean isKeyguardGoingAway() { + return false; + } + + @Override + public boolean isLaunchTransitionFadingAway() { + return false; + } + + @Override + public long getKeyguardFadingAwayDuration() { + return 0; + } + + @Override + public long getKeyguardFadingAwayDelay() { + return 0; + } + + @Override + public long calculateGoingToFullShadeDelay() { + return 0; + } + + @Override + public float getDismissAmount() { + return 0; + } + + @Override + public boolean isDismissingFromSwipe() { + return false; + } + + @Override + public boolean isFlingingToDismissKeyguard() { + return false; + } + + @Override + public boolean isFlingingToDismissKeyguardDuringSwipeGesture() { + return false; + } + + @Override + public boolean isSnappingKeyguardBackAfterSwipe() { + return false; + } + + @Override + public void notifyPanelFlingStart(boolean dismiss) { + + } + + @Override + public void notifyPanelFlingEnd() { + + } + + @Override + public boolean isKeyguardScreenRotationAllowed() { + return false; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeLocationController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeLocationController.java new file mode 100644 index 000000000000..838a2739f0b0 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeLocationController.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.testing.LeakCheck; + +import com.android.systemui.statusbar.policy.LocationController; +import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback; + +public class FakeLocationController extends BaseLeakChecker + implements LocationController { + public FakeLocationController(LeakCheck test) { + super(test, "location"); + } + + @Override + public boolean isLocationActive() { + return false; + } + + @Override + public boolean isLocationEnabled() { + return false; + } + + @Override + public boolean setLocationEnabled(boolean enabled) { + return false; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeManagedProfileController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeManagedProfileController.java new file mode 100644 index 000000000000..18b07cf25fbc --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeManagedProfileController.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.testing.LeakCheck; + +import com.android.systemui.statusbar.phone.ManagedProfileController; +import com.android.systemui.statusbar.phone.ManagedProfileController.Callback; + +public class FakeManagedProfileController extends BaseLeakChecker implements + ManagedProfileController { + public FakeManagedProfileController(LeakCheck test) { + super(test, "profile"); + } + + @Override + public void setWorkModeEnabled(boolean enabled) { + + } + + @Override + public boolean hasActiveProfile() { + return false; + } + + @Override + public boolean isWorkModeEnabled() { + return false; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeNetworkController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeNetworkController.java new file mode 100644 index 000000000000..33ef9cf7a9c5 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeNetworkController.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.os.Bundle; +import android.testing.LeakCheck; + +import com.android.settingslib.net.DataUsageController; +import com.android.systemui.statusbar.connectivity.AccessPointController; +import com.android.systemui.statusbar.connectivity.NetworkController; +import com.android.systemui.statusbar.connectivity.SignalCallback; +import com.android.systemui.statusbar.policy.DataSaverController; + +public class FakeNetworkController extends BaseLeakChecker + implements NetworkController { + + private final FakeDataSaverController mDataSaverController; + private final BaseLeakChecker mEmergencyChecker; + + public FakeNetworkController(LeakCheck test) { + super(test, "network"); + mDataSaverController = new FakeDataSaverController(test); + mEmergencyChecker = new BaseLeakChecker<>(test, "emergency"); + } + + @Override + public void addEmergencyListener(EmergencyListener listener) { + mEmergencyChecker.addCallback(listener); + } + + @Override + public void removeEmergencyListener(EmergencyListener listener) { + mEmergencyChecker.removeCallback(listener); + } + + @Override + public boolean hasEmergencyCryptKeeperText() { + return false; + } + + @Override + public boolean isRadioOn() { + return false; + } + + @Override + public DataSaverController getDataSaverController() { + return mDataSaverController; + } + + @Override + public boolean hasMobileDataFeature() { + return false; + } + + @Override + public void setWifiEnabled(boolean enabled) { + + } + + @Override + public AccessPointController getAccessPointController() { + return null; + } + + @Override + public DataUsageController getMobileDataController() { + return null; + } + + @Override + public boolean hasVoiceCallingFeature() { + return false; + } + + @Override + public void dispatchDemoCommand(String command, Bundle args) { + + } + + @Override + public String getMobileDataNetworkName() { + return ""; + } + + @Override + public boolean isMobileDataNetworkInService() { + return false; + } + + @Override + public int getNumberSubscriptions() { + return 0; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeNextAlarmController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeNextAlarmController.java new file mode 100644 index 000000000000..5ae8e22c06ee --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeNextAlarmController.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.testing.LeakCheck; + +import com.android.systemui.statusbar.policy.NextAlarmController; +import com.android.systemui.statusbar.policy.NextAlarmController.NextAlarmChangeCallback; + +public class FakeNextAlarmController extends BaseLeakChecker + implements NextAlarmController { + + public FakeNextAlarmController(LeakCheck test) { + super(test, "alarm"); + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakePluginManager.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakePluginManager.java new file mode 100644 index 000000000000..d245c727dcf8 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakePluginManager.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2017 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.utils.leaks; + +import android.testing.LeakCheck; + +import com.android.systemui.plugins.Plugin; +import com.android.systemui.plugins.PluginListener; +import com.android.systemui.shared.plugins.PluginManager; + +public class FakePluginManager implements PluginManager { + + private final BaseLeakChecker> mLeakChecker; + + public FakePluginManager(LeakCheck test) { + mLeakChecker = new BaseLeakChecker<>(test, "Plugin"); + } + + @Override + public void addPluginListener(String action, PluginListener listener, + Class cls, boolean allowMultiple) { + mLeakChecker.addCallback(listener); + } + + @Override + public void addPluginListener(PluginListener listener, Class cls) { + mLeakChecker.addCallback(listener); + } + + @Override + public void addPluginListener(PluginListener listener, Class cls, + boolean allowMultiple) { + mLeakChecker.addCallback(listener); + } + + @Override + public void addPluginListener(String action, PluginListener listener, + Class cls) { + mLeakChecker.addCallback(listener); + } + + @Override + public void removePluginListener(PluginListener listener) { + mLeakChecker.removeCallback(listener); + } + + @Override + public boolean dependsOn(Plugin p, Class cls) { + return false; + } + + @Override + public String[] getPrivilegedPlugins() { + return new String[0]; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeRotationLockController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeRotationLockController.java new file mode 100644 index 000000000000..4f9cb35db1a3 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeRotationLockController.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.testing.LeakCheck; + +import com.android.systemui.statusbar.policy.RotationLockController; +import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback; + +public class FakeRotationLockController extends BaseLeakChecker + implements RotationLockController { + public FakeRotationLockController(LeakCheck test) { + super(test, "rotation"); + } + + @Override + public void setListening(boolean listening) { + + } + + @Override + public int getRotationLockOrientation() { + return 0; + } + + @Override + public boolean isRotationLockAffordanceVisible() { + return false; + } + + @Override + public boolean isRotationLocked() { + return false; + } + + @Override + public void setRotationLocked(boolean locked) { + + } + + @Override + public boolean isCameraRotationEnabled() { + return false; + } + + @Override + public void setRotationLockedAtAngle(boolean locked, int rotation) { + + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeSecurityController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeSecurityController.java new file mode 100644 index 000000000000..d5348dc39832 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeSecurityController.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.app.admin.DeviceAdminInfo; +import android.content.ComponentName; +import android.graphics.drawable.Drawable; +import android.testing.LeakCheck; + +import com.android.systemui.statusbar.policy.SecurityController; +import com.android.systemui.statusbar.policy.SecurityController.SecurityControllerCallback; + +public class FakeSecurityController extends BaseLeakChecker + implements SecurityController { + public FakeSecurityController(LeakCheck test) { + super(test, "security"); + } + + @Override + public boolean isDeviceManaged() { + return false; + } + + @Override + public boolean hasProfileOwner() { + return false; + } + + @Override + public boolean hasWorkProfile() { + return false; + } + + @Override + public boolean isWorkProfileOn() { + return false; + } + + @Override + public boolean isProfileOwnerOfOrganizationOwnedDevice() { + return false; + } + + @Override + public String getDeviceOwnerName() { + return null; + } + + @Override + public String getProfileOwnerName() { + return null; + } + + @Override + public CharSequence getDeviceOwnerOrganizationName() { + return null; + } + + @Override + public CharSequence getWorkProfileOrganizationName() { + return null; + } + + @Override + public ComponentName getDeviceOwnerComponentOnAnyUser() { + return null; + } + + @Override + public int getDeviceOwnerType(ComponentName admin) { + return 0; + } + + @Override + public boolean isNetworkLoggingEnabled() { + return false; + } + + @Override + public boolean isVpnEnabled() { + return false; + } + + @Override + public boolean isVpnRestricted() { + return false; + } + + @Override + public boolean isVpnBranded() { + return false; + } + + @Override + public String getPrimaryVpnName() { + return null; + } + + @Override + public String getWorkProfileVpnName() { + return null; + } + + @Override + public boolean hasCACertInCurrentUser() { + return false; + } + + @Override + public boolean hasCACertInWorkProfile() { + return false; + } + + @Override + public void onUserSwitched(int newUserId) { + + } + + @Override + public boolean isParentalControlsEnabled() { + return false; + } + + @Override + public DeviceAdminInfo getDeviceAdminInfo() { + return null; + } + + @Override + public Drawable getIcon(DeviceAdminInfo info) { + return null; + } + + @Override + public CharSequence getLabel(DeviceAdminInfo info) { + return null; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java new file mode 100644 index 000000000000..2be67edfc946 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2017 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.utils.leaks; + +import android.testing.LeakCheck; + +import com.android.internal.statusbar.StatusBarIcon; +import com.android.systemui.statusbar.phone.StatusBarIconController; +import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager; +import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.CallIndicatorIconState; +import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; +import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; + +import java.util.List; + +public class FakeStatusBarIconController extends BaseLeakChecker + implements StatusBarIconController { + + public FakeStatusBarIconController(LeakCheck test) { + super(test, "StatusBarGroup"); + } + + @Override + public void addIconGroup(IconManager iconManager) { + addCallback(iconManager); + } + + @Override + public void removeIconGroup(IconManager iconManager) { + removeCallback(iconManager); + } + + @Override + public void refreshIconGroup(IconManager iconManager) { + } + + @Override + public void setExternalIcon(String slot) { + + } + + @Override + public void setIcon(String slot, int resourceId, CharSequence contentDescription) { + + } + + @Override + public void setIcon(String slot, StatusBarIcon icon) { + + } + + @Override + public void setSignalIcon(String slot, WifiIconState state) { + } + + @Override + public void setMobileIcons(String slot, List states) { + } + + @Override + public void setCallStrengthIcons(String slot, List states) { + } + + @Override + public void setNoCallingIcons(String slot, List states) { + } + + @Override + public void setIconVisibility(String slotTty, boolean b) { + } + + @Override + public void removeIcon(String slot, int tag) { + } + + @Override + public void removeAllIconsForSlot(String slot) { + } + + @Override + public void setIconAccessibilityLiveRegion(String slot, int mode) { + } + +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeTunerService.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeTunerService.java new file mode 100644 index 000000000000..7d8a28812fde --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeTunerService.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2017 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.utils.leaks; + +import android.testing.LeakCheck; + +import com.android.systemui.tuner.TunerService; + +public class FakeTunerService extends TunerService { + + private final BaseLeakChecker mBaseLeakChecker; + private boolean mEnabled; + + public FakeTunerService(LeakCheck test) { + super(null); + mBaseLeakChecker = new BaseLeakChecker<>(test, "tunable"); + } + + @Override + public void addTunable(Tunable tunable, String... keys) { + for (String key : keys) { + tunable.onTuningChanged(key, null); + } + mBaseLeakChecker.addCallback(tunable); + } + + @Override + public void removeTunable(Tunable tunable) { + mBaseLeakChecker.removeCallback(tunable); + } + + @Override + public void clearAll() { + + } + + @Override + public void destroy() { + + } + + @Override + public String getValue(String setting) { + return null; + } + + @Override + public int getValue(String setting, int def) { + return def; + } + + @Override + public String getValue(String setting, String def) { + return def; + } + + @Override + public void setValue(String setting, String value) { + + } + + @Override + public void setValue(String setting, int value) { + + } + + @Override + public void setTunerEnabled(boolean enabled) { + mEnabled = enabled; + } + + @Override + public boolean isTunerEnabled() { + return mEnabled; + } + + @Override + public void showResetRequest(Runnable onDisabled) {} +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeUserInfoController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeUserInfoController.java new file mode 100644 index 000000000000..f7ef653aebf2 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeUserInfoController.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.testing.LeakCheck; + +import com.android.systemui.statusbar.policy.UserInfoController; +import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener; + +public class FakeUserInfoController extends BaseLeakChecker + implements UserInfoController { + public FakeUserInfoController(LeakCheck test) { + super(test, "user_info"); + } + + @Override + public void reloadUserInfo() { + + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeZenModeController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeZenModeController.java new file mode 100644 index 000000000000..75df4e67db23 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeZenModeController.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.app.NotificationManager; +import android.content.ComponentName; +import android.net.Uri; +import android.service.notification.ZenModeConfig; +import android.service.notification.ZenModeConfig.ZenRule; +import android.testing.LeakCheck; + +import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.statusbar.policy.ZenModeController.Callback; + +public class FakeZenModeController extends BaseLeakChecker implements ZenModeController { + public FakeZenModeController(LeakCheck test) { + super(test, "zen"); + } + + @Override + public void setZen(int zen, Uri conditionId, String reason) { + + } + + @Override + public int getZen() { + return 0; + } + + @Override + public ZenRule getManualRule() { + return null; + } + + @Override + public ZenModeConfig getConfig() { + return null; + } + + @Override + public NotificationManager.Policy getConsolidatedPolicy() { + return null; + } + + @Override + public long getNextAlarm() { + return 0; + } + + @Override + public boolean isZenAvailable() { + return false; + } + + @Override + public ComponentName getEffectsSuppressor() { + return null; + } + + @Override + public boolean isCountdownConditionSupported() { + return false; + } + + @Override + public int getCurrentUser() { + return 0; + } + + @Override + public boolean isVolumeRestricted() { + return false; + } + + @Override + public boolean areNotificationsHiddenInShade() { + return false; + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckedTest.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckedTest.java new file mode 100644 index 000000000000..dc6a8fb9a4c4 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckedTest.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2016 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.utils.leaks; + +import android.testing.LeakCheck; +import android.util.ArrayMap; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.shared.plugins.PluginManager; +import com.android.systemui.statusbar.connectivity.NetworkController; +import com.android.systemui.statusbar.phone.ManagedProfileController; +import com.android.systemui.statusbar.phone.StatusBarIconController; +import com.android.systemui.statusbar.policy.BatteryController; +import com.android.systemui.statusbar.policy.BluetoothController; +import com.android.systemui.statusbar.policy.CastController; +import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.statusbar.policy.FlashlightController; +import com.android.systemui.statusbar.policy.HotspotController; +import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.statusbar.policy.LocationController; +import com.android.systemui.statusbar.policy.NextAlarmController; +import com.android.systemui.statusbar.policy.RotationLockController; +import com.android.systemui.statusbar.policy.SecurityController; +import com.android.systemui.statusbar.policy.UserInfoController; +import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.tuner.TunerService; + +import org.junit.Assert; +import org.junit.Rule; + +import java.util.Map; + +/** + * Base class for tests to check if receivers are left registered, services bound, or other + * listeners listening. + */ +public abstract class LeakCheckedTest extends SysuiTestCase { + private static final String TAG = "LeakCheckedTest"; + + public static final Class[] ALL_SUPPORTED_CLASSES = new Class[]{ + BluetoothController.class, + LocationController.class, + RotationLockController.class, + ZenModeController.class, + CastController.class, + HotspotController.class, + FlashlightController.class, + UserInfoController.class, + KeyguardStateController.class, + BatteryController.class, + SecurityController.class, + ManagedProfileController.class, + NextAlarmController.class, + NetworkController.class, + PluginManager.class, + TunerService.class, + StatusBarIconController.class, + ConfigurationController.class, + }; + + @Rule + public SysuiLeakCheck mLeakCheck = new SysuiLeakCheck(); + + @Override + public LeakCheck getLeakCheck() { + return mLeakCheck; + } + + public void injectLeakCheckedDependencies(Class... cls) { + for (Class c : cls) { + injectLeakCheckedDependency(c); + } + } + + public void injectLeakCheckedDependency(Class c) { + mDependency.injectTestDependency(c, mLeakCheck.getLeakChecker(c)); + } + + public static class SysuiLeakCheck extends LeakCheck { + + private final Map mLeakCheckers = new ArrayMap<>(); + + public SysuiLeakCheck() { + super(); + } + + public T getLeakChecker(Class cls) { + Object obj = mLeakCheckers.get(cls); + if (obj == null) { + // Lazy create checkers so we only have the ones we need. + if (cls == BluetoothController.class) { + obj = new FakeBluetoothController(this); + } else if (cls == LocationController.class) { + obj = new FakeLocationController(this); + } else if (cls == RotationLockController.class) { + obj = new FakeRotationLockController(this); + } else if (cls == ZenModeController.class) { + obj = new FakeZenModeController(this); + } else if (cls == CastController.class) { + obj = new FakeCastController(this); + } else if (cls == HotspotController.class) { + obj = new FakeHotspotController(this); + } else if (cls == FlashlightController.class) { + obj = new FakeFlashlightController(this); + } else if (cls == UserInfoController.class) { + obj = new FakeUserInfoController(this); + } else if (cls == KeyguardStateController.class) { + obj = new FakeKeyguardStateController(this); + } else if (cls == BatteryController.class) { + obj = new FakeBatteryController(this); + } else if (cls == SecurityController.class) { + obj = new FakeSecurityController(this); + } else if (cls == ManagedProfileController.class) { + obj = new FakeManagedProfileController(this); + } else if (cls == NextAlarmController.class) { + obj = new FakeNextAlarmController(this); + } else if (cls == NetworkController.class) { + obj = new FakeNetworkController(this); + } else if (cls == PluginManager.class) { + obj = new FakePluginManager(this); + } else if (cls == TunerService.class) { + obj = new FakeTunerService(this); + } else if (cls == StatusBarIconController.class) { + obj = new FakeStatusBarIconController(this); + } else if (cls == ConfigurationController.class) { + obj = new FakeConfigurationController(this); + } else { + Assert.fail(cls.getName() + " is not supported by LeakCheckedTest yet"); + } + mLeakCheckers.put(cls, obj); + } + return (T) obj; + } + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/os/FakeHandler.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/os/FakeHandler.java new file mode 100644 index 000000000000..5a7d4b5e54b3 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/os/FakeHandler.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2017 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.utils.os; + +import android.os.Handler; +import android.os.Looper; +import android.os.Message; + +import java.util.ArrayList; + +/** + * A handler that allows control over when to dispatch messages and callbacks. + * + * WARNING: Because most Handler methods are final, the only thing this handler can intercept + * are sending messages and posting runnables, but *NOT* removing messages nor runnables. + * It also *CANNOT* intercept messages posted to the front of queue. + */ +public class FakeHandler extends Handler { + + private Mode mMode = Mode.IMMEDIATE; + private ArrayList mQueuedMessages = new ArrayList<>(); + + public FakeHandler(Looper looper) { + super(looper); + } + + @Override + public boolean sendMessageAtTime(Message msg, long uptimeMillis) { + mQueuedMessages.add(msg); + if (mMode == Mode.IMMEDIATE) { + dispatchQueuedMessages(); + } + return true; + } + + public void setMode(Mode mode) { + mMode = mode; + } + + /** + * Dispatch any messages that have been queued on the calling thread. + */ + public void dispatchQueuedMessages() { + ArrayList messages = new ArrayList<>(mQueuedMessages); + mQueuedMessages.clear(); + for (Message msg : messages) { + dispatchMessage(msg); + } + } + + public enum Mode { + /** Messages are dispatched immediately on the calling thread. */ + IMMEDIATE, + /** Messages are queued until {@link #dispatchQueuedMessages()} is called. */ + QUEUEING, + } +} -- cgit v1.2.3-59-g8ed1b