diff options
author | Justin Paupore <jpaupore@google.com> | 2019-03-29 15:04:00 -0700 |
---|---|---|
committer | Justin Paupore <jpaupore@google.com> | 2019-04-09 17:04:56 -0700 |
commit | a057d0575e7c667a5f6a2bdd8bfb44bd75196c4b (patch) | |
tree | b1df0458e54891aad3aa073af6302f37d5e27a80 /tests/CarLibTests | |
parent | 428f7d508752ab51f3f2a7548c08ac199e70e4ba (diff) | |
download | Car-a057d0575e7c667a5f6a2bdd8bfb44bd75196c4b.tar.gz |
CarProjectionManager: Introduce ProjectionKeyEventHandler
This API will be used in the place of CarProjectionListener to allow
projection clients to register to handle specific input events from the
system. Unlike the previous CarProjectionListener API, this API can be
extended to additional input events as needed in the future.
This new API also supports the following new events:
- Immediate notification of key-down for the VOICE_ASSIST key
- Key-up after a long-press of the VOICE_ASSIST key
- Short-press, long-press, key-down, and long-press-key-up events
for the CALL key
Test: Manual test, atest CarServiceUnitTest CarLibTests
Bug: 129706517
Change-Id: I93a2c1551738e44e9240b2a42f04a804e0d13543
Diffstat (limited to 'tests/CarLibTests')
-rw-r--r-- | tests/CarLibTests/src/android/car/CarProjectionManagerTest.java | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/tests/CarLibTests/src/android/car/CarProjectionManagerTest.java b/tests/CarLibTests/src/android/car/CarProjectionManagerTest.java index 012bc9668a..970cac99b8 100644 --- a/tests/CarLibTests/src/android/car/CarProjectionManagerTest.java +++ b/tests/CarLibTests/src/android/car/CarProjectionManagerTest.java @@ -20,8 +20,13 @@ import static android.car.CarProjectionManager.ProjectionAccessPointCallback.ERR import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import android.car.CarProjectionManager.ProjectionAccessPointCallback; @@ -30,6 +35,7 @@ import android.car.testapi.FakeCar; import android.content.Context; import android.content.Intent; import android.net.wifi.WifiConfiguration; +import android.util.ArraySet; import androidx.test.core.app.ApplicationProvider; import androidx.test.runner.AndroidJUnit4; @@ -40,11 +46,16 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; +import org.mockito.InOrder; import org.mockito.Spy; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) @@ -60,6 +71,9 @@ public class CarProjectionManagerTest { private static final int DEFAULT_TIMEOUT_MS = 1000; + /** An {@link Executor} that immediately runs its callbacks synchronously. */ + private static final Executor DIRECT_EXECUTOR = Runnable::run; + private CarProjectionManager mProjectionManager; private CarProjectionController mController; private ApCallback mApCallback; @@ -109,6 +123,135 @@ public class CarProjectionManagerTest { assertThat(mIntentArgumentCaptor.getValue()).isEqualTo(intent); } + @Test + public void keyEventListener_registerMultipleEventListeners() { + CarProjectionManager.ProjectionKeyEventHandler eventHandler1 = + mock(CarProjectionManager.ProjectionKeyEventHandler.class); + CarProjectionManager.ProjectionKeyEventHandler eventHandler2 = + mock(CarProjectionManager.ProjectionKeyEventHandler.class); + + mProjectionManager.addKeyEventHandler( + Collections.singleton(CarProjectionManager.KEY_EVENT_CALL_SHORT_PRESS_KEY_UP), + DIRECT_EXECUTOR, + eventHandler1); + mProjectionManager.addKeyEventHandler( + new ArraySet<>( + Arrays.asList( + CarProjectionManager.KEY_EVENT_CALL_SHORT_PRESS_KEY_UP, + CarProjectionManager.KEY_EVENT_CALL_LONG_PRESS_KEY_DOWN)), + DIRECT_EXECUTOR, + eventHandler2); + + mController.fireKeyEvent(CarProjectionManager.KEY_EVENT_CALL_SHORT_PRESS_KEY_UP); + verify(eventHandler1).onKeyEvent(CarProjectionManager.KEY_EVENT_CALL_SHORT_PRESS_KEY_UP); + verify(eventHandler2).onKeyEvent(CarProjectionManager.KEY_EVENT_CALL_SHORT_PRESS_KEY_UP); + + mController.fireKeyEvent(CarProjectionManager.KEY_EVENT_CALL_LONG_PRESS_KEY_DOWN); + verify(eventHandler1, never()) + .onKeyEvent(CarProjectionManager.KEY_EVENT_CALL_LONG_PRESS_KEY_DOWN); + verify(eventHandler2).onKeyEvent(CarProjectionManager.KEY_EVENT_CALL_LONG_PRESS_KEY_DOWN); + + mController.fireKeyEvent(CarProjectionManager.KEY_EVENT_CALL_KEY_DOWN); + verify(eventHandler1, never()).onKeyEvent(CarProjectionManager.KEY_EVENT_CALL_KEY_DOWN); + verify(eventHandler2, never()).onKeyEvent(CarProjectionManager.KEY_EVENT_CALL_KEY_DOWN); + } + + @Test + public void keyEventHandler_canRegisterAllEvents() { + CarProjectionManager.ProjectionKeyEventHandler eventHandler = + mock(CarProjectionManager.ProjectionKeyEventHandler.class); + + Set<Integer> events = new ArraySet<>(CarProjectionManager.NUM_KEY_EVENTS); + for (int evt = 0; evt < CarProjectionManager.NUM_KEY_EVENTS; evt++) { + events.add(evt); + } + + mProjectionManager.addKeyEventHandler(events, DIRECT_EXECUTOR, eventHandler); + + for (int evt : events) { + mController.fireKeyEvent(evt); + verify(eventHandler).onKeyEvent(evt); + } + } + + @Test + public void keyEventHandler_eventsOutOfRange_throw() { + CarProjectionManager.ProjectionKeyEventHandler eventHandler = + mock(CarProjectionManager.ProjectionKeyEventHandler.class); + + try { + mProjectionManager.addKeyEventHandler(Collections.singleton(-1), eventHandler); + fail(); + } catch (IllegalArgumentException expected) { } + + try { + mProjectionManager.addKeyEventHandler( + Collections.singleton(CarProjectionManager.NUM_KEY_EVENTS), eventHandler); + fail(); + } catch (IllegalArgumentException expected) { } + } + + @Test + public void keyEventHandler_whenRegisteredAgain_replacesEventList() { + CarProjectionManager.ProjectionKeyEventHandler eventHandler = + mock(CarProjectionManager.ProjectionKeyEventHandler.class); + InOrder inOrder = inOrder(eventHandler); + + mProjectionManager.addKeyEventHandler( + Collections.singleton(CarProjectionManager.KEY_EVENT_CALL_SHORT_PRESS_KEY_UP), + DIRECT_EXECUTOR, + eventHandler); + mController.fireKeyEvent(CarProjectionManager.KEY_EVENT_CALL_SHORT_PRESS_KEY_UP); + inOrder.verify(eventHandler) + .onKeyEvent(CarProjectionManager.KEY_EVENT_CALL_SHORT_PRESS_KEY_UP); + + mProjectionManager.addKeyEventHandler( + Collections.singleton(CarProjectionManager.KEY_EVENT_CALL_LONG_PRESS_KEY_DOWN), + DIRECT_EXECUTOR, + eventHandler); + mController.fireKeyEvent(CarProjectionManager.KEY_EVENT_CALL_SHORT_PRESS_KEY_UP); + inOrder.verify(eventHandler, never()) + .onKeyEvent(CarProjectionManager.KEY_EVENT_CALL_SHORT_PRESS_KEY_UP); + } + + @Test + public void keyEventHandler_removed_noLongerFires() { + CarProjectionManager.ProjectionKeyEventHandler eventHandler = + mock(CarProjectionManager.ProjectionKeyEventHandler.class); + + mProjectionManager.addKeyEventHandler( + Collections.singleton(CarProjectionManager.KEY_EVENT_CALL_SHORT_PRESS_KEY_UP), + DIRECT_EXECUTOR, + eventHandler); + mProjectionManager.removeKeyEventHandler(eventHandler); + + mController.fireKeyEvent(CarProjectionManager.KEY_EVENT_CALL_SHORT_PRESS_KEY_UP); + verify(eventHandler, never()) + .onKeyEvent(CarProjectionManager.KEY_EVENT_CALL_SHORT_PRESS_KEY_UP); + } + + @Test + public void keyEventHandler_withAlternateExecutor_usesExecutor() { + CarProjectionManager.ProjectionKeyEventHandler eventHandler = + mock(CarProjectionManager.ProjectionKeyEventHandler.class); + Executor executor = mock(Executor.class); + ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class); + + mProjectionManager.addKeyEventHandler( + Collections.singleton( + CarProjectionManager.KEY_EVENT_VOICE_SEARCH_SHORT_PRESS_KEY_UP), + executor, + eventHandler); + + mController.fireKeyEvent(CarProjectionManager.KEY_EVENT_VOICE_SEARCH_SHORT_PRESS_KEY_UP); + verify(eventHandler, never()).onKeyEvent(anyInt()); + verify(executor).execute(runnableCaptor.capture()); + + runnableCaptor.getValue().run(); + verify(eventHandler) + .onKeyEvent(CarProjectionManager.KEY_EVENT_VOICE_SEARCH_SHORT_PRESS_KEY_UP); + } + private static class ApCallback extends ProjectionAccessPointCallback { CountDownLatch mStarted = new CountDownLatch(1); CountDownLatch mFailed = new CountDownLatch(1); |