1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.media.cts; 18 19 import android.content.Context; 20 import android.media.RemoteController; 21 import android.media.RemoteController.OnClientUpdateListener; 22 import android.platform.test.annotations.AppModeFull; 23 import android.test.InstrumentationTestCase; 24 import android.test.UiThreadTest; 25 import android.view.KeyEvent; 26 import android.util.Log; 27 28 import java.lang.reflect.Method; 29 import java.util.ArrayList; 30 import java.util.Arrays; 31 import java.util.HashSet; 32 import java.util.HashMap; 33 import java.util.List; 34 import java.util.Map; 35 import java.util.Set; 36 37 /** 38 * Tests for {@link RemoteController}. 39 */ 40 @AppModeFull(reason = "TODO: evaluate and port to instant") 41 public class RemoteControllerTest extends InstrumentationTestCase { 42 43 private static final Set<Integer> MEDIA_KEY_EVENT = new HashSet<Integer>(); 44 static { 45 MEDIA_KEY_EVENT.add(KeyEvent.KEYCODE_MEDIA_PLAY); 46 MEDIA_KEY_EVENT.add(KeyEvent.KEYCODE_MEDIA_PAUSE); 47 MEDIA_KEY_EVENT.add(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE); 48 MEDIA_KEY_EVENT.add(KeyEvent.KEYCODE_MUTE); 49 MEDIA_KEY_EVENT.add(KeyEvent.KEYCODE_HEADSETHOOK); 50 MEDIA_KEY_EVENT.add(KeyEvent.KEYCODE_MEDIA_STOP); 51 MEDIA_KEY_EVENT.add(KeyEvent.KEYCODE_MEDIA_NEXT); 52 MEDIA_KEY_EVENT.add(KeyEvent.KEYCODE_MEDIA_PREVIOUS); 53 MEDIA_KEY_EVENT.add(KeyEvent.KEYCODE_MEDIA_REWIND); 54 MEDIA_KEY_EVENT.add(KeyEvent.KEYCODE_MEDIA_RECORD); 55 MEDIA_KEY_EVENT.add(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD); 56 } 57 58 static OnClientUpdateListener listener = new OnClientUpdateListener() { 59 @Override 60 public void onClientChange(boolean clearing) {} 61 @Override 62 public void onClientPlaybackStateUpdate(int state) {} 63 @Override 64 public void onClientPlaybackStateUpdate( 65 int state, long stateChangeTimeMs, long currentPosMs, float speed) {} 66 @Override 67 public void onClientTransportControlUpdate(int transportControlFlags) {} 68 @Override 69 public void onClientMetadataUpdate(RemoteController.MetadataEditor metadataEditor) {} 70 }; 71 72 private Context mContext; 73 74 @Override 75 protected void setUp() throws Exception { 76 super.setUp(); 77 mContext = getInstrumentation().getTargetContext(); 78 } 79 80 private RemoteController createRemoteController() { 81 return new RemoteController(mContext, listener); 82 } 83 84 @UiThreadTest 85 public void testGetEstimatedMediaPosition() { 86 assertTrue(createRemoteController().getEstimatedMediaPosition() < 0); 87 } 88 89 @UiThreadTest 90 public void testSendMediaKeyEvent() { 91 RemoteController remoteController = createRemoteController(); 92 for (Integer mediaKeyEvent : MEDIA_KEY_EVENT) { 93 assertFalse(remoteController.sendMediaKeyEvent( 94 new KeyEvent(KeyEvent.ACTION_DOWN, mediaKeyEvent))); 95 } 96 } 97 98 @UiThreadTest 99 public void testSeekTo_negativeValues() { 100 try { 101 createRemoteController().seekTo(-1); 102 fail("timeMs must be >= 0"); 103 } catch (IllegalArgumentException expected) {} 104 } 105 106 @UiThreadTest 107 public void testSeekTo() { 108 assertTrue(createRemoteController().seekTo(0)); 109 } 110 111 @UiThreadTest 112 public void testSetArtworkConfiguration() { 113 assertTrue(createRemoteController().setArtworkConfiguration(1, 1)); 114 } 115 116 @UiThreadTest 117 public void testClearArtworkConfiguration() { 118 assertTrue(createRemoteController().clearArtworkConfiguration()); 119 } 120 121 @UiThreadTest 122 public void testSetSynchronizationMode_unregisteredRemoteController() { 123 RemoteController remoteController = createRemoteController(); 124 assertFalse(remoteController.setSynchronizationMode( 125 RemoteController.POSITION_SYNCHRONIZATION_NONE)); 126 assertFalse(remoteController.setSynchronizationMode( 127 RemoteController.POSITION_SYNCHRONIZATION_CHECK)); 128 } 129 130 @UiThreadTest 131 public void testEditMetadata() { 132 assertNotNull(createRemoteController().editMetadata()); 133 } 134 135 @UiThreadTest 136 public void testOnClientUpdateListenerUnchanged() throws Exception { 137 Map<String, List<Method>> methodMap = new HashMap<String, List<Method>>(); 138 for (Method method : listener.getClass().getDeclaredMethods()) { 139 if (!methodMap.containsKey(method.getName())) { 140 methodMap.put(method.getName(), new ArrayList<Method>()); 141 } 142 methodMap.get(method.getName()).add(method); 143 } 144 145 for (Method method : OnClientUpdateListener.class.getDeclaredMethods()) { 146 assertTrue("Method not found: " + method.getName(), 147 methodMap.containsKey(method.getName())); 148 List<Method> implementedMethodList = methodMap.get(method.getName()); 149 assertTrue("Method signature changed: " + method, 150 matchMethod(method, implementedMethodList)); 151 } 152 } 153 154 private static boolean matchMethod(Method method, List<Method> potentialMatches) { 155 for (Method potentialMatch : potentialMatches) { 156 if (method.getName().equals(potentialMatch.getName()) && 157 method.getReturnType().equals(potentialMatch.getReturnType()) && 158 Arrays.equals(method.getTypeParameters(), 159 potentialMatch.getTypeParameters())) { 160 return true; 161 } 162 } 163 return false; 164 } 165 } 166