From 3316a0a08e79739b0508087232efcb3f2803dafe Mon Sep 17 00:00:00 2001 From: Dominik Laskowski Date: Fri, 25 Jan 2019 02:56:41 -0800 Subject: Generalize physical display management This CL enables the framework to manage an arbitrary number of physical displays. It also surfaces physical display IDs, which are stable across reboots and encode (model, port) information that will be propagated further up in a follow-up CL. Bug: 116025192 Test: Boot with more than two displays Test: Hotplug works with any number of displays Test: Verify stable display IDs with "dumpsys display" Change-Id: Idb2eaff66b2e0873be6ad27d337ff18b730d1331 --- libs/androidfw/DisplayEventDispatcher.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'libs/androidfw/DisplayEventDispatcher.cpp') diff --git a/libs/androidfw/DisplayEventDispatcher.cpp b/libs/androidfw/DisplayEventDispatcher.cpp index 7708e4340397..3b9a348047ba 100644 --- a/libs/androidfw/DisplayEventDispatcher.cpp +++ b/libs/androidfw/DisplayEventDispatcher.cpp @@ -68,7 +68,7 @@ status_t DisplayEventDispatcher::scheduleVsync() { // Drain all pending events. nsecs_t vsyncTimestamp; - int32_t vsyncDisplayId; + PhysicalDisplayId vsyncDisplayId; uint32_t vsyncCount; if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) { ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "", @@ -101,10 +101,11 @@ int DisplayEventDispatcher::handleEvent(int, int events, void*) { // Drain all pending events, keep the last vsync. nsecs_t vsyncTimestamp; - int32_t vsyncDisplayId; + PhysicalDisplayId vsyncDisplayId; uint32_t vsyncCount; if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) { - ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", id=%d, count=%d", + ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", displayId=%" + ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", count=%d", this, ns2ms(vsyncTimestamp), vsyncDisplayId, vsyncCount); mWaitingForVsync = false; dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount); @@ -114,7 +115,7 @@ int DisplayEventDispatcher::handleEvent(int, int events, void*) { } bool DisplayEventDispatcher::processPendingEvents( - nsecs_t* outTimestamp, int32_t* outId, uint32_t* outCount) { + nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId, uint32_t* outCount) { bool gotVsync = false; DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE]; ssize_t n; @@ -128,11 +129,11 @@ bool DisplayEventDispatcher::processPendingEvents( // ones. That's fine, we only care about the most recent. gotVsync = true; *outTimestamp = ev.header.timestamp; - *outId = ev.header.id; + *outDisplayId = ev.header.displayId; *outCount = ev.vsync.count; break; case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: - dispatchHotplug(ev.header.timestamp, ev.header.id, ev.hotplug.connected); + dispatchHotplug(ev.header.timestamp, ev.header.displayId, ev.hotplug.connected); break; default: ALOGW("dispatcher %p ~ ignoring unknown event type %#x", this, ev.header.type); -- cgit v1.2.3-59-g8ed1b From a5a21f70e125d58184f5446863fc4e3ac022e149 Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Wed, 13 Feb 2019 16:41:59 -0800 Subject: DisplayEventDispatcher: add DISPLAY_EVENT_CONFIG_CHANGED Add a new event for display configuration change. This event will be sent by SF anytime it changes the display config. Test: Generate DISPLAY_EVENT_CONFIG_CHANGED and observe the log Bug: 122905403 Change-Id: Ifa473a34d7b313501e5e4e8a67186fb82754fdcd --- core/java/android/view/DisplayEventReceiver.java | 18 ++++++++++++++++++ core/jni/android_view_DisplayEventReceiver.cpp | 22 ++++++++++++++++++++++ libs/androidfw/DisplayEventDispatcher.cpp | 3 +++ .../include/androidfw/DisplayEventDispatcher.h | 2 ++ native/android/choreographer.cpp | 9 +++++++++ .../server/display/LocalDisplayAdapter.java | 19 +++++++++++++++---- 6 files changed, 69 insertions(+), 4 deletions(-) (limited to 'libs/androidfw/DisplayEventDispatcher.cpp') diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index 3e8002f4634d..60daddd663d5 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -155,6 +155,17 @@ public abstract class DisplayEventReceiver { public void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected) { } + /** + * Called when a display config changed event is received. + * + * @param timestampNanos The timestamp of the event, in the {@link System#nanoTime()} + * timebase. + * @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair. + * @param configId The new config Id + */ + public void onConfigChanged(long timestampNanos, long physicalDisplayId, int configId) { + } + /** * Schedules a single vertical sync pulse to be delivered when the next * display frame begins. @@ -182,4 +193,11 @@ public abstract class DisplayEventReceiver { private void dispatchHotplug(long timestampNanos, long physicalDisplayId, boolean connected) { onHotplug(timestampNanos, physicalDisplayId, connected); } + + // Called from native code. + @SuppressWarnings("unused") + private void dispatchConfigChanged(long timestampNanos, long physicalDisplayId, int configId) { + onConfigChanged(timestampNanos, physicalDisplayId, configId); + } + } diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp index 191472d086f6..8d702d11d8fe 100644 --- a/core/jni/android_view_DisplayEventReceiver.cpp +++ b/core/jni/android_view_DisplayEventReceiver.cpp @@ -41,6 +41,7 @@ static struct { jmethodID dispatchVsync; jmethodID dispatchHotplug; + jmethodID dispatchConfigChanged; } gDisplayEventReceiverClassInfo; @@ -61,6 +62,8 @@ private: void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) override; void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override; + void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId, + int32_t configId) override; }; @@ -114,6 +117,23 @@ void NativeDisplayEventReceiver::dispatchHotplug(nsecs_t timestamp, PhysicalDisp mMessageQueue->raiseAndClearException(env, "dispatchHotplug"); } +void NativeDisplayEventReceiver::dispatchConfigChanged(nsecs_t timestamp, + PhysicalDisplayId displayId, + int32_t configId) { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + + ScopedLocalRef receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); + if (receiverObj.get()) { + ALOGV("receiver %p ~ Invoking config changed handler.", this); + env->CallVoidMethod(receiverObj.get(), + gDisplayEventReceiverClassInfo.dispatchConfigChanged, + timestamp, displayId, configId); + ALOGV("receiver %p ~ Returned from config changed handler.", this); + } + + mMessageQueue->raiseAndClearException(env, "dispatchConfigChanged"); +} + static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj, jint vsyncSource) { @@ -180,6 +200,8 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJI)V"); gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V"); + gDisplayEventReceiverClassInfo.dispatchConfigChanged = GetMethodIDOrDie(env, + gDisplayEventReceiverClassInfo.clazz, "dispatchConfigChanged", "(JJI)V"); return res; } diff --git a/libs/androidfw/DisplayEventDispatcher.cpp b/libs/androidfw/DisplayEventDispatcher.cpp index 3b9a348047ba..660614895603 100644 --- a/libs/androidfw/DisplayEventDispatcher.cpp +++ b/libs/androidfw/DisplayEventDispatcher.cpp @@ -135,6 +135,9 @@ bool DisplayEventDispatcher::processPendingEvents( case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: dispatchHotplug(ev.header.timestamp, ev.header.displayId, ev.hotplug.connected); break; + case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED: + dispatchConfigChanged(ev.header.timestamp, ev.header.displayId, ev.config.configId); + break; default: ALOGW("dispatcher %p ~ ignoring unknown event type %#x", this, ev.header.type); break; diff --git a/libs/androidfw/include/androidfw/DisplayEventDispatcher.h b/libs/androidfw/include/androidfw/DisplayEventDispatcher.h index d2addba61679..5381c0174cb0 100644 --- a/libs/androidfw/include/androidfw/DisplayEventDispatcher.h +++ b/libs/androidfw/include/androidfw/DisplayEventDispatcher.h @@ -40,6 +40,8 @@ private: virtual void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) = 0; virtual void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) = 0; + virtual void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId, + int32_t configId) = 0; virtual int handleEvent(int receiveFd, int events, void* data); bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId, diff --git a/native/android/choreographer.cpp b/native/android/choreographer.cpp index 2db575bf5a13..3fecd53b43e2 100644 --- a/native/android/choreographer.cpp +++ b/native/android/choreographer.cpp @@ -70,6 +70,8 @@ private: void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) override; void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override; + void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId, + int32_t configId) override; void scheduleCallbacks(); @@ -164,6 +166,13 @@ void Choreographer::dispatchHotplug(nsecs_t, PhysicalDisplayId displayId, bool c this, displayId, toString(connected)); } +void Choreographer::dispatchConfigChanged(nsecs_t, PhysicalDisplayId displayId, + int32_t configId) { + ALOGV("choreographer %p ~ received config changed event (displayId=%" + ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", configId=%s), ignoring.", + this, displayId, toString(configId)); +} + void Choreographer::handleMessage(const Message& message) { switch (message.what) { case MSG_SCHEDULE_CALLBACKS: diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 489194726c5a..77df10bf536a 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -65,7 +65,8 @@ final class LocalDisplayAdapter extends DisplayAdapter { new LongSparseArray(); @SuppressWarnings("unused") // Becomes active at instantiation time. - private HotplugDisplayEventReceiver mHotplugReceiver; + private PhysicalDisplayEventReceiver mPhysicalDisplayEventReceiver; + // Called with SyncRoot lock held. public LocalDisplayAdapter(DisplayManagerService.SyncRoot syncRoot, @@ -77,7 +78,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { public void registerLocked() { super.registerLocked(); - mHotplugReceiver = new HotplugDisplayEventReceiver(getHandler().getLooper()); + mPhysicalDisplayEventReceiver = new PhysicalDisplayEventReceiver(getHandler().getLooper()); for (long physicalDisplayId : SurfaceControl.getPhysicalDisplayIds()) { tryConnectDisplayLocked(physicalDisplayId); @@ -727,8 +728,8 @@ final class LocalDisplayAdapter extends DisplayAdapter { } } - private final class HotplugDisplayEventReceiver extends DisplayEventReceiver { - public HotplugDisplayEventReceiver(Looper looper) { + private final class PhysicalDisplayEventReceiver extends DisplayEventReceiver { + PhysicalDisplayEventReceiver(Looper looper) { super(looper, VSYNC_SOURCE_APP); } @@ -742,5 +743,15 @@ final class LocalDisplayAdapter extends DisplayAdapter { } } } + + @Override + public void onConfigChanged(long timestampNanos, long physicalDisplayId, int configId) { + if (DEBUG) { + Slog.d(TAG, "onConfigChanged(" + + "timestampNanos=" + timestampNanos + + ", builtInDisplayId=" + physicalDisplayId + + ", configId=" + configId + ")"); + } + } } } -- cgit v1.2.3-59-g8ed1b