Merge "LightsOut has its own controller"
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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() + "]";
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user