1 /* 2 * Copyright (C) 2008 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.widget.cts; 18 19 import static org.junit.Assert.assertFalse; 20 import static org.junit.Assert.assertTrue; 21 import static org.junit.Assert.fail; 22 import static org.mockito.Mockito.mock; 23 24 import android.app.Activity; 25 import android.app.Instrumentation; 26 import android.content.Context; 27 import android.util.AttributeSet; 28 import android.util.Xml; 29 import android.view.MotionEvent; 30 import android.view.View; 31 import android.widget.MediaController; 32 import android.widget.VideoView; 33 34 import androidx.test.InstrumentationRegistry; 35 import androidx.test.annotation.UiThreadTest; 36 import androidx.test.filters.MediumTest; 37 import androidx.test.rule.ActivityTestRule; 38 import androidx.test.runner.AndroidJUnit4; 39 40 import com.android.compatibility.common.util.PollingCheck; 41 import com.android.compatibility.common.util.WidgetTestUtils; 42 43 import org.junit.Before; 44 import org.junit.Rule; 45 import org.junit.Test; 46 import org.junit.runner.RunWith; 47 import org.xmlpull.v1.XmlPullParser; 48 49 import java.io.IOException; 50 import java.io.InputStream; 51 import java.io.OutputStream; 52 53 /** 54 * Test {@link MediaController}. 55 */ 56 @MediumTest 57 @RunWith(AndroidJUnit4.class) 58 public class MediaControllerTest { 59 private Instrumentation mInstrumentation; 60 private Activity mActivity; 61 private MediaController mMediaController; 62 63 @Rule 64 public ActivityTestRule<MediaControllerCtsActivity> mActivityRule = 65 new ActivityTestRule<>(MediaControllerCtsActivity.class); 66 67 @Before setup()68 public void setup() { 69 mInstrumentation = InstrumentationRegistry.getInstrumentation(); 70 mActivity = mActivityRule.getActivity(); 71 } 72 73 @UiThreadTest 74 @Test testConstructor()75 public void testConstructor() { 76 new MediaController(mActivity, null); 77 78 new MediaController(mActivity, true); 79 80 new MediaController(mActivity); 81 82 final XmlPullParser parser = 83 mActivity.getResources().getXml(R.layout.mediacontroller_layout); 84 final AttributeSet attrs = Xml.asAttributeSet(parser); 85 new MediaController(mActivity, attrs); 86 } 87 88 /** 89 * scenario description: 90 * 1. Show the MediaController. 91 * 92 */ 93 @UiThreadTest 94 @Test testMediaController()95 public void testMediaController() { 96 mMediaController = new MediaController(mActivity); 97 final MockMediaPlayerControl mediaPlayerControl = new MockMediaPlayerControl(); 98 mMediaController.setMediaPlayer(mediaPlayerControl); 99 100 assertFalse(mMediaController.isShowing()); 101 mMediaController.show(); 102 // setAnchorView() must be called before show(), 103 // otherwise MediaController never show. 104 assertFalse(mMediaController.isShowing()); 105 106 View videoview = mActivity.findViewById(R.id.mediacontroller_videoview); 107 mMediaController.setAnchorView(videoview); 108 109 mMediaController.show(); 110 assertTrue(mMediaController.isShowing()); 111 112 // ideally test would trigger pause/play/ff/rew here and test response, but no way 113 // to trigger those actions from MediaController 114 115 mMediaController = new MediaController(mActivity, false); 116 mMediaController.setMediaPlayer(mediaPlayerControl); 117 videoview = mActivity.findViewById(R.id.mediacontroller_videoview); 118 mMediaController.setAnchorView(videoview); 119 120 mMediaController.show(); 121 assertTrue(mMediaController.isShowing()); 122 } 123 124 @Test testShow()125 public void testShow() throws Throwable { 126 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mActivity.getWindow().getDecorView(), 127 () -> mMediaController = new MediaController(mActivity, true)); 128 assertFalse(mMediaController.isShowing()); 129 130 final MockMediaPlayerControl mediaPlayerControl = new MockMediaPlayerControl(); 131 mMediaController.setMediaPlayer(mediaPlayerControl); 132 133 final VideoView videoView = 134 (VideoView) mActivity.findViewById(R.id.mediacontroller_videoview); 135 mMediaController.setAnchorView(videoView); 136 137 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mActivity.getWindow().getDecorView(), 138 mMediaController::show); 139 assertTrue(mMediaController.isShowing()); 140 141 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mActivity.getWindow().getDecorView(), 142 mMediaController::hide); 143 assertFalse(mMediaController.isShowing()); 144 145 final int timeout = 2000; 146 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mActivity.getWindow().getDecorView(), 147 () -> mMediaController.show(timeout)); 148 assertTrue(mMediaController.isShowing()); 149 150 // isShowing() should return false, but MediaController still shows, this may be a bug. 151 PollingCheck.waitFor(500, mMediaController::isShowing); 152 } 153 prepareSampleVideo()154 private String prepareSampleVideo() { 155 final String VIDEO_NAME = "testvideo.3gp"; 156 157 try (InputStream source = mActivity.getResources().openRawResource(R.raw.testvideo); 158 OutputStream target = mActivity.openFileOutput(VIDEO_NAME, Context.MODE_PRIVATE)) { 159 160 final byte[] buffer = new byte[1024]; 161 for (int len = source.read(buffer); len > 0; len = source.read(buffer)) { 162 target.write(buffer, 0, len); 163 } 164 } catch (final IOException e) { 165 fail(e.getMessage()); 166 } 167 168 return mActivity.getFileStreamPath(VIDEO_NAME).getAbsolutePath(); 169 } 170 171 @Test testOnTrackballEvent()172 public void testOnTrackballEvent() throws Throwable { 173 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mActivity.getWindow().getDecorView(), 174 () -> mMediaController = new MediaController(mActivity)); 175 final MockMediaPlayerControl mediaPlayerControl = new MockMediaPlayerControl(); 176 mMediaController.setMediaPlayer(mediaPlayerControl); 177 178 final VideoView videoView = 179 (VideoView) mActivity.findViewById(R.id.mediacontroller_videoview); 180 videoView.setMediaController(mMediaController); 181 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mActivity.getWindow().getDecorView(), 182 () -> { 183 videoView.setVideoPath(prepareSampleVideo()); 184 videoView.requestFocus(); 185 }); 186 187 final long curTime = System.currentTimeMillis(); 188 // get the center of the VideoView. 189 final int[] xy = new int[2]; 190 videoView.getLocationOnScreen(xy); 191 192 final int viewWidth = videoView.getWidth(); 193 final int viewHeight = videoView.getHeight(); 194 195 final float x = xy[0] + viewWidth / 2.0f; 196 final float y = xy[1] + viewHeight / 2.0f; 197 final MotionEvent event = MotionEvent.obtain(curTime, 100, 198 MotionEvent.ACTION_DOWN, x, y, 0); 199 mInstrumentation.sendTrackballEventSync(event); 200 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mActivity.getWindow().getDecorView(), 201 null); 202 } 203 204 @UiThreadTest 205 @Test testSetEnabled()206 public void testSetEnabled() { 207 final View videoView = mActivity.findViewById(R.id.mediacontroller_videoview); 208 final MockMediaPlayerControl mediaPlayerControl = new MockMediaPlayerControl(); 209 210 mMediaController = new MediaController(mActivity); 211 mMediaController.setAnchorView(videoView); 212 mMediaController.setMediaPlayer(mediaPlayerControl); 213 214 final View.OnClickListener mockNextClickListener = mock(View.OnClickListener.class); 215 final View.OnClickListener mockPrevClickListener = mock(View.OnClickListener.class); 216 mMediaController.setPrevNextListeners(mockNextClickListener, mockPrevClickListener); 217 218 mMediaController.show(); 219 220 mMediaController.setEnabled(true); 221 assertTrue(mMediaController.isEnabled()); 222 223 mMediaController.setEnabled(false); 224 assertFalse(mMediaController.isEnabled()); 225 } 226 227 @UiThreadTest 228 @Test testSetPrevNextListeners()229 public void testSetPrevNextListeners() { 230 final View videoView = mActivity.findViewById(R.id.mediacontroller_videoview); 231 final MockMediaPlayerControl mediaPlayerControl = new MockMediaPlayerControl(); 232 233 mMediaController = new MediaController(mActivity); 234 mMediaController.setAnchorView(videoView); 235 mMediaController.setMediaPlayer(mediaPlayerControl); 236 237 final View.OnClickListener mockNextClickListener = mock(View.OnClickListener.class); 238 final View.OnClickListener mockPrevClickListener = mock(View.OnClickListener.class); 239 mMediaController.setPrevNextListeners(mockNextClickListener, mockPrevClickListener); 240 } 241 242 private static class MockMediaPlayerControl implements MediaController.MediaPlayerControl { 243 private boolean mIsPlaying = false; 244 private int mPosition = 0; 245 start()246 public void start() { 247 mIsPlaying = true; 248 } 249 pause()250 public void pause() { 251 mIsPlaying = false; 252 } 253 getDuration()254 public int getDuration() { 255 return 0; 256 } 257 getCurrentPosition()258 public int getCurrentPosition() { 259 return mPosition; 260 } 261 seekTo(int pos)262 public void seekTo(int pos) { 263 mPosition = pos; 264 } 265 isPlaying()266 public boolean isPlaying() { 267 return mIsPlaying; 268 } 269 getBufferPercentage()270 public int getBufferPercentage() { 271 return 0; 272 } 273 canPause()274 public boolean canPause() { 275 return true; 276 } 277 canSeekBackward()278 public boolean canSeekBackward() { 279 return true; 280 } 281 canSeekForward()282 public boolean canSeekForward() { 283 return true; 284 } 285 286 @Override getAudioSessionId()287 public int getAudioSessionId() { 288 return 0; 289 } 290 } 291 } 292