Loading core/api/current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -48507,6 +48507,7 @@ package android.view { public static class SurfaceControl.Transaction implements java.io.Closeable android.os.Parcelable { ctor public SurfaceControl.Transaction(); method @NonNull public android.view.SurfaceControl.Transaction addTransactionCommittedListener(@NonNull java.util.concurrent.Executor, @NonNull android.view.TransactionCommittedListener); method public void apply(); method public void close(); method public int describeContents(); Loading Loading @@ -48633,6 +48634,10 @@ package android.view { field public static final int TO_RIGHT = 8; // 0x8 } public interface TransactionCommittedListener { method public void onTransactionCommitted(); } public final class VelocityTracker { method public void addMovement(android.view.MotionEvent); method public void clear(); core/java/android/view/OWNERS +1 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ per-file SyncRtSurfaceTransactionApplier.java = file:/services/core/java/com/and per-file ViewRootInsetsControllerHost.java = file:/services/core/java/com/android/server/wm/OWNERS per-file Window*.java = file:/services/core/java/com/android/server/wm/OWNERS per-file Window*.aidl = file:/services/core/java/com/android/server/wm/OWNERS per-file TransactionCommittedCallback.java = file:/services/core/java/com/android/server/wm/OWNERS # Scroll Capture per-file *ScrollCapture*.aidl = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS Loading core/java/android/view/SurfaceControl.java +29 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import static android.view.SurfaceControlProto.HASH_CODE; import static android.view.SurfaceControlProto.LAYER_ID; import static android.view.SurfaceControlProto.NAME; import android.annotation.CallbackExecutor; import android.annotation.FloatRange; import android.annotation.IntDef; import android.annotation.IntRange; Loading Loading @@ -74,6 +75,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; /** Loading Loading @@ -244,6 +246,8 @@ public final class SurfaceControl implements Parcelable { private static native void nativeSetTransformHint(long nativeObject, int transformHint); private static native int nativeGetTransformHint(long nativeObject); private static native int nativeGetLayerId(long nativeObject); private static native void nativeAddTransactionCommittedListener(long nativeObject, TransactionCommittedListener listener); @Nullable @GuardedBy("mLock") Loading Loading @@ -3518,6 +3522,31 @@ public final class SurfaceControl implements Parcelable { return this; } /** * Request to add a {@link TransactionCommittedListener}. * * The callback is invoked when transaction is applied and the updates are ready to be * presented. This callback does not mean buffers have been released! It simply means that * any new transactions applied will not overwrite the transaction for which we are * receiving a callback and instead will be included in the next frame. If you are trying * to avoid dropping frames (overwriting transactions), and unable to use timestamps (Which * provide a more efficient solution), then this method provides a method to pace your * transaction application. * * @param executor The executor that the callback should be invoked on. * @param listener The callback that will be invoked when the transaction has been * committed. */ @NonNull public Transaction addTransactionCommittedListener( @NonNull @CallbackExecutor Executor executor, @NonNull TransactionCommittedListener listener) { TransactionCommittedListener listenerInner = () -> executor.execute(listener::onTransactionCommitted); nativeAddTransactionCommittedListener(mNativeObject, listenerInner); return this; } /** * Writes the transaction to parcel, clearing the transaction as if it had been applied so * it can be used to store future transactions. It's the responsibility of the parcel Loading core/java/android/view/TransactionCommittedListener.java 0 → 100644 +30 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 android.view; import java.util.concurrent.Executor; /** * Interface to handle request to * {@link SurfaceControl.Transaction#addTransactionCommittedListener(Executor, TransactionCommittedListener)} */ public interface TransactionCommittedListener { /** * Invoked when the transaction has been committed in SurfaceFlinger. */ void onTransactionCommitted(); } core/jni/android_view_SurfaceControl.cpp +64 −0 Original line number Diff line number Diff line Loading @@ -238,6 +238,11 @@ static struct { jmethodID ctor; } gJankDataClassInfo; static struct { jclass clazz; jmethodID onTransactionCommitted; } gTransactionCommittedListenerClassInfo; class JNamedColorSpace { public: // ColorSpace.Named.SRGB.ordinal() = 0; Loading Loading @@ -329,6 +334,44 @@ private: } }; class TransactionCommittedListenerWrapper { public: explicit TransactionCommittedListenerWrapper(JNIEnv* env, jobject object) { env->GetJavaVM(&mVm); mTransactionCommittedListenerObject = env->NewGlobalRef(object); LOG_ALWAYS_FATAL_IF(!mTransactionCommittedListenerObject, "Failed to make global ref"); } ~TransactionCommittedListenerWrapper() { getenv()->DeleteGlobalRef(mTransactionCommittedListenerObject); } void callback() { JNIEnv* env = getenv(); env->CallVoidMethod(mTransactionCommittedListenerObject, gTransactionCommittedListenerClassInfo.onTransactionCommitted); } static void transactionCallbackThunk(void* context, nsecs_t /*latchTime*/, const sp<Fence>& /*presentFence*/, const std::vector<SurfaceControlStats>& /*stats*/) { TransactionCommittedListenerWrapper* listener = reinterpret_cast<TransactionCommittedListenerWrapper*>(context); listener->callback(); delete listener; } private: jobject mTransactionCommittedListenerObject; JavaVM* mVm; JNIEnv* getenv() { JNIEnv* env; mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6); return env; } }; // ---------------------------------------------------------------------------- static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) { Loading Loading @@ -1736,6 +1779,17 @@ static void nativeSetFrameTimelineVsync(JNIEnv* env, jclass clazz, jlong transac {frameTimelineVsyncId, android::os::IInputConstants::INVALID_INPUT_EVENT_ID}); } static void nativeAddTransactionCommittedListener(JNIEnv* env, jclass clazz, jlong transactionObj, jobject transactionCommittedListenerObject) { auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); void* context = new TransactionCommittedListenerWrapper(env, transactionCommittedListenerObject); transaction->addTransactionCommittedCallback(TransactionCommittedListenerWrapper:: transactionCallbackThunk, context); } class JankDataListenerWrapper : public JankDataListener { public: JankDataListenerWrapper(JNIEnv* env, jobject onJankDataListenerObject) { Loading Loading @@ -2035,6 +2089,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeGetLayerId }, {"nativeSetDropInputMode", "(JJI)V", (void*)nativeSetDropInputMode }, {"nativeAddTransactionCommittedListener", "(JLandroid/view/TransactionCommittedListener;)V", (void*) nativeAddTransactionCommittedListener }, // clang-format on }; Loading Loading @@ -2250,6 +2306,14 @@ int register_android_view_SurfaceControl(JNIEnv* env) gJankDataListenerClassInfo.onJankDataAvailable = GetMethodIDOrDie(env, onJankDataListenerClazz, "onJankDataAvailable", "([Landroid/view/SurfaceControl$JankData;)V"); jclass transactionCommittedListenerClazz = FindClassOrDie(env, "android/view/TransactionCommittedListener"); gTransactionCommittedListenerClassInfo.clazz = MakeGlobalRefOrDie(env, transactionCommittedListenerClazz); gTransactionCommittedListenerClassInfo.onTransactionCommitted = GetMethodIDOrDie(env, transactionCommittedListenerClazz, "onTransactionCommitted", "()V"); return err; } Loading Loading
core/api/current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -48507,6 +48507,7 @@ package android.view { public static class SurfaceControl.Transaction implements java.io.Closeable android.os.Parcelable { ctor public SurfaceControl.Transaction(); method @NonNull public android.view.SurfaceControl.Transaction addTransactionCommittedListener(@NonNull java.util.concurrent.Executor, @NonNull android.view.TransactionCommittedListener); method public void apply(); method public void close(); method public int describeContents(); Loading Loading @@ -48633,6 +48634,10 @@ package android.view { field public static final int TO_RIGHT = 8; // 0x8 } public interface TransactionCommittedListener { method public void onTransactionCommitted(); } public final class VelocityTracker { method public void addMovement(android.view.MotionEvent); method public void clear();
core/java/android/view/OWNERS +1 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ per-file SyncRtSurfaceTransactionApplier.java = file:/services/core/java/com/and per-file ViewRootInsetsControllerHost.java = file:/services/core/java/com/android/server/wm/OWNERS per-file Window*.java = file:/services/core/java/com/android/server/wm/OWNERS per-file Window*.aidl = file:/services/core/java/com/android/server/wm/OWNERS per-file TransactionCommittedCallback.java = file:/services/core/java/com/android/server/wm/OWNERS # Scroll Capture per-file *ScrollCapture*.aidl = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS Loading
core/java/android/view/SurfaceControl.java +29 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import static android.view.SurfaceControlProto.HASH_CODE; import static android.view.SurfaceControlProto.LAYER_ID; import static android.view.SurfaceControlProto.NAME; import android.annotation.CallbackExecutor; import android.annotation.FloatRange; import android.annotation.IntDef; import android.annotation.IntRange; Loading Loading @@ -74,6 +75,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; /** Loading Loading @@ -244,6 +246,8 @@ public final class SurfaceControl implements Parcelable { private static native void nativeSetTransformHint(long nativeObject, int transformHint); private static native int nativeGetTransformHint(long nativeObject); private static native int nativeGetLayerId(long nativeObject); private static native void nativeAddTransactionCommittedListener(long nativeObject, TransactionCommittedListener listener); @Nullable @GuardedBy("mLock") Loading Loading @@ -3518,6 +3522,31 @@ public final class SurfaceControl implements Parcelable { return this; } /** * Request to add a {@link TransactionCommittedListener}. * * The callback is invoked when transaction is applied and the updates are ready to be * presented. This callback does not mean buffers have been released! It simply means that * any new transactions applied will not overwrite the transaction for which we are * receiving a callback and instead will be included in the next frame. If you are trying * to avoid dropping frames (overwriting transactions), and unable to use timestamps (Which * provide a more efficient solution), then this method provides a method to pace your * transaction application. * * @param executor The executor that the callback should be invoked on. * @param listener The callback that will be invoked when the transaction has been * committed. */ @NonNull public Transaction addTransactionCommittedListener( @NonNull @CallbackExecutor Executor executor, @NonNull TransactionCommittedListener listener) { TransactionCommittedListener listenerInner = () -> executor.execute(listener::onTransactionCommitted); nativeAddTransactionCommittedListener(mNativeObject, listenerInner); return this; } /** * Writes the transaction to parcel, clearing the transaction as if it had been applied so * it can be used to store future transactions. It's the responsibility of the parcel Loading
core/java/android/view/TransactionCommittedListener.java 0 → 100644 +30 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 android.view; import java.util.concurrent.Executor; /** * Interface to handle request to * {@link SurfaceControl.Transaction#addTransactionCommittedListener(Executor, TransactionCommittedListener)} */ public interface TransactionCommittedListener { /** * Invoked when the transaction has been committed in SurfaceFlinger. */ void onTransactionCommitted(); }
core/jni/android_view_SurfaceControl.cpp +64 −0 Original line number Diff line number Diff line Loading @@ -238,6 +238,11 @@ static struct { jmethodID ctor; } gJankDataClassInfo; static struct { jclass clazz; jmethodID onTransactionCommitted; } gTransactionCommittedListenerClassInfo; class JNamedColorSpace { public: // ColorSpace.Named.SRGB.ordinal() = 0; Loading Loading @@ -329,6 +334,44 @@ private: } }; class TransactionCommittedListenerWrapper { public: explicit TransactionCommittedListenerWrapper(JNIEnv* env, jobject object) { env->GetJavaVM(&mVm); mTransactionCommittedListenerObject = env->NewGlobalRef(object); LOG_ALWAYS_FATAL_IF(!mTransactionCommittedListenerObject, "Failed to make global ref"); } ~TransactionCommittedListenerWrapper() { getenv()->DeleteGlobalRef(mTransactionCommittedListenerObject); } void callback() { JNIEnv* env = getenv(); env->CallVoidMethod(mTransactionCommittedListenerObject, gTransactionCommittedListenerClassInfo.onTransactionCommitted); } static void transactionCallbackThunk(void* context, nsecs_t /*latchTime*/, const sp<Fence>& /*presentFence*/, const std::vector<SurfaceControlStats>& /*stats*/) { TransactionCommittedListenerWrapper* listener = reinterpret_cast<TransactionCommittedListenerWrapper*>(context); listener->callback(); delete listener; } private: jobject mTransactionCommittedListenerObject; JavaVM* mVm; JNIEnv* getenv() { JNIEnv* env; mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6); return env; } }; // ---------------------------------------------------------------------------- static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) { Loading Loading @@ -1736,6 +1779,17 @@ static void nativeSetFrameTimelineVsync(JNIEnv* env, jclass clazz, jlong transac {frameTimelineVsyncId, android::os::IInputConstants::INVALID_INPUT_EVENT_ID}); } static void nativeAddTransactionCommittedListener(JNIEnv* env, jclass clazz, jlong transactionObj, jobject transactionCommittedListenerObject) { auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); void* context = new TransactionCommittedListenerWrapper(env, transactionCommittedListenerObject); transaction->addTransactionCommittedCallback(TransactionCommittedListenerWrapper:: transactionCallbackThunk, context); } class JankDataListenerWrapper : public JankDataListener { public: JankDataListenerWrapper(JNIEnv* env, jobject onJankDataListenerObject) { Loading Loading @@ -2035,6 +2089,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeGetLayerId }, {"nativeSetDropInputMode", "(JJI)V", (void*)nativeSetDropInputMode }, {"nativeAddTransactionCommittedListener", "(JLandroid/view/TransactionCommittedListener;)V", (void*) nativeAddTransactionCommittedListener }, // clang-format on }; Loading Loading @@ -2250,6 +2306,14 @@ int register_android_view_SurfaceControl(JNIEnv* env) gJankDataListenerClassInfo.onJankDataAvailable = GetMethodIDOrDie(env, onJankDataListenerClazz, "onJankDataAvailable", "([Landroid/view/SurfaceControl$JankData;)V"); jclass transactionCommittedListenerClazz = FindClassOrDie(env, "android/view/TransactionCommittedListener"); gTransactionCommittedListenerClassInfo.clazz = MakeGlobalRefOrDie(env, transactionCommittedListenerClazz); gTransactionCommittedListenerClassInfo.onTransactionCommitted = GetMethodIDOrDie(env, transactionCommittedListenerClazz, "onTransactionCommitted", "()V"); return err; } Loading