summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Sunny Goyal <sunnygoyal@google.com> 2025-03-18 14:43:53 -0700
committer Sunny Goyal <sunnygoyal@google.com> 2025-03-24 08:51:53 -0700
commit836a832bfe4de06ab5ebec4fe3aaa8f44392bbd4 (patch)
tree0d555f51f5af44ed36de9172f15405dc97eeeac2
parent91a081f26c9f2c25fd2b5cb97bc7487cd6f1f45a (diff)
Using Choreographer for getting refreshrate instead of display manager
Bug: 404582684 Flag: EXEMPT bugfix Test: Manually verified that values are same as before even after changing refresh rate `adb shell settings put system peak_refresh_rate [30/60/90/120]` Change-Id: I5d5468d8ab81a9a5e8d8cd67a9097423b750edb3
-rw-r--r--quickstep/src/com/android/launcher3/dagger/Modules.kt6
-rw-r--r--quickstep/src/com/android/quickstep/util/ChoreographerFrameRateTracker.kt31
-rw-r--r--src/com/android/launcher3/dagger/LauncherBaseAppComponent.java1
-rw-r--r--src/com/android/launcher3/util/window/RefreshRateTracker.java92
-rw-r--r--src/com/android/launcher3/util/window/RefreshRateTracker.kt70
-rw-r--r--src_no_quickstep/com/android/launcher3/dagger/Modules.kt7
6 files changed, 114 insertions, 93 deletions
diff --git a/quickstep/src/com/android/launcher3/dagger/Modules.kt b/quickstep/src/com/android/launcher3/dagger/Modules.kt
index 7671a82869..9723b42c62 100644
--- a/quickstep/src/com/android/launcher3/dagger/Modules.kt
+++ b/quickstep/src/com/android/launcher3/dagger/Modules.kt
@@ -21,8 +21,10 @@ import com.android.launcher3.uioverrides.SystemApiWrapper
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapperImpl
import com.android.launcher3.util.ApiWrapper
import com.android.launcher3.util.PluginManagerWrapper
+import com.android.launcher3.util.window.RefreshRateTracker
import com.android.launcher3.util.window.WindowManagerProxy
import com.android.launcher3.widget.LauncherWidgetHolder.WidgetHolderFactory
+import com.android.quickstep.util.ChoreographerFrameRateTracker
import com.android.quickstep.util.GestureExclusionManager
import com.android.quickstep.util.SystemWindowManagerProxy
import dagger.Binds
@@ -60,4 +62,8 @@ object StaticObjectModule {
@Provides
@JvmStatic
fun provideGestureExclusionManager(): GestureExclusionManager = GestureExclusionManager.INSTANCE
+
+ @Provides
+ @JvmStatic
+ fun provideRefreshRateTracker(): RefreshRateTracker = ChoreographerFrameRateTracker
}
diff --git a/quickstep/src/com/android/quickstep/util/ChoreographerFrameRateTracker.kt b/quickstep/src/com/android/quickstep/util/ChoreographerFrameRateTracker.kt
new file mode 100644
index 0000000000..1b61a6af6b
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/ChoreographerFrameRateTracker.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2025 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.quickstep.util
+
+import android.util.TimeUtils
+import android.view.Choreographer
+import com.android.launcher3.util.window.RefreshRateTracker
+
+/** [RefreshRateTracker] using main thread [Choreographer] */
+object ChoreographerFrameRateTracker : RefreshRateTracker {
+
+ override val singleFrameMs: Int
+ get() =
+ Choreographer.getMainThreadInstance()?.let {
+ (it.frameIntervalNanos / TimeUtils.NANOS_PER_MS).toInt().coerceAtLeast(1)
+ } ?: 1
+}
diff --git a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
index f86772e5f5..c95c376290 100644
--- a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
+++ b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
@@ -91,6 +91,7 @@ public interface LauncherBaseAppComponent {
LoaderCursorFactory getLoaderCursorFactory();
WidgetHolderFactory getWidgetHolderFactory();
+ RefreshRateTracker getFrameRateProvider();
/** Builder for LauncherBaseAppComponent. */
interface Builder {
diff --git a/src/com/android/launcher3/util/window/RefreshRateTracker.java b/src/com/android/launcher3/util/window/RefreshRateTracker.java
deleted file mode 100644
index e3397d4359..0000000000
--- a/src/com/android/launcher3/util/window/RefreshRateTracker.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2022 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.launcher3.util.window;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-
-import android.content.Context;
-import android.hardware.display.DisplayManager;
-import android.hardware.display.DisplayManager.DisplayListener;
-import android.view.Display;
-
-import androidx.annotation.WorkerThread;
-
-import com.android.launcher3.dagger.ApplicationContext;
-import com.android.launcher3.dagger.LauncherAppComponent;
-import com.android.launcher3.dagger.LauncherAppSingleton;
-import com.android.launcher3.util.DaggerSingletonObject;
-import com.android.launcher3.util.DaggerSingletonTracker;
-import com.android.launcher3.util.SafeCloseable;
-
-import javax.inject.Inject;
-
-/**
- * Utility class to track refresh rate of the current device
- */
-@LauncherAppSingleton
-public class RefreshRateTracker implements DisplayListener, SafeCloseable {
-
- private static final DaggerSingletonObject<RefreshRateTracker> INSTANCE =
- new DaggerSingletonObject<>(LauncherAppComponent::getRefreshRateTracker);
-
- private int mSingleFrameMs = 1;
-
- private final DisplayManager mDM;
-
- @Inject
- RefreshRateTracker(@ApplicationContext Context context, DaggerSingletonTracker tracker) {
- mDM = context.getSystemService(DisplayManager.class);
- updateSingleFrameMs();
- mDM.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
- tracker.addCloseable(this);
- }
-
- /**
- * Returns the single frame time in ms
- */
- public static int getSingleFrameMs(Context context) {
- return INSTANCE.get(context).mSingleFrameMs;
- }
-
- @Override
- public final void onDisplayAdded(int displayId) { }
-
- @Override
- public final void onDisplayRemoved(int displayId) { }
-
- @WorkerThread
- @Override
- public final void onDisplayChanged(int displayId) {
- if (displayId == DEFAULT_DISPLAY) {
- updateSingleFrameMs();
- }
- }
-
- private void updateSingleFrameMs() {
- Display display = mDM.getDisplay(DEFAULT_DISPLAY);
- if (display != null) {
- float refreshRate = display.getRefreshRate();
- mSingleFrameMs = refreshRate > 0 ? (int) (1000 / refreshRate) : 16;
- }
- }
-
- @Override
- public void close() {
- mDM.unregisterDisplayListener(this);
- }
-}
diff --git a/src/com/android/launcher3/util/window/RefreshRateTracker.kt b/src/com/android/launcher3/util/window/RefreshRateTracker.kt
new file mode 100644
index 0000000000..577fec1136
--- /dev/null
+++ b/src/com/android/launcher3/util/window/RefreshRateTracker.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2025 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.launcher3.util.window
+
+import android.content.Context
+import android.hardware.display.DisplayManager
+import android.hardware.display.DisplayManager.DisplayListener
+import android.view.Display.DEFAULT_DISPLAY
+import com.android.launcher3.dagger.ApplicationContext
+import com.android.launcher3.dagger.LauncherAppSingleton
+import com.android.launcher3.dagger.LauncherComponentProvider.appComponent
+import com.android.launcher3.util.DaggerSingletonTracker
+import com.android.launcher3.util.Executors
+import javax.inject.Inject
+
+/** Utility class to track refresh rate of the current device */
+interface RefreshRateTracker {
+
+ val singleFrameMs: Int
+
+ @LauncherAppSingleton
+ class RefreshRateTrackerImpl
+ @Inject
+ constructor(@ApplicationContext ctx: Context, tracker: DaggerSingletonTracker) :
+ RefreshRateTracker, DisplayListener {
+
+ private val displayManager: DisplayManager =
+ ctx.getSystemService(DisplayManager::class.java)!!.also {
+ it.registerDisplayListener(this, Executors.UI_HELPER_EXECUTOR.handler)
+ tracker.addCloseable { it.unregisterDisplayListener(this) }
+ }
+
+ override var singleFrameMs: Int = updateSingleFrameMs()
+
+ private fun updateSingleFrameMs(): Int {
+ val refreshRate = displayManager.getDisplay(DEFAULT_DISPLAY)?.refreshRate
+ return if (refreshRate != null && refreshRate > 0) (1000 / refreshRate).toInt() else 16
+ }
+
+ override fun onDisplayChanged(displayId: Int) {
+ if (displayId == DEFAULT_DISPLAY) {
+ singleFrameMs = updateSingleFrameMs()
+ }
+ }
+
+ override fun onDisplayAdded(displayId: Int) {}
+
+ override fun onDisplayRemoved(displayId: Int) {}
+ }
+
+ companion object {
+
+ /** Returns the single frame time in ms */
+ @JvmStatic fun Context.getSingleFrameMs() = appComponent.frameRateProvider.singleFrameMs
+ }
+}
diff --git a/src_no_quickstep/com/android/launcher3/dagger/Modules.kt b/src_no_quickstep/com/android/launcher3/dagger/Modules.kt
index 7dbe9c3119..21d8e06cdd 100644
--- a/src_no_quickstep/com/android/launcher3/dagger/Modules.kt
+++ b/src_no_quickstep/com/android/launcher3/dagger/Modules.kt
@@ -16,6 +16,8 @@
package com.android.launcher3.dagger
+import com.android.launcher3.util.window.RefreshRateTracker
+import com.android.launcher3.util.window.RefreshRateTracker.RefreshRateTrackerImpl
import com.android.launcher3.widget.LauncherWidgetHolder.WidgetHolderFactory
import com.android.launcher3.widget.LauncherWidgetHolder.WidgetHolderFactoryImpl
import dagger.Binds
@@ -35,7 +37,10 @@ abstract class WidgetModule {
@Module abstract class PluginManagerWrapperModule {}
-@Module object StaticObjectModule {}
+@Module
+abstract class StaticObjectModule {
+ @Binds abstract fun bindRefreshRateTracker(tracker: RefreshRateTrackerImpl): RefreshRateTracker
+}
// Module containing bindings for the final derivative app
@Module abstract class AppModule {}