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

Commit 01ff3b3c authored by Perry Wu's avatar Perry Wu
Browse files

[Flicker] Add test for entering PIP with source rect hint

Adds flicker test for the CUJ with entering pip with source rect hint.
This specifically tests with auto enter enabled, but we can probably
add a separate case for entering manually. The test uses a rectangle
as the source rect, and there is a jump at the end of the transition
as the app doesn't update the layout for pip, but this is more of an
app issue and doesn't affect the test case.

Flags: N/A
Bug: 284200208
Test: atest EnterPipWithSourceRectHintTest
Change-Id: I47ab50f19dc421dc0e0262c7b14f5b37dfb3551e
parent 2bcb9138
Loading
Loading
Loading
Loading
+86 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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

import android.platform.test.annotations.Presubmit
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized

/**
 * Test auto entering pip using a source rect hint.
 *
 * To run this test: `atest AutoEnterPipWithSourceRectHintTest`
 *
 * Actions:
 * ```
 *     Launch an app in full screen
 *     Select "Auto-enter PiP" radio button
 *     Press "Set SourceRectHint" to create a temporary view that is used as the source rect hint
 *     Press Home button or swipe up to go Home and put [pipApp] in pip mode
 * ```
 *
 * Notes:
 * ```
 *     1. All assertions are inherited from [AutoEnterPipOnGoToHomeTest]
 *     2. Part of the test setup occurs automatically via
 *        [android.tools.device.flicker.legacy.runner.TransitionRunner],
 *        including configuring navigation mode, initial orientation and ensuring no
 *        apps are running before setup
 * ```
 */
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class AutoEnterPipWithSourceRectHintTest(flicker: LegacyFlickerTest) :
    AutoEnterPipOnGoToHomeTest(flicker) {
    override val defaultEnterPip: FlickerBuilder.() -> Unit = {
        setup {
            pipApp.launchViaIntent(wmHelper)
            pipApp.setSourceRectHint()
            pipApp.enableAutoEnterForPipActivity()
        }
    }

    @Presubmit
    @Test
    fun pipOverlayNotShown() {
        val overlay = ComponentNameMatcher.PIP_CONTENT_OVERLAY
        flicker.assertLayers {
            this.notContains(overlay)
        }
    }
    @Presubmit
    @Test
    override fun pipOverlayLayerAppearThenDisappear() {
        // we don't use overlay when entering with sourceRectHint
    }

    @Presubmit
    @Test
    override fun pipLayerOrOverlayRemainInsideVisibleBounds() {
        // TODO (b/323511194): Looks like there is some bounciness with pip when using
        // auto enter and sourceRectHint that causes the app to move outside of the display
        // bounds during the transition.
    }
}
 No newline at end of file
+5 −0
Original line number Diff line number Diff line
@@ -296,6 +296,10 @@ open class PipAppHelper(instrumentation: Instrumentation) :
        clickObject(MEDIA_SESSION_START_RADIO_BUTTON_ID)
    }

    fun setSourceRectHint() {
        clickObject(SOURCE_RECT_HINT)
    }

    fun checkWithCustomActionsCheckbox() =
        uiDevice
            .findObject(By.res(packageName, WITH_CUSTOM_ACTIONS_BUTTON_ID))
@@ -444,6 +448,7 @@ open class PipAppHelper(instrumentation: Instrumentation) :
        private const val MEDIA_SESSION_START_RADIO_BUTTON_ID = "media_session_start"
        private const val ENTER_PIP_ON_USER_LEAVE_HINT = "enter_pip_on_leave_manual"
        private const val ENTER_PIP_AUTOENTER = "enter_pip_on_leave_autoenter"
        private const val SOURCE_RECT_HINT = "set_source_rect_hint"
        // minimum number of steps to take, when animating gestures, needs to be 2
        // so that there is at least a single intermediate layer that flicker tests can check
        private const val MIN_STEPS_TO_ANIMATE = 2
+16 −0
Original line number Diff line number Diff line
@@ -27,6 +27,15 @@
         where things are arranged differently and to circle back up to the top once we reach the
         bottom. -->

    <!-- View used for testing sourceRectHint. -->
    <View
        android:id="@+id/source_rect"
        android:layout_width="320dp"
        android:layout_height="180dp"
        android:visibility="gone"
        android:background="@android:color/holo_green_light"
        />

    <Button
        android:id="@+id/enter_pip"
        android:layout_width="wrap_content"
@@ -113,6 +122,13 @@
            android:onClick="onRatioSelected"/>
    </RadioGroup>

    <Button
        android:id="@+id/set_source_rect_hint"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Set SourceRectHint"
        android:onClick="setSourceRectHint"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
+25 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Rect;
import android.graphics.drawable.Icon;
import android.media.MediaMetadata;
import android.media.session.MediaSession;
@@ -45,6 +46,7 @@ import android.os.Bundle;
import android.util.Log;
import android.util.Rational;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.widget.CheckBox;
@@ -248,6 +250,29 @@ public class PipActivity extends Activity {
        }
    }

    /**
     * Adds a temporary view used for testing sourceRectHint.
     *
     */
    public void setSourceRectHint(View v) {
        View rectView = findViewById(R.id.source_rect);
        if (rectView != null) {
            rectView.setVisibility(View.VISIBLE);
            rectView.getViewTreeObserver().addOnGlobalLayoutListener(
                    new ViewTreeObserver.OnGlobalLayoutListener() {
                        @Override
                        public void onGlobalLayout() {
                            Rect boundingRect = new Rect();
                            rectView.getGlobalVisibleRect(boundingRect);
                            mPipParamsBuilder.setSourceRectHint(boundingRect);
                            setPictureInPictureParams(mPipParamsBuilder.build());
                            rectView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        }
                    });
            rectView.invalidate(); // changing the visibility, invalidating to redraw the view
        }
    }

    public void onRatioSelected(View v) {
        switch (v.getId()) {
            case R.id.ratio_default: