Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java +1 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ public class HeadsUpTouchHelper implements Gefingerpoken { mPanel.setPanelScrimMinFraction((float) expandedHeight / mPanel.getMaxPanelHeight()); mPanel.startExpandMotion(x, y, true /* startTracking */, expandedHeight); mPanel.startExpandingFromPeek(); // This call needs to be after the expansion start otherwise we will get a // flicker of one frame as it's not expanded yet. mHeadsUpManager.unpinAll(); Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +4 −0 Original line number Diff line number Diff line Loading @@ -407,6 +407,10 @@ public abstract class PanelView extends FrameLayout { return Math.abs(yDiff) >= Math.abs(xDiff); } protected void startExpandingFromPeek() { mStatusBar.handlePeekToExpandTransistion(); } protected void startExpandMotion(float newX, float newY, boolean startTracking, float expandedHeight) { mInitialOffsetOnTouch = expandedHeight; Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +12 −3 Original line number Diff line number Diff line Loading @@ -661,7 +661,7 @@ public class StatusBar extends SystemUI implements DemoMode, // Tracks notifications currently visible in mNotificationStackScroller and // emits visibility events via NoMan on changes. private final Runnable mVisibilityReporter = new Runnable() { protected final Runnable mVisibilityReporter = new Runnable() { private final ArraySet<NotificationVisibility> mTmpNewlyVisibleNotifications = new ArraySet<>(); private final ArraySet<NotificationVisibility> mTmpCurrentlyVisibleNotifications = Loading Loading @@ -3822,6 +3822,17 @@ public class StatusBar extends SystemUI implements DemoMode, } } void handlePeekToExpandTransistion() { try { // consider the transition from peek to expanded to be a panel open, // but not one that clears notification effects. int notificationLoad = mNotificationData.getActiveNotifications().size(); mBarService.onPanelRevealed(false, notificationLoad); } catch (RemoteException ex) { // Won't fail unless the world has ended. } } /** * The LEDs are turned off when the notification panel is shown, even just a little bit. * See also StatusBar.setPanelExpanded for another place where we attempt to do this. Loading @@ -3837,8 +3848,6 @@ public class StatusBar extends SystemUI implements DemoMode, int notificationLoad = mNotificationData.getActiveNotifications().size(); if (pinnedHeadsUp && isPanelFullyCollapsed()) { notificationLoad = 1; } else { mMetricsLogger.histogram("note_load", notificationLoad); } mBarService.onPanelRevealed(clearNotificationEffects, notificationLoad); } else { Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +111 −9 Original line number Diff line number Diff line Loading @@ -20,37 +20,54 @@ import static android.app.NotificationManager.IMPORTANCE_HIGH; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static junit.framework.TestCase.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.when; import static org.mockito.Mockito.verify; import android.app.Notification; import android.metrics.LogMaker; import android.os.Handler; import android.os.HandlerThread; import android.os.IPowerManager; import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.RemoteException; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.support.test.filters.SmallTest; import android.support.test.metricshelper.MetricsAsserts; import android.support.test.runner.AndroidJUnit4; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.MessageHandler; import android.testing.TestableLooper.RunWithLooper; import android.util.DisplayMetrics; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.testing.FakeMetricsLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.keyguard.KeyguardHostView.OnDismissAction; import com.android.systemui.SysuiTestCase; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.statusbar.ActivatableNotificationView; import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.NotificationData.Entry; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; Loading @@ -58,21 +75,26 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.ArrayList; @SmallTest @RunWith(AndroidJUnit4.class) @RunWith(AndroidTestingRunner.class) @RunWithLooper public class StatusBarTest extends SysuiTestCase { StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; UnlockMethodCache mUnlockMethodCache; KeyguardIndicationController mKeyguardIndicationController; NotificationStackScrollLayout mStackScroller; StatusBar mStatusBar; TestableStatusBar mStatusBar; FakeMetricsLogger mMetricsLogger; HeadsUpManager mHeadsUpManager; NotificationData mNotificationData; PowerManager mPowerManager; SystemServicesProxy mSystemServicesProxy; NotificationPanelView mNotificationPanelView; IStatusBarService mBarService; ArrayList<Entry> mNotificationList; private DisplayMetrics mDisplayMetrics = new DisplayMetrics(); @Before Loading @@ -86,18 +108,20 @@ public class StatusBarTest extends SysuiTestCase { mNotificationData = mock(NotificationData.class); mSystemServicesProxy = mock(SystemServicesProxy.class); mNotificationPanelView = mock(NotificationPanelView.class); mNotificationList = mock(ArrayList.class); IPowerManager powerManagerService = mock(IPowerManager.class); HandlerThread handlerThread = new HandlerThread("TestThread"); handlerThread.start(); mPowerManager = new PowerManager(mContext, powerManagerService, new Handler(handlerThread.getLooper())); when(powerManagerService.isInteractive()).thenReturn(true); mBarService = mock(IStatusBarService.class); mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger); mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache, mKeyguardIndicationController, mStackScroller, mHeadsUpManager, mNotificationData, mPowerManager, mSystemServicesProxy, mNotificationPanelView); mNotificationData, mPowerManager, mSystemServicesProxy, mNotificationPanelView, mBarService); doAnswer(invocation -> { OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0]; onDismissAction.onDismiss(); Loading @@ -111,6 +135,15 @@ public class StatusBarTest extends SysuiTestCase { }).when(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any()); when(mStackScroller.getActivatedChild()).thenReturn(null); TestableLooper.get(this).setMessageHandler(new MessageHandler() { @Override public boolean onMessageHandled(Message m) { if (m.getCallback() == mStatusBar.mVisibilityReporter) { return false; } return true; } }); } @Test Loading Loading @@ -284,11 +317,80 @@ public class StatusBarTest extends SysuiTestCase { assertFalse(mStatusBar.shouldPeek(entry, sbn)); } @Test public void testLogHidden() { try { mStatusBar.handleVisibleToUserChanged(false); verify(mBarService, times(1)).onPanelHidden(); verify(mBarService, never()).onPanelRevealed(anyBoolean(), anyInt()); } catch (RemoteException e) { fail(); } } @Test public void testPanelOpenForPeek() { when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true); when(mNotificationData.getActiveNotifications()).thenReturn(mNotificationList); when(mNotificationList.size()).thenReturn(5); when(mNotificationPanelView.isFullyCollapsed()).thenReturn(true); mStatusBar.setBarStateForTest(StatusBarState.SHADE); try { mStatusBar.handleVisibleToUserChanged(true); verify(mBarService, never()).onPanelHidden(); verify(mBarService, times(1)).onPanelRevealed(false, 1); } catch (RemoteException e) { fail(); } TestableLooper.get(this).processAllMessages(); } @Test public void testPanelOpenAndClear() { when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false); when(mNotificationData.getActiveNotifications()).thenReturn(mNotificationList); when(mNotificationList.size()).thenReturn(5); when(mNotificationPanelView.isFullyCollapsed()).thenReturn(false); mStatusBar.setBarStateForTest(StatusBarState.SHADE); try { mStatusBar.handleVisibleToUserChanged(true); verify(mBarService, never()).onPanelHidden(); verify(mBarService, times(1)).onPanelRevealed(true, 5); } catch (RemoteException e) { fail(); } TestableLooper.get(this).processAllMessages(); } @Test public void testPanelOpenAndNoClear() { when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false); when(mNotificationData.getActiveNotifications()).thenReturn(mNotificationList); when(mNotificationList.size()).thenReturn(5); when(mNotificationPanelView.isFullyCollapsed()).thenReturn(false); mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD); try { mStatusBar.handleVisibleToUserChanged(true); verify(mBarService, never()).onPanelHidden(); verify(mBarService, times(1)).onPanelRevealed(false, 5); } catch (RemoteException e) { fail(); } TestableLooper.get(this).processAllMessages(); } static class TestableStatusBar extends StatusBar { public TestableStatusBar(StatusBarKeyguardViewManager man, UnlockMethodCache unlock, KeyguardIndicationController key, NotificationStackScrollLayout stack, HeadsUpManager hum, NotificationData nd, PowerManager pm, SystemServicesProxy ssp, NotificationPanelView panelView) { PowerManager pm, SystemServicesProxy ssp, NotificationPanelView panelView, IStatusBarService barService) { mStatusBarKeyguardViewManager = man; mUnlockMethodCache = unlock; mKeyguardIndicationController = key; Loading @@ -299,11 +401,11 @@ public class StatusBarTest extends SysuiTestCase { mPowerManager = pm; mSystemServicesProxy = ssp; mNotificationPanel = panelView; mBarService = barService; } @Override protected H createHandler() { return null; public void setBarStateForTest(int state) { mState = state; } } } No newline at end of file services/core/java/com/android/server/notification/NotificationManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -607,7 +607,7 @@ public class NotificationManagerService extends SystemService { @Override public void onPanelRevealed(boolean clearEffects, int items) { MetricsLogger.visible(getContext(), MetricsEvent.NOTIFICATION_PANEL); MetricsLogger.histogram(getContext(), "notification_load", items); MetricsLogger.histogram(getContext(), "note_load", items); EventLogTags.writeNotificationPanelRevealed(items); if (clearEffects) { clearEffects(); Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java +1 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ public class HeadsUpTouchHelper implements Gefingerpoken { mPanel.setPanelScrimMinFraction((float) expandedHeight / mPanel.getMaxPanelHeight()); mPanel.startExpandMotion(x, y, true /* startTracking */, expandedHeight); mPanel.startExpandingFromPeek(); // This call needs to be after the expansion start otherwise we will get a // flicker of one frame as it's not expanded yet. mHeadsUpManager.unpinAll(); Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +4 −0 Original line number Diff line number Diff line Loading @@ -407,6 +407,10 @@ public abstract class PanelView extends FrameLayout { return Math.abs(yDiff) >= Math.abs(xDiff); } protected void startExpandingFromPeek() { mStatusBar.handlePeekToExpandTransistion(); } protected void startExpandMotion(float newX, float newY, boolean startTracking, float expandedHeight) { mInitialOffsetOnTouch = expandedHeight; Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +12 −3 Original line number Diff line number Diff line Loading @@ -661,7 +661,7 @@ public class StatusBar extends SystemUI implements DemoMode, // Tracks notifications currently visible in mNotificationStackScroller and // emits visibility events via NoMan on changes. private final Runnable mVisibilityReporter = new Runnable() { protected final Runnable mVisibilityReporter = new Runnable() { private final ArraySet<NotificationVisibility> mTmpNewlyVisibleNotifications = new ArraySet<>(); private final ArraySet<NotificationVisibility> mTmpCurrentlyVisibleNotifications = Loading Loading @@ -3822,6 +3822,17 @@ public class StatusBar extends SystemUI implements DemoMode, } } void handlePeekToExpandTransistion() { try { // consider the transition from peek to expanded to be a panel open, // but not one that clears notification effects. int notificationLoad = mNotificationData.getActiveNotifications().size(); mBarService.onPanelRevealed(false, notificationLoad); } catch (RemoteException ex) { // Won't fail unless the world has ended. } } /** * The LEDs are turned off when the notification panel is shown, even just a little bit. * See also StatusBar.setPanelExpanded for another place where we attempt to do this. Loading @@ -3837,8 +3848,6 @@ public class StatusBar extends SystemUI implements DemoMode, int notificationLoad = mNotificationData.getActiveNotifications().size(); if (pinnedHeadsUp && isPanelFullyCollapsed()) { notificationLoad = 1; } else { mMetricsLogger.histogram("note_load", notificationLoad); } mBarService.onPanelRevealed(clearNotificationEffects, notificationLoad); } else { Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +111 −9 Original line number Diff line number Diff line Loading @@ -20,37 +20,54 @@ import static android.app.NotificationManager.IMPORTANCE_HIGH; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static junit.framework.TestCase.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.when; import static org.mockito.Mockito.verify; import android.app.Notification; import android.metrics.LogMaker; import android.os.Handler; import android.os.HandlerThread; import android.os.IPowerManager; import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.RemoteException; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.support.test.filters.SmallTest; import android.support.test.metricshelper.MetricsAsserts; import android.support.test.runner.AndroidJUnit4; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.MessageHandler; import android.testing.TestableLooper.RunWithLooper; import android.util.DisplayMetrics; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.testing.FakeMetricsLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.keyguard.KeyguardHostView.OnDismissAction; import com.android.systemui.SysuiTestCase; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.statusbar.ActivatableNotificationView; import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.NotificationData.Entry; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; Loading @@ -58,21 +75,26 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.ArrayList; @SmallTest @RunWith(AndroidJUnit4.class) @RunWith(AndroidTestingRunner.class) @RunWithLooper public class StatusBarTest extends SysuiTestCase { StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; UnlockMethodCache mUnlockMethodCache; KeyguardIndicationController mKeyguardIndicationController; NotificationStackScrollLayout mStackScroller; StatusBar mStatusBar; TestableStatusBar mStatusBar; FakeMetricsLogger mMetricsLogger; HeadsUpManager mHeadsUpManager; NotificationData mNotificationData; PowerManager mPowerManager; SystemServicesProxy mSystemServicesProxy; NotificationPanelView mNotificationPanelView; IStatusBarService mBarService; ArrayList<Entry> mNotificationList; private DisplayMetrics mDisplayMetrics = new DisplayMetrics(); @Before Loading @@ -86,18 +108,20 @@ public class StatusBarTest extends SysuiTestCase { mNotificationData = mock(NotificationData.class); mSystemServicesProxy = mock(SystemServicesProxy.class); mNotificationPanelView = mock(NotificationPanelView.class); mNotificationList = mock(ArrayList.class); IPowerManager powerManagerService = mock(IPowerManager.class); HandlerThread handlerThread = new HandlerThread("TestThread"); handlerThread.start(); mPowerManager = new PowerManager(mContext, powerManagerService, new Handler(handlerThread.getLooper())); when(powerManagerService.isInteractive()).thenReturn(true); mBarService = mock(IStatusBarService.class); mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger); mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache, mKeyguardIndicationController, mStackScroller, mHeadsUpManager, mNotificationData, mPowerManager, mSystemServicesProxy, mNotificationPanelView); mNotificationData, mPowerManager, mSystemServicesProxy, mNotificationPanelView, mBarService); doAnswer(invocation -> { OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0]; onDismissAction.onDismiss(); Loading @@ -111,6 +135,15 @@ public class StatusBarTest extends SysuiTestCase { }).when(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any()); when(mStackScroller.getActivatedChild()).thenReturn(null); TestableLooper.get(this).setMessageHandler(new MessageHandler() { @Override public boolean onMessageHandled(Message m) { if (m.getCallback() == mStatusBar.mVisibilityReporter) { return false; } return true; } }); } @Test Loading Loading @@ -284,11 +317,80 @@ public class StatusBarTest extends SysuiTestCase { assertFalse(mStatusBar.shouldPeek(entry, sbn)); } @Test public void testLogHidden() { try { mStatusBar.handleVisibleToUserChanged(false); verify(mBarService, times(1)).onPanelHidden(); verify(mBarService, never()).onPanelRevealed(anyBoolean(), anyInt()); } catch (RemoteException e) { fail(); } } @Test public void testPanelOpenForPeek() { when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true); when(mNotificationData.getActiveNotifications()).thenReturn(mNotificationList); when(mNotificationList.size()).thenReturn(5); when(mNotificationPanelView.isFullyCollapsed()).thenReturn(true); mStatusBar.setBarStateForTest(StatusBarState.SHADE); try { mStatusBar.handleVisibleToUserChanged(true); verify(mBarService, never()).onPanelHidden(); verify(mBarService, times(1)).onPanelRevealed(false, 1); } catch (RemoteException e) { fail(); } TestableLooper.get(this).processAllMessages(); } @Test public void testPanelOpenAndClear() { when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false); when(mNotificationData.getActiveNotifications()).thenReturn(mNotificationList); when(mNotificationList.size()).thenReturn(5); when(mNotificationPanelView.isFullyCollapsed()).thenReturn(false); mStatusBar.setBarStateForTest(StatusBarState.SHADE); try { mStatusBar.handleVisibleToUserChanged(true); verify(mBarService, never()).onPanelHidden(); verify(mBarService, times(1)).onPanelRevealed(true, 5); } catch (RemoteException e) { fail(); } TestableLooper.get(this).processAllMessages(); } @Test public void testPanelOpenAndNoClear() { when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false); when(mNotificationData.getActiveNotifications()).thenReturn(mNotificationList); when(mNotificationList.size()).thenReturn(5); when(mNotificationPanelView.isFullyCollapsed()).thenReturn(false); mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD); try { mStatusBar.handleVisibleToUserChanged(true); verify(mBarService, never()).onPanelHidden(); verify(mBarService, times(1)).onPanelRevealed(false, 5); } catch (RemoteException e) { fail(); } TestableLooper.get(this).processAllMessages(); } static class TestableStatusBar extends StatusBar { public TestableStatusBar(StatusBarKeyguardViewManager man, UnlockMethodCache unlock, KeyguardIndicationController key, NotificationStackScrollLayout stack, HeadsUpManager hum, NotificationData nd, PowerManager pm, SystemServicesProxy ssp, NotificationPanelView panelView) { PowerManager pm, SystemServicesProxy ssp, NotificationPanelView panelView, IStatusBarService barService) { mStatusBarKeyguardViewManager = man; mUnlockMethodCache = unlock; mKeyguardIndicationController = key; Loading @@ -299,11 +401,11 @@ public class StatusBarTest extends SysuiTestCase { mPowerManager = pm; mSystemServicesProxy = ssp; mNotificationPanel = panelView; mBarService = barService; } @Override protected H createHandler() { return null; public void setBarStateForTest(int state) { mState = state; } } } No newline at end of file
services/core/java/com/android/server/notification/NotificationManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -607,7 +607,7 @@ public class NotificationManagerService extends SystemService { @Override public void onPanelRevealed(boolean clearEffects, int items) { MetricsLogger.visible(getContext(), MetricsEvent.NOTIFICATION_PANEL); MetricsLogger.histogram(getContext(), "notification_load", items); MetricsLogger.histogram(getContext(), "note_load", items); EventLogTags.writeNotificationPanelRevealed(items); if (clearEffects) { clearEffects(); Loading