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

Commit 277f1608 authored by chaviw's avatar chaviw
Browse files

Store last data received from WindowInfosListener

Store the last data received from WindowInfoListener on the client so it
can easily be retrieved when a new caller registers to listen for
updates. This will help with accessibility since they won't need to
register their listener all the time and instead just get the last data
that was sent, immediately.

From the system server process, the data is constantly being updated
because WindowInfo is sent to InputDispatcher when any geometry in SF
changes. If a different process registers for the WindowInfoListener,
it's possible the initial data will be empty since we won't explicitly
request the latest data immediately.

Bug: 222767081
Test: Accessibility register only when enabled
Change-Id: Ib87edde7a14be8584504d5d8d6c41f20bde5c698
parent ecd166ee
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -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<InputWindowHandle[], DisplayInfo[]> 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<InputWindowHandle[], DisplayInfo[]> nativeRegister(long ptr);
    private static native void nativeUnregister(long ptr);
    private static native long nativeGetFinalizer();

+47 −23
Original line number Diff line number Diff line
@@ -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<WindowInfo>& windowInfos) {
    jobjectArray jWindowHandlesArray =
            env->NewObjectArray(windowInfos.size(), gInputWindowHandleClass, nullptr);
    for (int i = 0; i < windowInfos.size(); i++) {
        ScopedLocalRef<jobject>
                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<DisplayInfo>& displayInfos) {
    jobjectArray jDisplayInfoArray =
            env->NewObjectArray(displayInfos.size(), gDisplayInfoClassInfo.clazz, nullptr);
    for (int i = 0; i < displayInfos.size(); i++) {
        ScopedLocalRef<jobject> 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<jobjectArray>
                jWindowHandlesArray(env,
                                    env->NewObjectArray(windowInfos.size(), gInputWindowHandleClass,
                                                        nullptr));
        for (int i = 0; i < windowInfos.size(); i++) {
            ScopedLocalRef<jobject>
                    jWindowHandle(env,
                                  android_view_InputWindowHandle_fromWindowInfo(env,
                                                                                windowInfos[i]));
            env->SetObjectArrayElement(jWindowHandlesArray.get(), i, jWindowHandle.get());
        }

        ScopedLocalRef<jobjectArray>
                jDisplayInfoArray(env,
                                  env->NewObjectArray(displayInfos.size(),
                                                      gDisplayInfoClassInfo.clazz, nullptr));
        for (int i = 0; i < displayInfos.size(); i++) {
            ScopedLocalRef<jobject> jDisplayInfo(env, fromDisplayInfo(env, displayInfos[i]));
            env->SetObjectArrayElement(jDisplayInfoArray.get(), i, jDisplayInfo.get());
        }
        ScopedLocalRef<jobjectArray> jWindowHandlesArray(env, fromWindowInfos(env, windowInfos));
        ScopedLocalRef<jobjectArray> 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<WindowInfosListener> listener = reinterpret_cast<WindowInfosListener*>(ptr);
    SurfaceComposerClient::getDefault()->addWindowInfosListener(listener);
    std::pair<std::vector<gui::WindowInfo>, std::vector<gui::DisplayInfo>> initialInfo;
    SurfaceComposerClient::getDefault()->addWindowInfosListener(listener, &initialInfo);

    ScopedLocalRef<jobjectArray> jWindowHandlesArray(env, fromWindowInfos(env, initialInfo.first));
    ScopedLocalRef<jobjectArray> 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, "<init>",
                                                  "(IIILandroid/graphics/Matrix;)V");

    clazz = env->FindClass("android/util/Pair");
    gPairClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
    gPairClassInfo.ctor = env->GetMethodID(gPairClassInfo.clazz, "<init>",
                                           "(Ljava/lang/Object;Ljava/lang/Object;)V");

    return 0;
}

+4 −3
Original line number Diff line number Diff line
@@ -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<InputWindowHandle[], DisplayInfo[]> info = register();
                onWindowInfosChangedInternal(info.first, info.second);
            } else {
                unregister();
                releaseResources();
            }
        }