100fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown/* 200fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown * Copyright (C) 2010 The Android Open Source Project 300fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown * 400fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 500fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown * you may not use this file except in compliance with the License. 600fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown * You may obtain a copy of the License at 700fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown * 800fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 900fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown * 1000fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown * Unless required by applicable law or agreed to in writing, software 1100fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 1200fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1300fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown * See the License for the specific language governing permissions and 1400fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown * limitations under the License. 1500fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown */ 1600fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 1700fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown#define LOG_TAG "PowerManagerService-JNI" 1800fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 1900fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown//#define LOG_NDEBUG 0 2000fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 2100fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown#include "JNIHelp.h" 2200fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown#include "jni.h" 23b08a1af667b16cb1faaea2aec1cf2a0e4659cb3fJoe Onorato 249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown#include <ScopedUtfChars.h> 259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2600fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown#include <limits.h> 27b08a1af667b16cb1faaea2aec1cf2a0e4659cb3fJoe Onorato 2800fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown#include <android_runtime/AndroidRuntime.h> 2987eac99a21772ae56018cb81db6966557b459554Ruben Brunk#include <android_runtime/Log.h> 307304c343821309dd15f769b18f1de2fa43751573Jeff Brown#include <utils/Timers.h> 317304c343821309dd15f769b18f1de2fa43751573Jeff Brown#include <utils/misc.h> 327304c343821309dd15f769b18f1de2fa43751573Jeff Brown#include <utils/String8.h> 339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown#include <utils/Log.h> 347304c343821309dd15f769b18f1de2fa43751573Jeff Brown#include <hardware/power.h> 357304c343821309dd15f769b18f1de2fa43751573Jeff Brown#include <hardware_legacy/power.h> 367304c343821309dd15f769b18f1de2fa43751573Jeff Brown#include <suspend/autosuspend.h> 37b08a1af667b16cb1faaea2aec1cf2a0e4659cb3fJoe Onorato 384f8ecd80296508a1dc69d3f3a23fd91e962c2784Jeff Brown#include "com_android_server_power_PowerManagerService.h" 3900fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 4000fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brownnamespace android { 4100fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 4200fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown// ---------------------------------------------------------------------------- 4300fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 4400fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brownstatic struct { 459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown jmethodID userActivityFromNative; 4600fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown} gPowerManagerServiceClassInfo; 4700fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 4800fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown// ---------------------------------------------------------------------------- 4900fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 5000fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brownstatic jobject gPowerManagerServiceObj; 517304c343821309dd15f769b18f1de2fa43751573Jeff Brownstatic struct power_module* gPowerModule; 5200fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 53b696de5c10ebcc7bf42d8487fc0e56e0e937754dJeff Brownstatic nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1]; 5490291577a08f582e0978651f55dd950f40eb111dJeff Brown 5590291577a08f582e0978651f55dd950f40eb111dJeff Brown// Throttling interval for user activity calls. 5690291577a08f582e0978651f55dd950f40eb111dJeff Brownstatic const nsecs_t MIN_TIME_BETWEEN_USERACTIVITIES = 500 * 1000000L; // 500ms 5790291577a08f582e0978651f55dd950f40eb111dJeff Brown 5800fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown// ---------------------------------------------------------------------------- 5900fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 6000fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brownstatic bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { 6100fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown if (env->ExceptionCheck()) { 623762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("An exception was thrown by callback '%s'.", methodName); 6300fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown LOGE_EX(env); 6400fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown env->ExceptionClear(); 6500fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown return true; 6600fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown } 6700fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown return false; 6800fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown} 6900fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 7000fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brownvoid android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) { 71d232afa003689d87b637cb4525aae9a6af426700Jeff Brown // Tell the power HAL when user activity occurs. 72d232afa003689d87b637cb4525aae9a6af426700Jeff Brown if (gPowerModule && gPowerModule->powerHint) { 73d232afa003689d87b637cb4525aae9a6af426700Jeff Brown gPowerModule->powerHint(gPowerModule, POWER_HINT_INTERACTION, NULL); 7430e5eb4826a2b6880fb8ef3844206cc5ffd13ed9Jeff Brown } 7530e5eb4826a2b6880fb8ef3844206cc5ffd13ed9Jeff Brown 7600fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown if (gPowerManagerServiceObj) { 7790291577a08f582e0978651f55dd950f40eb111dJeff Brown // Throttle calls into user activity by event type. 7890291577a08f582e0978651f55dd950f40eb111dJeff Brown // We're a little conservative about argument checking here in case the caller 7990291577a08f582e0978651f55dd950f40eb111dJeff Brown // passes in bad data which could corrupt system state. 80b696de5c10ebcc7bf42d8487fc0e56e0e937754dJeff Brown if (eventType >= 0 && eventType <= USER_ACTIVITY_EVENT_LAST) { 8190291577a08f582e0978651f55dd950f40eb111dJeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 8290291577a08f582e0978651f55dd950f40eb111dJeff Brown if (eventTime > now) { 8390291577a08f582e0978651f55dd950f40eb111dJeff Brown eventTime = now; 8490291577a08f582e0978651f55dd950f40eb111dJeff Brown } 8590291577a08f582e0978651f55dd950f40eb111dJeff Brown 8690291577a08f582e0978651f55dd950f40eb111dJeff Brown if (gLastEventTime[eventType] + MIN_TIME_BETWEEN_USERACTIVITIES > eventTime) { 8790291577a08f582e0978651f55dd950f40eb111dJeff Brown return; 8890291577a08f582e0978651f55dd950f40eb111dJeff Brown } 8990291577a08f582e0978651f55dd950f40eb111dJeff Brown gLastEventTime[eventType] = eventTime; 9090291577a08f582e0978651f55dd950f40eb111dJeff Brown } 9190291577a08f582e0978651f55dd950f40eb111dJeff Brown 9200fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown JNIEnv* env = AndroidRuntime::getJNIEnv(); 9300fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown env->CallVoidMethod(gPowerManagerServiceObj, 959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown gPowerManagerServiceClassInfo.userActivityFromNative, 969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown nanoseconds_to_milliseconds(eventTime), eventType, 0); 979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown checkAndClearExceptionFromCallback(env, "userActivityFromNative"); 9800fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown } 9900fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown} 10000fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 10100fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown// ---------------------------------------------------------------------------- 10200fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 1037304c343821309dd15f769b18f1de2fa43751573Jeff Brownstatic void nativeInit(JNIEnv* env, jobject obj) { 10400fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown gPowerManagerServiceObj = env->NewGlobalRef(obj); 1057304c343821309dd15f769b18f1de2fa43751573Jeff Brown 1067304c343821309dd15f769b18f1de2fa43751573Jeff Brown status_t err = hw_get_module(POWER_HARDWARE_MODULE_ID, 1077304c343821309dd15f769b18f1de2fa43751573Jeff Brown (hw_module_t const**)&gPowerModule); 108d232afa003689d87b637cb4525aae9a6af426700Jeff Brown if (!err) { 109d232afa003689d87b637cb4525aae9a6af426700Jeff Brown gPowerModule->init(gPowerModule); 110d232afa003689d87b637cb4525aae9a6af426700Jeff Brown } else { 111d232afa003689d87b637cb4525aae9a6af426700Jeff Brown ALOGE("Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err)); 1127304c343821309dd15f769b18f1de2fa43751573Jeff Brown } 11300fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown} 11400fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 1159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownstatic void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) { 1169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown ScopedUtfChars name(env, nameStr); 1179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str()); 118b08a1af667b16cb1faaea2aec1cf2a0e4659cb3fJoe Onorato} 119b08a1af667b16cb1faaea2aec1cf2a0e4659cb3fJoe Onorato 1209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownstatic void nativeReleaseSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) { 1219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown ScopedUtfChars name(env, nameStr); 1229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown release_wake_lock(name.c_str()); 1237304c343821309dd15f769b18f1de2fa43751573Jeff Brown} 1247304c343821309dd15f769b18f1de2fa43751573Jeff Brown 1259e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brownstatic void nativeSetInteractive(JNIEnv *env, jclass clazz, jboolean enable) { 1260a19d001c4ffbeec7e4e23b7640fff6bd7f11bc7Jeff Brown if (gPowerModule) { 1270a19d001c4ffbeec7e4e23b7640fff6bd7f11bc7Jeff Brown if (enable) { 1280a19d001c4ffbeec7e4e23b7640fff6bd7f11bc7Jeff Brown ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on"); 1290a19d001c4ffbeec7e4e23b7640fff6bd7f11bc7Jeff Brown gPowerModule->setInteractive(gPowerModule, true); 1300a19d001c4ffbeec7e4e23b7640fff6bd7f11bc7Jeff Brown } else { 1310a19d001c4ffbeec7e4e23b7640fff6bd7f11bc7Jeff Brown ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(false) while turning screen off"); 1320a19d001c4ffbeec7e4e23b7640fff6bd7f11bc7Jeff Brown gPowerModule->setInteractive(gPowerModule, false); 1330a19d001c4ffbeec7e4e23b7640fff6bd7f11bc7Jeff Brown } 1349e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown } 1359e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown} 1367304c343821309dd15f769b18f1de2fa43751573Jeff Brown 1379e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brownstatic void nativeSetAutoSuspend(JNIEnv *env, jclass clazz, jboolean enable) { 1389e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown if (enable) { 1399e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_enable() while turning screen off"); 1409e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown autosuspend_enable(); 1419e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown } else { 1429e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_disable() while turning screen on"); 1439e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown autosuspend_disable(); 1449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1457304c343821309dd15f769b18f1de2fa43751573Jeff Brown} 1467304c343821309dd15f769b18f1de2fa43751573Jeff Brown 147f20a5eb279035d462e1f5d9895f4eb66cc152215Ruchi Kandoistatic void nativeSendPowerHint(JNIEnv *env, jclass clazz, jint hintId, jint data) { 148654d75fec9e04306a3e08e4ef0c3aa0ec9ef96eaRuchi Kandoi int data_param = data; 149654d75fec9e04306a3e08e4ef0c3aa0ec9ef96eaRuchi Kandoi 150f20a5eb279035d462e1f5d9895f4eb66cc152215Ruchi Kandoi if (gPowerModule && gPowerModule->powerHint) { 151654d75fec9e04306a3e08e4ef0c3aa0ec9ef96eaRuchi Kandoi if(data) 152654d75fec9e04306a3e08e4ef0c3aa0ec9ef96eaRuchi Kandoi gPowerModule->powerHint(gPowerModule, (power_hint_t)hintId, &data_param); 153654d75fec9e04306a3e08e4ef0c3aa0ec9ef96eaRuchi Kandoi else { 154654d75fec9e04306a3e08e4ef0c3aa0ec9ef96eaRuchi Kandoi gPowerModule->powerHint(gPowerModule, (power_hint_t)hintId, NULL); 155654d75fec9e04306a3e08e4ef0c3aa0ec9ef96eaRuchi Kandoi } 156f20a5eb279035d462e1f5d9895f4eb66cc152215Ruchi Kandoi } 157f20a5eb279035d462e1f5d9895f4eb66cc152215Ruchi Kandoi} 158f20a5eb279035d462e1f5d9895f4eb66cc152215Ruchi Kandoi 15900fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown// ---------------------------------------------------------------------------- 16000fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 16100fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brownstatic JNINativeMethod gPowerManagerServiceMethods[] = { 16200fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown /* name, signature, funcPtr */ 16300fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown { "nativeInit", "()V", 1647304c343821309dd15f769b18f1de2fa43751573Jeff Brown (void*) nativeInit }, 1659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown { "nativeAcquireSuspendBlocker", "(Ljava/lang/String;)V", 1669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown (void*) nativeAcquireSuspendBlocker }, 1679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown { "nativeReleaseSuspendBlocker", "(Ljava/lang/String;)V", 1689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown (void*) nativeReleaseSuspendBlocker }, 1699e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown { "nativeSetInteractive", "(Z)V", 1709e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown (void*) nativeSetInteractive }, 1719e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown { "nativeSetAutoSuspend", "(Z)V", 1729e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown (void*) nativeSetAutoSuspend }, 173f20a5eb279035d462e1f5d9895f4eb66cc152215Ruchi Kandoi { "nativeSendPowerHint", "(II)V", 174f20a5eb279035d462e1f5d9895f4eb66cc152215Ruchi Kandoi (void*) nativeSendPowerHint }, 17500fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown}; 17600fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 17700fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown#define FIND_CLASS(var, className) \ 17800fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown var = env->FindClass(className); \ 17917cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro LOG_FATAL_IF(! var, "Unable to find class " className); 18000fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 18100fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 18200fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 18300fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown LOG_FATAL_IF(! var, "Unable to find method " methodName); 18400fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 18500fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 18600fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 18700fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown LOG_FATAL_IF(! var, "Unable to find field " fieldName); 18800fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 18900fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brownint register_android_server_PowerManagerService(JNIEnv* env) { 1904f8ecd80296508a1dc69d3f3a23fd91e962c2784Jeff Brown int res = jniRegisterNativeMethods(env, "com/android/server/power/PowerManagerService", 19100fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown gPowerManagerServiceMethods, NELEM(gPowerManagerServiceMethods)); 19200fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown LOG_FATAL_IF(res < 0, "Unable to register native methods."); 19300fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 19400fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown // Callbacks 19500fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 19617cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro jclass clazz; 1974f8ecd80296508a1dc69d3f3a23fd91e962c2784Jeff Brown FIND_CLASS(clazz, "com/android/server/power/PowerManagerService"); 19800fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 1999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivityFromNative, clazz, 2009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown "userActivityFromNative", "(JII)V"); 20100fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 20290291577a08f582e0978651f55dd950f40eb111dJeff Brown // Initialize 203b696de5c10ebcc7bf42d8487fc0e56e0e937754dJeff Brown for (int i = 0; i <= USER_ACTIVITY_EVENT_LAST; i++) { 20490291577a08f582e0978651f55dd950f40eb111dJeff Brown gLastEventTime[i] = LLONG_MIN; 20590291577a08f582e0978651f55dd950f40eb111dJeff Brown } 20630e5eb4826a2b6880fb8ef3844206cc5ffd13ed9Jeff Brown gPowerManagerServiceObj = NULL; 20730e5eb4826a2b6880fb8ef3844206cc5ffd13ed9Jeff Brown gPowerModule = NULL; 20800fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown return 0; 20900fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown} 21000fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown 21100fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown} /* namespace android */ 212