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

Commit 1ce8dab2 authored by Mark Harman's avatar Mark Harman
Browse files

New testWindowInsets().

parent e3c62e92
Loading
Loading
Loading
Loading
+155 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ import android.annotation.TargetApi;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Insets;
import android.hardware.camera2.CameraExtensionCharacteristics;
import android.media.CamcorderProfile;
import android.os.Build;
@@ -21,6 +22,7 @@ import android.os.Looper;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.SeekBar;

import androidx.test.core.app.ApplicationProvider;
@@ -46,6 +48,8 @@ import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;

interface MainTests {}

interface PhotoTests {}

interface VideoTests {}
@@ -156,6 +160,13 @@ public class InstrumentedTest {
        }
    }

    private void restart() {
        Log.d(TAG, "restart");
        mActivityRule.getScenario().recreate();
        waitUntilCameraOpened();
        Log.d(TAG, "restart done");
    }

    private void pauseAndResume() {
        Log.d(TAG, "pauseAndResume");
        boolean camera_is_open = getActivityValue(activity -> activity.getPreview().getCameraController() != null);
@@ -6195,6 +6206,150 @@ public class InstrumentedTest {
        Log.d(TAG, "done taking photo");
    }

    /** Tests behaviour of the MainActivity.OnApplyWindowInsetsListener() for edge-to-edge mode on
     *  Android 15.
     */
    @Category(MainTests.class)
    @Test
    public void testWindowInsets() throws InterruptedException {
        Log.d(TAG, "testTakePhoto");
        setToDefault();

        if( !getActivityValue(MainActivity::getEdgeToEdgeMode) ) {
            Log.d(TAG, "test requires edge-to-edge mode");
            return;
        }

        MainActivity.test_force_system_orientation = true;
        MainActivity.test_force_window_insets = true;

        // portrait, typical with navigation at bottom, cutout at top
        MainActivity.test_system_orientation = MainActivity.SystemOrientation.PORTRAIT;
        MainActivity.test_insets = Insets.of(0, 200, 0, 300);
        MainActivity.test_cutout_insets = Insets.of(0, 200, 0, 0);
        restart(); // resstart to force OnApplyWindowInsetsListener() to be called with new test values
        mActivityRule.getScenario().onActivity(activity -> {
            assertEquals(300, activity.getNavigationGap());
            assertEquals(0, activity.getNavigationGapLandscape());
            assertEquals(0, activity.getNavigationGapReverseLandscape());
        });
        // landscape
        MainActivity.test_system_orientation = MainActivity.SystemOrientation.LANDSCAPE;
        MainActivity.test_insets = Insets.of(200, 0, 300, 0);
        MainActivity.test_cutout_insets = Insets.of(200, 0, 0, 0);
        restart(); // resstart to force OnApplyWindowInsetsListener() to be called with new test values
        mActivityRule.getScenario().onActivity(activity -> {
            assertEquals(300, activity.getNavigationGap());
            assertEquals(0, activity.getNavigationGapLandscape());
            assertEquals(0, activity.getNavigationGapReverseLandscape());
        });
        // reverse landscape
        MainActivity.test_system_orientation = MainActivity.SystemOrientation.REVERSE_LANDSCAPE;
        MainActivity.test_insets = Insets.of(300, 0, 200, 0);
        MainActivity.test_cutout_insets = Insets.of(0, 0, 200, 0);
        restart(); // resstart to force OnApplyWindowInsetsListener() to be called with new test values
        mActivityRule.getScenario().onActivity(activity -> {
            assertEquals(300, activity.getNavigationGap());
            assertEquals(0, activity.getNavigationGapLandscape());
            assertEquals(0, activity.getNavigationGapReverseLandscape());
        });

        // portrait, navigation at bottom, double cutout at top and bottom
        MainActivity.test_system_orientation = MainActivity.SystemOrientation.PORTRAIT;
        MainActivity.test_insets = Insets.of(0, 100, 0, 500);
        MainActivity.test_cutout_insets = Insets.of(0, 100, 0, 300);
        restart(); // resstart to force OnApplyWindowInsetsListener() to be called with new test values
        mActivityRule.getScenario().onActivity(activity -> {
            assertEquals(200, activity.getNavigationGap()); // should only include the gap for the navigation, not the bottom cutout
            assertEquals(0, activity.getNavigationGapLandscape());
            assertEquals(0, activity.getNavigationGapReverseLandscape());
        });
        // landscape
        MainActivity.test_system_orientation = MainActivity.SystemOrientation.LANDSCAPE;
        MainActivity.test_insets = Insets.of(100, 0, 500, 0);
        MainActivity.test_cutout_insets = Insets.of(100, 0, 300, 0);
        restart(); // resstart to force OnApplyWindowInsetsListener() to be called with new test values
        mActivityRule.getScenario().onActivity(activity -> {
            assertEquals(200, activity.getNavigationGap()); // should only include the gap for the navigation, not the bottom cutout
            assertEquals(0, activity.getNavigationGapLandscape());
            assertEquals(0, activity.getNavigationGapReverseLandscape());
        });
        // reverse landscape
        MainActivity.test_system_orientation = MainActivity.SystemOrientation.REVERSE_LANDSCAPE;
        MainActivity.test_insets = Insets.of(500, 0, 100, 0);
        MainActivity.test_cutout_insets = Insets.of(300, 0, 100, 0);
        restart(); // resstart to force OnApplyWindowInsetsListener() to be called with new test values
        mActivityRule.getScenario().onActivity(activity -> {
            assertEquals(200, activity.getNavigationGap()); // should only include the gap for the navigation, not the bottom cutout
            assertEquals(0, activity.getNavigationGapLandscape());
            assertEquals(0, activity.getNavigationGapReverseLandscape());
        });

        // portrait, no navigation bar, waterfall cutout
        MainActivity.test_system_orientation = MainActivity.SystemOrientation.PORTRAIT;
        MainActivity.test_insets = Insets.of(50, 100, 50, 100);
        MainActivity.test_cutout_insets = Insets.of(50, 100, 50, 100);
        restart(); // resstart to force OnApplyWindowInsetsListener() to be called with new test values
        mActivityRule.getScenario().onActivity(activity -> {
            // navigation gaps should be 0, as shouldn't include cutout
            assertEquals(0, activity.getNavigationGap());
            assertEquals(0, activity.getNavigationGapLandscape());
            assertEquals(0, activity.getNavigationGapReverseLandscape());
        });

        // landscape, navigation along landscape edge
        MainActivity.test_system_orientation = MainActivity.SystemOrientation.LANDSCAPE;
        MainActivity.test_insets = Insets.of(100, 0, 0, 250);
        MainActivity.test_cutout_insets = Insets.of(100, 0, 0, 0);
        restart(); // resstart to force OnApplyWindowInsetsListener() to be called with new test values
        mActivityRule.getScenario().onActivity(activity -> {
            assertEquals(0, activity.getNavigationGap());
            assertEquals(250, activity.getNavigationGapLandscape());
            assertEquals(0, activity.getNavigationGapReverseLandscape());
        });
        if( getActivityValue(activity -> activity.getPreview().usingCamera2API()) ) {
            // also test manual focus seekbar
            mActivityRule.getScenario().onActivity(activity -> {
                View focus_seekbar = activity.findViewById(R.id.focus_seekbar);
                assertEquals(focus_seekbar.getVisibility(), View.GONE);
            });
            switchToFocusValue("focus_mode_manual2");
            mActivityRule.getScenario().onActivity(activity -> {
                View focus_seekbar = activity.findViewById(R.id.focus_seekbar);
                assertEquals(focus_seekbar.getVisibility(), View.VISIBLE);
                RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)focus_seekbar.getLayoutParams();
                assertEquals(0, layoutParams.leftMargin);
                assertEquals(0, layoutParams.topMargin);
                assertEquals(0, layoutParams.rightMargin);
                assertEquals(250, layoutParams.bottomMargin);
            });
        }

        // reverse landscape, navigation along landscape edge
        MainActivity.test_system_orientation = MainActivity.SystemOrientation.REVERSE_LANDSCAPE;
        MainActivity.test_insets = Insets.of(0, 0, 100, 250);
        MainActivity.test_cutout_insets = Insets.of(0, 0, 100, 0);
        restart(); // resstart to force OnApplyWindowInsetsListener() to be called with new test values
        mActivityRule.getScenario().onActivity(activity -> {
            assertEquals(0, activity.getNavigationGap());
            assertEquals(0, activity.getNavigationGapLandscape());
            assertEquals(250, activity.getNavigationGapReverseLandscape());
        });
        if( getActivityValue(activity -> activity.getPreview().usingCamera2API()) ) {
            // also test manual focus seekbar
            switchToFocusValue("focus_mode_manual2");
            mActivityRule.getScenario().onActivity(activity -> {
                View focus_seekbar = activity.findViewById(R.id.focus_seekbar);
                assertEquals(focus_seekbar.getVisibility(), View.VISIBLE);
                RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)focus_seekbar.getLayoutParams();
                assertEquals(0, layoutParams.leftMargin);
                assertEquals(0, layoutParams.topMargin);
                assertEquals(0, layoutParams.rightMargin);
                assertEquals(0, layoutParams.bottomMargin);
            });
        }
    }

    private void subTestTouchToFocus(final boolean wait_after_focus, final boolean single_tap_photo, final boolean double_tap_photo, final boolean manual_can_auto_focus, final boolean can_focus_area, final String focus_value, final String focus_value_ui) throws InterruptedException {
        // touch to auto-focus with focus area (will also exit immersive mode)
        // autofocus shouldn't be immediately, but after a delay
+13 −0
Original line number Diff line number Diff line
package net.sourceforge.opencamera;

import org.junit.experimental.categories.Categories;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;

/** Tests that don't fit into another of the Test suites.
 */

@RunWith(Categories.class)
@Categories.IncludeCategory(MainTests.class)
@Suite.SuiteClasses({InstrumentedTest.class})
public class MainInstrumentedTests {}
+1 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ import org.junit.experimental.categories.Categories;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;

/** Tests related to taking photos; note that tests to do with photo mode that don't take photos are still part of MainTests.
/** Tests related to taking photos; note that tests to do with photo mode that don't take photos are still part of MainInstrumentedTests.
 */

@RunWith(Categories.class)
+15 −0
Original line number Diff line number Diff line
@@ -169,6 +169,11 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen
    public static volatile boolean test_preview_want_no_limits; // test flag, if set to true then instead use test_preview_want_no_limits_value; needs to be static, as it needs to be set before activity is created to take effect
    public static volatile boolean test_preview_want_no_limits_value;
    public volatile boolean test_set_show_under_navigation; // test flag, the value of enable for the last call of showUnderNavigation() (or false if not yet called)
    public static volatile boolean test_force_system_orientation; // test flag, if set to true, that getSystemOrientation() returns test_system_orientation
    public static volatile SystemOrientation test_system_orientation = SystemOrientation.PORTRAIT;
    public static volatile boolean test_force_window_insets; // test flag, if set to true, then the OnApplyWindowInsetsListener will read from the following flags
    public static volatile Insets test_insets; // test insets for WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout()
    public static volatile Insets test_cutout_insets; // test insets for WindowInsets.Type.displayCutout()

    // whether this is a multi-camera device (note, this isn't simply having more than 1 camera, but also having more than one with the same facing)
    // note that in most cases, code should check the MultiCamButtonPreferenceKey preference as well as the is_multi_cam flag,
@@ -1835,6 +1840,9 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen
     *  getDefaultDisplay().getRotation() changes after the configuration changes.
     */
    public SystemOrientation getSystemOrientation() {
        if( test_force_system_orientation ) {
            return test_system_orientation;
        }
        if( lock_to_landscape ) {
            return SystemOrientation.LANDSCAPE;
        }
@@ -3825,6 +3833,10 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen
                        // Open Camera view
                        Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout());
                        Insets cutout_insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.displayCutout());
                        if( test_force_window_insets ) {
                            insets = test_insets;
                            cutout_insets = test_cutout_insets;
                        }
                        inset_left = insets.left - cutout_insets.left;
                        inset_top = insets.top - cutout_insets.top;
                        inset_right = insets.right - cutout_insets.right;
@@ -3847,6 +3859,9 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen
                        // easier to ensure the entire activity avoids display cutouts - for the preview, we still support
                        // it showing under the navigation bar
                        Insets insets = windowInsets.getInsets(WindowInsets.Type.displayCutout());
                        if( test_force_window_insets ) {
                            insets = test_cutout_insets;
                        }
                        v.setPadding(insets.left, insets.top, insets.right, insets.bottom);

                        // also handle change of immersive mode (instead of using deprecated setOnSystemUiVisibilityChangeListener below