Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 97064796 authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Android (Google) Code Review
Browse files

Merge "Expose TransactionCommittedCallback to Java"

parents 2b56bb6a 9df2acb3
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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();
+1 −0
Original line number Diff line number Diff line
@@ -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
+29 −0
Original line number Diff line number Diff line
@@ -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
+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();
}
+64 −0
Original line number Diff line number Diff line
@@ -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;
}