summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt8
-rw-r--r--core/java/android/view/SurfaceControlViewHost.java3
-rw-r--r--core/java/android/view/SurfaceView.java2
-rw-r--r--core/java/android/view/ViewRootImpl.java10
-rw-r--r--core/java/android/window/SurfaceSyncGroup.java330
-rw-r--r--core/java/android/window/SurfaceSyncGroup.md2
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt4
-rw-r--r--services/core/java/com/android/server/wm/SurfaceSyncGroupController.java2
-rw-r--r--services/tests/wmtests/AndroidManifest.xml3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java54
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SurfaceViewSyncContinuousTest.java (renamed from services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupContinuousTest.java)34
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SurfaceViewSyncValidatorTestCase.java (renamed from services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupValidatorTestCase.java)8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/scvh/EmbeddedSCVHService.java127
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindow.aidl27
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindowCallback.aidl23
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/scvh/SyncValidatorSCVHTestCase.java241
-rw-r--r--tests/SurfaceControlViewHostTest/src/com/android/test/viewembed/SurfaceControlViewHostSyncTest.java4
-rw-r--r--tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java4
18 files changed, 272 insertions, 614 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index e87487a750a1..6c38e266aa84 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -60257,6 +60257,14 @@ package android.window {
method @UiThread public void remove();
}
+ public class SurfaceSyncGroup {
+ ctor public SurfaceSyncGroup(@NonNull String);
+ method @UiThread public boolean add(@Nullable android.view.AttachedSurfaceControl, @Nullable Runnable);
+ method public boolean add(@NonNull android.view.SurfaceControlViewHost.SurfacePackage, @Nullable Runnable);
+ method public void addTransaction(@NonNull android.view.SurfaceControl.Transaction);
+ method public void markSyncReady();
+ }
+
}
package javax.microedition.khronos.egl {
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index 490091bf2352..f7bdd094ff2c 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -97,7 +97,8 @@ public class SurfaceControlViewHost {
public ISurfaceSyncGroup getSurfaceSyncGroup() {
CompletableFuture<ISurfaceSyncGroup> surfaceSyncGroup = new CompletableFuture<>();
mViewRoot.mHandler.post(
- () -> surfaceSyncGroup.complete(mViewRoot.getOrCreateSurfaceSyncGroup()));
+ () -> surfaceSyncGroup.complete(
+ mViewRoot.getOrCreateSurfaceSyncGroup().mISurfaceSyncGroup));
try {
return surfaceSyncGroup.get(1, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index e559a71757c8..1eb87c9e039e 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -1091,7 +1091,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
t = syncBufferTransactionCallback.waitForTransaction();
}
- surfaceSyncGroup.addTransactionToSync(t);
+ surfaceSyncGroup.addTransaction(t);
surfaceSyncGroup.markSyncReady();
onDrawFinished();
});
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 84ed845d62f8..9119ea4bab94 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3768,7 +3768,7 @@ public final class ViewRootImpl implements ViewParent,
Log.d(mTag, "Setup new sync=" + mWmsRequestSyncGroup.getName());
}
- mWmsRequestSyncGroup.addToSync(this);
+ mWmsRequestSyncGroup.add(this, null /* runnable */);
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
@@ -11354,7 +11354,7 @@ public final class ViewRootImpl implements ViewParent,
// pendingDrawFinished.
if ((syncResult
& (SYNC_LOST_SURFACE_REWARD_IF_FOUND | SYNC_CONTEXT_IS_STOPPED)) != 0) {
- surfaceSyncGroup.addTransactionToSync(
+ surfaceSyncGroup.addTransaction(
mBlastBufferQueue.gatherPendingTransactions(frame));
surfaceSyncGroup.markSyncReady();
return null;
@@ -11368,7 +11368,7 @@ public final class ViewRootImpl implements ViewParent,
mBlastBufferQueue.syncNextTransaction(new Consumer<Transaction>() {
@Override
public void accept(Transaction transaction) {
- surfaceSyncGroup.addTransactionToSync(transaction);
+ surfaceSyncGroup.addTransaction(transaction);
surfaceSyncGroup.markSyncReady();
}
});
@@ -11391,7 +11391,7 @@ 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.addTransactionToSync(
+ surfaceSyncGroup.addTransaction(
mBlastBufferQueue.gatherPendingTransactions(frame));
surfaceSyncGroup.markSyncReady();
return;
@@ -11481,7 +11481,7 @@ public final class ViewRootImpl implements ViewParent,
if (mActiveSurfaceSyncGroup == null) {
return;
}
- mActiveSurfaceSyncGroup.addToSync(syncable, false /* parentSyncGroupMerge */);
+ mActiveSurfaceSyncGroup.add(syncable, null /* Runnable */);
}
@Override
diff --git a/core/java/android/window/SurfaceSyncGroup.java b/core/java/android/window/SurfaceSyncGroup.java
index 12cd3408bf87..2e55041d2e8c 100644
--- a/core/java/android/window/SurfaceSyncGroup.java
+++ b/core/java/android/window/SurfaceSyncGroup.java
@@ -42,14 +42,18 @@ import java.util.function.Consumer;
import java.util.function.Supplier;
/**
- * Used to organize syncs for surfaces.
+ * A way for data to be gathered so multiple surfaces can be synced. This is intended to be
+ * used with AttachedSurfaceControl, SurfaceView, and SurfaceControlViewHost. This allows different
+ * parts of the system to synchronize different surfaces themselves without having to manage timing
+ * of different rendering threads.
+ * This will also allow synchronization of surfaces across multiple processes. The caller can add
+ * SurfaceControlViewHosts from another process to the SurfaceSyncGroup in a different process
+ * and this clas will ensure all the surfaces are ready before applying everything together.
* </p>
- * See SurfaceSyncGroup.md
+ * see the <a href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/window/SurfaceSyncGroup.md">SurfaceSyncGroup documentation</a>
* </p>
- *
- * @hide
*/
-public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
+public class SurfaceSyncGroup {
private static final String TAG = "SurfaceSyncGroup";
private static final boolean DEBUG = false;
@@ -93,6 +97,11 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
private ISurfaceSyncGroupCompletedListener mSurfaceSyncGroupCompletedListener;
/**
+ * @hide
+ */
+ public final ISurfaceSyncGroup mISurfaceSyncGroup = new ISurfaceSyncGroupImpl();
+
+ /**
* Token to identify this SurfaceSyncGroup. This is used to register the SurfaceSyncGroup in
* WindowManager. This token is also sent to other processes' SurfaceSyncGroup that want to be
* included in this SurfaceSyncGroup.
@@ -104,8 +113,8 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
}
private static SurfaceSyncGroup getSurfaceSyncGroup(ISurfaceSyncGroup iSurfaceSyncGroup) {
- if (iSurfaceSyncGroup instanceof SurfaceSyncGroup) {
- return (SurfaceSyncGroup) iSurfaceSyncGroup;
+ if (iSurfaceSyncGroup instanceof ISurfaceSyncGroupImpl) {
+ return ((ISurfaceSyncGroupImpl) iSurfaceSyncGroup).getSurfaceSyncGroup();
}
return null;
}
@@ -119,8 +128,10 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
/**
* Starts a sync and will automatically apply the final, merged transaction.
+ *
+ * @param name Used for identifying and debugging.
*/
- public SurfaceSyncGroup(String name) {
+ public SurfaceSyncGroup(@NonNull String name) {
this(name, transaction -> {
if (transaction != null) {
if (DEBUG) {
@@ -134,6 +145,7 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
/**
* Creates a sync.
*
+ * @param name Used for identifying and debugging.
* @param transactionReadyConsumer The complete callback that contains the syncId and
* transaction with all the sync data merged. The Transaction
* passed back can be null.
@@ -157,19 +169,23 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
Log.d(TAG, "Sending non null transaction " + transaction + " to callback for "
+ mName);
}
- Trace.instant(Trace.TRACE_TAG_VIEW,
- "Final TransactionCallback with " + transaction + " for " + mName);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.instant(Trace.TRACE_TAG_VIEW,
+ "Final TransactionCallback with " + transaction + " for " + mName);
+ }
transactionReadyConsumer.accept(transaction);
synchronized (mLock) {
// If there's a registered listener with WMS, that means we aren't actually complete
// until WMS notifies us that the parent has completed.
if (mSurfaceSyncGroupCompletedListener == null) {
- invokeSyncCompleteListeners();
+ invokeSyncCompleteCallbacks();
}
}
};
- Trace.instant(Trace.TRACE_TAG_VIEW, "new SurfaceSyncGroup " + mName);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.instant(Trace.TRACE_TAG_VIEW, "new SurfaceSyncGroup " + mName);
+ }
if (DEBUG) {
Log.d(TAG, "setupSync " + mName + " " + Debug.getCallers(2));
@@ -177,7 +193,7 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
}
@GuardedBy("mLock")
- private void invokeSyncCompleteListeners() {
+ private void invokeSyncCompleteCallbacks() {
mSyncCompleteCallbacks.forEach(
executorRunnablePair -> executorRunnablePair.first.execute(
executorRunnablePair.second));
@@ -188,6 +204,7 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
*
* @param executor The Executor to invoke the Runnable on
* @param runnable The Runnable to get called
+ * @hide
*/
public void addSyncCompleteCallback(Executor executor, Runnable runnable) {
synchronized (mLock) {
@@ -196,13 +213,16 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
}
/**
- * Mark the sync set as ready to complete. No more data can be added to the specified
- * syncId.
- * Once the sync set is marked as ready, it will be able to complete once all Syncables in the
- * set have completed their sync
+ * Mark the SurfaceSyncGroup as ready to complete. No more data can be added to this
+ * SurfaceSyncGroup.
+ * <p>
+ * Once the SurfaceSyncGroup is marked as ready, it will be able to complete once all child
+ * SurfaceSyncGroup have completed their sync.
*/
public void markSyncReady() {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "markSyncReady " + mName);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "markSyncReady " + mName);
+ }
synchronized (mLock) {
if (mHasWMSync) {
try {
@@ -213,28 +233,29 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
mSyncReady = true;
checkIfSyncIsComplete();
}
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
}
/**
- * Add a SurfaceView to a sync set. This is different than
- * {@link #addToSync(AttachedSurfaceControl)} because it requires the caller to notify the start
- * and finish drawing in order to sync.
+ * Add a SurfaceView to a SurfaceSyncGroup. This requires the caller to notify the start
+ * and finish drawing in order to sync since the client owns the rendering of the SurfaceView.
*
* @param surfaceView The SurfaceView to add to the sync.
* @param frameCallbackConsumer The callback that's invoked to allow the caller to notify
- * the
- * Syncer when the SurfaceView has started drawing and
- * finished.
+ * SurfaceSyncGroup when the SurfaceView has started drawing.
* @return true if the SurfaceView was successfully added to the SyncGroup, false otherwise.
+ * @hide
*/
@UiThread
- public boolean addToSync(SurfaceView surfaceView,
+ public boolean add(SurfaceView surfaceView,
Consumer<SurfaceViewFrameCallback> frameCallbackConsumer) {
SurfaceSyncGroup surfaceSyncGroup = new SurfaceSyncGroup(surfaceView.getName());
- if (addToSync(surfaceSyncGroup, false /* parentSyncGroupMerge */)) {
+ if (add(surfaceSyncGroup.mISurfaceSyncGroup, false /* parentSyncGroupMerge */,
+ null /* runnable */)) {
frameCallbackConsumer.accept(() -> surfaceView.syncNextFrame(transaction -> {
- surfaceSyncGroup.addTransactionToSync(transaction);
+ surfaceSyncGroup.addTransaction(transaction);
surfaceSyncGroup.markSyncReady();
}));
return true;
@@ -243,54 +264,53 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
}
/**
- * Add an AttachedSurfaceControl to a sync set.
- *
- * @param viewRoot The viewRoot that will be add to the sync set.
- * @return true if the View was successfully added to the SyncGroup, false otherwise.
- * @see #addToSync(AttachedSurfaceControl, Runnable)
- */
- @UiThread
- public boolean addToSync(@Nullable AttachedSurfaceControl viewRoot) {
- return addToSync(viewRoot, null /* runnable */);
- }
-
- /**
- * Add an AttachedSurfaceControl to a sync set. The AttachedSurfaceControl will pause rendering
- * to ensure the runnable can be invoked and the sync picks up the frame that contains the
- * changes.
+ * Add an AttachedSurfaceControl to the SurfaceSyncGroup. The AttachedSurfaceControl will pause
+ * rendering to ensure the runnable can be invoked and that the sync picks up the frame that
+ * contains the changes.
*
- * @param viewRoot The viewRoot that will be add to the sync set.
- * @param runnable The runnable to be invoked before adding to the sync group.
- * @return true if the View was successfully added to the SyncGroup, false otherwise.
- * @see #addToSync(AttachedSurfaceControl)
+ * @param attachedSurfaceControl The AttachedSurfaceControl that will be add to this
+ * SurfaceSyncGroup.
+ * @param runnable This is run on the same thread that the call was made on, but
+ * after the rendering is paused and before continuing to render
+ * the next frame. This method will not return until the
+ * execution of the runnable completes. This can be used to make
+ * changes to the AttachedSurfaceControl, ensuring that the
+ * changes are included in the sync.
+ * @return true if the AttachedSurfaceControl was successfully added to the SurfaceSyncGroup,
+ * false otherwise.
*/
@UiThread
- public boolean addToSync(@Nullable AttachedSurfaceControl viewRoot,
+ public boolean add(@Nullable AttachedSurfaceControl attachedSurfaceControl,
@Nullable Runnable runnable) {
- if (viewRoot == null) {
+ if (attachedSurfaceControl == null) {
return false;
}
- SurfaceSyncGroup surfaceSyncGroup = viewRoot.getOrCreateSurfaceSyncGroup();
+ SurfaceSyncGroup surfaceSyncGroup = attachedSurfaceControl.getOrCreateSurfaceSyncGroup();
if (surfaceSyncGroup == null) {
return false;
}
- return addToSync(surfaceSyncGroup, false /* parentSyncGroupMerge */, runnable);
+ return add(surfaceSyncGroup, runnable);
}
/**
- * Helper method to add a SurfaceControlViewHost.SurfacePackage to the sync group. This will
+ * Add a SurfaceControlViewHost.SurfacePackage to the SurfaceSyncGroup. This will
* get the SurfaceSyncGroup from the SurfacePackage, which will pause rendering for the
* SurfaceControlViewHost. The runnable will be invoked to allow the host to update the SCVH
* in a synchronized way. Finally, it will add the SCVH to the SurfaceSyncGroup and unpause
* rendering in the SCVH, allowing the changes to get picked up and included in the sync.
*
- * @param surfacePackage The SurfacePackage that should be synced
- * @param runnable The Runnable that's invoked before getting the frame to sync.
- * @return true if the SCVH was successfully added to the current SyncGroup, false
- * otherwise.
+ * @param surfacePackage The SurfacePackage that will be added to this SurfaceSyncGroup.
+ * @param runnable This is run on the same thread that the call was made on, but
+ * after the rendering is paused and before continuing to render
+ * the next frame. This method will not return until the
+ * execution of the runnable completes. This can be used to make
+ * changes to the SurfaceControlViewHost, ensuring that the
+ * changes are included in the sync.
+ * @return true if the SurfaceControlViewHost was successfully added to the current
+ * SurfaceSyncGroup, false otherwise.
*/
- public boolean addToSync(@NonNull SurfaceControlViewHost.SurfacePackage surfacePackage,
+ public boolean add(@NonNull SurfaceControlViewHost.SurfacePackage surfacePackage,
@Nullable Runnable runnable) {
ISurfaceSyncGroup surfaceSyncGroup;
try {
@@ -305,20 +325,31 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
+ "SCVH returned null SurfaceSyncGroup");
return false;
}
- return addToSync(surfaceSyncGroup, false /* parentSyncGroupMerge */, runnable);
+ return add(surfaceSyncGroup, false /* parentSyncGroupMerge */, runnable);
}
- @Override
- public boolean addToSync(ISurfaceSyncGroup surfaceSyncGroup, boolean parentSyncGroupMerge) {
- return addToSync(surfaceSyncGroup, parentSyncGroupMerge, null);
+ /**
+ * Add a SurfaceSyncGroup to the current SurfaceSyncGroup.
+ *
+ * @param surfaceSyncGroup The SurfaceSyncGroup that will be added to this SurfaceSyncGroup.
+ * @param runnable This is run on the same thread that the call was made on, This
+ * method will not return until the execution of the runnable
+ * completes. This can be used to make changes to the SurfaceSyncGroup,
+ * ensuring that the changes are included in the sync.
+ * @return true if the requested SurfaceSyncGroup was successfully added to the
+ * SurfaceSyncGroup, false otherwise.
+ * @hide
+ */
+ public boolean add(@NonNull SurfaceSyncGroup surfaceSyncGroup,
+ @Nullable Runnable runnable) {
+ return add(surfaceSyncGroup.mISurfaceSyncGroup, false /* parentSyncGroupMerge */,
+ runnable);
}
/**
- * Add a {@link SurfaceSyncGroup} to a sync set. The sync set will wait for all
- * SyncableSurfaces to complete before notifying.
+ * Add a {@link ISurfaceSyncGroup} to a SurfaceSyncGroup.
*
- * @param surfaceSyncGroup A SyncableSurface that implements how to handle syncing
- * buffers.
+ * @param surfaceSyncGroup An ISyncableSurface that will be added to this SurfaceSyncGroup.
* @param parentSyncGroupMerge true if the ISurfaceSyncGroup is added because its child was
* added to a new SurfaceSyncGroup. That would require the code to
* call newParent.addToSync(oldParent). When this occurs, we need to
@@ -327,15 +358,20 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
* @param runnable The Runnable that's invoked before adding the SurfaceSyncGroup
* @return true if the SyncGroup was successfully added to the current SyncGroup, false
* otherwise.
+ * @hide
*/
- public boolean addToSync(ISurfaceSyncGroup surfaceSyncGroup, boolean parentSyncGroupMerge,
+ public boolean add(ISurfaceSyncGroup surfaceSyncGroup, boolean parentSyncGroupMerge,
@Nullable Runnable runnable) {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW,
- "addToSync token=" + mToken.hashCode() + " parent=" + mName);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW,
+ "addToSync token=" + mToken.hashCode() + " parent=" + mName);
+ }
synchronized (mLock) {
if (mSyncReady) {
Log.w(TAG, "Trying to add to sync when already marked as ready " + mName);
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
return false;
}
}
@@ -346,7 +382,9 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
if (isLocalBinder(surfaceSyncGroup.asBinder())) {
boolean didAddLocalSync = addLocalSync(surfaceSyncGroup, parentSyncGroupMerge);
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
return didAddLocalSync;
}
@@ -365,14 +403,16 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
@Override
public void onSurfaceSyncGroupComplete() {
synchronized (mLock) {
- invokeSyncCompleteListeners();
+ invokeSyncCompleteCallbacks();
}
}
};
if (!addSyncToWm(mToken, false /* parentSyncGroupMerge */,
mSurfaceSyncGroupCompletedListener)) {
mSurfaceSyncGroupCompletedListener = null;
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
return false;
}
mHasWMSync = true;
@@ -382,38 +422,35 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
try {
surfaceSyncGroup.onAddedToSyncGroup(mToken, parentSyncGroupMerge);
} catch (RemoteException e) {
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
return false;
}
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
return true;
}
- @Override
- public final boolean onAddedToSyncGroup(IBinder parentSyncGroupToken,
- boolean parentSyncGroupMerge) {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW,
- "onAddedToSyncGroup token=" + parentSyncGroupToken.hashCode() + " child=" + mName);
- boolean didAdd = addSyncToWm(parentSyncGroupToken, parentSyncGroupMerge, null);
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
- return didAdd;
- }
-
-
/**
- * Add a Transaction to this sync set. This allows the caller to provide other info that
- * should be synced with the transactions.
+ * Add a Transaction to this SurfaceSyncGroup. This allows the caller to provide other info that
+ * should be synced with the other transactions in this SurfaceSyncGroup.
+ *
+ * @param transaction The transaction to add to the SurfaceSyncGroup.
*/
- public void addTransactionToSync(Transaction t) {
+ public void addTransaction(@NonNull Transaction transaction) {
synchronized (mLock) {
- mTransaction.merge(t);
+ mTransaction.merge(transaction);
}
}
/**
* Invoked when the SurfaceSyncGroup has been added to another SurfaceSyncGroup and is ready
* to proceed.
+ *
+ * @hide
*/
public void onSyncReady() {
}
@@ -425,23 +462,31 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
Log.d(TAG, "Attempting to add remote sync to " + mName
+ ". Setting up Sync in WindowManager.");
}
- Trace.traceBegin(Trace.TRACE_TAG_VIEW,
- "addSyncToWm=" + token.hashCode() + " group=" + mName);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW,
+ "addSyncToWm=" + token.hashCode() + " group=" + mName);
+ }
AddToSurfaceSyncGroupResult addToSyncGroupResult = new AddToSurfaceSyncGroupResult();
if (!WindowManagerGlobal.getWindowManagerService().addToSurfaceSyncGroup(token,
parentSyncGroupMerge, surfaceSyncGroupCompletedListener,
addToSyncGroupResult)) {
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
return false;
}
setTransactionCallbackFromParent(addToSyncGroupResult.mParentSyncGroup,
addToSyncGroupResult.mTransactionReadyCallback);
} catch (RemoteException e) {
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
return false;
}
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
return true;
}
@@ -457,8 +502,10 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
return false;
}
- Trace.traceBegin(Trace.TRACE_TAG_VIEW,
- "addLocalSync=" + childSurfaceSyncGroup.mName + " parent=" + mName);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW,
+ "addLocalSync=" + childSurfaceSyncGroup.mName + " parent=" + mName);
+ }
ITransactionReadyCallback callback =
createTransactionReadyCallback(parentSyncGroupMerge);
@@ -466,8 +513,10 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
return false;
}
- childSurfaceSyncGroup.setTransactionCallbackFromParent(this, callback);
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ childSurfaceSyncGroup.setTransactionCallbackFromParent(mISurfaceSyncGroup, callback);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
return true;
}
@@ -477,9 +526,11 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
Log.d(TAG, "setTransactionCallbackFromParent " + mName);
}
boolean finished = false;
- Trace.traceBegin(Trace.TRACE_TAG_VIEW,
- "setTransactionCallbackFromParent " + mName + " callback="
- + transactionReadyCallback.hashCode());
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW,
+ "setTransactionCallbackFromParent " + mName + " callback="
+ + transactionReadyCallback.hashCode());
+ }
synchronized (mLock) {
if (mFinished) {
finished = true;
@@ -510,9 +561,11 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
Consumer<Transaction> lastCallback = mTransactionReadyConsumer;
mParentSyncGroup = parentSyncGroup;
mTransactionReadyConsumer = (transaction) -> {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW,
- "transactionReadyCallback " + mName + " callback="
- + transactionReadyCallback.hashCode());
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW,
+ "transactionReadyCallback " + mName + " callback="
+ + transactionReadyCallback.hashCode());
+ }
lastCallback.accept(null);
try {
@@ -520,7 +573,9 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
} catch (RemoteException e) {
transaction.apply();
}
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
};
}
}
@@ -535,9 +590,14 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
} else {
onSyncReady();
}
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
}
+ /**
+ * @hide
+ */
public String getName() {
return mName;
}
@@ -552,9 +612,11 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
return;
}
- Trace.instant(Trace.TRACE_TAG_VIEW,
- "checkIfSyncIsComplete " + mName + " mSyncReady=" + mSyncReady + " mPendingSyncs="
- + mPendingSyncs.size());
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.instant(Trace.TRACE_TAG_VIEW,
+ "checkIfSyncIsComplete " + mName + " mSyncReady=" + mSyncReady
+ + " mPendingSyncs=" + mPendingSyncs.size());
+ }
if (!mSyncReady || !mPendingSyncs.isEmpty()) {
if (DEBUG) {
@@ -574,7 +636,7 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
/**
* Create an {@link ITransactionReadyCallback} that the current SurfaceSyncGroup will wait on
* before completing. The caller must ensure that the
- * {@link ITransactionReadyCallback#onTransactionReady(Transaction)} in order for this
+ * {@link ITransactionReadyCallback#onTransactionReady(Transaction)} is called in order for this
* SurfaceSyncGroup to complete.
*
* @param parentSyncGroupMerge true if the ISurfaceSyncGroup is added because its child was
@@ -582,6 +644,7 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
* call newParent.addToSync(oldParent). When this occurs, we need to
* reverse the merge order because the oldParent should always be
* considered older than any other SurfaceSyncGroups.
+ * @hide
*/
public ITransactionReadyCallback createTransactionReadyCallback(boolean parentSyncGroupMerge) {
if (DEBUG) {
@@ -603,9 +666,11 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
mTransaction.merge(t);
}
mPendingSyncs.remove(this);
- Trace.instant(Trace.TRACE_TAG_VIEW,
- "onTransactionReady group=" + mName + " callback="
- + hashCode());
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.instant(Trace.TRACE_TAG_VIEW,
+ "onTransactionReady group=" + mName + " callback="
+ + hashCode());
+ }
checkIfSyncIsComplete();
}
}
@@ -618,19 +683,50 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub {
return null;
}
mPendingSyncs.add(transactionReadyCallback);
- Trace.instant(Trace.TRACE_TAG_VIEW,
- "createTransactionReadyCallback " + mName + " mPendingSyncs="
- + mPendingSyncs.size() + " transactionReady="
- + transactionReadyCallback.hashCode());
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.instant(Trace.TRACE_TAG_VIEW,
+ "createTransactionReadyCallback " + mName + " mPendingSyncs="
+ + mPendingSyncs.size() + " transactionReady="
+ + transactionReadyCallback.hashCode());
+ }
}
return transactionReadyCallback;
}
+ private class ISurfaceSyncGroupImpl extends ISurfaceSyncGroup.Stub {
+ @Override
+ public boolean onAddedToSyncGroup(IBinder parentSyncGroupToken,
+ boolean parentSyncGroupMerge) {
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW,
+ "onAddedToSyncGroup token=" + parentSyncGroupToken.hashCode() + " child="
+ + mName);
+ }
+ boolean didAdd = addSyncToWm(parentSyncGroupToken, parentSyncGroupMerge, null);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
+ return didAdd;
+ }
+
+ @Override
+ public boolean addToSync(ISurfaceSyncGroup surfaceSyncGroup, boolean parentSyncGroupMerge) {
+ return SurfaceSyncGroup.this.add(surfaceSyncGroup, parentSyncGroupMerge,
+ null /* runnable */);
+ }
+
+ SurfaceSyncGroup getSurfaceSyncGroup() {
+ return SurfaceSyncGroup.this;
+ }
+ }
+
/**
* A frame callback that is used to synchronize SurfaceViews. The owner of the SurfaceView must
* implement onFrameStarted when trying to sync the SurfaceView. This is to ensure the sync
* knows when the frame is ready to add to the sync.
+ *
+ * @hide
*/
public interface SurfaceViewFrameCallback {
/**
diff --git a/core/java/android/window/SurfaceSyncGroup.md b/core/java/android/window/SurfaceSyncGroup.md
index 406c230ad920..04577a26190f 100644
--- a/core/java/android/window/SurfaceSyncGroup.md
+++ b/core/java/android/window/SurfaceSyncGroup.md
@@ -2,7 +2,7 @@
### Overview
-A generic way for data to be gathered so multiple surfaces can be synced. This is intended to be used with Views, SurfaceView, and any other surface that wants to be involved in a sync. This allows different parts of the Android system to synchronize different windows and layers themselves.
+A generic way for data to be gathered so multiple surfaces can be synced. This is intended to be used with AttachedSurfaceControl, SurfaceView, SurfaceControlViewHost, and any other surface that wants to be involved in a sync. This allows different parts of the Android system to synchronize different windows and layers themselves.
### Code
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt
index fd9355d6a77d..e4f6db57f689 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt
@@ -30,8 +30,8 @@ object ViewRootSync {
val syncGroup = SurfaceSyncGroup("SysUIAnimation")
syncGroup.addSyncCompleteCallback(view.context.mainExecutor) { then() }
- syncGroup.addToSync(view.rootSurfaceControl)
- syncGroup.addToSync(otherView.rootSurfaceControl)
+ syncGroup.add(view.rootSurfaceControl, null /* runnable */)
+ syncGroup.add(otherView.rootSurfaceControl, null /* runnable */)
syncGroup.markSyncReady()
}
diff --git a/services/core/java/com/android/server/wm/SurfaceSyncGroupController.java b/services/core/java/com/android/server/wm/SurfaceSyncGroupController.java
index 75691caad246..1711845247f9 100644
--- a/services/core/java/com/android/server/wm/SurfaceSyncGroupController.java
+++ b/services/core/java/com/android/server/wm/SurfaceSyncGroupController.java
@@ -63,7 +63,7 @@ class SurfaceSyncGroupController {
if (callback == null) {
return false;
}
- outAddToSyncGroupResult.mParentSyncGroup = root;
+ outAddToSyncGroupResult.mParentSyncGroup = root.mISurfaceSyncGroup;
outAddToSyncGroupResult.mTransactionReadyCallback = callback;
return true;
}
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index b51feb3ac5c7..593ee4a7fa1a 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -90,9 +90,6 @@
android:foregroundServiceType="mediaProjection"
android:enabled="true">
</service>
-
- <service android:name="com.android.server.wm.scvh.EmbeddedSCVHService"
- android:process="com.android.server.wm.scvh.embedded_process" />
</application>
<instrumentation
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java
index f655242afac8..22d72ed3d361 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java
@@ -55,7 +55,7 @@ public class SurfaceSyncGroupTest {
SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(TAG);
syncGroup.addSyncCompleteCallback(mExecutor, finishedLatch::countDown);
SyncTarget syncTarget = new SyncTarget();
- syncGroup.addToSync(syncTarget, false /* parentSyncGroupMerge */);
+ syncGroup.add(syncTarget, null /* runnable */);
syncGroup.markSyncReady();
syncTarget.onBufferReady();
@@ -73,9 +73,9 @@ public class SurfaceSyncGroupTest {
SyncTarget syncTarget2 = new SyncTarget();
SyncTarget syncTarget3 = new SyncTarget();
- syncGroup.addToSync(syncTarget1, false /* parentSyncGroupMerge */);
- syncGroup.addToSync(syncTarget2, false /* parentSyncGroupMerge */);
- syncGroup.addToSync(syncTarget3, false /* parentSyncGroupMerge */);
+ syncGroup.add(syncTarget1, null /* runnable */);
+ syncGroup.add(syncTarget2, null /* runnable */);
+ syncGroup.add(syncTarget3, null /* runnable */);
syncGroup.markSyncReady();
syncTarget1.onBufferReady();
@@ -97,11 +97,11 @@ public class SurfaceSyncGroupTest {
SyncTarget syncTarget1 = new SyncTarget();
SyncTarget syncTarget2 = new SyncTarget();
- assertTrue(syncGroup.addToSync(syncTarget1, false /* parentSyncGroupMerge */));
+ assertTrue(syncGroup.add(syncTarget1, null /* runnable */));
syncGroup.markSyncReady();
// Adding to a sync that has been completed is also invalid since the sync id has been
// cleared.
- assertFalse(syncGroup.addToSync(syncTarget2, false /* parentSyncGroupMerge */));
+ assertFalse(syncGroup.add(syncTarget2, null /* runnable */));
}
@Test
@@ -117,8 +117,8 @@ public class SurfaceSyncGroupTest {
SyncTarget syncTarget1 = new SyncTarget();
SyncTarget syncTarget2 = new SyncTarget();
- assertTrue(syncGroup1.addToSync(syncTarget1, false /* parentSyncGroupMerge */));
- assertTrue(syncGroup2.addToSync(syncTarget2, false /* parentSyncGroupMerge */));
+ assertTrue(syncGroup1.add(syncTarget1, null /* runnable */));
+ assertTrue(syncGroup2.add(syncTarget2, null /* runnable */));
syncGroup1.markSyncReady();
syncGroup2.markSyncReady();
@@ -147,10 +147,10 @@ public class SurfaceSyncGroupTest {
SyncTarget syncTarget1 = new SyncTarget();
SyncTarget syncTarget2 = new SyncTarget();
- assertTrue(syncGroup1.addToSync(syncTarget1, false /* parentSyncGroupMerge */));
- assertTrue(syncGroup2.addToSync(syncTarget2, false /* parentSyncGroupMerge */));
+ assertTrue(syncGroup1.add(syncTarget1, null /* runnable */));
+ assertTrue(syncGroup2.add(syncTarget2, null /* runnable */));
syncGroup1.markSyncReady();
- syncGroup2.addToSync(syncGroup1, false /* parentSyncGroupMerge */);
+ syncGroup2.add(syncGroup1, null /* runnable */);
syncGroup2.markSyncReady();
// Finish syncTarget2 first to test that the syncGroup is not complete until the merged sync
@@ -183,8 +183,8 @@ public class SurfaceSyncGroupTest {
SyncTarget syncTarget1 = new SyncTarget();
SyncTarget syncTarget2 = new SyncTarget();
- assertTrue(syncGroup1.addToSync(syncTarget1, false /* parentSyncGroupMerge */));
- assertTrue(syncGroup2.addToSync(syncTarget2, false /* parentSyncGroupMerge */));
+ assertTrue(syncGroup1.add(syncTarget1, null /* runnable */));
+ assertTrue(syncGroup2.add(syncTarget2, null /* runnable */));
syncGroup1.markSyncReady();
syncTarget1.onBufferReady();
@@ -192,7 +192,7 @@ public class SurfaceSyncGroupTest {
finishedLatch1.await(5, TimeUnit.SECONDS);
assertEquals(0, finishedLatch1.getCount());
- syncGroup2.addToSync(syncGroup1, false /* parentSyncGroupMerge */);
+ syncGroup2.add(syncGroup1, null /* runnable */);
syncGroup2.markSyncReady();
syncTarget2.onBufferReady();
@@ -216,12 +216,12 @@ public class SurfaceSyncGroupTest {
SyncTarget syncTarget2 = new SyncTarget();
SyncTarget syncTarget3 = new SyncTarget();
- assertTrue(syncGroup1.addToSync(syncTarget1, false /* parentSyncGroupMerge */));
- assertTrue(syncGroup1.addToSync(syncTarget2, false /* parentSyncGroupMerge */));
+ assertTrue(syncGroup1.add(syncTarget1, null /* runnable */));
+ assertTrue(syncGroup1.add(syncTarget2, null /* runnable */));
// Add syncTarget1 to syncGroup2 so it forces syncGroup1 into syncGroup2
- assertTrue(syncGroup2.addToSync(syncTarget1, false /* parentSyncGroupMerge */));
- assertTrue(syncGroup2.addToSync(syncTarget3, false /* parentSyncGroupMerge */));
+ assertTrue(syncGroup2.add(syncTarget1, null /* runnable */));
+ assertTrue(syncGroup2.add(syncTarget3, null /* runnable */));
syncGroup1.markSyncReady();
syncGroup2.markSyncReady();
@@ -261,13 +261,13 @@ public class SurfaceSyncGroupTest {
SyncTarget syncTarget2 = new SyncTarget();
SyncTarget syncTarget3 = new SyncTarget();
- assertTrue(syncGroup1.addToSync(syncTarget1, false /* parentSyncGroupMerge */));
- assertTrue(syncGroup1.addToSync(syncTarget2, false /* parentSyncGroupMerge */));
+ assertTrue(syncGroup1.add(syncTarget1, null /* runnable */));
+ assertTrue(syncGroup1.add(syncTarget2, null /* runnable */));
syncTarget2.onBufferReady();
// Add syncTarget1 to syncGroup2 so it forces syncGroup1 into syncGroup2
- assertTrue(syncGroup2.addToSync(syncTarget1, false /* parentSyncGroupMerge */));
- assertTrue(syncGroup2.addToSync(syncTarget3, false /* parentSyncGroupMerge */));
+ assertTrue(syncGroup2.add(syncTarget1, null /* runnable */));
+ assertTrue(syncGroup2.add(syncTarget3, null /* runnable */));
syncGroup1.markSyncReady();
syncGroup2.markSyncReady();
@@ -303,7 +303,9 @@ public class SurfaceSyncGroupTest {
SurfaceSyncGroup.setTransactionFactory(() -> targetTransaction);
SyncTarget syncTarget = new SyncTarget();
- assertTrue(syncGroup.addToSync(syncTarget, true /* parentSyncGroupMerge */));
+ assertTrue(
+ syncGroup.add(syncTarget.mISurfaceSyncGroup, true /* parentSyncGroupMerge */,
+ null /* runnable */));
syncTarget.markSyncReady();
// When parentSyncGroupMerge is true, the transaction passed in merges the main SyncGroup
@@ -328,7 +330,7 @@ public class SurfaceSyncGroupTest {
SurfaceSyncGroup.setTransactionFactory(() -> targetTransaction);
SyncTarget syncTarget = new SyncTarget();
- assertTrue(syncGroup.addToSync(syncTarget, false /* parentSyncGroupMerge */));
+ assertTrue(syncGroup.add(syncTarget, null /* runnable */));
syncTarget.markSyncReady();
// When parentSyncGroupMerge is false, the transaction passed in should not merge
@@ -343,9 +345,9 @@ public class SurfaceSyncGroupTest {
SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(TAG);
syncGroup.addSyncCompleteCallback(mExecutor, finishedLatch::countDown);
SyncTarget syncTarget = new SyncTarget();
- syncGroup.addToSync(syncTarget, false /* parentSyncGroupMerge */);
+ syncGroup.add(syncTarget, null /* runnable */);
// Add the syncTarget to the same syncGroup and ensure it doesn't crash.
- syncGroup.addToSync(syncTarget, false /* parentSyncGroupMerge */);
+ syncGroup.add(syncTarget, null /* runnable */);
syncGroup.markSyncReady();
syncTarget.onBufferReady();
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupContinuousTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceViewSyncContinuousTest.java
index eef7cc25eee7..ad7314c9bc60 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupContinuousTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceViewSyncContinuousTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -22,15 +22,10 @@ import static android.server.wm.WindowManagerState.getLogicalDisplaySize;
import android.app.KeyguardManager;
import android.os.PowerManager;
-import android.platform.test.annotations.Presubmit;
-import android.view.SurfaceControl;
import android.view.cts.surfacevalidator.CapturedActivity;
-import android.window.SurfaceSyncGroup;
import androidx.test.rule.ActivityTestRule;
-import com.android.server.wm.scvh.SyncValidatorSCVHTestCase;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -38,7 +33,7 @@ import org.junit.rules.TestName;
import java.util.Objects;
-public class SurfaceSyncGroupContinuousTest {
+public class SurfaceViewSyncContinuousTest {
@Rule
public TestName mName = new TestName();
@@ -59,33 +54,10 @@ public class SurfaceSyncGroupContinuousTest {
pressWakeupButton();
pressUnlockButton();
}
- SurfaceSyncGroup.setTransactionFactory(SurfaceControl.Transaction::new);
}
@Test
public void testSurfaceViewSyncDuringResize() throws Throwable {
- mCapturedActivity.verifyTest(new SurfaceSyncGroupValidatorTestCase(), mName);
- }
-
- @Test
- public void testSurfaceControlViewHostIPCSync_Fast() throws Throwable {
- mCapturedActivity.verifyTest(
- new SyncValidatorSCVHTestCase(0 /* delayMs */, false /* overrideDefaultDuration */),
- mName);
- }
-
- @Test
- public void testSurfaceControlViewHostIPCSync_Slow() throws Throwable {
- mCapturedActivity.verifyTest(new SyncValidatorSCVHTestCase(100 /* delayMs */,
- false /* overrideDefaultDuration */), mName);
- }
-
- @Test
- @Presubmit
- public void testSurfaceControlViewHostIPCSync_Short() throws Throwable {
- mCapturedActivity.setMinimumCaptureDurationMs(5000);
- mCapturedActivity.verifyTest(
- new SyncValidatorSCVHTestCase(0 /* delayMs */, true /* overrideDefaultDuration */),
- mName);
+ mCapturedActivity.verifyTest(new SurfaceViewSyncValidatorTestCase(), mName);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupValidatorTestCase.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceViewSyncValidatorTestCase.java
index 1fa0c2300173..93c1badd5e78 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupValidatorTestCase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceViewSyncValidatorTestCase.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -41,7 +41,7 @@ import androidx.annotation.NonNull;
* never an empty area (black color). The test uses {@link SurfaceSyncGroup} class to gather the
* content it wants to synchronize.
*/
-public class SurfaceSyncGroupValidatorTestCase implements ISurfaceValidatorTestCase {
+public class SurfaceViewSyncValidatorTestCase implements ISurfaceValidatorTestCase {
private static final String TAG = "SurfaceSyncGroupValidatorTestCase";
private final Runnable mRunnable = new Runnable() {
@@ -76,7 +76,7 @@ public class SurfaceSyncGroupValidatorTestCase implements ISurfaceValidatorTestC
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,
int height) {
if (mSyncGroup != null) {
- mSyncGroup.addToSync(mSurfaceView, frameCallback ->
+ mSyncGroup.add(mSurfaceView, frameCallback ->
mRenderingThread.setFrameCallback(frameCallback));
mSyncGroup.markSyncReady();
mSyncGroup = null;
@@ -133,7 +133,7 @@ public class SurfaceSyncGroupValidatorTestCase implements ISurfaceValidatorTestC
mRenderingThread.pauseRendering();
mSyncGroup = new SurfaceSyncGroup(TAG);
- mSyncGroup.addToSync(mParent.getRootSurfaceControl());
+ mSyncGroup.add(mParent.getRootSurfaceControl(), null /* runanble */);
ViewGroup.LayoutParams svParams = mSurfaceView.getLayoutParams();
svParams.height = height;
diff --git a/services/tests/wmtests/src/com/android/server/wm/scvh/EmbeddedSCVHService.java b/services/tests/wmtests/src/com/android/server/wm/scvh/EmbeddedSCVHService.java
deleted file mode 100644
index 3bd577cb1d64..000000000000
--- a/services/tests/wmtests/src/com/android/server/wm/scvh/EmbeddedSCVHService.java
+++ /dev/null
@@ -1,127 +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.server.wm.scvh;
-
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
-
-import android.annotation.Nullable;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
-import android.hardware.display.DisplayManager;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.view.Display;
-import android.view.SurfaceControl.Transaction;
-import android.view.SurfaceControlViewHost;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-
-import androidx.annotation.NonNull;
-
-public class EmbeddedSCVHService extends Service {
- private static final String TAG = "SCVHEmbeddedService";
- private SurfaceControlViewHost mVr;
-
- private Handler mHandler;
-
- @Override
- public void onCreate() {
- super.onCreate();
- mHandler = new Handler(Looper.getMainLooper());
- }
-
- @Nullable
- @Override
- public IBinder onBind(Intent intent) {
- // Return the interface
- return new AttachEmbeddedWindow();
- }
-
- public static class SlowView extends View {
- private long mDelayMs;
- public SlowView(Context context) {
- super(context);
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- try {
- Thread.sleep(mDelayMs);
- } catch (InterruptedException e) {
- }
- }
-
- public void setDelay(long delayMs) {
- mDelayMs = delayMs;
- }
- }
-
- private class AttachEmbeddedWindow extends IAttachEmbeddedWindow.Stub {
- @Override
- public void attachEmbedded(IBinder hostToken, int width,
- int height, int displayId, long delayMs, IAttachEmbeddedWindowCallback callback) {
- mHandler.post(() -> {
- Context context = EmbeddedSCVHService.this;
- Display display = getApplicationContext().getSystemService(
- DisplayManager.class).getDisplay(displayId);
- mVr = new SurfaceControlViewHost(context, display, hostToken);
- FrameLayout content = new FrameLayout(context);
-
- SlowView slowView = new SlowView(context);
- slowView.setDelay(delayMs);
- slowView.setBackgroundColor(Color.BLUE);
- content.addView(slowView);
- WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height,
- TYPE_APPLICATION, 0, PixelFormat.OPAQUE);
- lp.setTitle("EmbeddedWindow");
- mVr.setView(content, lp);
-
- content.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(@NonNull View v) {
- // First frame isn't included in the sync so don't notify the host about the
- // surface package until the first draw has completed.
- Transaction transaction = new Transaction().addTransactionCommittedListener(
- getMainExecutor(), () -> {
- try {
- callback.onEmbeddedWindowAttached(mVr.getSurfacePackage());
- } catch (RemoteException e) {
- }
- });
- v.getRootSurfaceControl().applyTransactionOnDraw(transaction);
- }
-
- @Override
- public void onViewDetachedFromWindow(@NonNull View v) {
- }
- });
- });
- }
-
- @Override
- public void relayout(WindowManager.LayoutParams lp) {
- mHandler.post(() -> mVr.relayout(lp));
- }
- }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindow.aidl b/services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindow.aidl
deleted file mode 100644
index 343956759f09..000000000000
--- a/services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindow.aidl
+++ /dev/null
@@ -1,27 +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.server.wm.scvh;
-
-import android.view.SurfaceControlViewHost.SurfacePackage;
-import android.os.IBinder;
-import com.android.server.wm.scvh.IAttachEmbeddedWindowCallback;
-import android.view.WindowManager.LayoutParams;
-
-interface IAttachEmbeddedWindow {
- void attachEmbedded(IBinder hostToken, int width, int height, int displayId, long delayMs, IAttachEmbeddedWindowCallback callback);
- void relayout(in LayoutParams lp);
-} \ No newline at end of file
diff --git a/services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindowCallback.aidl b/services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindowCallback.aidl
deleted file mode 100644
index 92abfc8eea24..000000000000
--- a/services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindowCallback.aidl
+++ /dev/null
@@ -1,23 +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.server.wm.scvh;
-
-import android.view.SurfaceControlViewHost.SurfacePackage;
-
-interface IAttachEmbeddedWindowCallback {
- void onEmbeddedWindowAttached(in SurfacePackage surfacePackage);
-} \ No newline at end of file
diff --git a/services/tests/wmtests/src/com/android/server/wm/scvh/SyncValidatorSCVHTestCase.java b/services/tests/wmtests/src/com/android/server/wm/scvh/SyncValidatorSCVHTestCase.java
deleted file mode 100644
index 07dac8d7fcc3..000000000000
--- a/services/tests/wmtests/src/com/android/server/wm/scvh/SyncValidatorSCVHTestCase.java
+++ /dev/null
@@ -1,241 +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.server.wm.scvh;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNotNull;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
-import android.graphics.Point;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.SurfaceControlViewHost.SurfacePackage;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.cts.surfacevalidator.ISurfaceValidatorTestCase;
-import android.view.cts.surfacevalidator.PixelChecker;
-import android.widget.FrameLayout;
-import android.window.SurfaceSyncGroup;
-
-import androidx.annotation.NonNull;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-public class SyncValidatorSCVHTestCase implements ISurfaceValidatorTestCase {
- private static final String TAG = "SCVHSyncValidatorTestCase";
-
- private final Point[] mSizes = new Point[]{new Point(500, 500), new Point(700, 400),
- new Point(300, 800), new Point(200, 200)};
- private int mLastSizeIndex = 1;
-
- private final long mDelayMs;
- private final boolean mOverrideDefaultDuration;
-
- public SyncValidatorSCVHTestCase(long delayMs, boolean overrideDefaultDuration) {
- mDelayMs = delayMs;
- mOverrideDefaultDuration = overrideDefaultDuration;
- }
-
- private final Runnable mRunnable = new Runnable() {
- @Override
- public void run() {
- Point size = mSizes[mLastSizeIndex % mSizes.length];
- Runnable svResizeRunnable = () -> {
- ViewGroup.LayoutParams svParams = mSurfaceView.getLayoutParams();
- svParams.width = size.x;
- svParams.height = size.y;
- mSurfaceView.setLayoutParams(svParams);
- };
- Runnable resizeRunnable = () -> {
- try {
- final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(size.x,
- size.y,
- WindowManager.LayoutParams.TYPE_APPLICATION, 0,
- PixelFormat.TRANSPARENT);
- mIAttachEmbeddedWindow.relayout(lp);
- } catch (RemoteException e) {
- }
- };
-
- SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(TAG);
- syncGroup.addToSync(mSurfaceView.getRootSurfaceControl(), svResizeRunnable);
- syncGroup.addToSync(mSurfacePackage, resizeRunnable);
- syncGroup.markSyncReady();
-
- mLastSizeIndex++;
-
- mHandler.postDelayed(this, mDelayMs + 50);
- }
- };
-
- private Handler mHandler;
- private SurfaceView mSurfaceView;
-
- private final CountDownLatch mReadyLatch = new CountDownLatch(1);
- private boolean mSurfaceCreated;
- private boolean mIsAttached;
- private final Object mLock = new Object();
- private int mDisplayId;
- private IAttachEmbeddedWindow mIAttachEmbeddedWindow;
- private SurfacePackage mSurfacePackage;
-
- final SurfaceHolder.Callback mCallback = new SurfaceHolder.Callback() {
- @Override
- public void surfaceCreated(@NonNull SurfaceHolder holder) {
- synchronized (mLock) {
- mSurfaceCreated = true;
- }
- if (isReadyToAttach()) {
- attachEmbedded();
- }
- }
-
- @Override
- public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,
- int height) {
- }
-
- @Override
- public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
- }
- };
-
- @Override
- public PixelChecker getChecker() {
- return new PixelChecker(Color.BLACK) {
- @Override
- public boolean checkPixels(int matchingPixelCount, int width, int height) {
- // Content has been set up yet.
- if (mReadyLatch.getCount() > 0) {
- return true;
- }
- return matchingPixelCount == 0;
- }
- };
- }
-
- private final ServiceConnection mConnection = new ServiceConnection() {
- // Called when the connection with the service is established
- public void onServiceConnected(ComponentName className, IBinder service) {
- Log.d(TAG, "Service Connected");
- synchronized (mLock) {
- mIAttachEmbeddedWindow = IAttachEmbeddedWindow.Stub.asInterface(service);
- }
- if (isReadyToAttach()) {
- attachEmbedded();
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- Log.d(TAG, "Service Disconnected");
- mIAttachEmbeddedWindow = null;
- synchronized (mLock) {
- mIsAttached = false;
- }
- }
- };
-
- private boolean isReadyToAttach() {
- synchronized (mLock) {
- if (!mSurfaceCreated) {
- Log.d(TAG, "surface is not created");
- }
- if (mIAttachEmbeddedWindow == null) {
- Log.d(TAG, "Service is not attached");
- }
- if (mIsAttached) {
- Log.d(TAG, "Already attached");
- }
-
- return mSurfaceCreated && mIAttachEmbeddedWindow != null && !mIsAttached;
- }
- }
-
- private void attachEmbedded() {
- synchronized (mLock) {
- mIsAttached = true;
- }
- try {
- mIAttachEmbeddedWindow.attachEmbedded(mSurfaceView.getHostToken(), mSizes[0].x,
- mSizes[0].y, mDisplayId, mDelayMs, new IAttachEmbeddedWindowCallback.Stub() {
- @Override
- public void onEmbeddedWindowAttached(SurfacePackage surfacePackage) {
- mHandler.post(() -> {
- mSurfacePackage = surfacePackage;
- mSurfaceView.setChildSurfacePackage(surfacePackage);
- mReadyLatch.countDown();
- });
- }
- });
- } catch (RemoteException e) {
- }
- }
-
- @Override
- public void start(Context context, FrameLayout parent) {
- mDisplayId = context.getDisplayId();
- mHandler = new Handler(Looper.getMainLooper());
-
- Intent intent = new Intent(context, EmbeddedSCVHService.class);
- intent.setAction(EmbeddedSCVHService.class.getName());
- context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
-
- mSurfaceView = new SurfaceView(context);
- mSurfaceView.getHolder().addCallback(mCallback);
-
- FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(mSizes[0].x,
- mSizes[0].y);
- layoutParams.gravity = Gravity.CENTER;
- parent.addView(mSurfaceView, layoutParams);
- }
-
- @Override
- public void waitForReady() {
-
- try {
- mReadyLatch.await(5, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- }
-
- assertEquals("Timed out waiting for setup", 0, mReadyLatch.getCount());
- assertNotNull("SurfacePackage is null", mSurfacePackage);
-
- mHandler.post(mRunnable);
- }
-
- @Override
- public void end() {
- mHandler.removeCallbacks(mRunnable);
- }
-
- @Override
- public boolean hasAnimation() {
- return !mOverrideDefaultDuration;
- }
-}
diff --git a/tests/SurfaceControlViewHostTest/src/com/android/test/viewembed/SurfaceControlViewHostSyncTest.java b/tests/SurfaceControlViewHostTest/src/com/android/test/viewembed/SurfaceControlViewHostSyncTest.java
index ea727b91768d..359eb35384c7 100644
--- a/tests/SurfaceControlViewHostTest/src/com/android/test/viewembed/SurfaceControlViewHostSyncTest.java
+++ b/tests/SurfaceControlViewHostTest/src/com/android/test/viewembed/SurfaceControlViewHostSyncTest.java
@@ -131,8 +131,8 @@ public class SurfaceControlViewHostSyncTest extends Activity implements SurfaceH
if (mSync) {
SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(TAG);
- syncGroup.addToSync(getWindow().getRootSurfaceControl(), svResizeRunnable);
- syncGroup.addToSync(mSurfacePackage, resizeRunnable);
+ syncGroup.add(getWindow().getRootSurfaceControl(), svResizeRunnable);
+ syncGroup.add(mSurfacePackage, resizeRunnable);
syncGroup.markSyncReady();
} else {
svResizeRunnable.run();
diff --git a/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java b/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java
index d5983d064c80..d1f2112f649d 100644
--- a/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java
+++ b/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java
@@ -90,7 +90,7 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
if (mEnableSyncSwitch.isChecked()) {
mSyncGroup = new SurfaceSyncGroup(TAG);
- mSyncGroup.addToSync(container.getRootSurfaceControl());
+ mSyncGroup.add(container.getRootSurfaceControl(), null /* runnable */);
}
ViewGroup.LayoutParams svParams = mSurfaceView.getLayoutParams();
@@ -114,7 +114,7 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C
mRenderingThread.renderFrame(null, width, height);
return;
}
- mSyncGroup.addToSync(mSurfaceView, frameCallback ->
+ mSyncGroup.add(mSurfaceView, frameCallback ->
mRenderingThread.renderFrame(frameCallback, width, height));
mSyncGroup.markSyncReady();
mSyncGroup = null;