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
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user