summaryrefslogtreecommitdiff
path: root/library/test/robotest/src/com/android/setupwizardlib/view/IllustrationVideoViewTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'library/test/robotest/src/com/android/setupwizardlib/view/IllustrationVideoViewTest.java')
-rw-r--r--library/test/robotest/src/com/android/setupwizardlib/view/IllustrationVideoViewTest.java383
1 files changed, 201 insertions, 182 deletions
diff --git a/library/test/robotest/src/com/android/setupwizardlib/view/IllustrationVideoViewTest.java b/library/test/robotest/src/com/android/setupwizardlib/view/IllustrationVideoViewTest.java
index 0e0e99c..e980563 100644
--- a/library/test/robotest/src/com/android/setupwizardlib/view/IllustrationVideoViewTest.java
+++ b/library/test/robotest/src/com/android/setupwizardlib/view/IllustrationVideoViewTest.java
@@ -17,204 +17,223 @@
package com.android.setupwizardlib.view;
import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
import static org.robolectric.RuntimeEnvironment.application;
-import android.annotation.TargetApi;
-import android.content.Context;
+import android.app.Activity;
import android.graphics.SurfaceTexture;
-import android.media.MediaPlayer;
-import android.os.Build.VERSION_CODES;
-import android.view.Surface;
-import android.view.View;
-
+import android.net.Uri;
import androidx.annotation.RawRes;
-
+import android.view.View;
import com.android.setupwizardlib.R;
-import com.android.setupwizardlib.robolectric.SuwLibRobolectricTestRunner;
-import com.android.setupwizardlib.shadow.ShadowLog;
-import com.android.setupwizardlib.shadow.ShadowLog.TerribleFailure;
-import com.android.setupwizardlib.view.IllustrationVideoViewTest.ShadowMockMediaPlayer;
-import com.android.setupwizardlib.view.IllustrationVideoViewTest.ShadowSurface;
-
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.annotation.RealObject;
-import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowMediaPlayer;
+import org.robolectric.shadows.ShadowMediaPlayer.InvalidStateBehavior;
+import org.robolectric.shadows.ShadowMediaPlayer.MediaInfo;
+import org.robolectric.shadows.util.DataSource;
import org.robolectric.util.ReflectionHelpers;
+import org.robolectric.util.ReflectionHelpers.ClassParameter;
-@RunWith(SuwLibRobolectricTestRunner.class)
-@Config(
- sdk = Config.NEWEST_SDK,
- shadows = {
- ShadowLog.class,
- ShadowMockMediaPlayer.class,
- ShadowSurface.class
- })
+@RunWith(RobolectricTestRunner.class)
+@Config(sdk = Config.NEWEST_SDK)
public class IllustrationVideoViewTest {
- @Mock
- private SurfaceTexture mSurfaceTexture;
-
- private IllustrationVideoView mView;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- }
-
- @After
- public void tearDown() {
- ShadowMockMediaPlayer.reset();
- }
-
- @Test
- public void nullMediaPlayer_shouldThrowWtf() {
- ShadowMockMediaPlayer.sMediaPlayer = null;
- try {
- createDefaultView();
- fail("WTF should be thrown for null media player");
- } catch (TerribleFailure e) {
- // pass
- }
- }
-
- @Test
- public void onVisibilityChanged_notVisible_shouldRelease() {
- createDefaultView();
- mView.onWindowVisibilityChanged(View.GONE);
-
- verify(ShadowMockMediaPlayer.sMediaPlayer).release();
- assertThat(mView.mSurface).isNull();
- assertThat(mView.mMediaPlayer).isNull();
- }
-
- @Test
- public void onVisibilityChanged_visible_shouldPlay() {
- createDefaultView();
-
- mView.onWindowVisibilityChanged(View.GONE);
- assertThat(mView.mSurface).isNull();
- assertThat(mView.mMediaPlayer).isNull();
-
- mView.onWindowVisibilityChanged(View.VISIBLE);
-
- assertThat(mView.mSurface).isNotNull();
- assertThat(mView.mMediaPlayer).isNotNull();
- }
-
- @Test
- public void testPausedWhenWindowFocusLost() {
- createDefaultView();
- mView.start();
-
- assertNotNull(mView.mMediaPlayer);
- assertNotNull(mView.mSurface);
-
- mView.onWindowFocusChanged(false);
- verify(ShadowMockMediaPlayer.getMock()).pause();
- }
-
- @Test
- public void testStartedWhenWindowFocusRegained() {
- testPausedWhenWindowFocusLost();
-
- // Clear verifications for calls in the other test
- reset(ShadowMockMediaPlayer.getMock());
-
- mView.onWindowFocusChanged(true);
- verify(ShadowMockMediaPlayer.getMock()).start();
- }
-
- @Test
- public void testSurfaceReleasedWhenTextureDestroyed() {
- createDefaultView();
- mView.start();
-
- assertNotNull(mView.mMediaPlayer);
- assertNotNull(mView.mSurface);
-
- mView.onSurfaceTextureDestroyed(mSurfaceTexture);
- verify(ShadowMockMediaPlayer.getMock()).release();
- }
-
- @Test
- public void testXmlSetVideoResId() {
- createDefaultView();
- assertEquals(android.R.color.white, ShadowMockMediaPlayer.sResId);
- }
-
- @Test
- public void testSetVideoResId() {
- createDefaultView();
-
- @RawRes int black = android.R.color.black;
- mView.setVideoResource(black);
-
- assertEquals(android.R.color.black, ShadowMockMediaPlayer.sResId);
- }
-
- private void createDefaultView() {
- mView = new IllustrationVideoView(
- application,
- Robolectric.buildAttributeSet()
- // Any resource attribute should work, since the media player is mocked
- .addAttribute(R.attr.suwVideo, "@android:color/white")
- .build());
- mView.setSurfaceTexture(mock(SurfaceTexture.class));
- mView.onSurfaceTextureAvailable(mSurfaceTexture, 500, 500);
- }
-
- @Implements(MediaPlayer.class)
- public static class ShadowMockMediaPlayer extends ShadowMediaPlayer {
-
- private static MediaPlayer sMediaPlayer = mock(MediaPlayer.class);
- private static int sResId;
-
- public static void reset() {
- sMediaPlayer = mock(MediaPlayer.class);
- sResId = 0;
- }
-
- @Implementation
- public static MediaPlayer create(Context context, int resId) {
- sResId = resId;
- return sMediaPlayer;
- }
-
- public static MediaPlayer getMock() {
- return sMediaPlayer;
- }
- }
-
- @Implements(Surface.class)
- @TargetApi(VERSION_CODES.HONEYCOMB)
- public static class ShadowSurface extends org.robolectric.shadows.ShadowSurface {
-
- @RealObject
- private Surface mRealSurface;
-
- public void __constructor__(SurfaceTexture surfaceTexture) {
- // Call the constructor on the real object, so that critical fields such as mLock is
- // initialized properly.
- Shadow.invokeConstructor(Surface.class, mRealSurface,
- ReflectionHelpers.ClassParameter.from(SurfaceTexture.class, surfaceTexture));
- super.__constructor__(surfaceTexture);
- }
- }
+ @Mock private SurfaceTexture surfaceTexture;
+
+ private IllustrationVideoView view;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ ShadowMediaPlayer.addMediaInfo(
+ DataSource.toDataSource(
+ "android.resource://" + application.getPackageName() + "/" + android.R.color.white),
+ new ShadowMediaPlayer.MediaInfo(100, 10));
+ ShadowMediaPlayer.addMediaInfo(
+ DataSource.toDataSource(
+ "android.resource://" + application.getPackageName() + "/" + android.R.color.black),
+ new ShadowMediaPlayer.MediaInfo(100, 10));
+ }
+
+ @Test
+ public void testPausedWhenWindowFocusLost() {
+ createDefaultView();
+ Robolectric.flushForegroundThreadScheduler();
+ view.start();
+
+ assertThat(view.mMediaPlayer).isNotNull();
+ assertThat(view.surface).isNotNull();
+
+ view.onWindowFocusChanged(false);
+ assertThat(getShadowMediaPlayer().getState()).isEqualTo(ShadowMediaPlayer.State.PAUSED);
+ }
+
+ @Test
+ public void testStartedWhenWindowFocusRegained() {
+ testPausedWhenWindowFocusLost();
+ Robolectric.flushForegroundThreadScheduler();
+
+ view.onWindowFocusChanged(true);
+ assertThat(getShadowMediaPlayer().getState()).isEqualTo(ShadowMediaPlayer.State.STARTED);
+ }
+
+ @Test
+ public void testSurfaceReleasedWhenTextureDestroyed() {
+ createDefaultView();
+ view.start();
+
+ assertThat(view.mMediaPlayer).isNotNull();
+ assertThat(view.surface).isNotNull();
+
+ // MediaPlayer is set to null after destroy. Retrieve it first before we call destroy.
+ ShadowMediaPlayer shadowMediaPlayer = getShadowMediaPlayer();
+ view.onSurfaceTextureDestroyed(surfaceTexture);
+ assertThat(shadowMediaPlayer.getState()).isEqualTo(ShadowMediaPlayer.State.END);
+ }
+
+ @Test
+ public void testXmlSetVideoResId() {
+ createDefaultView();
+ assertThat(getShadowMediaPlayer().getSourceUri().toString())
+ .isEqualTo("android.resource://com.android.setupwizardlib/" + android.R.color.white);
+ }
+
+ @Test
+ public void testSetVideoResId() {
+ createDefaultView();
+
+ @RawRes int black = android.R.color.black;
+ view.setVideoResource(black);
+
+ assertThat(getShadowMediaPlayer().getSourceUri().toString())
+ .isEqualTo("android.resource://com.android.setupwizardlib/" + android.R.color.black);
+ }
+
+ @Test
+ public void prepareVideo_shouldSetAspectRatio() {
+ createDefaultView();
+
+ ReflectionHelpers.setField(getShadowMediaPlayer(), "videoWidth", 720);
+ ReflectionHelpers.setField(getShadowMediaPlayer(), "videoHeight", 1280);
+
+ Robolectric.flushForegroundThreadScheduler();
+ view.start();
+
+ view.measure(
+ View.MeasureSpec.makeMeasureSpec(720, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(720, View.MeasureSpec.EXACTLY));
+
+ final float aspectRatio = (float) view.getMeasuredHeight() / view.getMeasuredWidth();
+ assertThat(aspectRatio).isWithin(0.001f).of(1280f / 720f);
+ }
+
+ @Test
+ public void prepareVideo_zeroHeight_shouldSetAspectRatioToZero() {
+ createDefaultView();
+
+ ReflectionHelpers.setField(getShadowMediaPlayer(), "videoWidth", 720);
+ ReflectionHelpers.setField(getShadowMediaPlayer(), "videoHeight", 0);
+
+ Robolectric.flushForegroundThreadScheduler();
+ view.start();
+
+ final float aspectRatio = (float) view.getHeight() / view.getWidth();
+ assertThat(aspectRatio).isEqualTo(0.0f);
+ }
+
+ @Test
+ public void setVideoResId_resetDiffVideoResFromDiffPackage_videoResShouldBeSet() {
+ // VideoRes default set as android.R.color.white with
+ // default package(com.android.setupwizardlib)
+ createDefaultView();
+
+ // reset different videoRes from different package
+ String newPackageName = "com.android.fakepackage";
+ @RawRes int black = android.R.color.black;
+ addMediaInfo(black, newPackageName);
+ view.setVideoResource(black, newPackageName);
+
+ // should be reset to black with the new package
+ assertThat(getShadowMediaPlayer().getSourceUri().toString())
+ .isEqualTo("android.resource://" + newPackageName + "/" + android.R.color.black);
+ }
+
+ @Test
+ public void setVideoResId_resetDiffVideoResFromSamePackage_videoResShouldBeSet() {
+ // VideoRes default set as android.R.color.white with
+ // default package(com.android.setupwizardlib)
+ createDefaultView();
+
+ // reset different videoRes from the same package(default package)
+ String defaultPackageName = "com.android.setupwizardlib";
+ @RawRes int black = android.R.color.black;
+ addMediaInfo(black, defaultPackageName);
+ view.setVideoResource(black, defaultPackageName);
+
+ // should be reset to black with the same package(default package)
+ assertThat(getShadowMediaPlayer().getSourceUri().toString())
+ .isEqualTo("android.resource://" + defaultPackageName + "/" + android.R.color.black);
+ }
+
+ @Test
+ public void setVideoResId_resetSameVideoResFromDifferentPackage_videoResShouldBeSet() {
+ // VideoRes default set as android.R.color.white with
+ // default package(com.android.setupwizardlib)
+ createDefaultView();
+
+ // reset same videoRes from different package
+ @RawRes int white = android.R.color.white;
+ String newPackageName = "com.android.fakepackage";
+ addMediaInfo(white, newPackageName);
+ view.setVideoResource(white, newPackageName);
+
+ // should be white with the new package
+ assertThat(getShadowMediaPlayer().getSourceUri().toString())
+ .isEqualTo("android.resource://" + newPackageName + "/" + android.R.color.white);
+ }
+
+ private ShadowMediaPlayer getShadowMediaPlayer() {
+ return Shadows.shadowOf(view.mMediaPlayer);
+ }
+
+ private void createDefaultView() {
+ view =
+ new IllustrationVideoView(
+ application,
+ Robolectric.buildAttributeSet()
+ // Any resource attribute should work, since the data source is fake
+ .addAttribute(R.attr.suwVideo, "@android:color/white")
+ .build());
+
+ Activity activity = Robolectric.setupActivity(Activity.class);
+ activity.setContentView(view);
+ setWindowVisible();
+
+ view.setSurfaceTexture(mock(SurfaceTexture.class));
+ view.onSurfaceTextureAvailable(surfaceTexture, 500, 500);
+ getShadowMediaPlayer().setInvalidStateBehavior(InvalidStateBehavior.EMULATE);
+ }
+
+ private void setWindowVisible() {
+ Object viewRootImpl = ReflectionHelpers.callInstanceMethod(view, "getViewRootImpl");
+ ReflectionHelpers.callInstanceMethod(
+ viewRootImpl, "handleAppVisibility", ClassParameter.from(boolean.class, true));
+ assertThat(view.isAttachedToWindow()).isTrue();
+ assertThat(view.getWindowVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ private void addMediaInfo(@RawRes int res, String packageName) {
+ ShadowMediaPlayer.addMediaInfo(
+ DataSource.toDataSource(
+ application, Uri.parse("android.resource://" + packageName + "/" + res), null),
+ new MediaInfo(5000, 1));
+ }
}