blob: 3df0e253a4f3e4b836fdcff51012bac15b28a828 [file] [log] [blame]
Naseer Ahmed72cf9762012-07-21 12:17:13 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
Saurabh Shah56f610d2012-08-07 15:27:06 -07003 * Copyright (C) 2012, The Linux Foundation. All rights reserved.
Naseer Ahmed72cf9762012-07-21 12:17:13 -07004 *
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 */
Saurabh Shah649cda62012-09-16 16:05:58 -070020#define UEVENT_DEBUG 0
Naseer Ahmed72cf9762012-07-21 12:17:13 -070021#include <hardware_legacy/uevent.h>
22#include <utils/Log.h>
23#include <sys/resource.h>
24#include <string.h>
25#include <stdlib.h>
26#include "hwc_utils.h"
Saurabh Shah56f610d2012-08-07 15:27:06 -070027#include "external.h"
Naseer Ahmed72cf9762012-07-21 12:17:13 -070028
29namespace qhwc {
30
Naseer Ahmedf8ec1622012-07-31 18:56:23 -070031const char* MSMFB_DEVICE_FB0 = "change@/devices/virtual/graphics/fb0";
32const char* MSMFB_DEVICE_FB1 = "change@/devices/virtual/graphics/fb1";
Naseer Ahmed72cf9762012-07-21 12:17:13 -070033const char* MSMFB_HDMI_NODE = "fb1";
34
35static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
36{
Naseer Ahmedf8ec1622012-07-31 18:56:23 -070037 int vsync = 0;
Naseer Ahmed72cf9762012-07-21 12:17:13 -070038 char* hdmi;
39 int64_t timestamp = 0;
40 const char *str = udata;
Saurabh Shah3e858eb2012-09-17 16:53:21 -070041 int display = HWC_DISPLAY_PRIMARY;
Naseer Ahmed72cf9762012-07-21 12:17:13 -070042
Naseer Ahmedf8ec1622012-07-31 18:56:23 -070043 if(!strcasestr(str, "@/devices/virtual/graphics/fb")) {
Saurabh Shah649cda62012-09-16 16:05:58 -070044 ALOGD_IF(UEVENT_DEBUG, "%s: Not Ext Disp Event ", __FUNCTION__);
Naseer Ahmed72cf9762012-07-21 12:17:13 -070045 return;
Naseer Ahmedf8ec1622012-07-31 18:56:23 -070046 }
47
Saurabh Shah3e858eb2012-09-17 16:53:21 -070048 //Check if its primary vsync
49 vsync = !strncmp(str, MSMFB_DEVICE_FB0, strlen(MSMFB_DEVICE_FB0));
50 //If not primary vsync, see if its an external vsync
51 if(isExternalActive(ctx) && !vsync) {
Naseer Ahmedf8ec1622012-07-31 18:56:23 -070052 vsync = !strncmp(str, MSMFB_DEVICE_FB1, strlen(MSMFB_DEVICE_FB1));
Saurabh Shah3e858eb2012-09-17 16:53:21 -070053 display = HWC_DISPLAY_EXTERNAL;
54 }
Naseer Ahmedf8ec1622012-07-31 18:56:23 -070055
56 hdmi = strcasestr(str, MSMFB_HDMI_NODE);
Saurabh Shah3e858eb2012-09-17 16:53:21 -070057
Naseer Ahmed72cf9762012-07-21 12:17:13 -070058 if(vsync) {
59 str += strlen(str) + 1;
60 while(*str) {
61 if (!strncmp(str, "VSYNC=", strlen("VSYNC="))) {
62 timestamp = strtoull(str + strlen("VSYNC="), NULL, 0);
Naseer Ahmed5b6708a2012-08-02 13:46:08 -070063 //XXX: Handle vsync from multiple displays
Saurabh Shah3e858eb2012-09-17 16:53:21 -070064 ctx->proc->vsync(ctx->proc, display, timestamp);
Naseer Ahmed72cf9762012-07-21 12:17:13 -070065 }
66 str += strlen(str) + 1;
67 if(str - udata >= len)
68 break;
69 }
Naseer Ahmedf8ec1622012-07-31 18:56:23 -070070 return;
Naseer Ahmed72cf9762012-07-21 12:17:13 -070071 }
72
73 if(hdmi) {
74 // parse HDMI events
75 // The event will be of the form:
76 // change@/devices/virtual/graphics/fb1 ACTION=change
77 // DEVPATH=/devices/virtual/graphics/fb1
78 // SUBSYSTEM=graphics HDCP_STATE=FAIL MAJOR=29
79 // for now just parsing onlin/offline info is enough
80 str = udata;
81 int connected = 0;
82 if(!(strncmp(str,"online@",strlen("online@")))) {
83 connected = 1;
Naseer Ahmed31278ad2012-07-31 19:14:54 -070084 ctx->mExtDisplay->setExternalDisplay(connected);
Naseer Ahmed72cf9762012-07-21 12:17:13 -070085 } else if(!(strncmp(str,"offline@",strlen("offline@")))) {
86 connected = 0;
Naseer Ahmed31278ad2012-07-31 19:14:54 -070087 ctx->mExtDisplay->setExternalDisplay(connected);
Naseer Ahmed72cf9762012-07-21 12:17:13 -070088 }
Naseer Ahmed72cf9762012-07-21 12:17:13 -070089 }
90
91}
92
93static void *uevent_loop(void *param)
94{
95 int len = 0;
96 static char udata[4096];
97 memset(udata, 0, sizeof(udata));
98 hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param);
99
100 setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
101 uevent_init();
102
103 while(1) {
104 len = uevent_next_event(udata, sizeof(udata) - 2);
105 handle_uevent(ctx, udata, len);
106 }
107
108 return NULL;
109}
110
111void init_uevent_thread(hwc_context_t* ctx)
112{
113 pthread_t uevent_thread;
114 pthread_create(&uevent_thread, NULL, uevent_loop, (void*) ctx);
115}
116
117}; //namespace