blob: a1df74bfd949547487f7b1d57cf818567966f24d [file] [log] [blame]
Naseer Ahmed72cf9762012-07-21 12:17:13 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 * Copyright (C) 2012, Code Aurora Forum. 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 "hwc_external.h"
30
31namespace qhwc {
32
33const char* MSMFB_DEVICE_CHANGE = "change@/devices/virtual/graphics/fb0";
34const char* MSMFB_HDMI_NODE = "fb1";
35
36static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
37{
38 int vsync;
39 char* hdmi;
40 int64_t timestamp = 0;
41 const char *str = udata;
42 hwc_procs* proc = reinterpret_cast<hwc_procs*>(ctx->device.reserved_proc[0]);
43
44 vsync = !strncmp(str, MSMFB_DEVICE_CHANGE, strlen(MSMFB_DEVICE_CHANGE));
45 hdmi = strcasestr(str, MSMFB_HDMI_NODE);
46 if(!vsync && !hdmi)
47 return;
48 if(vsync) {
49 str += strlen(str) + 1;
50 while(*str) {
51 if (!strncmp(str, "VSYNC=", strlen("VSYNC="))) {
52 timestamp = strtoull(str + strlen("VSYNC="), NULL, 0);
53 proc->vsync(proc, 0, timestamp);
54 }
55 str += strlen(str) + 1;
56 if(str - udata >= len)
57 break;
58 }
59 }
60
61 if(hdmi) {
62 // parse HDMI events
63 // The event will be of the form:
64 // change@/devices/virtual/graphics/fb1 ACTION=change
65 // DEVPATH=/devices/virtual/graphics/fb1
66 // SUBSYSTEM=graphics HDCP_STATE=FAIL MAJOR=29
67 // for now just parsing onlin/offline info is enough
68 str = udata;
69 int connected = 0;
70 if(!(strncmp(str,"online@",strlen("online@")))) {
71 connected = 1;
72 } else if(!(strncmp(str,"offline@",strlen("offline@")))) {
73 connected = 0;
74 }
75 ctx->mExtDisplay->setExternalDisplayStatus(connected);
76 }
77
78}
79
80static void *uevent_loop(void *param)
81{
82 int len = 0;
83 static char udata[4096];
84 memset(udata, 0, sizeof(udata));
85 hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param);
86
87 setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
88 uevent_init();
89
90 while(1) {
91 len = uevent_next_event(udata, sizeof(udata) - 2);
92 handle_uevent(ctx, udata, len);
93 }
94
95 return NULL;
96}
97
98void init_uevent_thread(hwc_context_t* ctx)
99{
100 pthread_t uevent_thread;
101 pthread_create(&uevent_thread, NULL, uevent_loop, (void*) ctx);
102}
103
104}; //namespace
105#endif //HWC_OBSERVER_H