• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 UEVENT_DEBUG 0
21 #include <hardware_legacy/uevent.h>
22 #include <utils/Log.h>
23 #include <sys/resource.h>
24 #include <sys/prctl.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include "hwc_utils.h"
28 #include "external.h"
29 
30 namespace qhwc {
31 
32 #define HWC_UEVENT_THREAD_NAME "hwcUeventThread"
33 
34 const char* MSMFB_HDMI_NODE = "fb1";
35 
handle_uevent(hwc_context_t * ctx,const char * udata,int len)36 static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
37 {
38     int vsync = 0;
39     char* hdmi;
40     int64_t timestamp = 0;
41     const char *str = udata;
42 
43     if(!strcasestr(str, "@/devices/virtual/graphics/fb")) {
44         ALOGD_IF(UEVENT_DEBUG, "%s: Not Ext Disp Event ", __FUNCTION__);
45         return;
46     }
47     hdmi = strcasestr(str, MSMFB_HDMI_NODE);
48     // parse HDMI events
49     // The event will be of the form:
50     // change@/devices/virtual/graphics/fb1 ACTION=change
51     // DEVPATH=/devices/virtual/graphics/fb1
52     // SUBSYSTEM=graphics HDCP_STATE=FAIL MAJOR=29
53     // for now just parsing onlin/offline info is enough
54     if (hdmi) {
55         str = udata;
56         int connected = -1; //some event other than online and offline .. e.g
57         if(!(strncmp(str,"online@",strlen("online@")))) {
58             //Disabled until SF calls unblank
59             ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
60             connected = 1;
61         } else if(!(strncmp(str,"offline@",strlen("offline@")))) {
62             //Disabled until SF calls unblank
63             ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
64             connected = 0;
65         }
66         if(connected != -1) { //either we got online or offline
67             ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
68             ctx->mExtDisplay->setExternalDisplay(connected);
69             ALOGD("%s sending hotplug: connected = %d", __FUNCTION__,connected);
70             Locker::Autolock _l(ctx->mExtSetLock); //hwc comp could be on
71             //TODO ideally should be done on "connected" not "online"
72             ctx->proc->hotplug(ctx->proc, HWC_DISPLAY_EXTERNAL, connected);
73         }
74     }
75 }
76 
uevent_loop(void * param)77 static void *uevent_loop(void *param)
78 {
79     int len = 0;
80     static char udata[PAGE_SIZE];
81     hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param);
82     char thread_name[64] = HWC_UEVENT_THREAD_NAME;
83     prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
84     setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
85     uevent_init();
86 
87     while(1) {
88         len = uevent_next_event(udata, sizeof(udata) - 2);
89         handle_uevent(ctx, udata, len);
90     }
91 
92     return NULL;
93 }
94 
init_uevent_thread(hwc_context_t * ctx)95 void init_uevent_thread(hwc_context_t* ctx)
96 {
97     pthread_t uevent_thread;
98     int ret;
99 
100     ALOGI("Initializing UEVENT Thread");
101     ret = pthread_create(&uevent_thread, NULL, uevent_loop, (void*) ctx);
102     if (ret) {
103         ALOGE("%s: failed to create %s: %s", __FUNCTION__,
104             HWC_UEVENT_THREAD_NAME, strerror(ret));
105     }
106 }
107 
108 }; //namespace
109