Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2018 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file |
| 5 | * except in compliance with the License. You may obtain a copy of the License at |
| 6 | * |
| 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | * |
| 9 | * Unless required by applicable law or agreed to in writing, software distributed under the |
| 10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 11 | * KIND, either express or implied. See the License for the specific language governing |
| 12 | * permissions and limitations under the License. |
| 13 | */ |
| 14 | |
| 15 | package com.android.systemui.statusbar.phone; |
| 16 | |
Charles Chen | f3d295c | 2018-11-30 18:15:21 +0800 | [diff] [blame] | 17 | import static android.view.Display.DEFAULT_DISPLAY; |
| 18 | |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 19 | import static org.junit.Assert.assertFalse; |
| 20 | import static org.mockito.Mockito.mock; |
Lucas Dupin | 086c6fc | 2018-10-16 18:06:43 -0700 | [diff] [blame] | 21 | import static org.mockito.Mockito.when; |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 22 | |
| 23 | import android.app.Notification; |
| 24 | import android.app.StatusBarManager; |
| 25 | import android.content.Context; |
| 26 | import android.metrics.LogMaker; |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 27 | import android.support.test.metricshelper.MetricsAsserts; |
| 28 | import android.testing.AndroidTestingRunner; |
| 29 | import android.testing.TestableLooper; |
| 30 | import android.testing.TestableLooper.RunWithLooper; |
| 31 | import android.view.ViewGroup; |
| 32 | |
Brett Chabot | 84151d9 | 2019-02-27 15:37:59 -0800 | [diff] [blame] | 33 | import androidx.test.filters.SmallTest; |
| 34 | |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 35 | import com.android.internal.logging.MetricsLogger; |
| 36 | import com.android.internal.logging.nano.MetricsProto.MetricsEvent; |
| 37 | import com.android.internal.logging.testing.FakeMetricsLogger; |
Lucas Dupin | d236ee3 | 2019-10-08 15:33:59 -0700 | [diff] [blame] | 38 | import com.android.systemui.InitController; |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 39 | import com.android.systemui.SysuiTestCase; |
Lucas Dupin | d236ee3 | 2019-10-08 15:33:59 -0700 | [diff] [blame] | 40 | import com.android.systemui.plugins.statusbar.StatusBarStateController; |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 41 | import com.android.systemui.statusbar.CommandQueue; |
Heemin Seog | 98df697 | 2019-12-05 13:01:38 -0800 | [diff] [blame] | 42 | import com.android.systemui.statusbar.KeyguardIndicationController; |
Lucas Dupin | d236ee3 | 2019-10-08 15:33:59 -0700 | [diff] [blame] | 43 | import com.android.systemui.statusbar.NotificationLockscreenUserManager; |
| 44 | import com.android.systemui.statusbar.NotificationMediaManager; |
| 45 | import com.android.systemui.statusbar.NotificationRemoteInputManager; |
| 46 | import com.android.systemui.statusbar.NotificationViewHierarchyManager; |
| 47 | import com.android.systemui.statusbar.RemoteInputController; |
| 48 | import com.android.systemui.statusbar.SysuiStatusBarStateController; |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 49 | import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; |
Selim Cinek | 5454a0d | 2019-07-30 17:14:50 -0700 | [diff] [blame] | 50 | import com.android.systemui.statusbar.notification.DynamicPrivacyController; |
Gus Prevas | b43dc65 | 2018-12-20 13:11:45 -0500 | [diff] [blame] | 51 | import com.android.systemui.statusbar.notification.NotificationAlertingManager; |
Lucas Dupin | d236ee3 | 2019-10-08 15:33:59 -0700 | [diff] [blame] | 52 | import com.android.systemui.statusbar.notification.NotificationEntryManager; |
| 53 | import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider; |
| 54 | import com.android.systemui.statusbar.notification.VisualStabilityManager; |
Ned Burns | f81c4c4 | 2019-01-07 14:10:43 -0500 | [diff] [blame] | 55 | import com.android.systemui.statusbar.notification.collection.NotificationEntry; |
Beverly | 79c89ec | 2019-12-13 10:33:01 -0500 | [diff] [blame] | 56 | import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; |
Ned Burns | c586467 | 2019-02-20 12:57:29 -0500 | [diff] [blame] | 57 | import com.android.systemui.statusbar.notification.collection.NotificationRowBinderImpl; |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 58 | import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; |
Lucas Dupin | d236ee3 | 2019-10-08 15:33:59 -0700 | [diff] [blame] | 59 | import com.android.systemui.statusbar.notification.row.NotificationGutsManager; |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 60 | import com.android.systemui.statusbar.notification.stack.NotificationListContainer; |
Lucas Dupin | d236ee3 | 2019-10-08 15:33:59 -0700 | [diff] [blame] | 61 | import com.android.systemui.statusbar.policy.KeyguardStateController; |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 62 | |
| 63 | import org.junit.Before; |
| 64 | import org.junit.Test; |
| 65 | import org.junit.runner.RunWith; |
| 66 | |
Lucas Dupin | d236ee3 | 2019-10-08 15:33:59 -0700 | [diff] [blame] | 67 | import java.util.ArrayList; |
| 68 | |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 69 | @SmallTest |
| 70 | @RunWith(AndroidTestingRunner.class) |
Aaron Heuckroth | 96cd93f | 2018-11-20 11:14:40 -0500 | [diff] [blame] | 71 | @RunWithLooper() |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 72 | public class StatusBarNotificationPresenterTest extends SysuiTestCase { |
| 73 | |
| 74 | |
Heemin Seog | bd9bcbf | 2019-12-04 17:07:32 -0800 | [diff] [blame] | 75 | private StatusBarNotificationPresenter mStatusBarNotificationPresenter; |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 76 | private CommandQueue mCommandQueue; |
| 77 | private FakeMetricsLogger mMetricsLogger; |
| 78 | private ShadeController mShadeController = mock(ShadeController.class); |
Heemin Seog | bd9bcbf | 2019-12-04 17:07:32 -0800 | [diff] [blame] | 79 | private StatusBar mStatusBar = mock(StatusBar.class); |
Dave Mankoff | 71fca1a | 2019-12-19 14:16:32 -0500 | [diff] [blame] | 80 | private InitController mInitController = new InitController(); |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 81 | |
| 82 | @Before |
| 83 | public void setup() { |
Lucas Dupin | d236ee3 | 2019-10-08 15:33:59 -0700 | [diff] [blame] | 84 | NotificationRemoteInputManager notificationRemoteInputManager = |
| 85 | mock(NotificationRemoteInputManager.class); |
| 86 | when(notificationRemoteInputManager.getController()) |
| 87 | .thenReturn(mock(RemoteInputController.class)); |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 88 | mMetricsLogger = new FakeMetricsLogger(); |
| 89 | mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger); |
Charles Chen | f3d295c | 2018-11-30 18:15:21 +0800 | [diff] [blame] | 90 | mCommandQueue = new CommandQueue(mContext); |
Lucas Dupin | d236ee3 | 2019-10-08 15:33:59 -0700 | [diff] [blame] | 91 | mDependency.injectTestDependency(StatusBarStateController.class, |
| 92 | mock(SysuiStatusBarStateController.class)); |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 93 | mDependency.injectTestDependency(ShadeController.class, mShadeController); |
Lucas Dupin | d236ee3 | 2019-10-08 15:33:59 -0700 | [diff] [blame] | 94 | mDependency.injectTestDependency(NotificationRemoteInputManager.class, |
| 95 | notificationRemoteInputManager); |
| 96 | mDependency.injectMockDependency(NotificationViewHierarchyManager.class); |
| 97 | mDependency.injectMockDependency(NotificationRemoteInputManager.Callback.class); |
| 98 | mDependency.injectMockDependency(NotificationLockscreenUserManager.class); |
| 99 | mDependency.injectMockDependency(NotificationInterruptionStateProvider.class); |
| 100 | mDependency.injectMockDependency(NotificationMediaManager.class); |
| 101 | mDependency.injectMockDependency(VisualStabilityManager.class); |
| 102 | mDependency.injectMockDependency(NotificationGutsManager.class); |
| 103 | mDependency.injectMockDependency(StatusBarWindowController.class); |
Lucas Dupin | d236ee3 | 2019-10-08 15:33:59 -0700 | [diff] [blame] | 104 | NotificationEntryManager entryManager = |
| 105 | mDependency.injectMockDependency(NotificationEntryManager.class); |
Evan Laird | 181de62 | 2019-10-24 09:53:02 -0400 | [diff] [blame] | 106 | when(entryManager.getActiveNotificationsForCurrentUser()).thenReturn(new ArrayList<>()); |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 107 | |
Lucas Dupin | 086c6fc | 2018-10-16 18:06:43 -0700 | [diff] [blame] | 108 | StatusBarWindowView statusBarWindowView = mock(StatusBarWindowView.class); |
| 109 | when(statusBarWindowView.getResources()).thenReturn(mContext.getResources()); |
Heemin Seog | bd9bcbf | 2019-12-04 17:07:32 -0800 | [diff] [blame] | 110 | mStatusBarNotificationPresenter = new StatusBarNotificationPresenter(mContext, |
Dave Mankoff | 59b9496 | 2019-12-16 16:42:15 -0500 | [diff] [blame] | 111 | mock(NotificationPanelViewController.class), mock(HeadsUpManagerPhone.class), |
Lucas Dupin | 086c6fc | 2018-10-16 18:06:43 -0700 | [diff] [blame] | 112 | statusBarWindowView, mock(NotificationListContainerViewGroup.class), |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 113 | mock(DozeScrimController.class), mock(ScrimController.class), |
Selim Cinek | 5454a0d | 2019-07-30 17:14:50 -0700 | [diff] [blame] | 114 | mock(ActivityLaunchAnimator.class), mock(DynamicPrivacyController.class), |
Ned Burns | c586467 | 2019-02-20 12:57:29 -0500 | [diff] [blame] | 115 | mock(NotificationAlertingManager.class), |
Dave Mankoff | bcaca8a | 2019-10-31 18:04:08 -0400 | [diff] [blame] | 116 | mock(NotificationRowBinderImpl.class), mock(KeyguardStateController.class), |
Heemin Seog | 98df697 | 2019-12-05 13:01:38 -0800 | [diff] [blame] | 117 | mock(KeyguardIndicationController.class), |
Dave Mankoff | 71fca1a | 2019-12-19 14:16:32 -0500 | [diff] [blame] | 118 | mStatusBar, mock(ShadeControllerImpl.class), mCommandQueue, mInitController); |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 119 | } |
| 120 | |
| 121 | @Test |
| 122 | public void testHeadsUp_disabledStatusBar() { |
| 123 | Notification n = new Notification.Builder(getContext(), "a").build(); |
Ned Burns | 636c379 | 2019-09-11 16:59:07 -0400 | [diff] [blame] | 124 | NotificationEntry entry = new NotificationEntryBuilder() |
| 125 | .setPkg("a") |
| 126 | .setOpPkg("a") |
| 127 | .setTag("a") |
| 128 | .setNotification(n) |
| 129 | .build(); |
Charles Chen | f3d295c | 2018-11-30 18:15:21 +0800 | [diff] [blame] | 130 | mCommandQueue.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_EXPAND, 0, |
| 131 | false /* animate */); |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 132 | TestableLooper.get(this).processAllMessages(); |
| 133 | |
| 134 | assertFalse("The panel shouldn't allow heads up while disabled", |
Heemin Seog | bd9bcbf | 2019-12-04 17:07:32 -0800 | [diff] [blame] | 135 | mStatusBarNotificationPresenter.canHeadsUp(entry, entry.getSbn())); |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 136 | } |
| 137 | |
| 138 | @Test |
| 139 | public void testHeadsUp_disabledNotificationShade() { |
| 140 | Notification n = new Notification.Builder(getContext(), "a").build(); |
Ned Burns | 636c379 | 2019-09-11 16:59:07 -0400 | [diff] [blame] | 141 | NotificationEntry entry = new NotificationEntryBuilder() |
| 142 | .setPkg("a") |
| 143 | .setOpPkg("a") |
| 144 | .setTag("a") |
| 145 | .setNotification(n) |
| 146 | .build(); |
Charles Chen | f3d295c | 2018-11-30 18:15:21 +0800 | [diff] [blame] | 147 | mCommandQueue.disable(DEFAULT_DISPLAY, 0, StatusBarManager.DISABLE2_NOTIFICATION_SHADE, |
| 148 | false /* animate */); |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 149 | TestableLooper.get(this).processAllMessages(); |
| 150 | |
| 151 | assertFalse("The panel shouldn't allow heads up while notitifcation shade disabled", |
Heemin Seog | bd9bcbf | 2019-12-04 17:07:32 -0800 | [diff] [blame] | 152 | mStatusBarNotificationPresenter.canHeadsUp(entry, entry.getSbn())); |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 153 | } |
| 154 | |
| 155 | @Test |
| 156 | public void onActivatedMetrics() { |
| 157 | ActivatableNotificationView view = mock(ActivatableNotificationView.class); |
Heemin Seog | bd9bcbf | 2019-12-04 17:07:32 -0800 | [diff] [blame] | 158 | mStatusBarNotificationPresenter.onActivated(view); |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 159 | |
| 160 | MetricsAsserts.assertHasLog("missing lockscreen note tap log", |
| 161 | mMetricsLogger.getLogs(), |
| 162 | new LogMaker(MetricsEvent.ACTION_LS_NOTE) |
| 163 | .setType(MetricsEvent.TYPE_ACTION)); |
| 164 | } |
| 165 | |
| 166 | // We need this because mockito doesn't know how to construct a mock that extends ViewGroup |
| 167 | // and implements NotificationListContainer without it because of classloader issues. |
| 168 | private abstract static class NotificationListContainerViewGroup extends ViewGroup |
| 169 | implements NotificationListContainer { |
| 170 | |
| 171 | public NotificationListContainerViewGroup(Context context) { |
| 172 | super(context); |
| 173 | } |
| 174 | } |
| 175 | } |
| 176 | |