Merge "Expose TransactionCommittedCallback to Java"

This commit is contained in:
Chavi Weingarten
2021-09-27 14:05:20 +00:00
committed by Android (Google) Code Review
5 changed files with 129 additions and 0 deletions

View File

@@ -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();
@@ -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();

View File

@@ -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

View File

@@ -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;
@@ -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;
/**
@@ -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")
@@ -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

View File

@@ -0,0 +1,30 @@
/*
* 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();
}

View File

@@ -238,6 +238,11 @@ static struct {
jmethodID ctor;
} gJankDataClassInfo;
static struct {
jclass clazz;
jmethodID onTransactionCommitted;
} gTransactionCommittedListenerClassInfo;
class JNamedColorSpace {
public:
// ColorSpace.Named.SRGB.ordinal() = 0;
@@ -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) {
@@ -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) {
@@ -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
};
@@ -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;
}