LightsOut has its own controller

Apps can request a low profile mode where status bar and
navigation icons dim. In this mode, a notification dot appears
where the notification icons would appear if they would be there
outside of this mode.

This CL moves the logic for this dot to its own controller

Test: manual (ie: NY times app)
Test: atest LightsOutNotifControllerTest
Change-Id: I46dfab2c7f83cc26c25c257ee02d84058b127036
This commit is contained in:
Beverly
2019-11-04 09:55:29 -05:00
parent 336aebcdb6
commit ea2010c1ec
9 changed files with 448 additions and 67 deletions

View File

@@ -116,6 +116,7 @@ import com.android.systemui.statusbar.phone.DozeServiceHost;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.LightsOutNotifController;
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -306,6 +307,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
RemoteInputUriController remoteInputUriController,
Optional<Divider> dividerOptional,
SuperStatusBarViewFactory superStatusBarViewFactory,
LightsOutNotifController lightsOutNotifController,
/* Car Settings injected components. */
CarNavigationBarController carNavigationBarController) {
super(
@@ -376,6 +378,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
pluginManager,
remoteInputUriController,
dividerOptional,
lightsOutNotifController,
superStatusBarViewFactory);
mScrimController = scrimController;
mCarNavigationBarController = carNavigationBarController;

View File

@@ -71,6 +71,7 @@ import com.android.systemui.statusbar.phone.DozeServiceHost;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.LightsOutNotifController;
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -175,6 +176,7 @@ public class CarStatusBarModule {
RemoteInputUriController remoteInputUriController,
Optional<Divider> dividerOptional,
SuperStatusBarViewFactory superStatusBarViewFactory,
LightsOutNotifController lightsOutNotifController,
CarNavigationBarController carNavigationBarController) {
return new CarStatusBar(
context,
@@ -244,6 +246,7 @@ public class CarStatusBarModule {
remoteInputUriController,
dividerOptional,
superStatusBarViewFactory,
lightsOutNotifController,
carNavigationBarController);
}
}

View File

@@ -0,0 +1,179 @@
/*
* 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.phone;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.Nullable;
import android.view.View;
import android.view.WindowInsetsController;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.view.AppearanceRegion;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* Apps can request a low profile mode {@link View.SYSTEM_UI_FLAG_LOW_PROFILE}
* where status bar and navigation icons dim. In this mode, a notification dot appears
* where the notification icons would appear if they would be shown outside of this mode.
*
* This controller shows and hides the notification dot in the status bar to indicate
* whether there are notifications when the device is in {@link View.SYSTEM_UI_FLAG_LOW_PROFILE}.
*/
@Singleton
public class LightsOutNotifController {
private final CommandQueue mCommandQueue;
private final NotificationEntryManager mEntryManager;
private final WindowManager mWindowManager;
/** @see android.view.WindowInsetsController#setSystemBarsAppearance(int) */
@VisibleForTesting @WindowInsetsController.Appearance int mAppearance;
private int mDisplayId;
private View mLightsOutNotifView;
@Inject
LightsOutNotifController(WindowManager windowManager,
NotificationEntryManager entryManager,
CommandQueue commandQueue) {
mWindowManager = windowManager;
mEntryManager = entryManager;
mCommandQueue = commandQueue;
}
/**
* Sets the notification dot view after it is created in the StatusBar.
* This is the view this controller will show and hide depending on whether:
* 1. there are active notifications
* 2. an app has requested {@link View.SYSTEM_UI_FLAG_LOW_PROFILE}
*/
void setLightsOutNotifView(View lightsOutNotifView) {
destroy();
mLightsOutNotifView = lightsOutNotifView;
if (mLightsOutNotifView != null) {
mLightsOutNotifView.setVisibility(View.GONE);
mLightsOutNotifView.setAlpha(0f);
init();
}
}
private void destroy() {
mEntryManager.removeNotificationEntryListener(mEntryListener);
mCommandQueue.removeCallback(mCallback);
}
private void init() {
mDisplayId = mWindowManager.getDefaultDisplay().getDisplayId();
mEntryManager.addNotificationEntryListener(mEntryListener);
mCommandQueue.addCallback(mCallback);
updateLightsOutView();
}
private boolean hasActiveNotifications() {
return !mEntryManager.getNotificationData().getActiveNotifications().isEmpty();
}
@VisibleForTesting
void updateLightsOutView() {
if (mLightsOutNotifView == null) {
return;
}
final boolean showDot = shouldShowDot();
if (showDot != isShowingDot()) {
if (showDot) {
mLightsOutNotifView.setAlpha(0f);
mLightsOutNotifView.setVisibility(View.VISIBLE);
}
mLightsOutNotifView.animate()
.alpha(showDot ? 1 : 0)
.setDuration(showDot ? 750 : 250)
.setInterpolator(new AccelerateInterpolator(2.0f))
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator a) {
mLightsOutNotifView.setAlpha(showDot ? 1 : 0);
mLightsOutNotifView.setVisibility(showDot ? View.VISIBLE : View.GONE);
}
})
.start();
}
}
@VisibleForTesting
boolean isShowingDot() {
return mLightsOutNotifView.getVisibility() == View.VISIBLE
&& mLightsOutNotifView.getAlpha() == 1.0f;
}
@VisibleForTesting
boolean shouldShowDot() {
return hasActiveNotifications() && areLightsOut();
}
@VisibleForTesting
boolean areLightsOut() {
return 0 != (mAppearance & APPEARANCE_LOW_PROFILE_BARS);
}
private final CommandQueue.Callbacks mCallback = new CommandQueue.Callbacks() {
@Override
public void onSystemBarAppearanceChanged(int displayId,
@WindowInsetsController.Appearance int appearance,
AppearanceRegion[] appearanceRegions,
boolean navbarColorManagedByIme) {
if (displayId != mDisplayId) {
return;
}
mAppearance = appearance;
updateLightsOutView();
}
};
private final NotificationEntryListener mEntryListener = new NotificationEntryListener() {
// Cares about notifications post-filtering
@Override
public void onNotificationAdded(NotificationEntry entry) {
updateLightsOutView();
}
@Override
public void onPostEntryUpdated(NotificationEntry entry) {
updateLightsOutView();
}
@Override
public void onEntryRemoved(@Nullable NotificationEntry entry,
NotificationVisibility visibility, boolean removedByUser) {
updateLightsOutView();
}
};
}

View File

@@ -141,12 +141,6 @@ public interface ShadeController {
*/
void onLaunchAnimationCancelled();
/**
* When notifications update, give the shade controller a chance to do thing in response to
* the new data set
*/
void updateAreThereNotifications();
/**
* Callback to notify the shade controller that a {@link ActivatableNotificationView} has become
* inactive

View File

@@ -47,8 +47,6 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARE
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
@@ -117,7 +115,6 @@ import android.view.WindowInsetsController.Appearance;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.AccelerateInterpolator;
import android.widget.DateTimeView;
import com.android.internal.annotations.VisibleForTesting;
@@ -399,6 +396,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private final RemoteInputUriController mRemoteInputUriController;
private final Optional<Divider> mDividerOptional;
private final SuperStatusBarViewFactory mSuperStatusBarViewFactory;
private final LightsOutNotifController mLightsOutNotifController;
// expanded notifications
protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -704,6 +702,7 @@ public class StatusBar extends SystemUI implements DemoMode,
PluginManager pluginManager,
RemoteInputUriController remoteInputUriController,
Optional<Divider> dividerOptional,
LightsOutNotifController lightsOutNotifController,
SuperStatusBarViewFactory superStatusBarViewFactory) {
super(context);
mFeatureFlags = featureFlags;
@@ -774,7 +773,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mDividerOptional = dividerOptional;
mSuperStatusBarViewFactory = superStatusBarViewFactory;
mLightsOutNotifController = lightsOutNotifController;
mBubbleExpandListener =
(isExpanding, key) -> {
mEntryManager.updateNotifications("onBubbleExpandChanged");
@@ -928,7 +927,6 @@ public class StatusBar extends SystemUI implements DemoMode,
mConfigurationController.addCallback(this);
// set the initial view visibility
Dependency.get(InitController.class).addPostInitTask(this::updateAreThereNotifications);
int disabledFlags1 = result.mDisabledFlags1;
int disabledFlags2 = result.mDisabledFlags2;
Dependency.get(InitController.class).addPostInitTask(
@@ -1057,8 +1055,10 @@ public class StatusBar extends SystemUI implements DemoMode,
mStatusBarStateController, mKeyguardBypassController,
mKeyguardStateController, mWakeUpCoordinator, mCommandQueue);
mHeadsUpAppearanceController.readFrom(oldController);
mLightsOutNotifController.setLightsOutNotifView(
mStatusBarView.findViewById(R.id.notification_lights_out));
mStatusBarWindowViewController.setStatusBarView(mStatusBarView);
updateAreThereNotifications();
checkBarModes();
}).getFragmentManager()
.beginTransaction()
@@ -1546,38 +1546,6 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
public void updateAreThereNotifications() {
if (SPEW) {
final boolean clearable = hasActiveNotifications() &&
mNotificationPanel.hasActiveClearableNotifications();
Log.d(TAG, "updateAreThereNotifications: N=" +
mEntryManager.getNotificationData().getActiveNotifications().size() + " any=" +
hasActiveNotifications() + " clearable=" + clearable);
}
if (mStatusBarView != null) {
final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
final boolean showDot = hasActiveNotifications() && !areLightsOn();
if (showDot != (nlo.getAlpha() == 1.0f)) {
if (showDot) {
nlo.setAlpha(0f);
nlo.setVisibility(View.VISIBLE);
}
nlo.animate()
.alpha(showDot ? 1 : 0)
.setDuration(showDot ? 750 : 250)
.setInterpolator(new AccelerateInterpolator(2.0f))
.setListener(showDot ? null : new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator _a) {
nlo.setVisibility(View.GONE);
}
})
.start();
}
}
}
private void updateReportRejectedTouchVisibility() {
if (mReportRejectedTouch == null) {
return;
@@ -2306,14 +2274,8 @@ public class StatusBar extends SystemUI implements DemoMode,
return;
}
boolean barModeChanged = false;
final int diff = mAppearance ^ appearance;
if (mAppearance != appearance) {
mAppearance = appearance;
// update low profile
if ((diff & APPEARANCE_LOW_PROFILE_BARS) != 0) {
updateAreThereNotifications();
}
barModeChanged = updateBarMode(barMode(mTransientShown, appearance));
}
mLightBarController.onStatusBarAppearanceChanged(appearanceRegions, barModeChanged,
@@ -2494,10 +2456,6 @@ public class StatusBar extends SystemUI implements DemoMode,
return mAppImmersive;
}
private boolean areLightsOn() {
return 0 == (mAppearance & APPEARANCE_LOW_PROFILE_BARS);
}
public static String viewInfo(View v) {
return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
+ ") " + v.getWidth() + "x" + v.getHeight() + "]";

View File

@@ -161,6 +161,7 @@ public class StatusBarModule {
PluginManager pluginManager,
RemoteInputUriController remoteInputUriController,
Optional<Divider> dividerOptional,
LightsOutNotifController lightsOutNotifController,
SuperStatusBarViewFactory superStatusBarViewFactory) {
return new StatusBar(
context,
@@ -230,6 +231,7 @@ public class StatusBarModule {
pluginManager,
remoteInputUriController,
dividerOptional,
lightsOutNotifController,
superStatusBarViewFactory);
}
}

View File

@@ -79,7 +79,8 @@ import java.util.ArrayList;
public class StatusBarNotificationPresenter implements NotificationPresenter,
ConfigurationController.ConfigurationListener,
NotificationRowBinderImpl.BindRowCallback {
NotificationRowBinderImpl.BindRowCallback,
CommandQueue.Callbacks {
private final LockscreenGestureLogger mLockscreenGestureLogger =
Dependency.get(LockscreenGestureLogger.class);
@@ -184,17 +185,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
NotificationListContainer notifListContainer = (NotificationListContainer) stackScroller;
Dependency.get(InitController.class).addPostInitTask(() -> {
NotificationEntryListener notificationEntryListener = new NotificationEntryListener() {
@Override
public void onNotificationAdded(NotificationEntry entry) {
// Recalculate the position of the sliding windows and the titles.
mShadeController.updateAreThereNotifications();
}
@Override
public void onPostEntryUpdated(NotificationEntry entry) {
mShadeController.updateAreThereNotifications();
}
@Override
public void onEntryRemoved(
@Nullable NotificationEntry entry,
@@ -333,7 +323,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
}
}
}
mShadeController.updateAreThereNotifications();
}
public boolean hasActiveNotifications() {

View File

@@ -0,0 +1,251 @@
/*
* 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.phone;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
import static com.android.internal.util.Preconditions.checkNotNull;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import android.view.Display;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.view.WindowManager;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
public class LightsOutNotifControllerTest extends SysuiTestCase {
private static final int LIGHTS_ON = 0;
private static final int LIGHTS_OUT = APPEARANCE_LOW_PROFILE_BARS;
@Mock private NotificationEntryManager mEntryManager;
@Mock private NotificationData mNotificationData;
@Mock private CommandQueue mCommandQueue;
@Mock private WindowManager mWindowManager;
@Mock private Display mDisplay;
@Captor private ArgumentCaptor<NotificationEntryListener> mListenerCaptor;
@Captor private ArgumentCaptor<CommandQueue.Callbacks> mCallbacksCaptor;
private View mLightsOutView;
private LightsOutNotifController mLightsOutNotifController;
private ArrayList<NotificationEntry> mActiveNotifications = new ArrayList<>();
private int mDisplayId;
private NotificationEntryListener mEntryListener;
private CommandQueue.Callbacks mCallbacks;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mDisplayId = mContext.getDisplayId();
mLightsOutView = new View(mContext);
when(mEntryManager.getNotificationData()).thenReturn(mNotificationData);
when(mNotificationData.getActiveNotifications()).thenReturn(mActiveNotifications);
when(mWindowManager.getDefaultDisplay()).thenReturn(mDisplay);
when(mDisplay.getDisplayId()).thenReturn(mDisplayId);
mLightsOutNotifController = new LightsOutNotifController(mWindowManager, mEntryManager,
mCommandQueue);
mLightsOutNotifController.setLightsOutNotifView(mLightsOutView);
// Capture the entry listener object so we can simulate events in tests below
verify(mEntryManager).addNotificationEntryListener(mListenerCaptor.capture());
mEntryListener = checkNotNull(mListenerCaptor.getValue());
// Capture the callback object so we can simulate callback events in tests below
verify(mCommandQueue).addCallback(mCallbacksCaptor.capture());
mCallbacks = checkNotNull(mCallbacksCaptor.getValue());
}
@Test
public void testAreLightsOut_lightsOut() {
mCallbacks.onSystemBarAppearanceChanged(
mDisplayId /* display id */,
LIGHTS_OUT /* appearance */,
null /* appearanceRegions */,
false /* navbarColorManagedByIme */);
assertTrue(mLightsOutNotifController.areLightsOut());
}
@Test
public void testAreLightsOut_lightsOn() {
mCallbacks.onSystemBarAppearanceChanged(
mDisplayId /* display id */,
LIGHTS_ON /* appearance */,
null /* appearanceRegions */,
false /* navbarColorManagedByIme */);
assertFalse(mLightsOutNotifController.areLightsOut());
}
@Test
public void testIsShowingDot_visible() {
mLightsOutView.setVisibility(View.VISIBLE);
mLightsOutView.setAlpha(1.0f);
assertTrue(mLightsOutNotifController.isShowingDot());
}
@Test
public void testIsShowingDot_gone() {
mLightsOutView.setVisibility(View.GONE);
mLightsOutView.setAlpha(0f);
assertFalse(mLightsOutNotifController.isShowingDot());
}
@Test
public void testLightsOut_withNotifs_onSystemBarAppearanceChanged() {
// GIVEN active visible notifications
mActiveNotifications.add(mock(NotificationEntry.class));
// WHEN lights out
mCallbacks.onSystemBarAppearanceChanged(
mDisplayId /* display id */,
LIGHTS_OUT /* appearance */,
null /* appearanceRegions */,
false /* navbarColorManagedByIme */);
// THEN we should show dot
assertTrue(mLightsOutNotifController.shouldShowDot());
assertIsShowingDot(true);
}
@Test
public void testLightsOut_withoutNotifs_onSystemBarAppearanceChanged() {
// GIVEN no active visible notifications
mActiveNotifications.clear();
// WHEN lights out
mCallbacks.onSystemBarAppearanceChanged(
mDisplayId /* display id */,
LIGHTS_OUT /* appearance */,
null /* appearanceRegions */,
false /* navbarColorManagedByIme */);
// THEN we shouldn't show the dot
assertFalse(mLightsOutNotifController.shouldShowDot());
assertIsShowingDot(false);
}
@Test
public void testLightsOn_afterLightsOut_onSystemBarAppearanceChanged() {
// GIVEN active visible notifications
mActiveNotifications.add(mock(NotificationEntry.class));
// WHEN lights on
mCallbacks.onSystemBarAppearanceChanged(
mDisplayId /* display id */,
LIGHTS_ON /* appearance */,
null /* appearanceRegions */,
false /* navbarColorManagedByIme */);
// THEN we shouldn't show the dot
assertFalse(mLightsOutNotifController.shouldShowDot());
assertIsShowingDot(false);
}
@Test
public void testEntryAdded() {
// GIVEN no visible notifications and lights out
mActiveNotifications.clear();
mLightsOutNotifController.mAppearance = LIGHTS_OUT;
mLightsOutNotifController.updateLightsOutView();
assertIsShowingDot(false);
// WHEN an active notification is added
mActiveNotifications.add(mock(NotificationEntry.class));
assertTrue(mLightsOutNotifController.shouldShowDot());
mEntryListener.onNotificationAdded(mock(NotificationEntry.class));
// THEN we should see the dot view
assertIsShowingDot(true);
}
@Test
public void testEntryRemoved() {
// GIVEN a visible notification and lights out
mActiveNotifications.add(mock(NotificationEntry.class));
mLightsOutNotifController.mAppearance = LIGHTS_OUT;
mLightsOutNotifController.updateLightsOutView();
assertIsShowingDot(true);
// WHEN all active notifications are removed
mActiveNotifications.clear();
assertFalse(mLightsOutNotifController.shouldShowDot());
mEntryListener.onEntryRemoved(mock(NotificationEntry.class), null, false);
// THEN we shouldn't see the dot view
assertIsShowingDot(false);
}
@Test
public void testEntryUpdated() {
// GIVEN no visible notifications and lights out
mActiveNotifications.clear();
mLightsOutNotifController.mAppearance = LIGHTS_OUT;
mLightsOutNotifController.updateLightsOutView();
assertIsShowingDot(false);
// WHEN an active notification is added
mActiveNotifications.add(mock(NotificationEntry.class));
assertTrue(mLightsOutNotifController.shouldShowDot());
mEntryListener.onPostEntryUpdated(mock(NotificationEntry.class));
// THEN we should see the dot view
assertIsShowingDot(true);
}
private void assertIsShowingDot(boolean isShowing) {
// cancel the animation so we can check the end state
final ViewPropertyAnimator animation = mLightsOutView.animate();
if (animation != null) {
animation.cancel();
}
if (isShowing) {
assertTrue(mLightsOutNotifController.isShowingDot());
} else {
assertFalse(mLightsOutNotifController.isShowingDot());
}
}
}

View File

@@ -237,6 +237,7 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private PluginManager mPluginManager;
@Mock private Divider mDivider;
@Mock private SuperStatusBarViewFactory mSuperStatusBarViewFactory;
@Mock private LightsOutNotifController mLightsOutNotifController;
@Before
public void setup() throws Exception {
@@ -376,6 +377,7 @@ public class StatusBarTest extends SysuiTestCase {
mPluginManager,
mRemoteInputUriController,
Optional.of(mDivider),
mLightsOutNotifController,
mSuperStatusBarViewFactory);
when(mStatusBarWindowView.findViewById(R.id.lock_icon_container)).thenReturn(