Loading services/core/java/com/android/server/wm/Transition.java +2 −2 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.wm.utils.SurfaceControlUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -1631,8 +1632,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { if (mTransactionCompletedListeners != null) { for (int i = 0; i < mTransactionCompletedListeners.size(); i++) { final Runnable listener = mTransactionCompletedListeners.get(i); transaction.addTransactionCompletedListener(Runnable::run, (stats) -> listener.run()); SurfaceControlUtils.addTransactionCompletedListener(transaction, listener); } } Loading services/core/java/com/android/server/wm/utils/SurfaceControlUtils.java 0 → 100644 +39 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.utils; import android.view.SurfaceControl; /** * JNI wrapper for ASurfaceTransaction_setOnComplete NDK method which is not * exposed as a Java API on older Android versions */ public class SurfaceControlUtils { /** * Adds a listener for transaction completion (when transaction is presented on the screen) * @param transaction transaction to which add the listener * @param runnable callback which will be called when transaction is presented */ public static void addTransactionCompletedListener(SurfaceControl.Transaction transaction, Runnable onComplete) { nativeAddTransactionCompletedListener(transaction, onComplete); } private static native void nativeAddTransactionCompletedListener( SurfaceControl.Transaction transaction, Runnable callback); } services/core/jni/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,7 @@ cc_library_static { "com_android_server_pm_PackageManagerShellCommandDataLoader.cpp", "com_android_server_sensor_SensorService.cpp", "com_android_server_wm_TaskFpsCallbackController.cpp", "com_android_server_wm_utils_SurfaceControlUtils.cpp", "onload.cpp", ":lib_cachedAppOptimizer_native", ":lib_gameManagerService_native", Loading services/core/jni/com_android_server_wm_utils_SurfaceControlUtils.cpp 0 → 100644 +105 −0 Original line number Diff line number Diff line /* * Copyright 2024 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. */ #define LOG_TAG "SurfaceControlUtils" #include <android_runtime/AndroidRuntime.h> #include <android_runtime/Log.h> #include <android/surface_control.h> #include <android/surface_control_jni.h> #include <nativehelper/JNIHelp.h> #include <utils/Log.h> #include <utils/RefBase.h> #include "core_jni_helpers.h" namespace android { namespace { static struct { jclass clazz; jmethodID run; } gRunnableClassInfo; class TransactionCompletedListenerWrapper { public: explicit TransactionCompletedListenerWrapper(JNIEnv* env, jobject object) { env->GetJavaVM(&mVm); mTransactionCompletedListenerObject = env->NewGlobalRef(object); LOG_ALWAYS_FATAL_IF(!mTransactionCompletedListenerObject, "Failed to make global ref"); } ~TransactionCompletedListenerWrapper() { getenv()->DeleteGlobalRef(mTransactionCompletedListenerObject); } void callback() { JNIEnv* env = getenv(); env->CallVoidMethod(mTransactionCompletedListenerObject, gRunnableClassInfo.run); DieIfException(env, "Uncaught exception in TransactionCompletedListener."); } static void transactionCallbackThunk(void* context, ASurfaceTransactionStats* stats) { TransactionCompletedListenerWrapper* listener = reinterpret_cast<TransactionCompletedListenerWrapper*>(context); listener->callback(); delete listener; } private: jobject mTransactionCompletedListenerObject; JavaVM* mVm; JNIEnv* getenv() { JNIEnv* env; mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6); return env; } }; static void nativeAddTransactionCompletedListener(JNIEnv* env, jclass clazz, jobject transactionObj, jobject transactionCompletedListener) { ASurfaceTransaction* transaction = ASurfaceTransaction_fromJava(env, transactionObj); auto context = new TransactionCompletedListenerWrapper(env, transactionCompletedListener); ASurfaceTransaction_setOnComplete(transaction, reinterpret_cast<void*>(context), TransactionCompletedListenerWrapper:: transactionCallbackThunk); } static const JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ {"nativeAddTransactionCompletedListener", "(Landroid/view/SurfaceControl$Transaction;Ljava/lang/Runnable;)V", (void*) nativeAddTransactionCompletedListener}}; } // namespace int register_com_android_server_wm_utils_SurfaceControlUtils(JNIEnv* env) { int res = jniRegisterNativeMethods(env, "com/android/server/wm/utils/SurfaceControlUtils", gMethods, NELEM(gMethods)); LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods."); jclass runnableClazz = FindClassOrDie(env, "java/lang/Runnable"); gRunnableClassInfo.clazz = MakeGlobalRefOrDie(env, runnableClazz); gRunnableClassInfo.run = GetMethodIDOrDie(env, runnableClazz, "run", "()V"); return 0; } } // namespace android services/core/jni/onload.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env); int register_android_server_companion_virtual_InputController(JNIEnv* env); int register_android_server_app_GameManagerService(JNIEnv* env); int register_com_android_server_wm_TaskFpsCallbackController(JNIEnv* env); int register_com_android_server_wm_utils_SurfaceControlUtils(JNIEnv* env); int register_com_android_server_display_DisplayControl(JNIEnv* env); int register_com_android_server_SystemClockTime(JNIEnv* env); int register_android_server_display_smallAreaDetectionController(JNIEnv* env); Loading Loading @@ -130,6 +131,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_android_server_companion_virtual_InputController(env); register_android_server_app_GameManagerService(env); register_com_android_server_wm_TaskFpsCallbackController(env); register_com_android_server_wm_utils_SurfaceControlUtils(env); register_com_android_server_display_DisplayControl(env); register_com_android_server_SystemClockTime(env); register_android_server_display_smallAreaDetectionController(env); Loading Loading
services/core/java/com/android/server/wm/Transition.java +2 −2 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.wm.utils.SurfaceControlUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -1631,8 +1632,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { if (mTransactionCompletedListeners != null) { for (int i = 0; i < mTransactionCompletedListeners.size(); i++) { final Runnable listener = mTransactionCompletedListeners.get(i); transaction.addTransactionCompletedListener(Runnable::run, (stats) -> listener.run()); SurfaceControlUtils.addTransactionCompletedListener(transaction, listener); } } Loading
services/core/java/com/android/server/wm/utils/SurfaceControlUtils.java 0 → 100644 +39 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.utils; import android.view.SurfaceControl; /** * JNI wrapper for ASurfaceTransaction_setOnComplete NDK method which is not * exposed as a Java API on older Android versions */ public class SurfaceControlUtils { /** * Adds a listener for transaction completion (when transaction is presented on the screen) * @param transaction transaction to which add the listener * @param runnable callback which will be called when transaction is presented */ public static void addTransactionCompletedListener(SurfaceControl.Transaction transaction, Runnable onComplete) { nativeAddTransactionCompletedListener(transaction, onComplete); } private static native void nativeAddTransactionCompletedListener( SurfaceControl.Transaction transaction, Runnable callback); }
services/core/jni/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,7 @@ cc_library_static { "com_android_server_pm_PackageManagerShellCommandDataLoader.cpp", "com_android_server_sensor_SensorService.cpp", "com_android_server_wm_TaskFpsCallbackController.cpp", "com_android_server_wm_utils_SurfaceControlUtils.cpp", "onload.cpp", ":lib_cachedAppOptimizer_native", ":lib_gameManagerService_native", Loading
services/core/jni/com_android_server_wm_utils_SurfaceControlUtils.cpp 0 → 100644 +105 −0 Original line number Diff line number Diff line /* * Copyright 2024 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. */ #define LOG_TAG "SurfaceControlUtils" #include <android_runtime/AndroidRuntime.h> #include <android_runtime/Log.h> #include <android/surface_control.h> #include <android/surface_control_jni.h> #include <nativehelper/JNIHelp.h> #include <utils/Log.h> #include <utils/RefBase.h> #include "core_jni_helpers.h" namespace android { namespace { static struct { jclass clazz; jmethodID run; } gRunnableClassInfo; class TransactionCompletedListenerWrapper { public: explicit TransactionCompletedListenerWrapper(JNIEnv* env, jobject object) { env->GetJavaVM(&mVm); mTransactionCompletedListenerObject = env->NewGlobalRef(object); LOG_ALWAYS_FATAL_IF(!mTransactionCompletedListenerObject, "Failed to make global ref"); } ~TransactionCompletedListenerWrapper() { getenv()->DeleteGlobalRef(mTransactionCompletedListenerObject); } void callback() { JNIEnv* env = getenv(); env->CallVoidMethod(mTransactionCompletedListenerObject, gRunnableClassInfo.run); DieIfException(env, "Uncaught exception in TransactionCompletedListener."); } static void transactionCallbackThunk(void* context, ASurfaceTransactionStats* stats) { TransactionCompletedListenerWrapper* listener = reinterpret_cast<TransactionCompletedListenerWrapper*>(context); listener->callback(); delete listener; } private: jobject mTransactionCompletedListenerObject; JavaVM* mVm; JNIEnv* getenv() { JNIEnv* env; mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6); return env; } }; static void nativeAddTransactionCompletedListener(JNIEnv* env, jclass clazz, jobject transactionObj, jobject transactionCompletedListener) { ASurfaceTransaction* transaction = ASurfaceTransaction_fromJava(env, transactionObj); auto context = new TransactionCompletedListenerWrapper(env, transactionCompletedListener); ASurfaceTransaction_setOnComplete(transaction, reinterpret_cast<void*>(context), TransactionCompletedListenerWrapper:: transactionCallbackThunk); } static const JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ {"nativeAddTransactionCompletedListener", "(Landroid/view/SurfaceControl$Transaction;Ljava/lang/Runnable;)V", (void*) nativeAddTransactionCompletedListener}}; } // namespace int register_com_android_server_wm_utils_SurfaceControlUtils(JNIEnv* env) { int res = jniRegisterNativeMethods(env, "com/android/server/wm/utils/SurfaceControlUtils", gMethods, NELEM(gMethods)); LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods."); jclass runnableClazz = FindClassOrDie(env, "java/lang/Runnable"); gRunnableClassInfo.clazz = MakeGlobalRefOrDie(env, runnableClazz); gRunnableClassInfo.run = GetMethodIDOrDie(env, runnableClazz, "run", "()V"); return 0; } } // namespace android
services/core/jni/onload.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env); int register_android_server_companion_virtual_InputController(JNIEnv* env); int register_android_server_app_GameManagerService(JNIEnv* env); int register_com_android_server_wm_TaskFpsCallbackController(JNIEnv* env); int register_com_android_server_wm_utils_SurfaceControlUtils(JNIEnv* env); int register_com_android_server_display_DisplayControl(JNIEnv* env); int register_com_android_server_SystemClockTime(JNIEnv* env); int register_android_server_display_smallAreaDetectionController(JNIEnv* env); Loading Loading @@ -130,6 +131,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_android_server_companion_virtual_InputController(env); register_android_server_app_GameManagerService(env); register_com_android_server_wm_TaskFpsCallbackController(env); register_com_android_server_wm_utils_SurfaceControlUtils(env); register_com_android_server_display_DisplayControl(env); register_com_android_server_SystemClockTime(env); register_android_server_display_smallAreaDetectionController(env); Loading