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:
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user