Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 160bd0f0 authored by Sergey Nikolaienkov's avatar Sergey Nikolaienkov
Browse files

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
parent 0451222a
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -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) {
+87 −0
Original line number Diff line number Diff line
/*
 * 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)
            )
        }
    }
}
 No newline at end of file
+42 −1
Original line number Diff line number Diff line
@@ -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"
+33 −6
Original line number Diff line number Diff line
@@ -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;