Loading core/java/android/view/ISurfaceControlViewHost.aidl +10 −4 Original line number Diff line number Diff line Loading @@ -19,13 +19,19 @@ package android.view; import android.content.res.Configuration; import android.graphics.Rect; import android.view.InsetsState; import android.window.ISurfaceSyncGroup; /** * API from content embedder back to embedded content in SurfaceControlViewHost * {@hide} */ oneway interface ISurfaceControlViewHost { void onConfigurationChanged(in Configuration newConfig); void onDispatchDetachedFromWindow(); void onInsetsChanged(in InsetsState state, in Rect insetFrame); interface ISurfaceControlViewHost { /** * TODO (b/263273252): Investigate the need for these to be blocking calls or add additional * APIs that are blocking */ oneway void onConfigurationChanged(in Configuration newConfig); oneway void onDispatchDetachedFromWindow(); oneway void onInsetsChanged(in InsetsState state, in Rect insetFrame); ISurfaceSyncGroup getSurfaceSyncGroup(); } core/java/android/view/IWindowManager.aidl +16 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,8 @@ import android.view.WindowManager; import android.view.SurfaceControl; import android.view.displayhash.DisplayHash; import android.view.displayhash.VerifiedDisplayHash; import android.window.AddToSurfaceSyncGroupResult; import android.window.ISurfaceSyncGroupCompletedListener; import android.window.ITaskFpsCallback; import android.window.ScreenCapture; Loading Loading @@ -984,4 +986,18 @@ interface IWindowManager * @return {@code true} if the key will be handled globally. */ boolean isGlobalKey(int keyCode); /** * Create or add to a SurfaceSyncGroup in WindowManager. WindowManager maintains some * SurfaceSyncGroups to ensure multiple processes can sync with each other without sharing * SurfaceControls */ boolean addToSurfaceSyncGroup(in IBinder syncGroupToken, boolean parentSyncGroupMerge, in @nullable ISurfaceSyncGroupCompletedListener completedListener, out AddToSurfaceSyncGroupResult addToSurfaceSyncGroupResult); /** * Mark a SurfaceSyncGroup stored in WindowManager as ready. */ oneway void markSurfaceSyncGroupReady(in IBinder syncGroupToken); } core/java/android/view/SurfaceControlViewHost.java +18 −0 Original line number Diff line number Diff line Loading @@ -29,9 +29,14 @@ import android.os.Parcelable; import android.os.RemoteException; import android.util.Log; import android.view.accessibility.IAccessibilityEmbeddedConnection; import android.window.ISurfaceSyncGroup; import android.window.WindowTokenClient; import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * Utility class for adding a View hierarchy to a {@link SurfaceControl}. The View hierarchy Loading Loading @@ -87,6 +92,19 @@ public class SurfaceControlViewHost { } mWm.setInsetsState(state); } @Override public ISurfaceSyncGroup getSurfaceSyncGroup() { CompletableFuture<ISurfaceSyncGroup> surfaceSyncGroup = new CompletableFuture<>(); mViewRoot.mHandler.post( () -> surfaceSyncGroup.complete(mViewRoot.getOrCreateSurfaceSyncGroup())); try { return surfaceSyncGroup.get(1, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { Log.e(TAG, "Failed to get SurfaceSyncGroup for SCVH", e); } return null; } } private ISurfaceControlViewHost mRemoteInterface = new ISurfaceControlViewHostImpl(); Loading core/java/android/view/SurfaceView.java +3 −2 Original line number Diff line number Diff line Loading @@ -1091,7 +1091,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall t = syncBufferTransactionCallback.waitForTransaction(); } surfaceSyncGroup.onTransactionReady(t); surfaceSyncGroup.addTransactionToSync(t); surfaceSyncGroup.markSyncReady(); onDrawFinished(); }); } Loading @@ -1106,7 +1107,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall synchronized (mSyncGroups) { mSyncGroups.remove(surfaceSyncGroup); } surfaceSyncGroup.onTransactionReady(null); surfaceSyncGroup.markSyncReady(); onDrawFinished(); }); Loading core/java/android/view/ViewRootImpl.java +57 −14 Original line number Diff line number Diff line Loading @@ -230,6 +230,7 @@ import java.util.Objects; import java.util.Queue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.function.Consumer; /** * The top of a view hierarchy, implementing the needed protocol between View Loading Loading @@ -860,6 +861,8 @@ public final class ViewRootImpl implements ViewParent, // animations until all are done. private static int sNumSyncsInProgress = 0; private int mNumPausedForSync = 0; private HashSet<ScrollCaptureCallback> mRootScrollCaptureCallbacks; private long mScrollCaptureRequestTimeout = SCROLL_CAPTURE_REQUEST_TIMEOUT_MILLIS; Loading Loading @@ -2808,6 +2811,19 @@ public final class ViewRootImpl implements ViewParent, return; } if (mNumPausedForSync > 0) { if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { Trace.instant(Trace.TRACE_TAG_VIEW, TextUtils.formatSimple("performTraversals#mNumPausedForSync=%d", mNumPausedForSync)); } if (DEBUG_BLAST) { Log.d(mTag, "Skipping traversal due to sync " + mNumPausedForSync); } mLastPerformTraversalsSkipDrawReason = "paused_for_sync"; return; } mIsInTraversal = true; mWillDrawSoon = true; boolean cancelDraw = false; Loading Loading @@ -3669,7 +3685,7 @@ public final class ViewRootImpl implements ViewParent, } if (mActiveSurfaceSyncGroup != null) { mActiveSurfaceSyncGroup.onTransactionReady(null); mActiveSurfaceSyncGroup.markSyncReady(); } } else if (cancelAndRedraw) { mLastPerformTraversalsSkipDrawReason = cancelDueToPreDrawListener Loading @@ -3685,7 +3701,7 @@ public final class ViewRootImpl implements ViewParent, mPendingTransitions.clear(); } if (!performDraw() && mActiveSurfaceSyncGroup != null) { mActiveSurfaceSyncGroup.onTransactionReady(null); mActiveSurfaceSyncGroup.markSyncReady(); } } Loading @@ -3702,7 +3718,7 @@ public final class ViewRootImpl implements ViewParent, mActiveSurfaceSyncGroup = null; mSyncBuffer = false; if (isInWMSRequestedSync()) { mWmsRequestSyncGroup.onTransactionReady(null); mWmsRequestSyncGroup.markSyncReady(); mWmsRequestSyncGroup = null; mWmsRequestSyncGroupState = WMS_SYNC_NONE; } Loading Loading @@ -4544,7 +4560,7 @@ public final class ViewRootImpl implements ViewParent, if (mSurfaceHolder != null && mSurface.isValid()) { final SurfaceSyncGroup surfaceSyncGroup = mActiveSurfaceSyncGroup; SurfaceCallbackHelper sch = new SurfaceCallbackHelper(() -> mHandler.post(() -> surfaceSyncGroup.onTransactionReady(null))); mHandler.post(() -> surfaceSyncGroup.markSyncReady())); mActiveSurfaceSyncGroup = null; SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks(); Loading @@ -4557,7 +4573,7 @@ public final class ViewRootImpl implements ViewParent, } } if (mActiveSurfaceSyncGroup != null && !usingAsyncReport) { mActiveSurfaceSyncGroup.onTransactionReady(null); mActiveSurfaceSyncGroup.markSyncReady(); } if (mPerformContentCapture) { performContentCaptureInitialReport(); Loading Loading @@ -11263,8 +11279,9 @@ public final class ViewRootImpl implements ViewParent, // pendingDrawFinished. if ((syncResult & (SYNC_LOST_SURFACE_REWARD_IF_FOUND | SYNC_CONTEXT_IS_STOPPED)) != 0) { surfaceSyncGroup.onTransactionReady( surfaceSyncGroup.addTransactionToSync( mBlastBufferQueue.gatherPendingTransactions(frame)); surfaceSyncGroup.markSyncReady(); return null; } Loading @@ -11273,8 +11290,13 @@ public final class ViewRootImpl implements ViewParent, } if (syncBuffer) { mBlastBufferQueue.syncNextTransaction( surfaceSyncGroup::onTransactionReady); mBlastBufferQueue.syncNextTransaction(new Consumer<Transaction>() { @Override public void accept(Transaction transaction) { surfaceSyncGroup.addTransactionToSync(transaction); surfaceSyncGroup.markSyncReady(); } }); } return didProduceBuffer -> { Loading @@ -11294,8 +11316,9 @@ public final class ViewRootImpl implements ViewParent, // since the frame didn't draw on this vsync. It's possible the frame will // draw later, but it's better to not be sync than to block on a frame that // may never come. surfaceSyncGroup.onTransactionReady( surfaceSyncGroup.addTransactionToSync( mBlastBufferQueue.gatherPendingTransactions(frame)); surfaceSyncGroup.markSyncReady(); return; } Loading @@ -11303,22 +11326,41 @@ public final class ViewRootImpl implements ViewParent, // syncNextTransaction callback. Instead, just report back to the Syncer so it // knows that this sync request is complete. if (!syncBuffer) { surfaceSyncGroup.onTransactionReady(null); surfaceSyncGroup.markSyncReady(); } }; } }); } private class VRISurfaceSyncGroup extends SurfaceSyncGroup { VRISurfaceSyncGroup(String name) { super(name); } @Override public void onSyncReady() { Runnable runnable = () -> { mNumPausedForSync--; if (!mIsInTraversal && mNumPausedForSync == 0) { scheduleTraversals(); } }; if (Thread.currentThread() == mThread) { runnable.run(); } else { mHandler.post(runnable); } } } @Override public SurfaceSyncGroup getOrCreateSurfaceSyncGroup() { boolean newSyncGroup = false; if (mActiveSurfaceSyncGroup == null) { mActiveSurfaceSyncGroup = new SurfaceSyncGroup(mTag); mActiveSurfaceSyncGroup = new VRISurfaceSyncGroup(mTag); updateSyncInProgressCount(mActiveSurfaceSyncGroup); if (!mIsInTraversal && !mTraversalScheduled) { scheduleTraversals(); } newSyncGroup = true; } Loading @@ -11334,6 +11376,7 @@ public final class ViewRootImpl implements ViewParent, } } mNumPausedForSync++; return mActiveSurfaceSyncGroup; }; Loading Loading
core/java/android/view/ISurfaceControlViewHost.aidl +10 −4 Original line number Diff line number Diff line Loading @@ -19,13 +19,19 @@ package android.view; import android.content.res.Configuration; import android.graphics.Rect; import android.view.InsetsState; import android.window.ISurfaceSyncGroup; /** * API from content embedder back to embedded content in SurfaceControlViewHost * {@hide} */ oneway interface ISurfaceControlViewHost { void onConfigurationChanged(in Configuration newConfig); void onDispatchDetachedFromWindow(); void onInsetsChanged(in InsetsState state, in Rect insetFrame); interface ISurfaceControlViewHost { /** * TODO (b/263273252): Investigate the need for these to be blocking calls or add additional * APIs that are blocking */ oneway void onConfigurationChanged(in Configuration newConfig); oneway void onDispatchDetachedFromWindow(); oneway void onInsetsChanged(in InsetsState state, in Rect insetFrame); ISurfaceSyncGroup getSurfaceSyncGroup(); }
core/java/android/view/IWindowManager.aidl +16 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,8 @@ import android.view.WindowManager; import android.view.SurfaceControl; import android.view.displayhash.DisplayHash; import android.view.displayhash.VerifiedDisplayHash; import android.window.AddToSurfaceSyncGroupResult; import android.window.ISurfaceSyncGroupCompletedListener; import android.window.ITaskFpsCallback; import android.window.ScreenCapture; Loading Loading @@ -984,4 +986,18 @@ interface IWindowManager * @return {@code true} if the key will be handled globally. */ boolean isGlobalKey(int keyCode); /** * Create or add to a SurfaceSyncGroup in WindowManager. WindowManager maintains some * SurfaceSyncGroups to ensure multiple processes can sync with each other without sharing * SurfaceControls */ boolean addToSurfaceSyncGroup(in IBinder syncGroupToken, boolean parentSyncGroupMerge, in @nullable ISurfaceSyncGroupCompletedListener completedListener, out AddToSurfaceSyncGroupResult addToSurfaceSyncGroupResult); /** * Mark a SurfaceSyncGroup stored in WindowManager as ready. */ oneway void markSurfaceSyncGroupReady(in IBinder syncGroupToken); }
core/java/android/view/SurfaceControlViewHost.java +18 −0 Original line number Diff line number Diff line Loading @@ -29,9 +29,14 @@ import android.os.Parcelable; import android.os.RemoteException; import android.util.Log; import android.view.accessibility.IAccessibilityEmbeddedConnection; import android.window.ISurfaceSyncGroup; import android.window.WindowTokenClient; import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * Utility class for adding a View hierarchy to a {@link SurfaceControl}. The View hierarchy Loading Loading @@ -87,6 +92,19 @@ public class SurfaceControlViewHost { } mWm.setInsetsState(state); } @Override public ISurfaceSyncGroup getSurfaceSyncGroup() { CompletableFuture<ISurfaceSyncGroup> surfaceSyncGroup = new CompletableFuture<>(); mViewRoot.mHandler.post( () -> surfaceSyncGroup.complete(mViewRoot.getOrCreateSurfaceSyncGroup())); try { return surfaceSyncGroup.get(1, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { Log.e(TAG, "Failed to get SurfaceSyncGroup for SCVH", e); } return null; } } private ISurfaceControlViewHost mRemoteInterface = new ISurfaceControlViewHostImpl(); Loading
core/java/android/view/SurfaceView.java +3 −2 Original line number Diff line number Diff line Loading @@ -1091,7 +1091,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall t = syncBufferTransactionCallback.waitForTransaction(); } surfaceSyncGroup.onTransactionReady(t); surfaceSyncGroup.addTransactionToSync(t); surfaceSyncGroup.markSyncReady(); onDrawFinished(); }); } Loading @@ -1106,7 +1107,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall synchronized (mSyncGroups) { mSyncGroups.remove(surfaceSyncGroup); } surfaceSyncGroup.onTransactionReady(null); surfaceSyncGroup.markSyncReady(); onDrawFinished(); }); Loading
core/java/android/view/ViewRootImpl.java +57 −14 Original line number Diff line number Diff line Loading @@ -230,6 +230,7 @@ import java.util.Objects; import java.util.Queue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.function.Consumer; /** * The top of a view hierarchy, implementing the needed protocol between View Loading Loading @@ -860,6 +861,8 @@ public final class ViewRootImpl implements ViewParent, // animations until all are done. private static int sNumSyncsInProgress = 0; private int mNumPausedForSync = 0; private HashSet<ScrollCaptureCallback> mRootScrollCaptureCallbacks; private long mScrollCaptureRequestTimeout = SCROLL_CAPTURE_REQUEST_TIMEOUT_MILLIS; Loading Loading @@ -2808,6 +2811,19 @@ public final class ViewRootImpl implements ViewParent, return; } if (mNumPausedForSync > 0) { if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { Trace.instant(Trace.TRACE_TAG_VIEW, TextUtils.formatSimple("performTraversals#mNumPausedForSync=%d", mNumPausedForSync)); } if (DEBUG_BLAST) { Log.d(mTag, "Skipping traversal due to sync " + mNumPausedForSync); } mLastPerformTraversalsSkipDrawReason = "paused_for_sync"; return; } mIsInTraversal = true; mWillDrawSoon = true; boolean cancelDraw = false; Loading Loading @@ -3669,7 +3685,7 @@ public final class ViewRootImpl implements ViewParent, } if (mActiveSurfaceSyncGroup != null) { mActiveSurfaceSyncGroup.onTransactionReady(null); mActiveSurfaceSyncGroup.markSyncReady(); } } else if (cancelAndRedraw) { mLastPerformTraversalsSkipDrawReason = cancelDueToPreDrawListener Loading @@ -3685,7 +3701,7 @@ public final class ViewRootImpl implements ViewParent, mPendingTransitions.clear(); } if (!performDraw() && mActiveSurfaceSyncGroup != null) { mActiveSurfaceSyncGroup.onTransactionReady(null); mActiveSurfaceSyncGroup.markSyncReady(); } } Loading @@ -3702,7 +3718,7 @@ public final class ViewRootImpl implements ViewParent, mActiveSurfaceSyncGroup = null; mSyncBuffer = false; if (isInWMSRequestedSync()) { mWmsRequestSyncGroup.onTransactionReady(null); mWmsRequestSyncGroup.markSyncReady(); mWmsRequestSyncGroup = null; mWmsRequestSyncGroupState = WMS_SYNC_NONE; } Loading Loading @@ -4544,7 +4560,7 @@ public final class ViewRootImpl implements ViewParent, if (mSurfaceHolder != null && mSurface.isValid()) { final SurfaceSyncGroup surfaceSyncGroup = mActiveSurfaceSyncGroup; SurfaceCallbackHelper sch = new SurfaceCallbackHelper(() -> mHandler.post(() -> surfaceSyncGroup.onTransactionReady(null))); mHandler.post(() -> surfaceSyncGroup.markSyncReady())); mActiveSurfaceSyncGroup = null; SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks(); Loading @@ -4557,7 +4573,7 @@ public final class ViewRootImpl implements ViewParent, } } if (mActiveSurfaceSyncGroup != null && !usingAsyncReport) { mActiveSurfaceSyncGroup.onTransactionReady(null); mActiveSurfaceSyncGroup.markSyncReady(); } if (mPerformContentCapture) { performContentCaptureInitialReport(); Loading Loading @@ -11263,8 +11279,9 @@ public final class ViewRootImpl implements ViewParent, // pendingDrawFinished. if ((syncResult & (SYNC_LOST_SURFACE_REWARD_IF_FOUND | SYNC_CONTEXT_IS_STOPPED)) != 0) { surfaceSyncGroup.onTransactionReady( surfaceSyncGroup.addTransactionToSync( mBlastBufferQueue.gatherPendingTransactions(frame)); surfaceSyncGroup.markSyncReady(); return null; } Loading @@ -11273,8 +11290,13 @@ public final class ViewRootImpl implements ViewParent, } if (syncBuffer) { mBlastBufferQueue.syncNextTransaction( surfaceSyncGroup::onTransactionReady); mBlastBufferQueue.syncNextTransaction(new Consumer<Transaction>() { @Override public void accept(Transaction transaction) { surfaceSyncGroup.addTransactionToSync(transaction); surfaceSyncGroup.markSyncReady(); } }); } return didProduceBuffer -> { Loading @@ -11294,8 +11316,9 @@ public final class ViewRootImpl implements ViewParent, // since the frame didn't draw on this vsync. It's possible the frame will // draw later, but it's better to not be sync than to block on a frame that // may never come. surfaceSyncGroup.onTransactionReady( surfaceSyncGroup.addTransactionToSync( mBlastBufferQueue.gatherPendingTransactions(frame)); surfaceSyncGroup.markSyncReady(); return; } Loading @@ -11303,22 +11326,41 @@ public final class ViewRootImpl implements ViewParent, // syncNextTransaction callback. Instead, just report back to the Syncer so it // knows that this sync request is complete. if (!syncBuffer) { surfaceSyncGroup.onTransactionReady(null); surfaceSyncGroup.markSyncReady(); } }; } }); } private class VRISurfaceSyncGroup extends SurfaceSyncGroup { VRISurfaceSyncGroup(String name) { super(name); } @Override public void onSyncReady() { Runnable runnable = () -> { mNumPausedForSync--; if (!mIsInTraversal && mNumPausedForSync == 0) { scheduleTraversals(); } }; if (Thread.currentThread() == mThread) { runnable.run(); } else { mHandler.post(runnable); } } } @Override public SurfaceSyncGroup getOrCreateSurfaceSyncGroup() { boolean newSyncGroup = false; if (mActiveSurfaceSyncGroup == null) { mActiveSurfaceSyncGroup = new SurfaceSyncGroup(mTag); mActiveSurfaceSyncGroup = new VRISurfaceSyncGroup(mTag); updateSyncInProgressCount(mActiveSurfaceSyncGroup); if (!mIsInTraversal && !mTraversalScheduled) { scheduleTraversals(); } newSyncGroup = true; } Loading @@ -11334,6 +11376,7 @@ public final class ViewRootImpl implements ViewParent, } } mNumPausedForSync++; return mActiveSurfaceSyncGroup; }; Loading