android_view_DisplayEventReceiver.cpp revision 27285821b74ca9bc381d33f40028f06ff0f85e0c
10a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown/* 20a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown * Copyright (C) 2011 The Android Open Source Project 30a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown * 40a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 50a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown * you may not use this file except in compliance with the License. 60a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown * You may obtain a copy of the License at 70a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown * 80a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 90a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown * 100a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown * Unless required by applicable law or agreed to in writing, software 110a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 120a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown * See the License for the specific language governing permissions and 140a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown * limitations under the License. 150a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown */ 160a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 170a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown#define LOG_TAG "DisplayEventReceiver" 180a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 190a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown//#define LOG_NDEBUG 0 200a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 210a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 220a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown#include "JNIHelp.h" 230a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 240a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown#include <android_runtime/AndroidRuntime.h> 250a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown#include <utils/Log.h> 260a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown#include <utils/Looper.h> 270a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown#include <utils/threads.h> 280a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown#include <gui/DisplayEventReceiver.h> 290a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown#include "android_os_MessageQueue.h" 300a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 310a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brownnamespace android { 320a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 330a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown// Number of events to read at a time from the DisplayEventReceiver pipe. 340a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown// The value should be large enough that we can quickly drain the pipe 350a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown// using just a few large reads. 360a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brownstatic const size_t EVENT_BUFFER_SIZE = 100; 370a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 380a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brownstatic struct { 390a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown jclass clazz; 400a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 410a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown jmethodID dispatchVsync; 42e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown jmethodID dispatchHotplug; 430a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown} gDisplayEventReceiverClassInfo; 440a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 450a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 4680a1de1007ddc62e1af2a4746008f499145aeaabJeff Brownclass NativeDisplayEventReceiver : public LooperCallback { 470a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brownpublic: 480a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown NativeDisplayEventReceiver(JNIEnv* env, 49603b44589682db3ff33ade172facb0c5e309f1beJeff Brown jobject receiverObj, const sp<MessageQueue>& messageQueue); 500a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 510a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown status_t initialize(); 5280a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown void dispose(); 530a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown status_t scheduleVsync(); 540a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 550a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brownprotected: 560a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown virtual ~NativeDisplayEventReceiver(); 570a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 580a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brownprivate: 590a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown jobject mReceiverObjGlobal; 60603b44589682db3ff33ade172facb0c5e309f1beJeff Brown sp<MessageQueue> mMessageQueue; 610a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown DisplayEventReceiver mReceiver; 620a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown bool mWaitingForVsync; 63bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown 6480a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown virtual int handleEvent(int receiveFd, int events, void* data); 6516823bd611689e9b5c0e1b675fee43579f85612aJesse Hall bool processPendingEvents(nsecs_t* outTimestamp, int32_t* id, uint32_t* outCount); 66e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count); 67e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected); 680a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown}; 690a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 700a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 710a0a1248cfc03940174cbd9af677bafd7280a3bcJeff BrownNativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, 72603b44589682db3ff33ade172facb0c5e309f1beJeff Brown jobject receiverObj, const sp<MessageQueue>& messageQueue) : 730a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown mReceiverObjGlobal(env->NewGlobalRef(receiverObj)), 74603b44589682db3ff33ade172facb0c5e309f1beJeff Brown mMessageQueue(messageQueue), mWaitingForVsync(false) { 750a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown ALOGV("receiver %p ~ Initializing input event receiver.", this); 760a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown} 770a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 780a0a1248cfc03940174cbd9af677bafd7280a3bcJeff BrownNativeDisplayEventReceiver::~NativeDisplayEventReceiver() { 790a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown JNIEnv* env = AndroidRuntime::getJNIEnv(); 800a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown env->DeleteGlobalRef(mReceiverObjGlobal); 810a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown} 820a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 830a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brownstatus_t NativeDisplayEventReceiver::initialize() { 840a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown status_t result = mReceiver.initCheck(); 850a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown if (result) { 868564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Failed to initialize display event receiver, status=%d", result); 870a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown return result; 880a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown } 890a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 9082b007d7572dceb0981b269338bd1ac6c40496c5Brian Carlstrom int rc = mMessageQueue->getLooper()->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT, 9180a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown this, NULL); 9258aedbc9bea13415e2d42cf7c9fe8a7efd243e66Jeff Brown if (rc < 0) { 9358aedbc9bea13415e2d42cf7c9fe8a7efd243e66Jeff Brown return UNKNOWN_ERROR; 9458aedbc9bea13415e2d42cf7c9fe8a7efd243e66Jeff Brown } 950a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown return OK; 960a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown} 970a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 9880a1de1007ddc62e1af2a4746008f499145aeaabJeff Brownvoid NativeDisplayEventReceiver::dispose() { 9980a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown ALOGV("receiver %p ~ Disposing display event receiver.", this); 10080a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown 10180a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown if (!mReceiver.initCheck()) { 10280a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown mMessageQueue->getLooper()->removeFd(mReceiver.getFd()); 10380a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown } 10480a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown} 10580a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown 1060a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brownstatus_t NativeDisplayEventReceiver::scheduleVsync() { 1070a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown if (!mWaitingForVsync) { 1080a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown ALOGV("receiver %p ~ Scheduling vsync.", this); 1090a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 1100a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown // Drain all pending events. 111bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown nsecs_t vsyncTimestamp; 112e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown int32_t vsyncDisplayId; 113bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown uint32_t vsyncCount; 11416823bd611689e9b5c0e1b675fee43579f85612aJesse Hall processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount); 1150a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 1166779df2c28a68616134b1988f009221652d9f2adMathias Agopian status_t status = mReceiver.requestNextVsync(); 1176779df2c28a68616134b1988f009221652d9f2adMathias Agopian if (status) { 1188564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Failed to request next vsync, status=%d", status); 1196779df2c28a68616134b1988f009221652d9f2adMathias Agopian return status; 1206779df2c28a68616134b1988f009221652d9f2adMathias Agopian } 1216779df2c28a68616134b1988f009221652d9f2adMathias Agopian 1220a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown mWaitingForVsync = true; 1230a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown } 1240a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown return OK; 1250a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown} 1260a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 12780a1de1007ddc62e1af2a4746008f499145aeaabJeff Brownint NativeDisplayEventReceiver::handleEvent(int receiveFd, int events, void* data) { 12882b007d7572dceb0981b269338bd1ac6c40496c5Brian Carlstrom if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) { 1293762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Display event receiver pipe was closed or an error occurred. " 1300a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown "events=0x%x", events); 1310a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown return 0; // remove the callback 1320a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown } 1330a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 13482b007d7572dceb0981b269338bd1ac6c40496c5Brian Carlstrom if (!(events & Looper::EVENT_INPUT)) { 1358564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Received spurious callback for unhandled poll event. " 1360a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown "events=0x%x", events); 1370a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown return 1; // keep the callback 1380a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown } 1390a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 1400a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown // Drain all pending events, keep the last vsync. 141bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown nsecs_t vsyncTimestamp; 142e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown int32_t vsyncDisplayId; 143bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown uint32_t vsyncCount; 14416823bd611689e9b5c0e1b675fee43579f85612aJesse Hall if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) { 14516823bd611689e9b5c0e1b675fee43579f85612aJesse Hall ALOGV("receiver %p ~ Vsync pulse: timestamp=%lld, id=%d, count=%d", 14616823bd611689e9b5c0e1b675fee43579f85612aJesse Hall this, vsyncTimestamp, vsyncDisplayId, vsyncCount); 14716823bd611689e9b5c0e1b675fee43579f85612aJesse Hall mWaitingForVsync = false; 14816823bd611689e9b5c0e1b675fee43579f85612aJesse Hall dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount); 1490a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown } 1500a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 15158aedbc9bea13415e2d42cf7c9fe8a7efd243e66Jeff Brown return 1; // keep the callback 1520a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown} 1530a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 15416823bd611689e9b5c0e1b675fee43579f85612aJesse Hallbool NativeDisplayEventReceiver::processPendingEvents( 155e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown nsecs_t* outTimestamp, int32_t* outId, uint32_t* outCount) { 15616823bd611689e9b5c0e1b675fee43579f85612aJesse Hall bool gotVsync = false; 157bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE]; 158bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown ssize_t n; 159bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown while ((n = mReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) { 160bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown ALOGV("receiver %p ~ Read %d events.", this, int(n)); 16116823bd611689e9b5c0e1b675fee43579f85612aJesse Hall for (ssize_t i = 0; i < n; i++) { 16216823bd611689e9b5c0e1b675fee43579f85612aJesse Hall const DisplayEventReceiver::Event& ev = buf[i]; 16316823bd611689e9b5c0e1b675fee43579f85612aJesse Hall switch (ev.header.type) { 16416823bd611689e9b5c0e1b675fee43579f85612aJesse Hall case DisplayEventReceiver::DISPLAY_EVENT_VSYNC: 16516823bd611689e9b5c0e1b675fee43579f85612aJesse Hall // Later vsync events will just overwrite the info from earlier 16616823bd611689e9b5c0e1b675fee43579f85612aJesse Hall // ones. That's fine, we only care about the most recent. 16716823bd611689e9b5c0e1b675fee43579f85612aJesse Hall gotVsync = true; 168e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown *outTimestamp = ev.header.timestamp; 169e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown *outId = ev.header.id; 170e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown *outCount = ev.vsync.count; 17116823bd611689e9b5c0e1b675fee43579f85612aJesse Hall break; 17216823bd611689e9b5c0e1b675fee43579f85612aJesse Hall case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: 173e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown dispatchHotplug(ev.header.timestamp, ev.header.id, ev.hotplug.connected); 17416823bd611689e9b5c0e1b675fee43579f85612aJesse Hall break; 17516823bd611689e9b5c0e1b675fee43579f85612aJesse Hall default: 17616823bd611689e9b5c0e1b675fee43579f85612aJesse Hall ALOGW("receiver %p ~ ignoring unknown event type %#x", this, ev.header.type); 17716823bd611689e9b5c0e1b675fee43579f85612aJesse Hall break; 178e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown } 179bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown } 180bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown } 181bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown if (n < 0) { 182bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown ALOGW("Failed to get events from display event receiver, status=%d", status_t(n)); 183bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown } 18416823bd611689e9b5c0e1b675fee43579f85612aJesse Hall return gotVsync; 185bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown} 186bec0a8682c75a40df6d0dca17e23db2103a950f3Jeff Brown 187e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brownvoid NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) { 188e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown JNIEnv* env = AndroidRuntime::getJNIEnv(); 189e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown 190e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown ALOGV("receiver %p ~ Invoking vsync handler.", this); 191e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown env->CallVoidMethod(mReceiverObjGlobal, 192e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, id, count); 193e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown ALOGV("receiver %p ~ Returned from vsync handler.", this); 194e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown 195e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown mMessageQueue->raiseAndClearException(env, "dispatchVsync"); 196e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown} 197e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown 198e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brownvoid NativeDisplayEventReceiver::dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected) { 199e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown JNIEnv* env = AndroidRuntime::getJNIEnv(); 200e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown 201e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown ALOGV("receiver %p ~ Invoking hotplug handler.", this); 202e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown env->CallVoidMethod(mReceiverObjGlobal, 203e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown gDisplayEventReceiverClassInfo.dispatchHotplug, timestamp, id, connected); 204e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown ALOGV("receiver %p ~ Returned from hotplug handler.", this); 205e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown 206e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown mMessageQueue->raiseAndClearException(env, "dispatchHotplug"); 207e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown} 208e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown 2090a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 21027285821b74ca9bc381d33f40028f06ff0f85e0cAshok Bhatstatic jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverObj, 2110a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown jobject messageQueueObj) { 212603b44589682db3ff33ade172facb0c5e309f1beJeff Brown sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); 213603b44589682db3ff33ade172facb0c5e309f1beJeff Brown if (messageQueue == NULL) { 2140a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown jniThrowRuntimeException(env, "MessageQueue is not initialized."); 2150a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown return 0; 2160a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown } 2170a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 2180a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env, 219603b44589682db3ff33ade172facb0c5e309f1beJeff Brown receiverObj, messageQueue); 2200a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown status_t status = receiver->initialize(); 2210a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown if (status) { 2220a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown String8 message; 2230a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown message.appendFormat("Failed to initialize display event receiver. status=%d", status); 2240a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown jniThrowRuntimeException(env, message.string()); 2250a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown return 0; 2260a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown } 2270a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 2280a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); // retain a reference for the object 22927285821b74ca9bc381d33f40028f06ff0f85e0cAshok Bhat return reinterpret_cast<jlong>(receiver.get()); 2300a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown} 2310a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 23227285821b74ca9bc381d33f40028f06ff0f85e0cAshok Bhatstatic void nativeDispose(JNIEnv* env, jclass clazz, jlong receiverPtr) { 2330a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown sp<NativeDisplayEventReceiver> receiver = 2340a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr); 23580a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown receiver->dispose(); 2360a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown receiver->decStrong(gDisplayEventReceiverClassInfo.clazz); // drop reference held by the object 2370a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown} 2380a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 23927285821b74ca9bc381d33f40028f06ff0f85e0cAshok Bhatstatic void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) { 2400a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown sp<NativeDisplayEventReceiver> receiver = 2410a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr); 2420a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown status_t status = receiver->scheduleVsync(); 2430a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown if (status) { 2440a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown String8 message; 2450a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown message.appendFormat("Failed to schedule next vertical sync pulse. status=%d", status); 2460a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown jniThrowRuntimeException(env, message.string()); 2470a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown } 2480a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown} 2490a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 2500a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 2510a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brownstatic JNINativeMethod gMethods[] = { 2520a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown /* name, signature, funcPtr */ 2530a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown { "nativeInit", 25427285821b74ca9bc381d33f40028f06ff0f85e0cAshok Bhat "(Landroid/view/DisplayEventReceiver;Landroid/os/MessageQueue;)J", 2550a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown (void*)nativeInit }, 2560a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown { "nativeDispose", 25727285821b74ca9bc381d33f40028f06ff0f85e0cAshok Bhat "(J)V", 2580a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown (void*)nativeDispose }, 25927285821b74ca9bc381d33f40028f06ff0f85e0cAshok Bhat { "nativeScheduleVsync", "(J)V", 2600a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown (void*)nativeScheduleVsync } 2610a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown}; 2620a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 2630a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown#define FIND_CLASS(var, className) \ 2640a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown var = env->FindClass(className); \ 2650a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown LOG_FATAL_IF(! var, "Unable to find class " className); \ 2660a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown var = jclass(env->NewGlobalRef(var)); 2670a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 2680a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 2690a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 2700a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown LOG_FATAL_IF(! var, "Unable to find method " methodName); 2710a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 2720a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brownint register_android_view_DisplayEventReceiver(JNIEnv* env) { 2730a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown int res = jniRegisterNativeMethods(env, "android/view/DisplayEventReceiver", 2740a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown gMethods, NELEM(gMethods)); 2750a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown LOG_FATAL_IF(res < 0, "Unable to register native methods."); 2760a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 2770a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown FIND_CLASS(gDisplayEventReceiverClassInfo.clazz, "android/view/DisplayEventReceiver"); 2780a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 2790a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown GET_METHOD_ID(gDisplayEventReceiverClassInfo.dispatchVsync, 2800a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown gDisplayEventReceiverClassInfo.clazz, 281e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown "dispatchVsync", "(JII)V"); 282e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown GET_METHOD_ID(gDisplayEventReceiverClassInfo.dispatchHotplug, 283e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown gDisplayEventReceiverClassInfo.clazz, 284e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown "dispatchHotplug", "(JIZ)V"); 2850a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown return 0; 2860a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown} 2870a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown 2880a0a1248cfc03940174cbd9af677bafd7280a3bcJeff Brown} // namespace android 289