@@ -39,6 +39,7 @@ static struct {
3939 jclass clazz;
4040
4141 jmethodID dispatchVsync;
42+ jmethodID dispatchHotplug;
4243} gDisplayEventReceiverClassInfo ;
4344
4445
@@ -61,7 +62,9 @@ class NativeDisplayEventReceiver : public LooperCallback {
6162 bool mWaitingForVsync ;
6263
6364 virtual int handleEvent (int receiveFd, int events, void * data);
64- bool readLastVsyncMessage (nsecs_t * outTimestamp, uint32_t * outCount);
65+ bool readLastVsyncMessage (nsecs_t * outTimestamp, int32_t * id, uint32_t * outCount);
66+ void dispatchVsync (nsecs_t timestamp, int32_t id, uint32_t count);
67+ void dispatchHotplug (nsecs_t timestamp, int32_t id, bool connected);
6568};
6669
6770
@@ -106,8 +109,9 @@ status_t NativeDisplayEventReceiver::scheduleVsync() {
106109
107110 // Drain all pending events.
108111 nsecs_t vsyncTimestamp;
112+ int32_t vsyncDisplayId;
109113 uint32_t vsyncCount;
110- readLastVsyncMessage (&vsyncTimestamp, &vsyncCount);
114+ readLastVsyncMessage (&vsyncTimestamp, &vsyncDisplayId, & vsyncCount);
111115
112116 status_t status = mReceiver .requestNextVsync ();
113117 if (status) {
@@ -135,39 +139,39 @@ int NativeDisplayEventReceiver::handleEvent(int receiveFd, int events, void* dat
135139
136140 // Drain all pending events, keep the last vsync.
137141 nsecs_t vsyncTimestamp;
142+ int32_t vsyncDisplayId;
138143 uint32_t vsyncCount;
139- if (!readLastVsyncMessage (&vsyncTimestamp, &vsyncCount)) {
144+ if (!readLastVsyncMessage (&vsyncTimestamp, &vsyncDisplayId, & vsyncCount)) {
140145 ALOGV (" receiver %p ~ Woke up but there was no vsync pulse!" , this );
141146 return 1 ; // keep the callback, did not obtain a vsync pulse
142147 }
143148
144- ALOGV (" receiver %p ~ Vsync pulse: timestamp=%lld, count=%d" ,
145- this , vsyncTimestamp, vsyncCount);
149+ ALOGV (" receiver %p ~ Vsync pulse: timestamp=%lld, id=%d, count=%d" ,
150+ this , vsyncTimestamp, vsyncDisplayId, vsyncCount);
146151 mWaitingForVsync = false ;
147152
148- JNIEnv* env = AndroidRuntime::getJNIEnv ();
149-
150- ALOGV (" receiver %p ~ Invoking vsync handler." , this );
151- env->CallVoidMethod (mReceiverObjGlobal ,
152- gDisplayEventReceiverClassInfo .dispatchVsync , vsyncTimestamp, vsyncCount);
153- ALOGV (" receiver %p ~ Returned from vsync handler." , this );
154-
155- mMessageQueue ->raiseAndClearException (env, " dispatchVsync" );
153+ dispatchVsync (vsyncTimestamp, vsyncDisplayId, vsyncCount);
156154 return 1 ; // keep the callback
157155}
158156
159157bool NativeDisplayEventReceiver::readLastVsyncMessage (
160- nsecs_t * outTimestamp, uint32_t * outCount) {
158+ nsecs_t * outTimestamp, int32_t * outId, uint32_t * outCount) {
161159 DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
162160 ssize_t n;
163161 while ((n = mReceiver .getEvents (buf, EVENT_BUFFER_SIZE)) > 0 ) {
164162 ALOGV (" receiver %p ~ Read %d events." , this , int (n));
165163 while (n-- > 0 ) {
166- if (buf[n].header .type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
167- *outTimestamp = buf[n].header .timestamp ;
168- *outCount = buf[n].vsync .count ;
164+ const DisplayEventReceiver::Event& ev = buf[n];
165+ if (ev.header .type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
166+ *outTimestamp = ev.header .timestamp ;
167+ *outId = ev.header .id ;
168+ *outCount = ev.vsync .count ;
169169 return true ; // stop at last vsync in the buffer
170170 }
171+
172+ if (ev.header .type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG) {
173+ dispatchHotplug (ev.header .timestamp , ev.header .id , ev.hotplug .connected );
174+ }
171175 }
172176 }
173177 if (n < 0 ) {
@@ -176,6 +180,28 @@ bool NativeDisplayEventReceiver::readLastVsyncMessage(
176180 return false ;
177181}
178182
183+ void NativeDisplayEventReceiver::dispatchVsync (nsecs_t timestamp, int32_t id, uint32_t count) {
184+ JNIEnv* env = AndroidRuntime::getJNIEnv ();
185+
186+ ALOGV (" receiver %p ~ Invoking vsync handler." , this );
187+ env->CallVoidMethod (mReceiverObjGlobal ,
188+ gDisplayEventReceiverClassInfo .dispatchVsync , timestamp, id, count);
189+ ALOGV (" receiver %p ~ Returned from vsync handler." , this );
190+
191+ mMessageQueue ->raiseAndClearException (env, " dispatchVsync" );
192+ }
193+
194+ void NativeDisplayEventReceiver::dispatchHotplug (nsecs_t timestamp, int32_t id, bool connected) {
195+ JNIEnv* env = AndroidRuntime::getJNIEnv ();
196+
197+ ALOGV (" receiver %p ~ Invoking hotplug handler." , this );
198+ env->CallVoidMethod (mReceiverObjGlobal ,
199+ gDisplayEventReceiverClassInfo .dispatchHotplug , timestamp, id, connected);
200+ ALOGV (" receiver %p ~ Returned from hotplug handler." , this );
201+
202+ mMessageQueue ->raiseAndClearException (env, " dispatchHotplug" );
203+ }
204+
179205
180206static jint nativeInit (JNIEnv* env, jclass clazz, jobject receiverObj,
181207 jobject messageQueueObj) {
@@ -248,7 +274,10 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) {
248274
249275 GET_METHOD_ID (gDisplayEventReceiverClassInfo .dispatchVsync ,
250276 gDisplayEventReceiverClassInfo .clazz ,
251- " dispatchVsync" , " (JI)V" );
277+ " dispatchVsync" , " (JII)V" );
278+ GET_METHOD_ID (gDisplayEventReceiverClassInfo .dispatchHotplug ,
279+ gDisplayEventReceiverClassInfo .clazz ,
280+ " dispatchHotplug" , " (JIZ)V" );
252281 return 0 ;
253282}
254283
0 commit comments