Test PiP on TV with different aspect ratios

Introduce TvPipBasicTest that runs a basic Pip scenario:
1) enter Pip;
2) open Pip menu using the Window button;
3) close Pip menu using the Back button;
4) close Pip.
The test runs with 4 times with different Pip window aspect ratios:
defaul; square(1:1); wide(2:1); tall(1:2).

Bug: 13054136
Test: atest WMShellFlickerTests:TvPipBasicPipTest
Change-Id: I9a138ba9daaac223d451bac750e6a028def0a468
This commit is contained in:
Sergey Nikolaienkov
2020-11-13 12:59:06 +00:00
parent 0451222aed
commit 160bd0f088
4 changed files with 168 additions and 11 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

@@ -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;