hwc_uevents.cpp revision 56f610dd235b577725198e9341caae92379fdf23
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * Copyright (C) 2012, The Linux Foundation. All rights reserved. 4 * 5 * Not a Contribution, Apache license notifications and license are 6 * retained for attribution purposes only. 7 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20#define DEBUG 0 21#ifndef HWC_OBSERVER_H 22#define HWC_OBSERVER_H 23#include <hardware_legacy/uevent.h> 24#include <utils/Log.h> 25#include <sys/resource.h> 26#include <string.h> 27#include <stdlib.h> 28#include "hwc_utils.h" 29#include "external.h" 30 31namespace qhwc { 32 33const char* MSMFB_DEVICE_FB0 = "change@/devices/virtual/graphics/fb0"; 34const char* MSMFB_DEVICE_FB1 = "change@/devices/virtual/graphics/fb1"; 35const char* MSMFB_HDMI_NODE = "fb1"; 36 37static void handle_uevent(hwc_context_t* ctx, const char* udata, int len) 38{ 39 int vsync = 0; 40 char* hdmi; 41 int64_t timestamp = 0; 42 const char *str = udata; 43 int hdmiconnected = ctx->mExtDisplay->getExternalDisplay(); 44 45 if(!strcasestr(str, "@/devices/virtual/graphics/fb")) { 46 ALOGD_IF(DEBUG, "%s: Not Ext Disp Event ", __FUNCTION__); 47 return; 48 } 49 50 if(hdmiconnected) 51 vsync = !strncmp(str, MSMFB_DEVICE_FB1, strlen(MSMFB_DEVICE_FB1)); 52 else 53 vsync = !strncmp(str, MSMFB_DEVICE_FB0, strlen(MSMFB_DEVICE_FB0)); 54 55 hdmi = strcasestr(str, MSMFB_HDMI_NODE); 56 if(vsync) { 57 str += strlen(str) + 1; 58 while(*str) { 59 if (!strncmp(str, "VSYNC=", strlen("VSYNC="))) { 60 timestamp = strtoull(str + strlen("VSYNC="), NULL, 0); 61 //XXX: Handle vsync from multiple displays 62 ctx->proc->vsync(ctx->proc, (int)ctx->dpys[0], timestamp); 63 } 64 str += strlen(str) + 1; 65 if(str - udata >= len) 66 break; 67 } 68 return; 69 } 70 71 if(hdmi) { 72 // parse HDMI events 73 // The event will be of the form: 74 // change@/devices/virtual/graphics/fb1 ACTION=change 75 // DEVPATH=/devices/virtual/graphics/fb1 76 // SUBSYSTEM=graphics HDCP_STATE=FAIL MAJOR=29 77 // for now just parsing onlin/offline info is enough 78 str = udata; 79 int connected = 0; 80 if(!(strncmp(str,"online@",strlen("online@")))) { 81 connected = 1; 82 ctx->mExtDisplay->setExternalDisplay(connected); 83 } else if(!(strncmp(str,"offline@",strlen("offline@")))) { 84 connected = 0; 85 ctx->mExtDisplay->setExternalDisplay(connected); 86 } 87 } 88 89} 90 91static void *uevent_loop(void *param) 92{ 93 int len = 0; 94 static char udata[4096]; 95 memset(udata, 0, sizeof(udata)); 96 hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param); 97 98 setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); 99 uevent_init(); 100 101 while(1) { 102 len = uevent_next_event(udata, sizeof(udata) - 2); 103 handle_uevent(ctx, udata, len); 104 } 105 106 return NULL; 107} 108 109void init_uevent_thread(hwc_context_t* ctx) 110{ 111 pthread_t uevent_thread; 112 pthread_create(&uevent_thread, NULL, uevent_loop, (void*) ctx); 113} 114 115}; //namespace 116#endif //HWC_OBSERVER_H 117