Loading packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java +11 −0 Original line number Diff line number Diff line Loading @@ -36,10 +36,21 @@ public class DozeScreenState implements DozeMachine.Part { @Override public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) { int screenState = newState.screenState(); if (newState == DozeMachine.State.FINISH) { // Make sure not to apply the screen state after DozeService was destroyed. mPendingScreenState = Display.STATE_UNKNOWN; mHandler.removeCallbacks(mApplyPendingScreenState); applyScreenState(screenState); return; } if (screenState == Display.STATE_UNKNOWN) { // We'll keep it in the existing state return; } boolean messagePending = mHandler.hasCallbacks(mApplyPendingScreenState); if (messagePending || oldState == DozeMachine.State.INITIALIZED) { // During initialization, we hide the navigation bar. That is however only applied after Loading packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java +32 −26 Original line number Diff line number Diff line Loading @@ -20,23 +20,22 @@ import static com.android.systemui.doze.DozeMachine.State.DOZE; import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD; import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING; import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE; import static com.android.systemui.doze.DozeMachine.State.FINISH; import static com.android.systemui.doze.DozeMachine.State.INITIALIZED; import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED; import static com.android.systemui.utils.os.FakeHandler.Mode.QUEUEING; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.Display; import com.android.systemui.SysuiTestCase; import com.android.systemui.utils.os.FakeHandler; import org.junit.Before; import org.junit.Test; Loading @@ -48,13 +47,13 @@ public class DozeScreenStateTest extends SysuiTestCase { DozeServiceFake mServiceFake; DozeScreenState mScreen; private ImmediateHandler mHandler; FakeHandler mHandlerFake; @Before public void setUp() throws Exception { mServiceFake = new DozeServiceFake(); mHandler = spy(new ImmediateHandler(Looper.getMainLooper())); mScreen = new DozeScreenState(mServiceFake, mHandler); mHandlerFake = new FakeHandler(Looper.getMainLooper()); mScreen = new DozeScreenState(mServiceFake, mHandlerFake); } @Test Loading Loading @@ -105,27 +104,34 @@ public class DozeScreenStateTest extends SysuiTestCase { } @Test public void test_postedToHandler() { public void test_initialScreenStatePostedToHandler() { mHandlerFake.setMode(QUEUEING); mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mServiceFake.screenStateSet = false; mScreen.transitionTo(INITIALIZED, DOZE_AOD); verify(mHandler).sendMessageAtTime(any(), anyLong()); } assertFalse(mServiceFake.screenStateSet); private static class ImmediateHandler extends Handler { mHandlerFake.dispatchQueuedMessages(); public ImmediateHandler(Looper looper) { super(looper); assertTrue(mServiceFake.screenStateSet); assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState); } @Override public boolean sendMessageAtTime(Message msg, long uptimeMillis) { Runnable callback = msg.getCallback(); if (callback != null) { callback.run(); return false; } return super.sendMessageAtTime(msg, uptimeMillis); } @Test public void test_noScreenStateSetAfterFinish() { mHandlerFake.setMode(QUEUEING); mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mScreen.transitionTo(INITIALIZED, DOZE_AOD); mScreen.transitionTo(DOZE_AOD, FINISH); mServiceFake.screenStateSet = false; mHandlerFake.dispatchQueuedMessages(); assertFalse(mServiceFake.screenStateSet); } } No newline at end of file packages/SystemUI/tests/src/com/android/systemui/doze/DozeServiceFake.java +9 −0 Original line number Diff line number Diff line Loading @@ -19,10 +19,16 @@ package com.android.systemui.doze; import android.os.PowerManager; import android.view.Display; /** * Fake implementation of {@link DozeMachine.Service} for tests. * * Useful instead of mocking because it allows verifying state instead of interactions. */ public class DozeServiceFake implements DozeMachine.Service { public boolean finished; public int screenState; public boolean screenStateSet; public boolean requestedWakeup; public int screenBrightness; Loading @@ -38,6 +44,7 @@ public class DozeServiceFake implements DozeMachine.Service { @Override public void setDozeScreenState(int state) { screenState = state; screenStateSet = true; } @Override Loading @@ -53,6 +60,8 @@ public class DozeServiceFake implements DozeMachine.Service { public void reset() { finished = false; screenState = Display.STATE_UNKNOWN; screenStateSet = false; requestedWakeup = false; screenBrightness = PowerManager.BRIGHTNESS_DEFAULT; } } packages/SystemUI/tests/src/com/android/systemui/utils/os/FakeHandler.java 0 → 100644 +71 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.utils.os; import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.ArrayList; /** * A handler that allows control over when to dispatch messages and callbacks. * * WARNING: Because most Handler methods are final, the only thing this handler can intercept * are sending messages and posting runnables, but *NOT* removing messages nor runnables. * It also *CANNOT* intercept messages posted to the front of queue. */ public class FakeHandler extends Handler { private Mode mMode = Mode.IMMEDIATE; private ArrayList<Message> mQueuedMessages = new ArrayList<>(); public FakeHandler(Looper looper) { super(looper); } @Override public boolean sendMessageAtTime(Message msg, long uptimeMillis) { mQueuedMessages.add(msg); if (mMode == Mode.IMMEDIATE) { dispatchQueuedMessages(); } return true; } public void setMode(Mode mode) { mMode = mode; } /** * Dispatch any messages that have been queued on the calling thread. */ public void dispatchQueuedMessages() { ArrayList<Message> messages = new ArrayList<>(mQueuedMessages); mQueuedMessages.clear(); for (Message msg : messages) { dispatchMessage(msg); } } public enum Mode { /** Messages are dispatched immediately on the calling thread. */ IMMEDIATE, /** Messages are queued until {@link #dispatchQueuedMessages()} is called. */ QUEUEING, } } Loading
packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java +11 −0 Original line number Diff line number Diff line Loading @@ -36,10 +36,21 @@ public class DozeScreenState implements DozeMachine.Part { @Override public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) { int screenState = newState.screenState(); if (newState == DozeMachine.State.FINISH) { // Make sure not to apply the screen state after DozeService was destroyed. mPendingScreenState = Display.STATE_UNKNOWN; mHandler.removeCallbacks(mApplyPendingScreenState); applyScreenState(screenState); return; } if (screenState == Display.STATE_UNKNOWN) { // We'll keep it in the existing state return; } boolean messagePending = mHandler.hasCallbacks(mApplyPendingScreenState); if (messagePending || oldState == DozeMachine.State.INITIALIZED) { // During initialization, we hide the navigation bar. That is however only applied after Loading
packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java +32 −26 Original line number Diff line number Diff line Loading @@ -20,23 +20,22 @@ import static com.android.systemui.doze.DozeMachine.State.DOZE; import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD; import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING; import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE; import static com.android.systemui.doze.DozeMachine.State.FINISH; import static com.android.systemui.doze.DozeMachine.State.INITIALIZED; import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED; import static com.android.systemui.utils.os.FakeHandler.Mode.QUEUEING; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.Display; import com.android.systemui.SysuiTestCase; import com.android.systemui.utils.os.FakeHandler; import org.junit.Before; import org.junit.Test; Loading @@ -48,13 +47,13 @@ public class DozeScreenStateTest extends SysuiTestCase { DozeServiceFake mServiceFake; DozeScreenState mScreen; private ImmediateHandler mHandler; FakeHandler mHandlerFake; @Before public void setUp() throws Exception { mServiceFake = new DozeServiceFake(); mHandler = spy(new ImmediateHandler(Looper.getMainLooper())); mScreen = new DozeScreenState(mServiceFake, mHandler); mHandlerFake = new FakeHandler(Looper.getMainLooper()); mScreen = new DozeScreenState(mServiceFake, mHandlerFake); } @Test Loading Loading @@ -105,27 +104,34 @@ public class DozeScreenStateTest extends SysuiTestCase { } @Test public void test_postedToHandler() { public void test_initialScreenStatePostedToHandler() { mHandlerFake.setMode(QUEUEING); mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mServiceFake.screenStateSet = false; mScreen.transitionTo(INITIALIZED, DOZE_AOD); verify(mHandler).sendMessageAtTime(any(), anyLong()); } assertFalse(mServiceFake.screenStateSet); private static class ImmediateHandler extends Handler { mHandlerFake.dispatchQueuedMessages(); public ImmediateHandler(Looper looper) { super(looper); assertTrue(mServiceFake.screenStateSet); assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState); } @Override public boolean sendMessageAtTime(Message msg, long uptimeMillis) { Runnable callback = msg.getCallback(); if (callback != null) { callback.run(); return false; } return super.sendMessageAtTime(msg, uptimeMillis); } @Test public void test_noScreenStateSetAfterFinish() { mHandlerFake.setMode(QUEUEING); mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mScreen.transitionTo(INITIALIZED, DOZE_AOD); mScreen.transitionTo(DOZE_AOD, FINISH); mServiceFake.screenStateSet = false; mHandlerFake.dispatchQueuedMessages(); assertFalse(mServiceFake.screenStateSet); } } No newline at end of file
packages/SystemUI/tests/src/com/android/systemui/doze/DozeServiceFake.java +9 −0 Original line number Diff line number Diff line Loading @@ -19,10 +19,16 @@ package com.android.systemui.doze; import android.os.PowerManager; import android.view.Display; /** * Fake implementation of {@link DozeMachine.Service} for tests. * * Useful instead of mocking because it allows verifying state instead of interactions. */ public class DozeServiceFake implements DozeMachine.Service { public boolean finished; public int screenState; public boolean screenStateSet; public boolean requestedWakeup; public int screenBrightness; Loading @@ -38,6 +44,7 @@ public class DozeServiceFake implements DozeMachine.Service { @Override public void setDozeScreenState(int state) { screenState = state; screenStateSet = true; } @Override Loading @@ -53,6 +60,8 @@ public class DozeServiceFake implements DozeMachine.Service { public void reset() { finished = false; screenState = Display.STATE_UNKNOWN; screenStateSet = false; requestedWakeup = false; screenBrightness = PowerManager.BRIGHTNESS_DEFAULT; } }
packages/SystemUI/tests/src/com/android/systemui/utils/os/FakeHandler.java 0 → 100644 +71 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.utils.os; import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.ArrayList; /** * A handler that allows control over when to dispatch messages and callbacks. * * WARNING: Because most Handler methods are final, the only thing this handler can intercept * are sending messages and posting runnables, but *NOT* removing messages nor runnables. * It also *CANNOT* intercept messages posted to the front of queue. */ public class FakeHandler extends Handler { private Mode mMode = Mode.IMMEDIATE; private ArrayList<Message> mQueuedMessages = new ArrayList<>(); public FakeHandler(Looper looper) { super(looper); } @Override public boolean sendMessageAtTime(Message msg, long uptimeMillis) { mQueuedMessages.add(msg); if (mMode == Mode.IMMEDIATE) { dispatchQueuedMessages(); } return true; } public void setMode(Mode mode) { mMode = mode; } /** * Dispatch any messages that have been queued on the calling thread. */ public void dispatchQueuedMessages() { ArrayList<Message> messages = new ArrayList<>(mQueuedMessages); mQueuedMessages.clear(); for (Message msg : messages) { dispatchMessage(msg); } } public enum Mode { /** Messages are dispatched immediately on the calling thread. */ IMMEDIATE, /** Messages are queued until {@link #dispatchQueuedMessages()} is called. */ QUEUEING, } }