diff --git a/core/java/android/window/WindowInfosListener.java b/core/java/android/window/WindowInfosListener.java index 9d4545c6e25d8..8db5a5eb0e471 100644 --- a/core/java/android/window/WindowInfosListener.java +++ b/core/java/android/window/WindowInfosListener.java @@ -17,6 +17,7 @@ package android.window; import android.graphics.Matrix; +import android.util.Pair; import android.util.Size; import android.view.InputWindowHandle; @@ -47,9 +48,13 @@ public abstract class WindowInfosListener { /** * Register the WindowInfosListener. + * + * @return The cached values for InputWindowHandles and DisplayInfos. This is the last updated + * value that was sent from SurfaceFlinger to this particular process. If there was nothing + * registered previously, then the data can be empty. */ - public void register() { - nativeRegister(mNativeListener); + public Pair register() { + return nativeRegister(mNativeListener); } /** @@ -60,7 +65,7 @@ public abstract class WindowInfosListener { } private static native long nativeCreate(WindowInfosListener thiz); - private static native void nativeRegister(long ptr); + private static native Pair nativeRegister(long ptr); private static native void nativeUnregister(long ptr); private static native long nativeGetFinalizer(); diff --git a/core/jni/android_window_WindowInfosListener.cpp b/core/jni/android_window_WindowInfosListener.cpp index 08c9f20b0815d..aae2549df4290 100644 --- a/core/jni/android_window_WindowInfosListener.cpp +++ b/core/jni/android_window_WindowInfosListener.cpp @@ -44,6 +44,11 @@ static struct { jmethodID ctor; } gDisplayInfoClassInfo; +static struct { + jclass clazz; + jmethodID ctor; +} gPairClassInfo; + static jclass gInputWindowHandleClass; jobject fromDisplayInfo(JNIEnv* env, gui::DisplayInfo displayInfo) { @@ -57,6 +62,30 @@ jobject fromDisplayInfo(JNIEnv* env, gui::DisplayInfo displayInfo) { displayInfo.logicalHeight, matrixObj.get()); } +static jobjectArray fromWindowInfos(JNIEnv* env, const std::vector& windowInfos) { + jobjectArray jWindowHandlesArray = + env->NewObjectArray(windowInfos.size(), gInputWindowHandleClass, nullptr); + for (int i = 0; i < windowInfos.size(); i++) { + ScopedLocalRef + jWindowHandle(env, + android_view_InputWindowHandle_fromWindowInfo(env, windowInfos[i])); + env->SetObjectArrayElement(jWindowHandlesArray, i, jWindowHandle.get()); + } + + return jWindowHandlesArray; +} + +static jobjectArray fromDisplayInfos(JNIEnv* env, const std::vector& displayInfos) { + jobjectArray jDisplayInfoArray = + env->NewObjectArray(displayInfos.size(), gDisplayInfoClassInfo.clazz, nullptr); + for (int i = 0; i < displayInfos.size(); i++) { + ScopedLocalRef jDisplayInfo(env, fromDisplayInfo(env, displayInfos[i])); + env->SetObjectArrayElement(jDisplayInfoArray, i, jDisplayInfo.get()); + } + + return jDisplayInfoArray; +} + struct WindowInfosListener : public gui::WindowInfosListener { WindowInfosListener(JNIEnv* env, jobject listener) : mListener(env->NewWeakGlobalRef(listener)) {} @@ -72,26 +101,8 @@ struct WindowInfosListener : public gui::WindowInfosListener { return; } - ScopedLocalRef - jWindowHandlesArray(env, - env->NewObjectArray(windowInfos.size(), gInputWindowHandleClass, - nullptr)); - for (int i = 0; i < windowInfos.size(); i++) { - ScopedLocalRef - jWindowHandle(env, - android_view_InputWindowHandle_fromWindowInfo(env, - windowInfos[i])); - env->SetObjectArrayElement(jWindowHandlesArray.get(), i, jWindowHandle.get()); - } - - ScopedLocalRef - jDisplayInfoArray(env, - env->NewObjectArray(displayInfos.size(), - gDisplayInfoClassInfo.clazz, nullptr)); - for (int i = 0; i < displayInfos.size(); i++) { - ScopedLocalRef jDisplayInfo(env, fromDisplayInfo(env, displayInfos[i])); - env->SetObjectArrayElement(jDisplayInfoArray.get(), i, jDisplayInfo.get()); - } + ScopedLocalRef jWindowHandlesArray(env, fromWindowInfos(env, windowInfos)); + ScopedLocalRef jDisplayInfoArray(env, fromDisplayInfos(env, displayInfos)); env->CallVoidMethod(listener, gListenerClassInfo.onWindowInfosChanged, jWindowHandlesArray.get(), jDisplayInfoArray.get()); @@ -124,9 +135,16 @@ void destroyNativeService(void* ptr) { listener->decStrong((void*)nativeCreate); } -void nativeRegister(JNIEnv* env, jclass clazz, jlong ptr) { +jobject nativeRegister(JNIEnv* env, jclass clazz, jlong ptr) { sp listener = reinterpret_cast(ptr); - SurfaceComposerClient::getDefault()->addWindowInfosListener(listener); + std::pair, std::vector> initialInfo; + SurfaceComposerClient::getDefault()->addWindowInfosListener(listener, &initialInfo); + + ScopedLocalRef jWindowHandlesArray(env, fromWindowInfos(env, initialInfo.first)); + ScopedLocalRef jDisplayInfoArray(env, fromDisplayInfos(env, initialInfo.second)); + + return env->NewObject(gPairClassInfo.clazz, gPairClassInfo.ctor, jWindowHandlesArray.get(), + jDisplayInfoArray.get()); } void nativeUnregister(JNIEnv* env, jclass clazz, jlong ptr) { @@ -141,7 +159,7 @@ static jlong nativeGetFinalizer(JNIEnv* /* env */, jclass /* clazz */) { const JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ {"nativeCreate", "(Landroid/window/WindowInfosListener;)J", (void*)nativeCreate}, - {"nativeRegister", "(J)V", (void*)nativeRegister}, + {"nativeRegister", "(J)Landroid/util/Pair;", (void*)nativeRegister}, {"nativeUnregister", "(J)V", (void*)nativeUnregister}, {"nativeGetFinalizer", "()J", (void*)nativeGetFinalizer}}; @@ -166,6 +184,12 @@ int register_android_window_WindowInfosListener(JNIEnv* env) { gDisplayInfoClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); gDisplayInfoClassInfo.ctor = env->GetMethodID(gDisplayInfoClassInfo.clazz, "", "(IIILandroid/graphics/Matrix;)V"); + + clazz = env->FindClass("android/util/Pair"); + gPairClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); + gPairClassInfo.ctor = env->GetMethodID(gPairClassInfo.clazz, "", + "(Ljava/lang/Object;Ljava/lang/Object;)V"); + return 0; } diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java index d4648a4f313c9..11ddac6a97403 100644 --- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java +++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java @@ -30,6 +30,7 @@ import android.os.IBinder; import android.os.InputConfig; import android.os.Looper; import android.os.Message; +import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.view.IWindow; @@ -94,8 +95,6 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener { mService = service; mAccessibilityController = accessibilityController; mHandler = new MyHandler(mService.mH.getLooper()); - - register(); } /** @@ -219,8 +218,10 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener { } mWindowsNotificationEnabled = register; if (mWindowsNotificationEnabled) { - populateVisibleWindowHandlesAndNotifyWindowsChangeIfNeeded(); + Pair info = register(); + onWindowInfosChangedInternal(info.first, info.second); } else { + unregister(); releaseResources(); } }