Merge changes I9a138ba9,Ied62beb0

* changes:
  Test PiP on TV with different aspect ratios
  Always run TV PiP tests with 0 rotation
This commit is contained in:
Sergey Nikolaienkov
2020-11-17 07:39:09 +00:00
committed by Android (Google) Code Review
7 changed files with 171 additions and 38 deletions

View File

@@ -29,6 +29,7 @@ import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME
import com.android.wm.shell.flicker.TEST_APP_PIP_ACTIVITY_COMPONENT_NAME
import com.android.wm.shell.flicker.TEST_APP_PIP_ACTIVITY_LABEL
import org.junit.Assert.assertNotNull
import org.junit.Assert.fail
class PipAppHelper(
instrumentation: Instrumentation
@@ -46,11 +47,12 @@ class PipAppHelper(
it.packageName == packageName
}
fun clickButton(resourceId: String) =
uiDevice.findObject(By.res(packageName, resourceId))?.click()
?: fail("$resourceId button is not found")
fun clickEnterPipButton() {
val enterPipButton = uiDevice.findObject(By.res(packageName, "enter_pip"))
assertNotNull("Pip button not found, this usually happens when the device " +
"was left in an unknown state (e.g. in split screen)", enterPipButton)
enterPipButton.click()
clickButton("enter_pip")
// TODO(b/172321238): remove this check once hasPipWindow is fixed on TVs
if (!isTelevision) {

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2020 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.wm.shell.flicker.pip.tv
import android.graphics.Rect
import android.util.Rational
import androidx.test.filters.RequiresDevice
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
/**
* Test Pip Menu on TV.
* To run this test: `atest WMShellFlickerTests:TvPipBasicTest`
*/
@RequiresDevice
@RunWith(Parameterized::class)
class TvPipBasicTest(
private val radioButtonId: String,
private val pipWindowRatio: Rational?
) : TvPipTestBase() {
@Test
fun enterPip_openMenu_pressBack_closePip() {
// Launch test app
testApp.launchViaIntent()
// Set up ratio and enter Pip
testApp.clickButton(radioButtonId)
testApp.clickEnterPipButton()
val actualRatio: Float = testApp.ui?.visibleBounds?.ratio
?: fail("Application UI not found")
pipWindowRatio?.let { expectedRatio ->
assertEquals("Wrong Pip window ratio", expectedRatio.toFloat(), actualRatio)
}
// Pressing the Window key should bring up Pip menu
uiDevice.pressWindowKey()
uiDevice.waitForTvPipMenu() ?: fail("Pip menu should have been shown")
// Pressing the Back key should close the Pip menu
uiDevice.pressBack()
assertTrue("Pip menu should have closed", uiDevice.waitForTvPipMenuToClose())
// Make sure Pip Window ration remained the same after Pip menu was closed
testApp.ui?.visibleBounds?.let { newBounds ->
assertEquals("Pip window ratio has changed", actualRatio, newBounds.ratio)
} ?: fail("Application UI not found")
// Close Pip
testApp.closePipWindow()
}
private val Rect.ratio: Float
get() = width().toFloat() / height()
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<Array<Any?>> {
infix fun Int.to(denominator: Int) = Rational(this, denominator)
return listOf(
arrayOf("ratio_default", null),
arrayOf("ratio_square", 1 to 1),
arrayOf("ratio_wide", 2 to 1),
arrayOf("ratio_tall", 1 to 2)
)
}
}
}

View File

@@ -23,17 +23,13 @@ import com.android.wm.shell.flicker.wait
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
/**
* Test Pip Menu on TV.
* To run this test: `atest WMShellFlickerTests:TvPipMenuTests`
*/
@RequiresDevice
@RunWith(Parameterized::class)
class TvPipMenuTests(rotationName: String, rotation: Int)
: TvPipTestBase(rotationName, rotation) {
class TvPipMenuTests : TvPipTestBase() {
private val systemUiResources =
packageManager.getResourcesForApplication(SYSTEM_UI_PACKAGE_NAME)
@@ -144,10 +140,4 @@ class TvPipMenuTests(rotationName: String, rotation: Int)
uiDevice.pressWindowKey()
return uiDevice.waitForTvPipMenu() ?: fail("Pip menu should have been shown")
}
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<Array<Any>> = rotationParams
}
}

View File

@@ -32,18 +32,13 @@ import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
/**
* Test Pip Notifications on TV.
* To run this test: `atest WMShellFlickerTests:TvPipNotificationTests`
*/
@RequiresDevice
@RunWith(Parameterized::class)
class TvPipNotificationTests(rotationName: String, rotation: Int)
: TvPipTestBase(rotationName, rotation) {
class TvPipNotificationTests : TvPipTestBase() {
@Before
override fun setUp() {
super.setUp()
@@ -154,10 +149,6 @@ class TvPipNotificationTests(rotationName: String, rotation: Int)
companion object {
private const val TITLE_MEDIA_SESSION_PLAYING = "TestApp media is playing"
private const val TITLE_MEDIA_SESSION_PAUSED = "TestApp media is paused"
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<Array<Any>> = rotationParams
}
}

View File

@@ -32,8 +32,7 @@ import org.junit.Assert.assertFalse
import org.junit.Assume
import org.junit.Before
abstract class TvPipTestBase(rotationName: String, rotation: Int)
: PipTestBase(rotationName, rotation) {
abstract class TvPipTestBase : PipTestBase(rotationToString(ROTATION_0), ROTATION_0) {
private val isTelevision: Boolean
get() = packageManager.run {
@@ -93,9 +92,5 @@ abstract class TvPipTestBase(rotationName: String, rotation: Int)
companion object {
private const val AFTER_TEXT_PROCESS_CHECK_DELAY = 1_000L // 1 sec
@JvmStatic
protected val rotationParams: Collection<Array<Any>> =
listOf(arrayOf(rotationToString(ROTATION_0), ROTATION_0))
}
}

View File

@@ -25,7 +25,48 @@
android:id="@+id/enter_pip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enter PIP"/>
android:text="Enter PIP"
android:onClick="enterPip"/>
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:checkedButton="@id/ratio_default">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ratio"/>
<RadioButton
android:id="@+id/ratio_default"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Default"
android:onClick="onRatioSelected"/>
<RadioButton
android:id="@+id/ratio_square"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Square [1:1]"
android:onClick="onRatioSelected"/>
<RadioButton
android:id="@+id/ratio_wide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Wide [2:1]"
android:onClick="onRatioSelected"/>
<RadioButton
android:id="@+id/ratio_tall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tall [1:2]"
android:onClick="onRatioSelected"/>
</RadioGroup>
<TextView
android:layout_width="wrap_content"

View File

@@ -26,12 +26,12 @@ import static android.media.session.PlaybackState.STATE_STOPPED;
import android.app.Activity;
import android.app.PictureInPictureParams;
import android.graphics.Rect;
import android.media.MediaMetadata;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
import android.os.Bundle;
import android.util.Rational;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
@@ -47,6 +47,12 @@ public class PipActivity extends Activity {
*/
private static final String TITLE_STATE_PAUSED = "TestApp media is paused";
private static final Rational RATIO_DEFAULT = null;
private static final Rational RATIO_SQUARE = new Rational(1, 1);
private static final Rational RATIO_WIDE = new Rational(2, 1);
private static final Rational RATIO_TALL = new Rational(1, 2);
private PictureInPictureParams.Builder mPipParamsBuilder;
private MediaSession mMediaSession;
private final PlaybackState.Builder mPlaybackStateBuilder = new PlaybackState.Builder()
.setActions(ACTION_PLAY | ACTION_PAUSE | ACTION_STOP)
@@ -66,11 +72,8 @@ public class PipActivity extends Activity {
setContentView(R.layout.activity_pip);
final PictureInPictureParams pipParams = new PictureInPictureParams.Builder()
.setAspectRatio(new Rational(1, 1))
.setSourceRectHint(new Rect(0, 0, 100, 100))
.build();
findViewById(R.id.enter_pip).setOnClickListener(v -> enterPictureInPictureMode(pipParams));
mPipParamsBuilder = new PictureInPictureParams.Builder()
.setAspectRatio(RATIO_DEFAULT);
findViewById(R.id.media_session_start)
.setOnClickListener(v -> updateMediaSessionState(STATE_PLAYING));
@@ -97,6 +100,30 @@ public class PipActivity extends Activity {
});
}
public void enterPip(View v) {
enterPictureInPictureMode(mPipParamsBuilder.build());
}
public void onRatioSelected(View v) {
switch (v.getId()) {
case R.id.ratio_default:
mPipParamsBuilder.setAspectRatio(RATIO_DEFAULT);
break;
case R.id.ratio_square:
mPipParamsBuilder.setAspectRatio(RATIO_SQUARE);
break;
case R.id.ratio_wide:
mPipParamsBuilder.setAspectRatio(RATIO_WIDE);
break;
case R.id.ratio_tall:
mPipParamsBuilder.setAspectRatio(RATIO_TALL);
break;
}
}
private void updateMediaSessionState(int newState) {
if (mPlaybackState.getState() == newState) {
return;