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

Commit 3b237ae7 authored by Greg Kaiser's avatar Greg Kaiser
Browse files

BouncyBall: Prefer to run the test at 60Hz

Many devices default to higher resolutions than 60Hz.  We have
our app prefer 60Hz, if it's available.  Otherwise, we test with
the lowest refresh rate above 60Hz.  If the device doesn't support
at least 60Hz, we abort in failure.

Bug: 408044970
Test: Locally ran on 90Hz device, which dialed back to 60Hz for this; tried on 60Hz device; tried on default 60Hz device supporting 90Hz with DESIRED_FRAME_RATE hacked to 80 and it switched to 90Hz; tried on device supporting max 90Hz with DESIRED_FRAME_RATE hacked to 100 and it aborted.
Flag: EXEMPT for test app
Change-Id: I2a7400931af2f842fb5865622ff4a48089caae08
parent d32e7863
Loading
Loading
Loading
Loading
+92 −0
Original line number Diff line number Diff line
@@ -16,18 +16,110 @@

package com.prefabulated.bouncyball;

import android.hardware.display.DisplayManager;
import android.os.Bundle;
import android.os.Trace;
import android.util.Log;
import android.view.Display;
import android.view.Window;
import android.view.WindowManager;

import androidx.appcompat.app.AppCompatActivity;

import java.util.concurrent.Executors;

public class BouncyBallActivity extends AppCompatActivity {
    private static final String LOG_TAG = "BouncyBall";
    private static final float DESIRED_FRAME_RATE = 60.0f;

    private int mDisplayId = -1;
    private float mFrameRate;
    private final DisplayManager.DisplayListener mDisplayListener =
            new DisplayManager.DisplayListener() {

                @Override
                public void onDisplayAdded(int ignored) { /* Don't care. */ }

                @Override
                public void onDisplayRemoved(int ignored) { /* Don't care. */ }

                @Override
                public void onDisplayChanged(int displayId) {
                    if (displayId != mDisplayId) {
                        return;
                    }
                    mFrameRate = getDisplay().getMode().getRefreshRate();
                    Log.d(LOG_TAG, "Using frame rate " + mFrameRate + "Hz");
                }
            };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Trace.beginSection("BouncyBallActivity onCreate");
        setContentView(R.layout.activity_bouncy_ball);

        DisplayManager manager = getSystemService(DisplayManager.class);
        manager.registerDisplayListener(Executors.newSingleThreadExecutor(),
                                        DisplayManager.EVENT_TYPE_DISPLAY_REFRESH_RATE,
                                        mDisplayListener);

        setFrameRatePreference();
        Trace.endSection();
    }

    // If available at our current resolution, use 60Hz.  If not, use the
    // lowest refresh rate above 60Hz which is available.  Otherwise, throw
    // an exception which kills the app.
    //
    // The philosophy is that, for now, we only require this test to run
    // solidly at 60Hz.  If a device has a higher refresh rate than that,
    // we slow it down to 60Hz to make this easier to pass.  If a device
    // isn't able to go all the way down to 60Hz, we use the lowest refresh
    // rate above 60Hz.  If the device only supports below 30Hz, that's below
    // our standards so we abort.
    private void setFrameRatePreference() {
        float preferredRate = Float.POSITIVE_INFINITY;

        Display display = getDisplay();
        Display.Mode currentMode = display.getMode();
        mDisplayId = display.getDisplayId();
        mFrameRate = currentMode.getRefreshRate();
        if (mFrameRate == DESIRED_FRAME_RATE) {
            Log.d(LOG_TAG, "Already running at " + mFrameRate + "Hz");
            // We're already using what we want.  Nothing to do here.
            return;
        }

        for (Display.Mode mode : display.getSupportedModes()) {
            if ((currentMode.getPhysicalHeight() != mode.getPhysicalHeight())
                    || (currentMode.getPhysicalWidth() != mode.getPhysicalWidth())) {
                // This is a different resolution; we'll skip it.
                continue;
            }
            float rate = mode.getRefreshRate();
            if (rate == DESIRED_FRAME_RATE) {
                // This is exactly what we were hoping for, so we can stop
                // looking.
                preferredRate = rate;
                break;
            }
            if ((rate > DESIRED_FRAME_RATE) && (rate < preferredRate)) {
                // This is the best rate we've seen so far in terms of being
                // closest to our desired rate without being under it.
                preferredRate = rate;
            }
        }
        if (preferredRate == Float.POSITIVE_INFINITY) {
            String msg = "No display mode with at least " + DESIRED_FRAME_RATE + "Hz";
            throw new RuntimeException(msg);
        }
        Log.d(LOG_TAG, "Changing preferred rate from " + mFrameRate + "Hz to "
                + preferredRate + "Hz");
        Window window = getWindow();
        WindowManager.LayoutParams params = window.getAttributes();
        params.preferredRefreshRate = preferredRate;
        window.setAttributes(params);
    }
}