1 package com.android.systemui.animation
2 
3 import android.view.View
4 import android.window.SurfaceSyncGroup
5 
6 /** A util class to synchronize 2 view roots. */
7 // TODO(b/200284684): Remove this class.
8 object ViewRootSync {
9 
10     /**
11      * Synchronize the next draw between the view roots of [view] and [otherView], then run [then].
12      *
13      * Note that in some cases, the synchronization might not be possible (e.g. WM consumed the next
14      * transactions) or disabled (temporarily, on low ram devices). In this case, [then] will be
15      * called without synchronizing.
16      */
17     fun synchronizeNextDraw(view: View, otherView: View, then: () -> Unit) {
18         if (
19             !view.isAttachedToWindow ||
20                 view.viewRootImpl == null ||
21                 !otherView.isAttachedToWindow ||
22                 otherView.viewRootImpl == null ||
23                 view.viewRootImpl == otherView.viewRootImpl
24         ) {
25             // No need to synchronize if either the touch surface or dialog view is not attached
26             // to a window.
27             then()
28             return
29         }
30 
31         val syncGroup = SurfaceSyncGroup("SysUIAnimation")
32         syncGroup.addSyncCompleteCallback(view.context.mainExecutor) { then() }
33         syncGroup.add(view.rootSurfaceControl, null /* runnable */)
34         syncGroup.add(otherView.rootSurfaceControl, null /* runnable */)
35         syncGroup.markSyncReady()
36     }
37 
38     /** A Java-friendly API for [synchronizeNextDraw]. */
39     @JvmStatic
40     fun synchronizeNextDraw(view: View, otherView: View, then: Runnable) {
41         synchronizeNextDraw(view, otherView, then::run)
42     }
43 }
44