The _Frame Rate API_ allows applications to communicate their desired frame rate to the _Android platform_ to enhance the user experience. The API is useful since many devices now offer varying refresh rates like 60Hz, 90Hz, or 120Hz.

== Why is this an issue?

Standard applications don't require a display refresh rate above 60Hz, hence it is advisable to avoid higher frequencies to avoid unnecessary energy consumption.

The rule flags an issue when `setFrameRate()` is invoked with a frameRate higher than 60Hz for `android.view.Surface` and `android.view.SurfaceControl.Transaction`.

It's important to note that the scheduler considers several factors when determining the display refresh rate. Therefore, using `setFrameRate()` doesn't guarantee your app will achieve the requested frame rate.

=== What is the potential impact?

* _Usability_: the device may run out of battery faster than expected.
* _Sustainability_: the extra battery usage has a negative impact on the environment.

== How to fix it

Use a frame rate of maximum 60Hz, unless you have a strong reason to used higher rates.
Valid exceptions are _gaming apps_, especially those with fast-paced action or high-quality graphics, or _AR/VR apps_.

=== Code examples

==== Noncompliant code example

[source,java,diff-id=1,diff-type=noncompliant]
----
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SurfaceView surfaceView = findViewById(R.id.my_surface_view);
        Surface surface = surfaceView.getHolder().getSurface();

        surface.setFrameRate(90.0f, Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); // Noncompliant
    }
}
----

==== Compliant solution

[source,java,diff-id=1,diff-type=compliant]
----
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SurfaceView surfaceView = findViewById(R.id.my_surface_view);
        Surface surface = surfaceView.getHolder().getSurface();

        surface.setFrameRate(60.0f, Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); // Compliant
    }
}
----

//=== How does this work?

//=== Pitfalls

//=== Going the extra mile


== Resources
=== Documentation

* https://developer.android.com/media/optimize/performance/frame-rate[Android for Developers: Frame Rate]
* https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/MTLBestPracticesGuide/FrameRate.html#//apple_ref/doc/uid/TP40016642-CH23-SW1[Developer Apple - Frame Rate]

//=== Articles & blog posts
//=== Conference presentations
//=== Standards
//=== External coding guidelines
//=== Benchmarks
