Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2020 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package com.android.systemui.globalactions; |
| 18 | |
Aran Ink | cf03827 | 2020-03-31 17:48:37 -0400 | [diff] [blame] | 19 | import static junit.framework.Assert.assertEquals; |
| 20 | |
| 21 | import static org.mockito.ArgumentMatchers.any; |
| 22 | import static org.mockito.Mockito.doReturn; |
| 23 | import static org.mockito.Mockito.spy; |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 24 | import static org.mockito.Mockito.times; |
| 25 | import static org.mockito.Mockito.verify; |
Fabian Kozynski | b6a2037 | 2020-04-01 09:36:43 -0400 | [diff] [blame] | 26 | import static org.mockito.Mockito.when; |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 27 | |
| 28 | import android.app.IActivityManager; |
| 29 | import android.app.admin.DevicePolicyManager; |
| 30 | import android.app.trust.TrustManager; |
| 31 | import android.content.ContentResolver; |
| 32 | import android.content.res.Resources; |
| 33 | import android.media.AudioManager; |
| 34 | import android.net.ConnectivityManager; |
Matt Pietal | 677981d | 2020-04-24 14:38:32 -0400 | [diff] [blame] | 35 | import android.os.Handler; |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 36 | import android.os.UserManager; |
| 37 | import android.service.dreams.IDreamManager; |
| 38 | import android.telephony.TelephonyManager; |
| 39 | import android.testing.AndroidTestingRunner; |
| 40 | import android.testing.TestableLooper; |
Chris Wren | af4ce846 | 2020-04-06 17:36:10 -0400 | [diff] [blame] | 41 | import android.util.FeatureFlagUtils; |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 42 | import android.view.IWindowManager; |
| 43 | |
| 44 | import androidx.test.filters.SmallTest; |
| 45 | |
| 46 | import com.android.internal.logging.MetricsLogger; |
| 47 | import com.android.internal.logging.UiEventLogger; |
| 48 | import com.android.internal.statusbar.IStatusBarService; |
| 49 | import com.android.internal.widget.LockPatternUtils; |
| 50 | import com.android.systemui.SysuiTestCase; |
| 51 | import com.android.systemui.broadcast.BroadcastDispatcher; |
| 52 | import com.android.systemui.colorextraction.SysuiColorExtractor; |
| 53 | import com.android.systemui.controls.controller.ControlsController; |
| 54 | import com.android.systemui.controls.management.ControlsListingController; |
| 55 | import com.android.systemui.controls.ui.ControlsUiController; |
| 56 | import com.android.systemui.plugins.ActivityStarter; |
| 57 | import com.android.systemui.plugins.GlobalActions; |
| 58 | import com.android.systemui.statusbar.BlurUtils; |
| 59 | import com.android.systemui.statusbar.NotificationShadeDepthController; |
| 60 | import com.android.systemui.statusbar.phone.NotificationShadeWindowController; |
| 61 | import com.android.systemui.statusbar.policy.ConfigurationController; |
| 62 | import com.android.systemui.statusbar.policy.KeyguardStateController; |
Fabian Kozynski | b6a2037 | 2020-04-01 09:36:43 -0400 | [diff] [blame] | 63 | import com.android.systemui.util.RingerModeLiveData; |
| 64 | import com.android.systemui.util.RingerModeTracker; |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 65 | |
| 66 | import org.junit.Before; |
| 67 | import org.junit.Test; |
| 68 | import org.junit.runner.RunWith; |
| 69 | import org.mockito.Mock; |
| 70 | import org.mockito.MockitoAnnotations; |
| 71 | |
| 72 | import java.util.concurrent.Executor; |
| 73 | |
| 74 | @SmallTest |
| 75 | @RunWith(AndroidTestingRunner.class) |
Chris Wren | af4ce846 | 2020-04-06 17:36:10 -0400 | [diff] [blame] | 76 | @TestableLooper.RunWithLooper() |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 77 | public class GlobalActionsDialogTest extends SysuiTestCase { |
| 78 | private GlobalActionsDialog mGlobalActionsDialog; |
| 79 | |
| 80 | @Mock private GlobalActions.GlobalActionsManager mWindowManagerFuncs; |
| 81 | @Mock private AudioManager mAudioManager; |
| 82 | @Mock private IDreamManager mDreamManager; |
| 83 | @Mock private DevicePolicyManager mDevicePolicyManager; |
| 84 | @Mock private LockPatternUtils mLockPatternUtils; |
| 85 | @Mock private BroadcastDispatcher mBroadcastDispatcher; |
| 86 | @Mock private ConnectivityManager mConnectivityManager; |
| 87 | @Mock private TelephonyManager mTelephonyManager; |
| 88 | @Mock private ContentResolver mContentResolver; |
| 89 | @Mock private Resources mResources; |
| 90 | @Mock private ConfigurationController mConfigurationController; |
| 91 | @Mock private ActivityStarter mActivityStarter; |
| 92 | @Mock private KeyguardStateController mKeyguardStateController; |
| 93 | @Mock private UserManager mUserManager; |
| 94 | @Mock private TrustManager mTrustManager; |
| 95 | @Mock private IActivityManager mActivityManager; |
| 96 | @Mock private MetricsLogger mMetricsLogger; |
| 97 | @Mock private NotificationShadeDepthController mDepthController; |
| 98 | @Mock private SysuiColorExtractor mColorExtractor; |
| 99 | @Mock private IStatusBarService mStatusBarService; |
| 100 | @Mock private BlurUtils mBlurUtils; |
| 101 | @Mock private NotificationShadeWindowController mNotificationShadeWindowController; |
| 102 | @Mock private ControlsUiController mControlsUiController; |
| 103 | @Mock private IWindowManager mWindowManager; |
| 104 | @Mock private Executor mBackgroundExecutor; |
| 105 | @Mock private ControlsListingController mControlsListingController; |
| 106 | @Mock private ControlsController mControlsController; |
| 107 | @Mock private UiEventLogger mUiEventLogger; |
Fabian Kozynski | b6a2037 | 2020-04-01 09:36:43 -0400 | [diff] [blame] | 108 | @Mock private RingerModeTracker mRingerModeTracker; |
| 109 | @Mock private RingerModeLiveData mRingerModeLiveData; |
Matt Pietal | 677981d | 2020-04-24 14:38:32 -0400 | [diff] [blame] | 110 | @Mock private Handler mHandler; |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 111 | |
| 112 | private TestableLooper mTestableLooper; |
| 113 | |
| 114 | @Before |
| 115 | public void setUp() throws Exception { |
| 116 | MockitoAnnotations.initMocks(this); |
| 117 | mTestableLooper = TestableLooper.get(this); |
| 118 | allowTestableLooperAsMainThread(); |
Fabian Kozynski | b6a2037 | 2020-04-01 09:36:43 -0400 | [diff] [blame] | 119 | |
| 120 | when(mRingerModeTracker.getRingerMode()).thenReturn(mRingerModeLiveData); |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 121 | mGlobalActionsDialog = new GlobalActionsDialog(mContext, |
| 122 | mWindowManagerFuncs, |
| 123 | mAudioManager, |
| 124 | mDreamManager, |
| 125 | mDevicePolicyManager, |
| 126 | mLockPatternUtils, |
| 127 | mBroadcastDispatcher, |
| 128 | mConnectivityManager, |
| 129 | mTelephonyManager, |
| 130 | mContentResolver, |
| 131 | null, |
| 132 | mResources, |
| 133 | mConfigurationController, |
| 134 | mActivityStarter, |
| 135 | mKeyguardStateController, |
| 136 | mUserManager, |
| 137 | mTrustManager, |
| 138 | mActivityManager, |
| 139 | null, |
| 140 | mMetricsLogger, |
| 141 | mDepthController, |
| 142 | mColorExtractor, |
| 143 | mStatusBarService, |
| 144 | mBlurUtils, |
| 145 | mNotificationShadeWindowController, |
| 146 | mControlsUiController, |
| 147 | mWindowManager, |
| 148 | mBackgroundExecutor, |
| 149 | mControlsListingController, |
| 150 | mControlsController, |
Fabian Kozynski | b6a2037 | 2020-04-01 09:36:43 -0400 | [diff] [blame] | 151 | mUiEventLogger, |
Matt Pietal | 677981d | 2020-04-24 14:38:32 -0400 | [diff] [blame] | 152 | mRingerModeTracker, |
| 153 | mHandler |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 154 | ); |
Chris Wren | af4ce846 | 2020-04-06 17:36:10 -0400 | [diff] [blame] | 155 | mGlobalActionsDialog.setZeroDialogPressDelayForTesting(); |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 156 | } |
Chris Wren | af4ce846 | 2020-04-06 17:36:10 -0400 | [diff] [blame] | 157 | |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 158 | @Test |
Chris Wren | 9756a00 | 2020-05-12 16:46:27 -0400 | [diff] [blame] | 159 | public void testShouldLogShow() { |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 160 | mGlobalActionsDialog.onShow(null); |
Chris Wren | af4ce846 | 2020-04-06 17:36:10 -0400 | [diff] [blame] | 161 | mTestableLooper.processAllMessages(); |
| 162 | verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_POWER_MENU_OPEN); |
| 163 | } |
| 164 | |
| 165 | @Test |
Chris Wren | 9756a00 | 2020-05-12 16:46:27 -0400 | [diff] [blame] | 166 | public void testShouldLogDismiss() { |
| 167 | mGlobalActionsDialog.onDismiss(mGlobalActionsDialog.mDialog); |
| 168 | mTestableLooper.processAllMessages(); |
| 169 | verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_POWER_MENU_CLOSE); |
| 170 | } |
| 171 | |
| 172 | @Test |
Chris Wren | af4ce846 | 2020-04-06 17:36:10 -0400 | [diff] [blame] | 173 | public void testShouldLogBugreportPress() throws InterruptedException { |
| 174 | GlobalActionsDialog.BugReportAction bugReportAction = |
| 175 | mGlobalActionsDialog.makeBugReportActionForTesting(); |
| 176 | bugReportAction.onPress(); |
| 177 | verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_BUGREPORT_PRESS); |
| 178 | } |
| 179 | |
| 180 | @Test |
| 181 | public void testShouldLogBugreportLongPress() { |
| 182 | GlobalActionsDialog.BugReportAction bugReportAction = |
| 183 | mGlobalActionsDialog.makeBugReportActionForTesting(); |
| 184 | bugReportAction.onLongPress(); |
| 185 | verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_BUGREPORT_LONG_PRESS); |
| 186 | } |
| 187 | |
| 188 | @Test |
| 189 | public void testShouldLogEmergencyDialerPress() { |
| 190 | GlobalActionsDialog.EmergencyDialerAction emergencyDialerAction = |
| 191 | mGlobalActionsDialog.makeEmergencyDialerActionForTesting(); |
| 192 | emergencyDialerAction.onPress(); |
| 193 | verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_EMERGENCY_DIALER_PRESS); |
| 194 | } |
| 195 | |
| 196 | @Test |
| 197 | public void testShouldLogScreenshotPress() { |
| 198 | GlobalActionsDialog.ScreenshotAction screenshotAction = |
| 199 | mGlobalActionsDialog.makeScreenshotActionForTesting(); |
| 200 | screenshotAction.onPress(); |
| 201 | verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_SCREENSHOT_PRESS); |
| 202 | } |
| 203 | |
| 204 | @Test |
| 205 | public void testShouldLogScreenshotLongPress() { |
| 206 | FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SCREENRECORD_LONG_PRESS, true); |
| 207 | GlobalActionsDialog.ScreenshotAction screenshotAction = |
| 208 | mGlobalActionsDialog.makeScreenshotActionForTesting(); |
| 209 | screenshotAction.onLongPress(); |
| 210 | verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_SCREENSHOT_LONG_PRESS); |
| 211 | } |
| 212 | |
| 213 | private void verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent event) { |
| 214 | mTestableLooper.processAllMessages(); |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 215 | verify(mUiEventLogger, times(1)) |
Chris Wren | af4ce846 | 2020-04-06 17:36:10 -0400 | [diff] [blame] | 216 | .log(event); |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 217 | } |
Aran Ink | cf03827 | 2020-03-31 17:48:37 -0400 | [diff] [blame] | 218 | |
| 219 | @Test |
| 220 | public void testCreateActionItems_maxThree() { |
| 221 | mGlobalActionsDialog = spy(mGlobalActionsDialog); |
| 222 | // allow 3 items to be shown |
| 223 | doReturn(3).when(mGlobalActionsDialog).getMaxShownPowerItems(); |
| 224 | // ensure items are not blocked by keyguard or device provisioning |
| 225 | doReturn(true).when(mGlobalActionsDialog).shouldShowAction(any()); |
| 226 | String[] actions = { |
| 227 | GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY, |
| 228 | GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER, |
| 229 | GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART, |
| 230 | GlobalActionsDialog.GLOBAL_ACTION_KEY_SCREENSHOT, |
| 231 | }; |
| 232 | doReturn(actions).when(mGlobalActionsDialog).getDefaultActions(); |
| 233 | mGlobalActionsDialog.createActionItems(); |
| 234 | |
| 235 | assertEquals(3, mGlobalActionsDialog.mItems.size()); |
| 236 | assertEquals(1, mGlobalActionsDialog.mOverflowItems.size()); |
| 237 | } |
| 238 | |
| 239 | @Test |
| 240 | public void testCreateActionItems_maxAny() { |
| 241 | mGlobalActionsDialog = spy(mGlobalActionsDialog); |
| 242 | // allow any number of power menu items to be shown |
| 243 | doReturn(Integer.MAX_VALUE).when(mGlobalActionsDialog).getMaxShownPowerItems(); |
| 244 | // ensure items are not blocked by keyguard or device provisioning |
| 245 | doReturn(true).when(mGlobalActionsDialog).shouldShowAction(any()); |
| 246 | String[] actions = { |
| 247 | GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY, |
| 248 | GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER, |
| 249 | GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART, |
| 250 | GlobalActionsDialog.GLOBAL_ACTION_KEY_SCREENSHOT, |
| 251 | }; |
| 252 | doReturn(actions).when(mGlobalActionsDialog).getDefaultActions(); |
| 253 | mGlobalActionsDialog.createActionItems(); |
| 254 | |
| 255 | assertEquals(4, mGlobalActionsDialog.mItems.size()); |
| 256 | assertEquals(0, mGlobalActionsDialog.mOverflowItems.size()); |
| 257 | } |
| 258 | |
| 259 | @Test |
| 260 | public void testCreateActionItems_maxThree_itemNotShown() { |
| 261 | mGlobalActionsDialog = spy(mGlobalActionsDialog); |
| 262 | // allow only 3 items to be shown |
| 263 | doReturn(3).when(mGlobalActionsDialog).getMaxShownPowerItems(); |
| 264 | String[] actions = { |
| 265 | GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY, |
| 266 | // screenshot blocked because device not provisioned |
| 267 | GlobalActionsDialog.GLOBAL_ACTION_KEY_SCREENSHOT, |
| 268 | GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER, |
| 269 | GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART, |
| 270 | }; |
| 271 | doReturn(actions).when(mGlobalActionsDialog).getDefaultActions(); |
| 272 | mGlobalActionsDialog.createActionItems(); |
| 273 | |
| 274 | assertEquals(3, mGlobalActionsDialog.mItems.size()); |
| 275 | assertEquals(0, mGlobalActionsDialog.mOverflowItems.size()); |
| 276 | } |
Chris Wren | 65a70c9 | 2020-04-02 10:43:46 -0400 | [diff] [blame] | 277 | } |