power.c revision 59fbd175b2373f8cafeafac594005fed412385aa
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16#include <errno.h> 17#include <string.h> 18#include <sys/types.h> 19#include <sys/stat.h> 20#include <sys/socket.h> 21#include <sys/un.h> 22#include <fcntl.h> 23#include <dlfcn.h> 24 25#define LOG_TAG "PowerHAL" 26#include <utils/Log.h> 27 28#include <hardware/hardware.h> 29#include <hardware/power.h> 30 31#define STATE_ON "state=1" 32#define STATE_OFF "state=0" 33 34#define BOOST_SOCKET "/dev/socket/pb" 35 36static int client_sockfd; 37static struct sockaddr_un client_addr; 38static int last_state = -1; 39 40static void socket_init() 41{ 42 if (!client_sockfd) { 43 client_sockfd = socket(PF_UNIX, SOCK_DGRAM, 0); 44 if (client_sockfd < 0) { 45 ALOGE("%s: failed to open: %s", __func__, strerror(errno)); 46 return; 47 } 48 memset(&client_addr, 0, sizeof(struct sockaddr_un)); 49 client_addr.sun_family = AF_UNIX; 50 snprintf(client_addr.sun_path, UNIX_PATH_MAX, BOOST_SOCKET); 51 } 52} 53 54static void power_init(struct power_module *module) 55{ 56 ALOGI("%s", __func__); 57 socket_init(); 58} 59 60static void sync_thread(int off) 61{ 62 int rc; 63 64 if (client_sockfd < 0) { 65 ALOGE("%s: boost socket not created", __func__); 66 return; 67 } 68 69 if (!off) { 70 rc = sendto(client_sockfd, "2", 1, 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un)); 71 } else { 72 rc = sendto(client_sockfd, "3", 1, 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un)); 73 } 74 75 if (rc < 0) { 76 ALOGE("%s: failed to send: %s", __func__, strerror(errno)); 77 } 78} 79 80static void process_video_encode_hint(void *metadata) 81{ 82 83 socket_init(); 84 85 if (client_sockfd < 0) { 86 ALOGE("%s: boost socket not created", __func__); 87 return; 88 } 89 90 if (metadata) { 91 if (!strncmp(metadata, STATE_ON, sizeof(STATE_ON))) { 92 /* Video encode started */ 93 sync_thread(1); 94 } else if (!strncmp(metadata, STATE_OFF, sizeof(STATE_OFF))) { 95 /* Video encode stopped */ 96 sync_thread(0); 97 } else 98 return; 99 } else { 100 return; 101 } 102 103} 104 105 106static void touch_boost() 107{ 108 int rc; 109 110 if (client_sockfd < 0) { 111 ALOGE("%s: boost socket not created", __func__); 112 return; 113 } 114 115 rc = sendto(client_sockfd, "1", 1, 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un)); 116 if (rc < 0) { 117 ALOGE("%s: failed to send: %s", __func__, strerror(errno)); 118 } 119} 120 121static void power_set_interactive(struct power_module *module, int on) 122{ 123 if (last_state == -1) { 124 last_state = on; 125 } else { 126 if (last_state == on) 127 return; 128 else 129 last_state = on; 130 } 131 132 ALOGV("%s %s", __func__, (on ? "ON" : "OFF")); 133 if (on) { 134 sync_thread(0); 135 touch_boost(); 136 } else { 137 sync_thread(1); 138 } 139} 140 141static void power_hint(struct power_module *module, power_hint_t hint, 142 void *data) { 143 switch (hint) { 144 case POWER_HINT_INTERACTION: 145 ALOGV("POWER_HINT_INTERACTION"); 146 touch_boost(); 147 break; 148#if 0 149 case POWER_HINT_VSYNC: 150 ALOGV("POWER_HINT_VSYNC %s", (data ? "ON" : "OFF")); 151 break; 152#endif 153 case POWER_HINT_VIDEO_ENCODE: 154 process_video_encode_hint(data); 155 break; 156 default: 157 break; 158 } 159} 160 161static struct hw_module_methods_t power_module_methods = { 162 .open = NULL, 163}; 164 165struct power_module HAL_MODULE_INFO_SYM = { 166 .common = { 167 .tag = HARDWARE_MODULE_TAG, 168 .module_api_version = POWER_MODULE_API_VERSION_0_2, 169 .hal_api_version = HARDWARE_HAL_API_VERSION, 170 .id = POWER_HARDWARE_MODULE_ID, 171 .name = "Qualcomm Power HAL", 172 .author = "The Android Open Source Project", 173 .methods = &power_module_methods, 174 }, 175 176 .init = power_init, 177 .setInteractive = power_set_interactive, 178 .powerHint = power_hint, 179}; 180