1 /* 2 * Copyright (C) 2016 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 17 #define LOG_TAG "android.hardware.power (at) 1.0-impl" 18 19 #include <log/log.h> 20 21 #include <hardware/hardware.h> 22 #include <hardware/power.h> 23 24 #include "Power.h" 25 26 namespace android { 27 namespace hardware { 28 namespace power { 29 namespace V1_0 { 30 namespace implementation { 31 32 Power::Power(power_module_t *module) : mModule(module) { 33 if (mModule) 34 mModule->init(mModule); 35 } 36 37 Power::~Power() { 38 delete(mModule); 39 } 40 41 // Methods from ::android::hardware::power::V1_0::IPower follow. 42 Return<void> Power::setInteractive(bool interactive) { 43 if (mModule->setInteractive) 44 mModule->setInteractive(mModule, interactive ? 1 : 0); 45 return Void(); 46 } 47 48 Return<void> Power::powerHint(PowerHint hint, int32_t data) { 49 int32_t param = data; 50 if (mModule->powerHint) { 51 if (data) 52 mModule->powerHint(mModule, static_cast<power_hint_t>(hint), ¶m); 53 else 54 mModule->powerHint(mModule, static_cast<power_hint_t>(hint), NULL); 55 } 56 return Void(); 57 } 58 59 Return<void> Power::setFeature(Feature feature, bool activate) { 60 if (mModule->setFeature) 61 mModule->setFeature(mModule, static_cast<feature_t>(feature), 62 activate ? 1 : 0); 63 return Void(); 64 } 65 66 Return<void> Power::getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) { 67 hidl_vec<PowerStatePlatformSleepState> states; 68 ssize_t number_platform_modes; 69 size_t *voters = nullptr; 70 power_state_platform_sleep_state_t *legacy_states = nullptr; 71 int ret; 72 73 if (mModule->get_number_of_platform_modes == nullptr || 74 mModule->get_voter_list == nullptr || 75 mModule->get_platform_low_power_stats == nullptr) 76 { 77 _hidl_cb(states, Status::SUCCESS); 78 return Void(); 79 } 80 81 number_platform_modes = mModule->get_number_of_platform_modes(mModule); 82 if (number_platform_modes) 83 { 84 if ((ssize_t) (SIZE_MAX / sizeof(size_t)) <= number_platform_modes) // overflow 85 goto done; 86 voters = new (std::nothrow) size_t [number_platform_modes]; 87 if (voters == nullptr) 88 goto done; 89 90 ret = mModule->get_voter_list(mModule, voters); 91 if (ret != 0) 92 goto done; 93 94 if ((ssize_t) (SIZE_MAX / sizeof(power_state_platform_sleep_state_t)) 95 <= number_platform_modes) // overflow 96 goto done; 97 legacy_states = new (std::nothrow) 98 power_state_platform_sleep_state_t [number_platform_modes]; 99 if (legacy_states == nullptr) 100 goto done; 101 102 for (int i = 0; i < number_platform_modes; i++) 103 { 104 legacy_states[i].voters = nullptr; 105 legacy_states[i].voters = new power_state_voter_t [voters[i]]; 106 if (legacy_states[i].voters == nullptr) 107 goto done; 108 } 109 110 ret = mModule->get_platform_low_power_stats(mModule, legacy_states); 111 if (ret != 0) 112 goto done; 113 114 states.resize(number_platform_modes); 115 for (int i = 0; i < number_platform_modes; i++) 116 { 117 power_state_platform_sleep_state_t& legacy_state = legacy_states[i]; 118 PowerStatePlatformSleepState& state = states[i]; 119 state.name = legacy_state.name; 120 state.residencyInMsecSinceBoot = legacy_state.residency_in_msec_since_boot; 121 state.totalTransitions = legacy_state.total_transitions; 122 state.supportedOnlyInSuspend = legacy_state.supported_only_in_suspend; 123 state.voters.resize(voters[i]); 124 for(size_t j = 0; j < voters[i]; j++) 125 { 126 state.voters[j].name = legacy_state.voters[j].name; 127 state.voters[j].totalTimeInMsecVotedForSinceBoot = legacy_state.voters[j].total_time_in_msec_voted_for_since_boot; 128 state.voters[j].totalNumberOfTimesVotedSinceBoot = legacy_state.voters[j].total_number_of_times_voted_since_boot; 129 } 130 } 131 } 132 done: 133 if (legacy_states) 134 { 135 for (int i = 0; i < number_platform_modes; i++) 136 { 137 if(legacy_states[i].voters) 138 delete(legacy_states[i].voters); 139 } 140 } 141 delete[] legacy_states; 142 delete[] voters; 143 _hidl_cb(states, Status::SUCCESS); 144 return Void(); 145 } 146 147 IPower* HIDL_FETCH_IPower(const char* /* name */) { 148 const hw_module_t* hw_module = nullptr; 149 power_module_t* power_module = nullptr; 150 int err = hw_get_module(POWER_HARDWARE_MODULE_ID, &hw_module); 151 if (err) { 152 ALOGE("hw_get_module %s failed: %d", POWER_HARDWARE_MODULE_ID, err); 153 return nullptr; 154 } 155 156 if (!hw_module->methods || !hw_module->methods->open) { 157 power_module = reinterpret_cast<power_module_t*>( 158 const_cast<hw_module_t*>(hw_module)); 159 } else { 160 err = hw_module->methods->open( 161 hw_module, POWER_HARDWARE_MODULE_ID, 162 reinterpret_cast<hw_device_t**>(&power_module)); 163 if (err) { 164 ALOGE("Passthrough failed to load legacy HAL."); 165 return nullptr; 166 } 167 } 168 return new Power(power_module); 169 } 170 171 } // namespace implementation 172 } // namespace V1_0 173 } // namespace power 174 } // namespace hardware 175 } // namespace android 176