Compare commits
12 Commits
eefa8480cd
...
97ff7826d5
Author | SHA1 | Date |
---|---|---|
Jenna-they-them | 97ff7826d5 | 2 months ago |
Jenna-they-them | 47a996fd83 | 2 months ago |
Tomasz Wasilczyk | d1f0635f3c | 2 months ago |
Ruchit | a311789ffa | 2 months ago |
Ruchit | 6e96822836 | 2 months ago |
Ruchit | d781b127f0 | 2 months ago |
Simon1511 | 7e6ba8a74d | 2 months ago |
Ruchit | 8793f1b532 | 2 months ago |
Jenna-they-them | f0db7e4df6 | 2 months ago |
Ruchit | bb6d90d5c5 | 2 months ago |
Ruchit | ddda16788c | 2 months ago |
Jenna-they-them | a043c26645 | 2 months ago |
@ -1,23 +0,0 @@ |
|||||||
// |
|
||||||
// Copyright (C) 2021 The LineageOS Project |
|
||||||
// |
|
||||||
// SPDX-License-Identifier: Apache-2.0 |
|
||||||
// |
|
||||||
|
|
||||||
cc_binary { |
|
||||||
name: "android.hardware.light-service.sm7125", |
|
||||||
relative_install_path: "hw", |
|
||||||
init_rc: ["android.hardware.light-service.sm7125.rc"], |
|
||||||
vintf_fragments: ["android.hardware.light-service.sm7125.xml"], |
|
||||||
local_include_dirs: ["include"], |
|
||||||
srcs: [ |
|
||||||
"Lights.cpp", |
|
||||||
"service.cpp", |
|
||||||
], |
|
||||||
shared_libs: [ |
|
||||||
"libbase", |
|
||||||
"libbinder_ndk", |
|
||||||
"android.hardware.light-V1-ndk", |
|
||||||
], |
|
||||||
vendor: true, |
|
||||||
} |
|
@ -1,189 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2021 The LineageOS Project |
|
||||||
* |
|
||||||
* SPDX-License-Identifier: Apache-2.0 |
|
||||||
*/ |
|
||||||
|
|
||||||
#define LOG_TAG "android.hardware.lights-service.sm7125" |
|
||||||
|
|
||||||
#include <android-base/stringprintf.h> |
|
||||||
#include <fstream> |
|
||||||
|
|
||||||
#include "Lights.h" |
|
||||||
|
|
||||||
#define COLOR_MASK 0x00ffffff |
|
||||||
#define MAX_INPUT_BRIGHTNESS 255 |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace android { |
|
||||||
namespace hardware { |
|
||||||
namespace light { |
|
||||||
|
|
||||||
/*
|
|
||||||
* Write value to path and close file. |
|
||||||
*/ |
|
||||||
template <typename T> |
|
||||||
static void set(const std::string& path, const T& value) { |
|
||||||
std::ofstream file(path); |
|
||||||
file << value << std::endl; |
|
||||||
} |
|
||||||
|
|
||||||
template <typename T> |
|
||||||
static T get(const std::string& path, const T& def) { |
|
||||||
std::ifstream file(path); |
|
||||||
T result; |
|
||||||
|
|
||||||
file >> result; |
|
||||||
return file.fail() ? def : result; |
|
||||||
} |
|
||||||
|
|
||||||
Lights::Lights() { |
|
||||||
mLights.emplace(LightType::BACKLIGHT, |
|
||||||
std::bind(&Lights::handleBacklight, this, std::placeholders::_1)); |
|
||||||
#ifdef BUTTON_BRIGHTNESS_NODE |
|
||||||
mLights.emplace(LightType::BUTTONS, std::bind(&Lights::handleButtons, this, std::placeholders::_1)); |
|
||||||
#endif /* BUTTON_BRIGHTNESS_NODE */ |
|
||||||
#ifdef LED_BLINK_NODE |
|
||||||
mLights.emplace(LightType::BATTERY, std::bind(&Lights::handleBattery, this, std::placeholders::_1)); |
|
||||||
mLights.emplace(LightType::NOTIFICATIONS, |
|
||||||
std::bind(&Lights::handleNotifications, this, std::placeholders::_1)); |
|
||||||
mLights.emplace(LightType::ATTENTION, |
|
||||||
std::bind(&Lights::handleAttention, this, std::placeholders::_1)); |
|
||||||
#endif /* LED_BLINK_NODE */ |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus Lights::setLightState(int32_t id, const HwLightState& state) { |
|
||||||
LightType type = static_cast<LightType>(id); |
|
||||||
auto it = mLights.find(type); |
|
||||||
|
|
||||||
if (it == mLights.end()) { |
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); |
|
||||||
} |
|
||||||
|
|
||||||
/*
|
|
||||||
* Lock global mutex until light state is updated. |
|
||||||
*/ |
|
||||||
std::lock_guard<std::mutex> lock(mLock); |
|
||||||
|
|
||||||
it->second(state); |
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
void Lights::handleBacklight(const HwLightState& state) { |
|
||||||
uint32_t max_brightness = get(PANEL_MAX_BRIGHTNESS_NODE, MAX_INPUT_BRIGHTNESS); |
|
||||||
uint32_t brightness = rgbToBrightness(state); |
|
||||||
|
|
||||||
if (max_brightness != MAX_INPUT_BRIGHTNESS) { |
|
||||||
brightness = brightness * max_brightness / MAX_INPUT_BRIGHTNESS; |
|
||||||
} |
|
||||||
|
|
||||||
set(PANEL_BRIGHTNESS_NODE, brightness); |
|
||||||
} |
|
||||||
|
|
||||||
#ifdef BUTTON_BRIGHTNESS_NODE |
|
||||||
void Lights::handleButtons(const HwLightState& state) { |
|
||||||
#ifdef VAR_BUTTON_BRIGHTNESS |
|
||||||
uint32_t brightness = rgbToBrightness(state); |
|
||||||
#else |
|
||||||
uint32_t brightness = (state.color & COLOR_MASK) ? 1 : 0; |
|
||||||
#endif |
|
||||||
|
|
||||||
set(BUTTON_BRIGHTNESS_NODE, brightness); |
|
||||||
} |
|
||||||
#endif |
|
||||||
|
|
||||||
#ifdef LED_BLINK_NODE |
|
||||||
void Lights::handleBattery(const HwLightState& state) { |
|
||||||
mBatteryState = state; |
|
||||||
setNotificationLED(); |
|
||||||
} |
|
||||||
|
|
||||||
void Lights::handleNotifications(const HwLightState& state) { |
|
||||||
mNotificationState = state; |
|
||||||
setNotificationLED(); |
|
||||||
} |
|
||||||
|
|
||||||
void Lights::handleAttention(const HwLightState& state) { |
|
||||||
mAttentionState = state; |
|
||||||
setNotificationLED(); |
|
||||||
} |
|
||||||
|
|
||||||
void Lights::setNotificationLED() { |
|
||||||
int32_t adjusted_brightness = MAX_INPUT_BRIGHTNESS; |
|
||||||
HwLightState state; |
|
||||||
#ifdef LED_BLN_NODE |
|
||||||
bool bln = false; |
|
||||||
#endif /* LED_BLN_NODE */ |
|
||||||
|
|
||||||
if (mNotificationState.color & COLOR_MASK) { |
|
||||||
adjusted_brightness = LED_BRIGHTNESS_NOTIFICATION; |
|
||||||
state = mNotificationState; |
|
||||||
#ifdef LED_BLN_NODE |
|
||||||
bln = true; |
|
||||||
#endif /* LED_BLN_NODE */ |
|
||||||
} else if (mAttentionState.color & COLOR_MASK) { |
|
||||||
adjusted_brightness = LED_BRIGHTNESS_ATTENTION; |
|
||||||
state = mAttentionState; |
|
||||||
if (state.flashMode == FlashMode::HARDWARE) { |
|
||||||
if (state.flashOnMs > 0 && state.flashOffMs == 0) state.flashMode = FlashMode::NONE; |
|
||||||
state.color = 0x000000ff; |
|
||||||
} |
|
||||||
if (state.flashMode == FlashMode::NONE) { |
|
||||||
state.color = 0; |
|
||||||
} |
|
||||||
} else if (mBatteryState.color & COLOR_MASK) { |
|
||||||
adjusted_brightness = LED_BRIGHTNESS_BATTERY; |
|
||||||
state = mBatteryState; |
|
||||||
} else { |
|
||||||
set(LED_BLINK_NODE, "0x00000000 0 0"); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
if (state.flashMode == FlashMode::NONE) { |
|
||||||
state.flashOnMs = 0; |
|
||||||
state.flashOffMs = 0; |
|
||||||
} |
|
||||||
|
|
||||||
state.color = calibrateColor(state.color & COLOR_MASK, adjusted_brightness); |
|
||||||
set(LED_BLINK_NODE, ::android::base::StringPrintf("0x%08x %d %d", state.color, state.flashOnMs, |
|
||||||
state.flashOffMs)); |
|
||||||
|
|
||||||
#ifdef LED_BLN_NODE |
|
||||||
if (bln) { |
|
||||||
set(LED_BLN_NODE, (state.color & COLOR_MASK) ? 1 : 0); |
|
||||||
} |
|
||||||
#endif /* LED_BLN_NODE */ |
|
||||||
} |
|
||||||
|
|
||||||
uint32_t Lights::calibrateColor(uint32_t color, int32_t brightness) { |
|
||||||
uint32_t red = ((color >> 16) & 0xFF) * LED_ADJUSTMENT_R; |
|
||||||
uint32_t green = ((color >> 8) & 0xFF) * LED_ADJUSTMENT_G; |
|
||||||
uint32_t blue = (color & 0xFF) * LED_ADJUSTMENT_B; |
|
||||||
|
|
||||||
return (((red * brightness) / 255) << 16) + (((green * brightness) / 255) << 8) + |
|
||||||
((blue * brightness) / 255); |
|
||||||
} |
|
||||||
#endif /* LED_BLINK_NODE */ |
|
||||||
|
|
||||||
#define AutoHwLight(light) {.id = (int32_t)light, .type = light, .ordinal = 0} |
|
||||||
|
|
||||||
ndk::ScopedAStatus Lights::getLights(std::vector<HwLight> *_aidl_return) { |
|
||||||
for (auto const& light : mLights) { |
|
||||||
_aidl_return->push_back(AutoHwLight(light.first)); |
|
||||||
} |
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
uint32_t Lights::rgbToBrightness(const HwLightState& state) { |
|
||||||
uint32_t color = state.color & COLOR_MASK; |
|
||||||
|
|
||||||
return ((77 * ((color >> 16) & 0xff)) + (150 * ((color >> 8) & 0xff)) + (29 * (color & 0xff))) >> |
|
||||||
8; |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace light
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace android
|
|
||||||
} // namespace aidl
|
|
@ -1,54 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2021 The LineageOS Project |
|
||||||
* |
|
||||||
* SPDX-License-Identifier: Apache-2.0 |
|
||||||
*/ |
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include <aidl/android/hardware/light/BnLights.h> |
|
||||||
#include <unordered_map> |
|
||||||
#include "samsung_lights.h" |
|
||||||
|
|
||||||
using ::aidl::android::hardware::light::HwLightState; |
|
||||||
using ::aidl::android::hardware::light::HwLight; |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace android { |
|
||||||
namespace hardware { |
|
||||||
namespace light { |
|
||||||
|
|
||||||
class Lights : public BnLights { |
|
||||||
public: |
|
||||||
Lights(); |
|
||||||
|
|
||||||
ndk::ScopedAStatus setLightState(int32_t id, const HwLightState& state) override; |
|
||||||
ndk::ScopedAStatus getLights(std::vector<HwLight> *_aidl_return) override; |
|
||||||
|
|
||||||
private: |
|
||||||
void handleBacklight(const HwLightState& state); |
|
||||||
#ifdef BUTTON_BRIGHTNESS_NODE |
|
||||||
void handleButtons(const HwLightState& state); |
|
||||||
#endif /* BUTTON_BRIGHTNESS_NODE */ |
|
||||||
#ifdef LED_BLINK_NODE |
|
||||||
void handleBattery(const HwLightState& state); |
|
||||||
void handleNotifications(const HwLightState& state); |
|
||||||
void handleAttention(const HwLightState& state); |
|
||||||
void setNotificationLED(); |
|
||||||
uint32_t calibrateColor(uint32_t color, int32_t brightness); |
|
||||||
|
|
||||||
HwLightState mAttentionState; |
|
||||||
HwLightState mBatteryState; |
|
||||||
HwLightState mNotificationState; |
|
||||||
#endif /* LED_BLINK_NODE */ |
|
||||||
|
|
||||||
uint32_t rgbToBrightness(const HwLightState& state); |
|
||||||
|
|
||||||
std::mutex mLock; |
|
||||||
std::unordered_map<LightType, std::function<void(const HwLightState&)>> mLights; |
|
||||||
}; |
|
||||||
|
|
||||||
} // namespace light
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace android
|
|
||||||
} // namespace aidl
|
|
@ -1,5 +0,0 @@ |
|||||||
service vendor.light-default /vendor/bin/hw/android.hardware.light-service.sm7125 |
|
||||||
class hal |
|
||||||
user system |
|
||||||
group system |
|
||||||
shutdown critical |
|
@ -1,6 +0,0 @@ |
|||||||
<manifest version="1.0" type="device"> |
|
||||||
<hal format="aidl"> |
|
||||||
<name>android.hardware.light</name> |
|
||||||
<fqname>ILights/default</fqname> |
|
||||||
</hal> |
|
||||||
</manifest> |
|
@ -1,55 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2016 The CyanogenMod Project |
|
||||||
* 2017-2022 The LineageOS Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
/*
|
|
||||||
* Board specific nodes |
|
||||||
* |
|
||||||
* If your kernel exposes these controls in another place, you can either |
|
||||||
* symlink to the locations given here, or override this header in your |
|
||||||
* device tree. |
|
||||||
*/ |
|
||||||
#define PANEL_BRIGHTNESS_NODE "/sys/class/backlight/panel/brightness" |
|
||||||
#define PANEL_MAX_BRIGHTNESS_NODE "/sys/class/backlight/panel/max_brightness" |
|
||||||
#define BUTTON_BRIGHTNESS_NODE "/sys/class/sec/sec_touchkey/brightness" |
|
||||||
#define LED_BLINK_NODE "/sys/class/sec/led/led_blink" |
|
||||||
#define LED_BLN_NODE "/sys/class/misc/backlightnotification/notification_led" |
|
||||||
|
|
||||||
// Uncomment to enable variable button brightness
|
|
||||||
//#define VAR_BUTTON_BRIGHTNESS 1
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Brightness adjustment factors |
|
||||||
* |
|
||||||
* If one of your device's LEDs is more powerful than the others, use these |
|
||||||
* values to equalise them. This value is in the range 0.0-1.0. |
|
||||||
*/ |
|
||||||
#define LED_ADJUSTMENT_R 1.0 |
|
||||||
#define LED_ADJUSTMENT_G 1.0 |
|
||||||
#define LED_ADJUSTMENT_B 1.0 |
|
||||||
|
|
||||||
/*
|
|
||||||
* Light brightness factors |
|
||||||
* |
|
||||||
* It might make sense for all colours to be scaled down (for example, if your |
|
||||||
* LED is too bright). Use these values to adjust the brightness of each |
|
||||||
* light. This value is within the range 0-255. |
|
||||||
*/ |
|
||||||
#define LED_BRIGHTNESS_BATTERY 255 |
|
||||||
#define LED_BRIGHTNESS_NOTIFICATION 255 |
|
||||||
#define LED_BRIGHTNESS_ATTENTION 255 |
|
@ -1,27 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2021 The LineageOS Project |
|
||||||
* |
|
||||||
* SPDX-License-Identifier: Apache-2.0 |
|
||||||
*/ |
|
||||||
|
|
||||||
#define LOG_TAG "android.hardware.light-service.sm7125" |
|
||||||
|
|
||||||
#include "Lights.h" |
|
||||||
|
|
||||||
#include <android/binder_manager.h> |
|
||||||
#include <android/binder_process.h> |
|
||||||
#include <android-base/logging.h> |
|
||||||
|
|
||||||
using ::aidl::android::hardware::light::Lights; |
|
||||||
|
|
||||||
int main() { |
|
||||||
ABinderProcess_setThreadPoolMaxThreadCount(0); |
|
||||||
std::shared_ptr<Lights> lights = ndk::SharedRefBase::make<Lights>(); |
|
||||||
|
|
||||||
const std::string instance = std::string() + Lights::descriptor + "/default"; |
|
||||||
binder_status_t status = AServiceManager_addService(lights->asBinder().get(), instance.c_str()); |
|
||||||
CHECK(status == STATUS_OK); |
|
||||||
|
|
||||||
ABinderProcess_joinThreadPool(); |
|
||||||
return EXIT_FAILURE; // should not reach
|
|
||||||
} |
|
@ -1,48 +0,0 @@ |
|||||||
// |
|
||||||
// Copyright (C) 2018 The Android Open Source Project |
|
||||||
// |
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
// you may not use this file except in compliance with the License. |
|
||||||
// You may obtain a copy of the License at |
|
||||||
// |
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0 |
|
||||||
// |
|
||||||
// Unless required by applicable law or agreed to in writing, software |
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
// See the License for the specific language governing permissions and |
|
||||||
// limitations under the License. |
|
||||||
|
|
||||||
soong_namespace { |
|
||||||
imports: [ |
|
||||||
"hardware/google/pixel", |
|
||||||
"hardware/google/interfaces", |
|
||||||
], |
|
||||||
} |
|
||||||
|
|
||||||
cc_binary { |
|
||||||
name: "android.hardware.power-service.sm7125-libperfmgr", |
|
||||||
relative_install_path: "hw", |
|
||||||
init_rc: ["android.hardware.power-service.sm7125-libperfmgr.rc"], |
|
||||||
vintf_fragments: ["android.hardware.power-service.sm7125.xml"], |
|
||||||
vendor: true, |
|
||||||
shared_libs: [ |
|
||||||
"android.hardware.power-V2-ndk", |
|
||||||
"libbase", |
|
||||||
"libcutils", |
|
||||||
"liblog", |
|
||||||
"libutils", |
|
||||||
"libbinder_ndk", |
|
||||||
"libperfmgr", |
|
||||||
"libprocessgroup", |
|
||||||
"pixel-power-ext-V1-ndk", |
|
||||||
], |
|
||||||
srcs: [ |
|
||||||
"service.cpp", |
|
||||||
"Power.cpp", |
|
||||||
"PowerExt.cpp", |
|
||||||
"InteractionHandler.cpp", |
|
||||||
"PowerHintSession.cpp", |
|
||||||
"PowerSessionManager.cpp", |
|
||||||
], |
|
||||||
} |
|
@ -1,283 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#define LOG_TAG "powerhal-libperfmgr" |
|
||||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL) |
|
||||||
|
|
||||||
#include <array> |
|
||||||
#include <memory> |
|
||||||
|
|
||||||
#include <fcntl.h> |
|
||||||
#include <poll.h> |
|
||||||
#include <sys/eventfd.h> |
|
||||||
#include <time.h> |
|
||||||
#include <unistd.h> |
|
||||||
|
|
||||||
#include <android-base/properties.h> |
|
||||||
#include <utils/Log.h> |
|
||||||
#include <utils/Trace.h> |
|
||||||
|
|
||||||
#include "InteractionHandler.h" |
|
||||||
|
|
||||||
#define MAX_LENGTH 64 |
|
||||||
|
|
||||||
#define MSINSEC 1000L |
|
||||||
#define NSINMS 1000000L |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace google { |
|
||||||
namespace hardware { |
|
||||||
namespace power { |
|
||||||
namespace impl { |
|
||||||
namespace pixel { |
|
||||||
|
|
||||||
namespace { |
|
||||||
|
|
||||||
static const bool kDisplayIdleSupport = |
|
||||||
::android::base::GetBoolProperty("vendor.powerhal.disp.idle_support", true); |
|
||||||
static const std::array<const char *, 2> kDispIdlePath = {"/sys/class/drm/card0/device/idle_state", |
|
||||||
"/sys/class/graphics/fb0/idle_state"}; |
|
||||||
static const uint32_t kWaitMs = |
|
||||||
::android::base::GetUintProperty("vendor.powerhal.disp.idle_wait", /*default*/ 100U); |
|
||||||
static const uint32_t kMinDurationMs = |
|
||||||
::android::base::GetUintProperty("vendor.powerhal.interaction.min", /*default*/ 1400U); |
|
||||||
static const uint32_t kMaxDurationMs = |
|
||||||
::android::base::GetUintProperty("vendor.powerhal.interaction.max", /*default*/ 5650U); |
|
||||||
static const uint32_t kDurationOffsetMs = |
|
||||||
::android::base::GetUintProperty("vendor.powerhal.interaction.offset", /*default*/ 650U); |
|
||||||
|
|
||||||
static size_t CalcTimespecDiffMs(struct timespec start, struct timespec end) { |
|
||||||
size_t diff_in_ms = 0; |
|
||||||
diff_in_ms += (end.tv_sec - start.tv_sec) * MSINSEC; |
|
||||||
diff_in_ms += (end.tv_nsec - start.tv_nsec) / NSINMS; |
|
||||||
return diff_in_ms; |
|
||||||
} |
|
||||||
|
|
||||||
static int FbIdleOpen(void) { |
|
||||||
int fd; |
|
||||||
for (const auto &path : kDispIdlePath) { |
|
||||||
fd = open(path, O_RDONLY); |
|
||||||
if (fd >= 0) |
|
||||||
return fd; |
|
||||||
} |
|
||||||
ALOGE("Unable to open fb idle state path (%d)", errno); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
InteractionHandler::InteractionHandler(std::shared_ptr<HintManager> const &hint_manager) |
|
||||||
: mState(INTERACTION_STATE_UNINITIALIZED), |
|
||||||
mDurationMs(0), |
|
||||||
mHintManager(hint_manager) {} |
|
||||||
|
|
||||||
InteractionHandler::~InteractionHandler() { |
|
||||||
Exit(); |
|
||||||
} |
|
||||||
|
|
||||||
bool InteractionHandler::Init() { |
|
||||||
std::lock_guard<std::mutex> lk(mLock); |
|
||||||
|
|
||||||
if (mState != INTERACTION_STATE_UNINITIALIZED) |
|
||||||
return true; |
|
||||||
|
|
||||||
int fd = FbIdleOpen(); |
|
||||||
if (fd < 0) |
|
||||||
return false; |
|
||||||
mIdleFd = fd; |
|
||||||
|
|
||||||
mEventFd = eventfd(0, EFD_NONBLOCK); |
|
||||||
if (mEventFd < 0) { |
|
||||||
ALOGE("Unable to create event fd (%d)", errno); |
|
||||||
close(mIdleFd); |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
mState = INTERACTION_STATE_IDLE; |
|
||||||
mThread = std::unique_ptr<std::thread>(new std::thread(&InteractionHandler::Routine, this)); |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
void InteractionHandler::Exit() { |
|
||||||
std::unique_lock<std::mutex> lk(mLock); |
|
||||||
if (mState == INTERACTION_STATE_UNINITIALIZED) |
|
||||||
return; |
|
||||||
|
|
||||||
AbortWaitLocked(); |
|
||||||
mState = INTERACTION_STATE_UNINITIALIZED; |
|
||||||
lk.unlock(); |
|
||||||
|
|
||||||
mCond.notify_all(); |
|
||||||
mThread->join(); |
|
||||||
|
|
||||||
close(mEventFd); |
|
||||||
close(mIdleFd); |
|
||||||
} |
|
||||||
|
|
||||||
void InteractionHandler::PerfLock() { |
|
||||||
ALOGV("%s: acquiring perf lock", __func__); |
|
||||||
if (!mHintManager->DoHint("INTERACTION")) { |
|
||||||
ALOGE("%s: do hint INTERACTION failed", __func__); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void InteractionHandler::PerfRel() { |
|
||||||
ALOGV("%s: releasing perf lock", __func__); |
|
||||||
if (!mHintManager->EndHint("INTERACTION")) { |
|
||||||
ALOGE("%s: end hint INTERACTION failed", __func__); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void InteractionHandler::Acquire(int32_t duration) { |
|
||||||
ATRACE_CALL(); |
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lk(mLock); |
|
||||||
|
|
||||||
int inputDuration = duration + kDurationOffsetMs; |
|
||||||
int finalDuration; |
|
||||||
if (inputDuration > kMaxDurationMs) |
|
||||||
finalDuration = kMaxDurationMs; |
|
||||||
else if (inputDuration > kMinDurationMs) |
|
||||||
finalDuration = inputDuration; |
|
||||||
else |
|
||||||
finalDuration = kMinDurationMs; |
|
||||||
|
|
||||||
// Fallback to do boost directly
|
|
||||||
// 1) override property is set OR
|
|
||||||
// 2) InteractionHandler not initialized
|
|
||||||
if (!kDisplayIdleSupport || mState == INTERACTION_STATE_UNINITIALIZED) { |
|
||||||
mHintManager->DoHint("INTERACTION", std::chrono::milliseconds(finalDuration)); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
struct timespec cur_timespec; |
|
||||||
clock_gettime(CLOCK_MONOTONIC, &cur_timespec); |
|
||||||
if (mState != INTERACTION_STATE_IDLE && finalDuration <= mDurationMs) { |
|
||||||
size_t elapsed_time = CalcTimespecDiffMs(mLastTimespec, cur_timespec); |
|
||||||
// don't hint if previous hint's duration covers this hint's duration
|
|
||||||
if (elapsed_time <= (mDurationMs - finalDuration)) { |
|
||||||
ALOGV("%s: Previous duration (%d) cover this (%d) elapsed: %lld", __func__, |
|
||||||
static_cast<int>(mDurationMs), static_cast<int>(finalDuration), |
|
||||||
static_cast<long long>(elapsed_time)); |
|
||||||
return; |
|
||||||
} |
|
||||||
} |
|
||||||
mLastTimespec = cur_timespec; |
|
||||||
mDurationMs = finalDuration; |
|
||||||
|
|
||||||
ALOGV("%s: input: %d final duration: %d", __func__, duration, finalDuration); |
|
||||||
|
|
||||||
if (mState == INTERACTION_STATE_WAITING) |
|
||||||
AbortWaitLocked(); |
|
||||||
else if (mState == INTERACTION_STATE_IDLE) |
|
||||||
PerfLock(); |
|
||||||
|
|
||||||
mState = INTERACTION_STATE_INTERACTION; |
|
||||||
mCond.notify_one(); |
|
||||||
} |
|
||||||
|
|
||||||
void InteractionHandler::Release() { |
|
||||||
std::lock_guard<std::mutex> lk(mLock); |
|
||||||
if (mState == INTERACTION_STATE_WAITING) { |
|
||||||
ATRACE_CALL(); |
|
||||||
PerfRel(); |
|
||||||
mState = INTERACTION_STATE_IDLE; |
|
||||||
} else { |
|
||||||
// clear any wait aborts pending in event fd
|
|
||||||
uint64_t val; |
|
||||||
ssize_t ret = read(mEventFd, &val, sizeof(val)); |
|
||||||
|
|
||||||
ALOGW_IF(ret < 0, "%s: failed to clear eventfd (%zd, %d)", __func__, ret, errno); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// should be called while locked
|
|
||||||
void InteractionHandler::AbortWaitLocked() { |
|
||||||
uint64_t val = 1; |
|
||||||
ssize_t ret = write(mEventFd, &val, sizeof(val)); |
|
||||||
if (ret != sizeof(val)) |
|
||||||
ALOGW("Unable to write to event fd (%zd)", ret); |
|
||||||
} |
|
||||||
|
|
||||||
void InteractionHandler::WaitForIdle(int32_t wait_ms, int32_t timeout_ms) { |
|
||||||
char data[MAX_LENGTH]; |
|
||||||
ssize_t ret; |
|
||||||
struct pollfd pfd[2]; |
|
||||||
|
|
||||||
ATRACE_CALL(); |
|
||||||
|
|
||||||
ALOGV("%s: wait:%d timeout:%d", __func__, wait_ms, timeout_ms); |
|
||||||
|
|
||||||
pfd[0].fd = mEventFd; |
|
||||||
pfd[0].events = POLLIN; |
|
||||||
pfd[1].fd = mIdleFd; |
|
||||||
pfd[1].events = POLLPRI | POLLERR; |
|
||||||
|
|
||||||
ret = poll(pfd, 1, wait_ms); |
|
||||||
if (ret > 0) { |
|
||||||
ALOGV("%s: wait aborted", __func__); |
|
||||||
return; |
|
||||||
} else if (ret < 0) { |
|
||||||
ALOGE("%s: error in poll while waiting", __func__); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
ret = pread(mIdleFd, data, sizeof(data), 0); |
|
||||||
if (!ret) { |
|
||||||
ALOGE("%s: Unexpected EOF!", __func__); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
if (!strncmp(data, "idle", 4)) { |
|
||||||
ALOGV("%s: already idle", __func__); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
ret = poll(pfd, 2, timeout_ms); |
|
||||||
if (ret < 0) |
|
||||||
ALOGE("%s: Error on waiting for idle (%zd)", __func__, ret); |
|
||||||
else if (ret == 0) |
|
||||||
ALOGV("%s: timed out waiting for idle", __func__); |
|
||||||
else if (pfd[0].revents) |
|
||||||
ALOGV("%s: wait for idle aborted", __func__); |
|
||||||
else if (pfd[1].revents) |
|
||||||
ALOGV("%s: idle detected", __func__); |
|
||||||
} |
|
||||||
|
|
||||||
void InteractionHandler::Routine() { |
|
||||||
pthread_setname_np(pthread_self(), "DispIdle"); |
|
||||||
std::unique_lock<std::mutex> lk(mLock, std::defer_lock); |
|
||||||
|
|
||||||
while (true) { |
|
||||||
lk.lock(); |
|
||||||
mCond.wait(lk, [&] { return mState != INTERACTION_STATE_IDLE; }); |
|
||||||
if (mState == INTERACTION_STATE_UNINITIALIZED) |
|
||||||
return; |
|
||||||
mState = INTERACTION_STATE_WAITING; |
|
||||||
lk.unlock(); |
|
||||||
|
|
||||||
WaitForIdle(kWaitMs, mDurationMs); |
|
||||||
Release(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace pixel
|
|
||||||
} // namespace impl
|
|
||||||
} // namespace power
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace google
|
|
||||||
} // namespace aidl
|
|
@ -1,76 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include <condition_variable> |
|
||||||
#include <memory> |
|
||||||
#include <mutex> |
|
||||||
#include <string> |
|
||||||
#include <thread> |
|
||||||
|
|
||||||
#include <perfmgr/HintManager.h> |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace google { |
|
||||||
namespace hardware { |
|
||||||
namespace power { |
|
||||||
namespace impl { |
|
||||||
namespace pixel { |
|
||||||
|
|
||||||
using ::android::perfmgr::HintManager; |
|
||||||
|
|
||||||
enum InteractionState { |
|
||||||
INTERACTION_STATE_UNINITIALIZED, |
|
||||||
INTERACTION_STATE_IDLE, |
|
||||||
INTERACTION_STATE_INTERACTION, |
|
||||||
INTERACTION_STATE_WAITING, |
|
||||||
}; |
|
||||||
|
|
||||||
class InteractionHandler { |
|
||||||
public: |
|
||||||
InteractionHandler(std::shared_ptr<HintManager> const &hint_manager); |
|
||||||
~InteractionHandler(); |
|
||||||
bool Init(); |
|
||||||
void Exit(); |
|
||||||
void Acquire(int32_t duration); |
|
||||||
|
|
||||||
private: |
|
||||||
void Release(); |
|
||||||
void WaitForIdle(int32_t wait_ms, int32_t timeout_ms); |
|
||||||
void AbortWaitLocked(); |
|
||||||
void Routine(); |
|
||||||
|
|
||||||
void PerfLock(); |
|
||||||
void PerfRel(); |
|
||||||
|
|
||||||
enum InteractionState mState; |
|
||||||
int mIdleFd; |
|
||||||
int mEventFd; |
|
||||||
int32_t mDurationMs; |
|
||||||
struct timespec mLastTimespec; |
|
||||||
std::unique_ptr<std::thread> mThread; |
|
||||||
std::mutex mLock; |
|
||||||
std::condition_variable mCond; |
|
||||||
std::shared_ptr<HintManager> mHintManager; |
|
||||||
}; |
|
||||||
|
|
||||||
} // namespace pixel
|
|
||||||
} // namespace impl
|
|
||||||
} // namespace power
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace google
|
|
||||||
} // namespace aidl
|
|
@ -1,296 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2020 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#define LOG_TAG "powerhal-libperfmgr" |
|
||||||
|
|
||||||
#include "Power.h" |
|
||||||
|
|
||||||
#include <mutex> |
|
||||||
|
|
||||||
#include <android-base/file.h> |
|
||||||
#include <android-base/logging.h> |
|
||||||
#include <android-base/properties.h> |
|
||||||
#include <android-base/stringprintf.h> |
|
||||||
#include <android-base/strings.h> |
|
||||||
|
|
||||||
#include <utils/Log.h> |
|
||||||
|
|
||||||
#include "PowerHintSession.h" |
|
||||||
#include "PowerSessionManager.h" |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace google { |
|
||||||
namespace hardware { |
|
||||||
namespace power { |
|
||||||
namespace impl { |
|
||||||
namespace pixel { |
|
||||||
|
|
||||||
using ::aidl::google::hardware::power::impl::pixel::PowerHintSession; |
|
||||||
|
|
||||||
constexpr char kPowerHalStateProp[] = "vendor.powerhal.state"; |
|
||||||
constexpr char kPowerHalAudioProp[] = "vendor.powerhal.audio"; |
|
||||||
constexpr char kPowerHalRenderingProp[] = "vendor.powerhal.rendering"; |
|
||||||
constexpr char kPowerHalAdpfRateProp[] = "vendor.powerhal.adpf.rate"; |
|
||||||
constexpr int64_t kPowerHalAdpfRateDefault = -1; |
|
||||||
|
|
||||||
Power::Power(std::shared_ptr<HintManager> hm) |
|
||||||
: mHintManager(hm), |
|
||||||
mInteractionHandler(nullptr), |
|
||||||
mVRModeOn(false), |
|
||||||
mSustainedPerfModeOn(false), |
|
||||||
mAdpfRateNs( |
|
||||||
::android::base::GetIntProperty(kPowerHalAdpfRateProp, kPowerHalAdpfRateDefault)) { |
|
||||||
mInteractionHandler = std::make_unique<InteractionHandler>(mHintManager); |
|
||||||
mInteractionHandler->Init(); |
|
||||||
|
|
||||||
std::string state = ::android::base::GetProperty(kPowerHalStateProp, ""); |
|
||||||
if (state == "SUSTAINED_PERFORMANCE") { |
|
||||||
LOG(INFO) << "Initialize with SUSTAINED_PERFORMANCE on"; |
|
||||||
mHintManager->DoHint("SUSTAINED_PERFORMANCE"); |
|
||||||
mSustainedPerfModeOn = true; |
|
||||||
} else if (state == "VR") { |
|
||||||
LOG(INFO) << "Initialize with VR on"; |
|
||||||
mHintManager->DoHint(state); |
|
||||||
mVRModeOn = true; |
|
||||||
} else if (state == "VR_SUSTAINED_PERFORMANCE") { |
|
||||||
LOG(INFO) << "Initialize with SUSTAINED_PERFORMANCE and VR on"; |
|
||||||
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE"); |
|
||||||
mSustainedPerfModeOn = true; |
|
||||||
mVRModeOn = true; |
|
||||||
} else { |
|
||||||
LOG(INFO) << "Initialize PowerHAL"; |
|
||||||
} |
|
||||||
|
|
||||||
state = ::android::base::GetProperty(kPowerHalAudioProp, ""); |
|
||||||
if (state == "AUDIO_STREAMING_LOW_LATENCY") { |
|
||||||
LOG(INFO) << "Initialize with AUDIO_LOW_LATENCY on"; |
|
||||||
mHintManager->DoHint(state); |
|
||||||
} |
|
||||||
|
|
||||||
state = ::android::base::GetProperty(kPowerHalRenderingProp, ""); |
|
||||||
if (state == "EXPENSIVE_RENDERING") { |
|
||||||
LOG(INFO) << "Initialize with EXPENSIVE_RENDERING on"; |
|
||||||
mHintManager->DoHint("EXPENSIVE_RENDERING"); |
|
||||||
} |
|
||||||
|
|
||||||
// Now start to take powerhint
|
|
||||||
LOG(INFO) << "PowerHAL ready to take hints, Adpf update rate: " << mAdpfRateNs; |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) { |
|
||||||
LOG(DEBUG) << "Power setMode: " << toString(type) << " to: " << enabled; |
|
||||||
PowerSessionManager::getInstance()->updateHintMode(toString(type), enabled); |
|
||||||
switch (type) { |
|
||||||
case Mode::LOW_POWER: |
|
||||||
if (enabled) { |
|
||||||
mHintManager->DoHint(toString(type)); |
|
||||||
} else { |
|
||||||
mHintManager->EndHint(toString(type)); |
|
||||||
} |
|
||||||
break; |
|
||||||
case Mode::SUSTAINED_PERFORMANCE: |
|
||||||
if (enabled && !mSustainedPerfModeOn) { |
|
||||||
if (!mVRModeOn) { // Sustained mode only.
|
|
||||||
mHintManager->DoHint("SUSTAINED_PERFORMANCE"); |
|
||||||
} else { // Sustained + VR mode.
|
|
||||||
mHintManager->EndHint("VR"); |
|
||||||
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE"); |
|
||||||
} |
|
||||||
mSustainedPerfModeOn = true; |
|
||||||
} else if (!enabled && mSustainedPerfModeOn) { |
|
||||||
mHintManager->EndHint("VR_SUSTAINED_PERFORMANCE"); |
|
||||||
mHintManager->EndHint("SUSTAINED_PERFORMANCE"); |
|
||||||
if (mVRModeOn) { // Switch back to VR Mode.
|
|
||||||
mHintManager->DoHint("VR"); |
|
||||||
} |
|
||||||
mSustainedPerfModeOn = false; |
|
||||||
} |
|
||||||
break; |
|
||||||
case Mode::VR: |
|
||||||
if (enabled && !mVRModeOn) { |
|
||||||
if (!mSustainedPerfModeOn) { // VR mode only.
|
|
||||||
mHintManager->DoHint("VR"); |
|
||||||
} else { // Sustained + VR mode.
|
|
||||||
mHintManager->EndHint("SUSTAINED_PERFORMANCE"); |
|
||||||
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE"); |
|
||||||
} |
|
||||||
mVRModeOn = true; |
|
||||||
} else if (!enabled && mVRModeOn) { |
|
||||||
mHintManager->EndHint("VR_SUSTAINED_PERFORMANCE"); |
|
||||||
mHintManager->EndHint("VR"); |
|
||||||
if (mSustainedPerfModeOn) { // Switch back to sustained Mode.
|
|
||||||
mHintManager->DoHint("SUSTAINED_PERFORMANCE"); |
|
||||||
} |
|
||||||
mVRModeOn = false; |
|
||||||
} |
|
||||||
break; |
|
||||||
case Mode::LAUNCH: |
|
||||||
if (mVRModeOn || mSustainedPerfModeOn) { |
|
||||||
break; |
|
||||||
} |
|
||||||
[[fallthrough]]; |
|
||||||
case Mode::DOUBLE_TAP_TO_WAKE: |
|
||||||
[[fallthrough]]; |
|
||||||
case Mode::FIXED_PERFORMANCE: |
|
||||||
[[fallthrough]]; |
|
||||||
case Mode::EXPENSIVE_RENDERING: |
|
||||||
[[fallthrough]]; |
|
||||||
case Mode::INTERACTIVE: |
|
||||||
[[fallthrough]]; |
|
||||||
case Mode::DEVICE_IDLE: |
|
||||||
[[fallthrough]]; |
|
||||||
case Mode::DISPLAY_INACTIVE: |
|
||||||
[[fallthrough]]; |
|
||||||
case Mode::AUDIO_STREAMING_LOW_LATENCY: |
|
||||||
[[fallthrough]]; |
|
||||||
case Mode::CAMERA_STREAMING_SECURE: |
|
||||||
[[fallthrough]]; |
|
||||||
case Mode::CAMERA_STREAMING_LOW: |
|
||||||
[[fallthrough]]; |
|
||||||
case Mode::CAMERA_STREAMING_MID: |
|
||||||
[[fallthrough]]; |
|
||||||
case Mode::CAMERA_STREAMING_HIGH: |
|
||||||
[[fallthrough]]; |
|
||||||
default: |
|
||||||
if (enabled) { |
|
||||||
mHintManager->DoHint(toString(type)); |
|
||||||
} else { |
|
||||||
mHintManager->EndHint(toString(type)); |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus Power::isModeSupported(Mode type, bool *_aidl_return) { |
|
||||||
bool supported = mHintManager->IsHintSupported(toString(type)); |
|
||||||
switch (type) { |
|
||||||
case Mode::LOW_POWER: // LOW_POWER handled insides PowerHAL specifically
|
|
||||||
supported = true; |
|
||||||
break; |
|
||||||
case Mode::DOUBLE_TAP_TO_WAKE: |
|
||||||
supported = true; |
|
||||||
break; |
|
||||||
case Mode::INTERACTIVE: |
|
||||||
supported = true; |
|
||||||
break; |
|
||||||
default: |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
LOG(INFO) << "Power mode " << toString(type) << " isModeSupported: " << supported; |
|
||||||
*_aidl_return = supported; |
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) { |
|
||||||
LOG(DEBUG) << "Power setBoost: " << toString(type) << " duration: " << durationMs; |
|
||||||
switch (type) { |
|
||||||
case Boost::INTERACTION: |
|
||||||
if (mVRModeOn || mSustainedPerfModeOn) { |
|
||||||
break; |
|
||||||
} |
|
||||||
mInteractionHandler->Acquire(durationMs); |
|
||||||
break; |
|
||||||
case Boost::DISPLAY_UPDATE_IMMINENT: |
|
||||||
[[fallthrough]]; |
|
||||||
case Boost::ML_ACC: |
|
||||||
[[fallthrough]]; |
|
||||||
case Boost::AUDIO_LAUNCH: |
|
||||||
[[fallthrough]]; |
|
||||||
case Boost::CAMERA_LAUNCH: |
|
||||||
[[fallthrough]]; |
|
||||||
case Boost::CAMERA_SHOT: |
|
||||||
[[fallthrough]]; |
|
||||||
default: |
|
||||||
if (mVRModeOn || mSustainedPerfModeOn) { |
|
||||||
break; |
|
||||||
} |
|
||||||
if (durationMs > 0) { |
|
||||||
mHintManager->DoHint(toString(type), std::chrono::milliseconds(durationMs)); |
|
||||||
} else if (durationMs == 0) { |
|
||||||
mHintManager->DoHint(toString(type)); |
|
||||||
} else { |
|
||||||
mHintManager->EndHint(toString(type)); |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool *_aidl_return) { |
|
||||||
bool supported = mHintManager->IsHintSupported(toString(type)); |
|
||||||
LOG(INFO) << "Power boost " << toString(type) << " isBoostSupported: " << supported; |
|
||||||
*_aidl_return = supported; |
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
constexpr const char *boolToString(bool b) { |
|
||||||
return b ? "true" : "false"; |
|
||||||
} |
|
||||||
|
|
||||||
binder_status_t Power::dump(int fd, const char **, uint32_t) { |
|
||||||
std::string buf(::android::base::StringPrintf( |
|
||||||
"HintManager Running: %s\n" |
|
||||||
"VRMode: %s\n" |
|
||||||
"SustainedPerformanceMode: %s\n", |
|
||||||
boolToString(mHintManager->IsRunning()), boolToString(mVRModeOn), |
|
||||||
boolToString(mSustainedPerfModeOn))); |
|
||||||
// Dump nodes through libperfmgr
|
|
||||||
mHintManager->DumpToFd(fd); |
|
||||||
if (!::android::base::WriteStringToFd(buf, fd)) { |
|
||||||
PLOG(ERROR) << "Failed to dump state to fd"; |
|
||||||
} |
|
||||||
fsync(fd); |
|
||||||
return STATUS_OK; |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus Power::createHintSession(int32_t tgid, int32_t uid, |
|
||||||
const std::vector<int32_t> &threadIds, |
|
||||||
int64_t durationNanos, |
|
||||||
std::shared_ptr<IPowerHintSession> *_aidl_return) { |
|
||||||
if (mAdpfRateNs <= 0) { |
|
||||||
*_aidl_return = nullptr; |
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); |
|
||||||
} |
|
||||||
if (threadIds.size() == 0) { |
|
||||||
LOG(ERROR) << "Error: threadIds.size() shouldn't be " << threadIds.size(); |
|
||||||
*_aidl_return = nullptr; |
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); |
|
||||||
} |
|
||||||
std::shared_ptr<IPowerHintSession> session = ndk::SharedRefBase::make<PowerHintSession>( |
|
||||||
tgid, uid, threadIds, durationNanos, nanoseconds(mAdpfRateNs)); |
|
||||||
*_aidl_return = session; |
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus Power::getHintSessionPreferredRate(int64_t *outNanoseconds) { |
|
||||||
*outNanoseconds = mAdpfRateNs; |
|
||||||
if (mAdpfRateNs <= 0) { |
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); |
|
||||||
} |
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace pixel
|
|
||||||
} // namespace impl
|
|
||||||
} // namespace power
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace google
|
|
||||||
} // namespace aidl
|
|
@ -1,67 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2020 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include <atomic> |
|
||||||
#include <memory> |
|
||||||
#include <thread> |
|
||||||
|
|
||||||
#include <aidl/android/hardware/power/BnPower.h> |
|
||||||
#include <perfmgr/HintManager.h> |
|
||||||
|
|
||||||
#include "InteractionHandler.h" |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace google { |
|
||||||
namespace hardware { |
|
||||||
namespace power { |
|
||||||
namespace impl { |
|
||||||
namespace pixel { |
|
||||||
|
|
||||||
using ::aidl::android::hardware::power::Boost; |
|
||||||
using ::aidl::android::hardware::power::IPowerHintSession; |
|
||||||
using ::aidl::android::hardware::power::Mode; |
|
||||||
using ::android::perfmgr::HintManager; |
|
||||||
|
|
||||||
class Power : public ::aidl::android::hardware::power::BnPower { |
|
||||||
public: |
|
||||||
Power(std::shared_ptr<HintManager> hm); |
|
||||||
ndk::ScopedAStatus setMode(Mode type, bool enabled) override; |
|
||||||
ndk::ScopedAStatus isModeSupported(Mode type, bool *_aidl_return) override; |
|
||||||
ndk::ScopedAStatus setBoost(Boost type, int32_t durationMs) override; |
|
||||||
ndk::ScopedAStatus isBoostSupported(Boost type, bool *_aidl_return) override; |
|
||||||
ndk::ScopedAStatus createHintSession(int32_t tgid, int32_t uid, |
|
||||||
const std::vector<int32_t> &threadIds, |
|
||||||
int64_t durationNanos, |
|
||||||
std::shared_ptr<IPowerHintSession> *_aidl_return) override; |
|
||||||
ndk::ScopedAStatus getHintSessionPreferredRate(int64_t *outNanoseconds) override; |
|
||||||
binder_status_t dump(int fd, const char **args, uint32_t numArgs) override; |
|
||||||
|
|
||||||
private: |
|
||||||
std::shared_ptr<HintManager> mHintManager; |
|
||||||
std::unique_ptr<InteractionHandler> mInteractionHandler; |
|
||||||
std::atomic<bool> mVRModeOn; |
|
||||||
std::atomic<bool> mSustainedPerfModeOn; |
|
||||||
const int64_t mAdpfRateNs; |
|
||||||
}; |
|
||||||
|
|
||||||
} // namespace pixel
|
|
||||||
} // namespace impl
|
|
||||||
} // namespace power
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace google
|
|
||||||
} // namespace aidl
|
|
@ -1,85 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2020 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#define LOG_TAG "android.hardware.power-service.sm7125.ext-libperfmgr" |
|
||||||
|
|
||||||
#include "PowerExt.h" |
|
||||||
#include "PowerSessionManager.h" |
|
||||||
|
|
||||||
#include <mutex> |
|
||||||
|
|
||||||
#include <android-base/file.h> |
|
||||||
#include <android-base/logging.h> |
|
||||||
#include <android-base/properties.h> |
|
||||||
#include <android-base/stringprintf.h> |
|
||||||
#include <android-base/strings.h> |
|
||||||
|
|
||||||
#include <utils/Log.h> |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace google { |
|
||||||
namespace hardware { |
|
||||||
namespace power { |
|
||||||
namespace impl { |
|
||||||
namespace pixel { |
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerExt::setMode(const std::string &mode, bool enabled) { |
|
||||||
LOG(DEBUG) << "PowerExt setMode: " << mode << " to: " << enabled; |
|
||||||
|
|
||||||
if (enabled) { |
|
||||||
mHintManager->DoHint(mode); |
|
||||||
} else { |
|
||||||
mHintManager->EndHint(mode); |
|
||||||
} |
|
||||||
PowerSessionManager::getInstance()->updateHintMode(mode, enabled); |
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerExt::isModeSupported(const std::string &mode, bool *_aidl_return) { |
|
||||||
bool supported = mHintManager->IsHintSupported(mode); |
|
||||||
LOG(INFO) << "PowerExt mode " << mode << " isModeSupported: " << supported; |
|
||||||
*_aidl_return = supported; |
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerExt::setBoost(const std::string &boost, int32_t durationMs) { |
|
||||||
LOG(DEBUG) << "PowerExt setBoost: " << boost << " duration: " << durationMs; |
|
||||||
|
|
||||||
if (durationMs > 0) { |
|
||||||
mHintManager->DoHint(boost, std::chrono::milliseconds(durationMs)); |
|
||||||
} else if (durationMs == 0) { |
|
||||||
mHintManager->DoHint(boost); |
|
||||||
} else { |
|
||||||
mHintManager->EndHint(boost); |
|
||||||
} |
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerExt::isBoostSupported(const std::string &boost, bool *_aidl_return) { |
|
||||||
bool supported = mHintManager->IsHintSupported(boost); |
|
||||||
LOG(INFO) << "PowerExt boost " << boost << " isBoostSupported: " << supported; |
|
||||||
*_aidl_return = supported; |
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace pixel
|
|
||||||
} // namespace impl
|
|
||||||
} // namespace power
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace google
|
|
||||||
} // namespace aidl
|
|
@ -1,53 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2020 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include <atomic> |
|
||||||
#include <memory> |
|
||||||
#include <thread> |
|
||||||
|
|
||||||
#include <aidl/google/hardware/power/extension/pixel/BnPowerExt.h> |
|
||||||
#include <perfmgr/HintManager.h> |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace google { |
|
||||||
namespace hardware { |
|
||||||
namespace power { |
|
||||||
namespace impl { |
|
||||||
namespace pixel { |
|
||||||
|
|
||||||
using ::android::perfmgr::HintManager; |
|
||||||
|
|
||||||
class PowerExt : public ::aidl::google::hardware::power::extension::pixel::BnPowerExt { |
|
||||||
public: |
|
||||||
PowerExt(std::shared_ptr<HintManager> hm) |
|
||||||
: mHintManager(hm) {} |
|
||||||
ndk::ScopedAStatus setMode(const std::string &mode, bool enabled) override; |
|
||||||
ndk::ScopedAStatus isModeSupported(const std::string &mode, bool *_aidl_return) override; |
|
||||||
ndk::ScopedAStatus setBoost(const std::string &boost, int32_t durationMs) override; |
|
||||||
ndk::ScopedAStatus isBoostSupported(const std::string &boost, bool *_aidl_return) override; |
|
||||||
|
|
||||||
private: |
|
||||||
std::shared_ptr<HintManager> mHintManager; |
|
||||||
}; |
|
||||||
|
|
||||||
} // namespace pixel
|
|
||||||
} // namespace impl
|
|
||||||
} // namespace power
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace google
|
|
||||||
} // namespace aidl
|
|
@ -1,481 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright 2021 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#define LOG_TAG "powerhal-libperfmgr" |
|
||||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL) |
|
||||||
|
|
||||||
#include <android-base/logging.h> |
|
||||||
#include <android-base/parsedouble.h> |
|
||||||
#include <android-base/properties.h> |
|
||||||
#include <android-base/stringprintf.h> |
|
||||||
#include <sys/syscall.h> |
|
||||||
#include <time.h> |
|
||||||
#include <utils/Trace.h> |
|
||||||
#include <atomic> |
|
||||||
|
|
||||||
#include "PowerHintSession.h" |
|
||||||
#include "PowerSessionManager.h" |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace google { |
|
||||||
namespace hardware { |
|
||||||
namespace power { |
|
||||||
namespace impl { |
|
||||||
namespace pixel { |
|
||||||
|
|
||||||
using ::android::base::StringPrintf; |
|
||||||
using std::chrono::duration_cast; |
|
||||||
using std::chrono::nanoseconds; |
|
||||||
using std::literals::chrono_literals::operator""s; |
|
||||||
|
|
||||||
constexpr char kPowerHalAdpfPidPOver[] = "vendor.powerhal.adpf.pid_p.over"; |
|
||||||
constexpr char kPowerHalAdpfPidPUnder[] = "vendor.powerhal.adpf.pid_p.under"; |
|
||||||
constexpr char kPowerHalAdpfPidI[] = "vendor.powerhal.adpf.pid_i"; |
|
||||||
constexpr char kPowerHalAdpfPidDOver[] = "vendor.powerhal.adpf.pid_d.over"; |
|
||||||
constexpr char kPowerHalAdpfPidDUnder[] = "vendor.powerhal.adpf.pid_d.under"; |
|
||||||
constexpr char kPowerHalAdpfPidIInit[] = "vendor.powerhal.adpf.pid_i.init"; |
|
||||||
constexpr char kPowerHalAdpfPidIHighLimit[] = "vendor.powerhal.adpf.pid_i.high_limit"; |
|
||||||
constexpr char kPowerHalAdpfPidILowLimit[] = "vendor.powerhal.adpf.pid_i.low_limit"; |
|
||||||
constexpr char kPowerHalAdpfUclampEnable[] = "vendor.powerhal.adpf.uclamp"; |
|
||||||
constexpr char kPowerHalAdpfUclampMinGranularity[] = "vendor.powerhal.adpf.uclamp_min.granularity"; |
|
||||||
constexpr char kPowerHalAdpfUclampMinHighLimit[] = "vendor.powerhal.adpf.uclamp_min.high_limit"; |
|
||||||
constexpr char kPowerHalAdpfUclampMinLowLimit[] = "vendor.powerhal.adpf.uclamp_min.low_limit"; |
|
||||||
constexpr char kPowerHalAdpfStaleTimeFactor[] = "vendor.powerhal.adpf.stale_timeout_factor"; |
|
||||||
constexpr char kPowerHalAdpfPSamplingWindow[] = "vendor.powerhal.adpf.p.window"; |
|
||||||
constexpr char kPowerHalAdpfISamplingWindow[] = "vendor.powerhal.adpf.i.window"; |
|
||||||
constexpr char kPowerHalAdpfDSamplingWindow[] = "vendor.powerhal.adpf.d.window"; |
|
||||||
|
|
||||||
namespace { |
|
||||||
/* there is no glibc or bionic wrapper */ |
|
||||||
struct sched_attr { |
|
||||||
__u32 size; |
|
||||||
__u32 sched_policy; |
|
||||||
__u64 sched_flags; |
|
||||||
__s32 sched_nice; |
|
||||||
__u32 sched_priority; |
|
||||||
__u64 sched_runtime; |
|
||||||
__u64 sched_deadline; |
|
||||||
__u64 sched_period; |
|
||||||
__u32 sched_util_min; |
|
||||||
__u32 sched_util_max; |
|
||||||
}; |
|
||||||
|
|
||||||
static int sched_setattr(int pid, struct sched_attr *attr, unsigned int flags) { |
|
||||||
static const bool kPowerHalAdpfUclamp = |
|
||||||
::android::base::GetBoolProperty(kPowerHalAdpfUclampEnable, true); |
|
||||||
if (!kPowerHalAdpfUclamp) { |
|
||||||
ALOGV("PowerHintSession:%s: skip", __func__); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
return syscall(__NR_sched_setattr, pid, attr, flags); |
|
||||||
} |
|
||||||
|
|
||||||
static inline int64_t ns_to_100us(int64_t ns) { |
|
||||||
return ns / 100000; |
|
||||||
} |
|
||||||
|
|
||||||
static double getDoubleProperty(const char *prop, double value) { |
|
||||||
std::string result = ::android::base::GetProperty(prop, std::to_string(value).c_str()); |
|
||||||
if (!::android::base::ParseDouble(result.c_str(), &value)) { |
|
||||||
ALOGE("PowerHintSession : failed to parse double in %s", prop); |
|
||||||
} |
|
||||||
return value; |
|
||||||
} |
|
||||||
|
|
||||||
static double sPidPOver = getDoubleProperty(kPowerHalAdpfPidPOver, 2.0); |
|
||||||
static double sPidPUnder = getDoubleProperty(kPowerHalAdpfPidPUnder, 1.0); |
|
||||||
static double sPidI = getDoubleProperty(kPowerHalAdpfPidI, 0.001); |
|
||||||
static double sPidDOver = getDoubleProperty(kPowerHalAdpfPidDOver, 500.0); |
|
||||||
static double sPidDUnder = getDoubleProperty(kPowerHalAdpfPidDUnder, 0.0); |
|
||||||
static const int64_t sPidIInit = |
|
||||||
(sPidI == 0) ? 0 |
|
||||||
: static_cast<int64_t>(::android::base::GetIntProperty<int64_t>( |
|
||||||
kPowerHalAdpfPidIInit, 200) / |
|
||||||
sPidI); |
|
||||||
static const int64_t sPidIHighLimit = |
|
||||||
(sPidI == 0) ? 0 |
|
||||||
: static_cast<int64_t>(::android::base::GetIntProperty<int64_t>( |
|
||||||
kPowerHalAdpfPidIHighLimit, 512) / |
|
||||||
sPidI); |
|
||||||
static const int64_t sPidILowLimit = |
|
||||||
(sPidI == 0) ? 0 |
|
||||||
: static_cast<int64_t>(::android::base::GetIntProperty<int64_t>( |
|
||||||
kPowerHalAdpfPidILowLimit, -30) / |
|
||||||
sPidI); |
|
||||||
static const int32_t sUclampMinHighLimit = |
|
||||||
::android::base::GetUintProperty<uint32_t>(kPowerHalAdpfUclampMinHighLimit, 384); |
|
||||||
static const int32_t sUclampMinLowLimit = |
|
||||||
::android::base::GetUintProperty<uint32_t>(kPowerHalAdpfUclampMinLowLimit, 2); |
|
||||||
static const uint32_t sUclampMinGranularity = |
|
||||||
::android::base::GetUintProperty<uint32_t>(kPowerHalAdpfUclampMinGranularity, 5); |
|
||||||
static const int64_t sStaleTimeFactor = |
|
||||||
::android::base::GetUintProperty<uint32_t>(kPowerHalAdpfStaleTimeFactor, 20); |
|
||||||
static const int64_t sPSamplingWindow = |
|
||||||
::android::base::GetUintProperty<uint32_t>(kPowerHalAdpfPSamplingWindow, 1); |
|
||||||
static const int64_t sISamplingWindow = |
|
||||||
::android::base::GetUintProperty<uint32_t>(kPowerHalAdpfISamplingWindow, 0); |
|
||||||
static const int64_t sDSamplingWindow = |
|
||||||
::android::base::GetUintProperty<uint32_t>(kPowerHalAdpfDSamplingWindow, 1); |
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
PowerHintSession::PowerHintSession(int32_t tgid, int32_t uid, const std::vector<int32_t> &threadIds, |
|
||||||
int64_t durationNanos, const nanoseconds adpfRate) |
|
||||||
: kAdpfRate(adpfRate) { |
|
||||||
mDescriptor = new AppHintDesc(tgid, uid, threadIds); |
|
||||||
mDescriptor->duration = std::chrono::nanoseconds(durationNanos); |
|
||||||
mStaleHandler = sp<StaleHandler>(new StaleHandler(this)); |
|
||||||
mPowerManagerHandler = PowerSessionManager::getInstance(); |
|
||||||
|
|
||||||
if (ATRACE_ENABLED()) { |
|
||||||
const std::string idstr = getIdString(); |
|
||||||
std::string sz = StringPrintf("adpf.%s-target", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), (int64_t)mDescriptor->duration.count()); |
|
||||||
sz = StringPrintf("adpf.%s-active", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), mDescriptor->is_active.load()); |
|
||||||
sz = StringPrintf("adpf.%s-stale", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), isStale()); |
|
||||||
} |
|
||||||
PowerSessionManager::getInstance()->addPowerSession(this); |
|
||||||
// init boost
|
|
||||||
setUclamp(sUclampMinHighLimit); |
|
||||||
ALOGV("PowerHintSession created: %s", mDescriptor->toString().c_str()); |
|
||||||
} |
|
||||||
|
|
||||||
PowerHintSession::~PowerHintSession() { |
|
||||||
close(); |
|
||||||
ALOGV("PowerHintSession deleted: %s", mDescriptor->toString().c_str()); |
|
||||||
if (ATRACE_ENABLED()) { |
|
||||||
const std::string idstr = getIdString(); |
|
||||||
std::string sz = StringPrintf("adpf.%s-target", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), 0); |
|
||||||
sz = StringPrintf("adpf.%s-actl_last", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), 0); |
|
||||||
sz = sz = StringPrintf("adpf.%s-active", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), 0); |
|
||||||
} |
|
||||||
delete mDescriptor; |
|
||||||
} |
|
||||||
|
|
||||||
std::string PowerHintSession::getIdString() const { |
|
||||||
std::string idstr = StringPrintf("%" PRId32 "-%" PRId32 "-%" PRIxPTR, mDescriptor->tgid, |
|
||||||
mDescriptor->uid, reinterpret_cast<uintptr_t>(this) & 0xffff); |
|
||||||
return idstr; |
|
||||||
} |
|
||||||
|
|
||||||
void PowerHintSession::updateUniveralBoostMode() { |
|
||||||
PowerHintMonitor::getInstance()->getLooper()->sendMessage(mPowerManagerHandler, NULL); |
|
||||||
} |
|
||||||
|
|
||||||
int PowerHintSession::setUclamp(int32_t min, int32_t max) { |
|
||||||
std::lock_guard<std::mutex> guard(mLock); |
|
||||||
min = std::max(0, min); |
|
||||||
min = std::min(min, max); |
|
||||||
max = std::max(0, max); |
|
||||||
max = std::max(min, max); |
|
||||||
if (ATRACE_ENABLED()) { |
|
||||||
const std::string idstr = getIdString(); |
|
||||||
std::string sz = StringPrintf("adpf.%s-min", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), min); |
|
||||||
} |
|
||||||
for (const auto tid : mDescriptor->threadIds) { |
|
||||||
sched_attr attr = {}; |
|
||||||
attr.size = sizeof(attr); |
|
||||||
|
|
||||||
attr.sched_flags = (SCHED_FLAG_KEEP_ALL | SCHED_FLAG_UTIL_CLAMP); |
|
||||||
attr.sched_util_min = min; |
|
||||||
attr.sched_util_max = max; |
|
||||||
|
|
||||||
int ret = sched_setattr(tid, &attr, 0); |
|
||||||
if (ret) { |
|
||||||
ALOGW("sched_setattr failed for thread %d, err=%d", tid, errno); |
|
||||||
} |
|
||||||
ALOGV("PowerHintSession tid: %d, uclamp(%d, %d)", tid, min, max); |
|
||||||
} |
|
||||||
mDescriptor->current_min = min; |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerHintSession::pause() { |
|
||||||
if (!mDescriptor->is_active.load()) |
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); |
|
||||||
// Reset to default uclamp value.
|
|
||||||
setUclamp(0); |
|
||||||
mDescriptor->is_active.store(false); |
|
||||||
if (ATRACE_ENABLED()) { |
|
||||||
const std::string idstr = getIdString(); |
|
||||||
std::string sz = StringPrintf("adpf.%s-active", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), mDescriptor->is_active.load()); |
|
||||||
} |
|
||||||
updateUniveralBoostMode(); |
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerHintSession::resume() { |
|
||||||
if (mDescriptor->is_active.load()) |
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); |
|
||||||
mDescriptor->is_active.store(true); |
|
||||||
mDescriptor->integral_error = std::max(sPidIInit, mDescriptor->integral_error); |
|
||||||
// resume boost
|
|
||||||
setUclamp(sUclampMinHighLimit); |
|
||||||
if (ATRACE_ENABLED()) { |
|
||||||
const std::string idstr = getIdString(); |
|
||||||
std::string sz = StringPrintf("adpf.%s-active", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), mDescriptor->is_active.load()); |
|
||||||
} |
|
||||||
updateUniveralBoostMode(); |
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerHintSession::close() { |
|
||||||
bool sessionClosedExpectedToBe = false; |
|
||||||
if (!mSessionClosed.compare_exchange_strong(sessionClosedExpectedToBe, true)) { |
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); |
|
||||||
} |
|
||||||
PowerHintMonitor::getInstance()->getLooper()->removeMessages(mStaleHandler); |
|
||||||
setUclamp(0); |
|
||||||
PowerSessionManager::getInstance()->removePowerSession(this); |
|
||||||
updateUniveralBoostMode(); |
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerHintSession::updateTargetWorkDuration(int64_t targetDurationNanos) { |
|
||||||
if (targetDurationNanos <= 0) { |
|
||||||
ALOGE("Error: targetDurationNanos(%" PRId64 ") should bigger than 0", targetDurationNanos); |
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); |
|
||||||
} |
|
||||||
ALOGV("update target duration: %" PRId64 " ns", targetDurationNanos); |
|
||||||
double ratio = |
|
||||||
targetDurationNanos == 0 ? 1.0 : mDescriptor->duration.count() / targetDurationNanos; |
|
||||||
mDescriptor->integral_error = |
|
||||||
std::max(sPidIInit, static_cast<int64_t>(mDescriptor->integral_error * ratio)); |
|
||||||
|
|
||||||
mDescriptor->duration = std::chrono::nanoseconds(targetDurationNanos); |
|
||||||
if (ATRACE_ENABLED()) { |
|
||||||
const std::string idstr = getIdString(); |
|
||||||
std::string sz = StringPrintf("adpf.%s-target", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), (int64_t)mDescriptor->duration.count()); |
|
||||||
} |
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerHintSession::reportActualWorkDuration( |
|
||||||
const std::vector<WorkDuration> &actualDurations) { |
|
||||||
if (mDescriptor->duration.count() == 0LL) { |
|
||||||
ALOGE("Expect to call updateTargetWorkDuration() first."); |
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); |
|
||||||
} |
|
||||||
if (actualDurations.size() == 0) { |
|
||||||
ALOGE("Error: duration.size() shouldn't be %zu.", actualDurations.size()); |
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); |
|
||||||
} |
|
||||||
if (!mDescriptor->is_active.load()) { |
|
||||||
ALOGE("Error: shouldn't report duration during pause state."); |
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); |
|
||||||
} |
|
||||||
if (PowerHintMonitor::getInstance()->isRunning() && isStale()) { |
|
||||||
mDescriptor->integral_error = std::max(sPidIInit, mDescriptor->integral_error); |
|
||||||
if (ATRACE_ENABLED()) { |
|
||||||
const std::string idstr = getIdString(); |
|
||||||
std::string sz = StringPrintf("adpf.%s-wakeup", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), mDescriptor->integral_error); |
|
||||||
ATRACE_INT(sz.c_str(), 0); |
|
||||||
} |
|
||||||
} |
|
||||||
int64_t targetDurationNanos = (int64_t)mDescriptor->duration.count(); |
|
||||||
int64_t length = actualDurations.size(); |
|
||||||
int64_t p_start = |
|
||||||
sPSamplingWindow == 0 || sPSamplingWindow > length ? 0 : length - sPSamplingWindow; |
|
||||||
int64_t i_start = |
|
||||||
sISamplingWindow == 0 || sISamplingWindow > length ? 0 : length - sISamplingWindow; |
|
||||||
int64_t d_start = |
|
||||||
sDSamplingWindow == 0 || sDSamplingWindow > length ? 0 : length - sDSamplingWindow; |
|
||||||
int64_t dt = ns_to_100us(targetDurationNanos); |
|
||||||
int64_t err_sum = 0; |
|
||||||
int64_t derivative_sum = 0; |
|
||||||
for (int64_t i = std::min({p_start, i_start, d_start}); i < length; i++) { |
|
||||||
int64_t actualDurationNanos = actualDurations[i].durationNanos; |
|
||||||
if (std::abs(actualDurationNanos) > targetDurationNanos * 20) { |
|
||||||
ALOGW("The actual duration is way far from the target (%" PRId64 " >> %" PRId64 ")", |
|
||||||
actualDurationNanos, targetDurationNanos); |
|
||||||
} |
|
||||||
// PID control algorithm
|
|
||||||
int64_t error = ns_to_100us(actualDurationNanos - targetDurationNanos); |
|
||||||
if (i >= d_start) { |
|
||||||
derivative_sum += error - mDescriptor->previous_error; |
|
||||||
} |
|
||||||
if (i >= p_start) { |
|
||||||
err_sum += error; |
|
||||||
} |
|
||||||
if (i >= i_start) { |
|
||||||
mDescriptor->integral_error = mDescriptor->integral_error + error * dt; |
|
||||||
mDescriptor->integral_error = std::min(sPidIHighLimit, mDescriptor->integral_error); |
|
||||||
mDescriptor->integral_error = std::max(sPidILowLimit, mDescriptor->integral_error); |
|
||||||
} |
|
||||||
mDescriptor->previous_error = error; |
|
||||||
} |
|
||||||
if (ATRACE_ENABLED()) { |
|
||||||
const std::string idstr = getIdString(); |
|
||||||
std::string sz = StringPrintf("adpf.%s-err", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), err_sum / (length - p_start)); |
|
||||||
sz = StringPrintf("adpf.%s-integral", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), mDescriptor->integral_error); |
|
||||||
sz = StringPrintf("adpf.%s-derivative", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), derivative_sum / dt / (length - d_start)); |
|
||||||
} |
|
||||||
int64_t pOut = static_cast<int64_t>((err_sum > 0 ? sPidPOver : sPidPUnder) * err_sum / |
|
||||||
(length - p_start)); |
|
||||||
int64_t iOut = static_cast<int64_t>(sPidI * mDescriptor->integral_error); |
|
||||||
int64_t dOut = static_cast<int64_t>((derivative_sum > 0 ? sPidDOver : sPidDUnder) * |
|
||||||
derivative_sum / dt / (length - d_start)); |
|
||||||
|
|
||||||
int64_t output = pOut + iOut + dOut; |
|
||||||
|
|
||||||
if (ATRACE_ENABLED()) { |
|
||||||
const std::string idstr = getIdString(); |
|
||||||
std::string sz = StringPrintf("adpf.%s-actl_last", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), actualDurations[length - 1].durationNanos); |
|
||||||
sz = StringPrintf("adpf.%s-target", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), (int64_t)mDescriptor->duration.count()); |
|
||||||
sz = StringPrintf("adpf.%s-sample_size", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), length); |
|
||||||
sz = StringPrintf("adpf.%s-pid.count", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), mDescriptor->update_count); |
|
||||||
sz = StringPrintf("adpf.%s-pid.pOut", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), pOut); |
|
||||||
sz = StringPrintf("adpf.%s-pid.iOut", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), iOut); |
|
||||||
sz = StringPrintf("adpf.%s-pid.dOut", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), dOut); |
|
||||||
sz = StringPrintf("adpf.%s-pid.output", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), output); |
|
||||||
sz = StringPrintf("adpf.%s-stale", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), isStale()); |
|
||||||
sz = StringPrintf("adpf.%s-pid.overtime", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), err_sum > 0); |
|
||||||
} |
|
||||||
mDescriptor->update_count++; |
|
||||||
|
|
||||||
mStaleHandler->updateStaleTimer(); |
|
||||||
|
|
||||||
/* apply to all the threads in the group */ |
|
||||||
if (output != 0) { |
|
||||||
int next_min = std::min(sUclampMinHighLimit, static_cast<int>(output)); |
|
||||||
next_min = std::max(sUclampMinLowLimit, next_min); |
|
||||||
if (std::abs(mDescriptor->current_min - next_min) > sUclampMinGranularity) { |
|
||||||
setUclamp(next_min); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
std::string AppHintDesc::toString() const { |
|
||||||
std::string out = |
|
||||||
StringPrintf("session %" PRIxPTR "\n", reinterpret_cast<uintptr_t>(this) & 0xffff); |
|
||||||
const int64_t durationNanos = duration.count(); |
|
||||||
out.append(StringPrintf(" duration: %" PRId64 " ns\n", durationNanos)); |
|
||||||
out.append(StringPrintf(" uclamp.min: %d \n", current_min)); |
|
||||||
out.append(StringPrintf(" uid: %d, tgid: %d\n", uid, tgid)); |
|
||||||
|
|
||||||
out.append(" threadIds: ["); |
|
||||||
bool first = true; |
|
||||||
for (int tid : threadIds) { |
|
||||||
if (!first) { |
|
||||||
out.append(", "); |
|
||||||
} |
|
||||||
out.append(std::to_string(tid)); |
|
||||||
first = false; |
|
||||||
} |
|
||||||
out.append("]\n"); |
|
||||||
return out; |
|
||||||
} |
|
||||||
|
|
||||||
bool PowerHintSession::isActive() { |
|
||||||
return mDescriptor->is_active.load(); |
|
||||||
} |
|
||||||
|
|
||||||
bool PowerHintSession::isStale() { |
|
||||||
auto now = std::chrono::steady_clock::now(); |
|
||||||
return now >= mStaleHandler->getStaleTime(); |
|
||||||
} |
|
||||||
|
|
||||||
const std::vector<int> &PowerHintSession::getTidList() const { |
|
||||||
return mDescriptor->threadIds; |
|
||||||
} |
|
||||||
|
|
||||||
void PowerHintSession::setStale() { |
|
||||||
if (ATRACE_ENABLED()) { |
|
||||||
const std::string idstr = getIdString(); |
|
||||||
std::string sz = StringPrintf("adpf.%s-stale", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), 1); |
|
||||||
} |
|
||||||
// Reset to default uclamp value.
|
|
||||||
setUclamp(0); |
|
||||||
// Deliver a task to check if all sessions are inactive.
|
|
||||||
updateUniveralBoostMode(); |
|
||||||
} |
|
||||||
|
|
||||||
void PowerHintSession::StaleHandler::updateStaleTimer() { |
|
||||||
std::lock_guard<std::mutex> guard(mStaleLock); |
|
||||||
if (PowerHintMonitor::getInstance()->isRunning()) { |
|
||||||
auto when = getStaleTime(); |
|
||||||
auto now = std::chrono::steady_clock::now(); |
|
||||||
mLastUpdatedTime.store(now); |
|
||||||
if (now > when) { |
|
||||||
mSession->updateUniveralBoostMode(); |
|
||||||
} |
|
||||||
if (!mIsMonitoringStale.load()) { |
|
||||||
auto next = getStaleTime(); |
|
||||||
PowerHintMonitor::getInstance()->getLooper()->sendMessageDelayed( |
|
||||||
duration_cast<nanoseconds>(next - now).count(), this, NULL); |
|
||||||
mIsMonitoringStale.store(true); |
|
||||||
} |
|
||||||
if (ATRACE_ENABLED()) { |
|
||||||
const std::string idstr = mSession->getIdString(); |
|
||||||
std::string sz = StringPrintf("adpf.%s-stale", idstr.c_str()); |
|
||||||
ATRACE_INT(sz.c_str(), 0); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
time_point<steady_clock> PowerHintSession::StaleHandler::getStaleTime() { |
|
||||||
return mLastUpdatedTime.load() + |
|
||||||
std::chrono::duration_cast<milliseconds>(mSession->kAdpfRate) * sStaleTimeFactor; |
|
||||||
} |
|
||||||
|
|
||||||
void PowerHintSession::StaleHandler::handleMessage(const Message &) { |
|
||||||
std::lock_guard<std::mutex> guard(mStaleLock); |
|
||||||
auto now = std::chrono::steady_clock::now(); |
|
||||||
auto when = getStaleTime(); |
|
||||||
// Check if the session is stale based on the last_updated_time.
|
|
||||||
if (now > when) { |
|
||||||
mSession->setStale(); |
|
||||||
mIsMonitoringStale.store(false); |
|
||||||
return; |
|
||||||
} |
|
||||||
// Schedule for the next checking time.
|
|
||||||
PowerHintMonitor::getInstance()->getLooper()->sendMessageDelayed( |
|
||||||
duration_cast<nanoseconds>(when - now).count(), this, NULL); |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace pixel
|
|
||||||
} // namespace impl
|
|
||||||
} // namespace power
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace google
|
|
||||||
} // namespace aidl
|
|
@ -1,119 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright 2021 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include <aidl/android/hardware/power/BnPowerHintSession.h> |
|
||||||
#include <aidl/android/hardware/power/WorkDuration.h> |
|
||||||
#include <utils/Looper.h> |
|
||||||
#include <utils/Thread.h> |
|
||||||
|
|
||||||
#include <mutex> |
|
||||||
#include <unordered_map> |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace google { |
|
||||||
namespace hardware { |
|
||||||
namespace power { |
|
||||||
namespace impl { |
|
||||||
namespace pixel { |
|
||||||
|
|
||||||
using aidl::android::hardware::power::BnPowerHintSession; |
|
||||||
using aidl::android::hardware::power::WorkDuration; |
|
||||||
using ::android::Message; |
|
||||||
using ::android::MessageHandler; |
|
||||||
using ::android::sp; |
|
||||||
using std::chrono::milliseconds; |
|
||||||
using std::chrono::nanoseconds; |
|
||||||
using std::chrono::steady_clock; |
|
||||||
using std::chrono::time_point; |
|
||||||
|
|
||||||
static const int32_t kMaxUclampValue = 1024; |
|
||||||
struct AppHintDesc { |
|
||||||
AppHintDesc(int32_t tgid, int32_t uid, std::vector<int> threadIds) |
|
||||||
: tgid(tgid), |
|
||||||
uid(uid), |
|
||||||
threadIds(std::move(threadIds)), |
|
||||||
duration(0LL), |
|
||||||
current_min(0), |
|
||||||
is_active(true), |
|
||||||
update_count(0), |
|
||||||
integral_error(0), |
|
||||||
previous_error(0) {} |
|
||||||
std::string toString() const; |
|
||||||
const int32_t tgid; |
|
||||||
const int32_t uid; |
|
||||||
const std::vector<int> threadIds; |
|
||||||
nanoseconds duration; |
|
||||||
int current_min; |
|
||||||
// status
|
|
||||||
std::atomic<bool> is_active; |
|
||||||
// pid
|
|
||||||
uint64_t update_count; |
|
||||||
int64_t integral_error; |
|
||||||
int64_t previous_error; |
|
||||||
}; |
|
||||||
|
|
||||||
class PowerHintSession : public BnPowerHintSession { |
|
||||||
public: |
|
||||||
explicit PowerHintSession(int32_t tgid, int32_t uid, const std::vector<int32_t> &threadIds, |
|
||||||
int64_t durationNanos, nanoseconds adpfRate); |
|
||||||
~PowerHintSession(); |
|
||||||
ndk::ScopedAStatus close() override; |
|
||||||
ndk::ScopedAStatus pause() override; |
|
||||||
ndk::ScopedAStatus resume() override; |
|
||||||
ndk::ScopedAStatus updateTargetWorkDuration(int64_t targetDurationNanos) override; |
|
||||||
ndk::ScopedAStatus reportActualWorkDuration( |
|
||||||
const std::vector<WorkDuration> &actualDurations) override; |
|
||||||
bool isActive(); |
|
||||||
bool isStale(); |
|
||||||
const std::vector<int> &getTidList() const; |
|
||||||
|
|
||||||
private: |
|
||||||
class StaleHandler : public MessageHandler { |
|
||||||
public: |
|
||||||
StaleHandler(PowerHintSession *session) |
|
||||||
: mSession(session), mIsMonitoringStale(false), mLastUpdatedTime(steady_clock::now()) {} |
|
||||||
void handleMessage(const Message &message) override; |
|
||||||
void updateStaleTimer(); |
|
||||||
time_point<steady_clock> getStaleTime(); |
|
||||||
|
|
||||||
private: |
|
||||||
PowerHintSession *mSession; |
|
||||||
std::atomic<bool> mIsMonitoringStale; |
|
||||||
std::atomic<time_point<steady_clock>> mLastUpdatedTime; |
|
||||||
std::mutex mStaleLock; |
|
||||||
}; |
|
||||||
|
|
||||||
private: |
|
||||||
void setStale(); |
|
||||||
void updateUniveralBoostMode(); |
|
||||||
int setUclamp(int32_t min, int32_t max = kMaxUclampValue); |
|
||||||
std::string getIdString() const; |
|
||||||
AppHintDesc *mDescriptor = nullptr; |
|
||||||
sp<StaleHandler> mStaleHandler; |
|
||||||
sp<MessageHandler> mPowerManagerHandler; |
|
||||||
std::mutex mLock; |
|
||||||
const nanoseconds kAdpfRate; |
|
||||||
std::atomic<bool> mSessionClosed = false; |
|
||||||
}; |
|
||||||
|
|
||||||
} // namespace pixel
|
|
||||||
} // namespace impl
|
|
||||||
} // namespace power
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace google
|
|
||||||
} // namespace aidl
|
|
@ -1,163 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright 2021 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#define LOG_TAG "powerhal-libperfmgr" |
|
||||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL) |
|
||||||
|
|
||||||
#include <log/log.h> |
|
||||||
#include <processgroup/processgroup.h> |
|
||||||
#include <utils/Trace.h> |
|
||||||
|
|
||||||
#include "PowerSessionManager.h" |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace google { |
|
||||||
namespace hardware { |
|
||||||
namespace power { |
|
||||||
namespace impl { |
|
||||||
namespace pixel { |
|
||||||
|
|
||||||
void PowerSessionManager::setHintManager(std::shared_ptr<HintManager> const &hint_manager) { |
|
||||||
// Only initialize hintmanager instance if hint is supported.
|
|
||||||
if (hint_manager->IsHintSupported(kDisableBoostHintName)) { |
|
||||||
mHintManager = hint_manager; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void PowerSessionManager::updateHintMode(const std::string &mode, bool enabled) { |
|
||||||
ALOGV("PowerSessionManager::updateHintMode: mode: %s, enabled: %d", mode.c_str(), enabled); |
|
||||||
if (enabled && mode.compare(0, 8, "REFRESH_") == 0) { |
|
||||||
if (mode.compare("REFRESH_120FPS") == 0) { |
|
||||||
mDisplayRefreshRate = 120; |
|
||||||
} else if (mode.compare("REFRESH_90FPS") == 0) { |
|
||||||
mDisplayRefreshRate = 90; |
|
||||||
} else if (mode.compare("REFRESH_60FPS") == 0) { |
|
||||||
mDisplayRefreshRate = 60; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
int PowerSessionManager::getDisplayRefreshRate() { |
|
||||||
return mDisplayRefreshRate; |
|
||||||
} |
|
||||||
|
|
||||||
void PowerSessionManager::addPowerSession(PowerHintSession *session) { |
|
||||||
std::lock_guard<std::mutex> guard(mLock); |
|
||||||
for (auto t : session->getTidList()) { |
|
||||||
if (mTidRefCountMap.find(t) == mTidRefCountMap.end()) { |
|
||||||
if (!SetTaskProfiles(t, {"ResetUclampGrp"})) { |
|
||||||
ALOGW("Failed to set ResetUclampGrp task profile for tid:%d", t); |
|
||||||
} else { |
|
||||||
mTidRefCountMap[t] = 1; |
|
||||||
} |
|
||||||
continue; |
|
||||||
} |
|
||||||
if (mTidRefCountMap[t] <= 0) { |
|
||||||
ALOGE("Error! Unexpected zero/negative RefCount:%d for tid:%d", mTidRefCountMap[t], t); |
|
||||||
continue; |
|
||||||
} |
|
||||||
mTidRefCountMap[t]++; |
|
||||||
} |
|
||||||
mSessions.insert(session); |
|
||||||
} |
|
||||||
|
|
||||||
void PowerSessionManager::removePowerSession(PowerHintSession *session) { |
|
||||||
std::lock_guard<std::mutex> guard(mLock); |
|
||||||
for (auto t : session->getTidList()) { |
|
||||||
if (mTidRefCountMap.find(t) == mTidRefCountMap.end()) { |
|
||||||
ALOGE("Unexpected Error! Failed to look up tid:%d in TidRefCountMap", t); |
|
||||||
continue; |
|
||||||
} |
|
||||||
mTidRefCountMap[t]--; |
|
||||||
if (mTidRefCountMap[t] <= 0) { |
|
||||||
if (!SetTaskProfiles(t, {"NoResetUclampGrp"})) { |
|
||||||
ALOGW("Failed to set NoResetUclampGrp task profile for tid:%d", t); |
|
||||||
} |
|
||||||
mTidRefCountMap.erase(t); |
|
||||||
} |
|
||||||
} |
|
||||||
mSessions.erase(session); |
|
||||||
} |
|
||||||
|
|
||||||
std::optional<bool> PowerSessionManager::isAnySessionActive() { |
|
||||||
std::lock_guard<std::mutex> guard(mLock); |
|
||||||
bool active = false; |
|
||||||
for (PowerHintSession *s : mSessions) { |
|
||||||
// session active and not stale is actually active.
|
|
||||||
if (s->isActive() && !s->isStale()) { |
|
||||||
active = true; |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
if (active == mActive) { |
|
||||||
return std::nullopt; |
|
||||||
} else { |
|
||||||
mActive = active; |
|
||||||
} |
|
||||||
|
|
||||||
return active; |
|
||||||
} |
|
||||||
|
|
||||||
void PowerSessionManager::handleMessage(const Message &) { |
|
||||||
auto active = isAnySessionActive(); |
|
||||||
if (!active.has_value()) { |
|
||||||
return; |
|
||||||
} |
|
||||||
if (active.value()) { |
|
||||||
disableSystemTopAppBoost(); |
|
||||||
} else { |
|
||||||
enableSystemTopAppBoost(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void PowerSessionManager::enableSystemTopAppBoost() { |
|
||||||
if (mHintManager) { |
|
||||||
ALOGV("PowerSessionManager::enableSystemTopAppBoost!!"); |
|
||||||
mHintManager->EndHint(kDisableBoostHintName); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void PowerSessionManager::disableSystemTopAppBoost() { |
|
||||||
if (mHintManager) { |
|
||||||
ALOGV("PowerSessionManager::disableSystemTopAppBoost!!"); |
|
||||||
mHintManager->DoHint(kDisableBoostHintName); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// =========== PowerHintMonitor implementation start from here ===========
|
|
||||||
void PowerHintMonitor::start() { |
|
||||||
if (!isRunning()) { |
|
||||||
run("PowerHintMonitor", ::android::PRIORITY_HIGHEST); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool PowerHintMonitor::threadLoop() { |
|
||||||
while (true) { |
|
||||||
mLooper->pollOnce(-1); |
|
||||||
} |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
sp<Looper> PowerHintMonitor::getLooper() { |
|
||||||
return mLooper; |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace pixel
|
|
||||||
} // namespace impl
|
|
||||||
} // namespace power
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace google
|
|
||||||
} // namespace aidl
|
|
@ -1,108 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright 2021 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include "PowerHintSession.h" |
|
||||||
|
|
||||||
#include <android-base/properties.h> |
|
||||||
#include <perfmgr/HintManager.h> |
|
||||||
#include <utils/Looper.h> |
|
||||||
|
|
||||||
#include <mutex> |
|
||||||
#include <optional> |
|
||||||
#include <unordered_set> |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace google { |
|
||||||
namespace hardware { |
|
||||||
namespace power { |
|
||||||
namespace impl { |
|
||||||
namespace pixel { |
|
||||||
|
|
||||||
using ::android::Looper; |
|
||||||
using ::android::Message; |
|
||||||
using ::android::MessageHandler; |
|
||||||
using ::android::Thread; |
|
||||||
using ::android::perfmgr::HintManager; |
|
||||||
|
|
||||||
constexpr char kPowerHalAdpfDisableTopAppBoost[] = "vendor.powerhal.adpf.disable.hint"; |
|
||||||
|
|
||||||
class PowerSessionManager : public MessageHandler { |
|
||||||
public: |
|
||||||
// current hint info
|
|
||||||
void updateHintMode(const std::string &mode, bool enabled); |
|
||||||
int getDisplayRefreshRate(); |
|
||||||
// monitoring session status
|
|
||||||
void addPowerSession(PowerHintSession *session); |
|
||||||
void removePowerSession(PowerHintSession *session); |
|
||||||
|
|
||||||
void handleMessage(const Message &message) override; |
|
||||||
void setHintManager(std::shared_ptr<HintManager> const &hint_manager); |
|
||||||
|
|
||||||
// Singleton
|
|
||||||
static sp<PowerSessionManager> getInstance() { |
|
||||||
static sp<PowerSessionManager> instance = new PowerSessionManager(); |
|
||||||
return instance; |
|
||||||
} |
|
||||||
|
|
||||||
private: |
|
||||||
std::optional<bool> isAnySessionActive(); |
|
||||||
void disableSystemTopAppBoost(); |
|
||||||
void enableSystemTopAppBoost(); |
|
||||||
const std::string kDisableBoostHintName; |
|
||||||
std::shared_ptr<HintManager> mHintManager; |
|
||||||
std::unordered_set<PowerHintSession *> mSessions; // protected by mLock
|
|
||||||
std::unordered_map<int, int> mTidRefCountMap; // protected by mLock
|
|
||||||
std::mutex mLock; |
|
||||||
int mDisplayRefreshRate; |
|
||||||
bool mActive; // protected by mLock
|
|
||||||
// Singleton
|
|
||||||
PowerSessionManager() |
|
||||||
: kDisableBoostHintName(::android::base::GetProperty(kPowerHalAdpfDisableTopAppBoost, |
|
||||||
"ADPF_DISABLE_TA_BOOST")), |
|
||||||
mHintManager(nullptr), |
|
||||||
mDisplayRefreshRate(60), |
|
||||||
mActive(false) {} |
|
||||||
PowerSessionManager(PowerSessionManager const &) = delete; |
|
||||||
void operator=(PowerSessionManager const &) = delete; |
|
||||||
}; |
|
||||||
|
|
||||||
class PowerHintMonitor : public Thread { |
|
||||||
public: |
|
||||||
void start(); |
|
||||||
bool threadLoop() override; |
|
||||||
sp<Looper> getLooper(); |
|
||||||
// Singleton
|
|
||||||
static sp<PowerHintMonitor> getInstance() { |
|
||||||
static sp<PowerHintMonitor> instance = new PowerHintMonitor(); |
|
||||||
return instance; |
|
||||||
} |
|
||||||
PowerHintMonitor(PowerHintMonitor const &) = delete; |
|
||||||
void operator=(PowerHintMonitor const &) = delete; |
|
||||||
|
|
||||||
private: |
|
||||||
sp<Looper> mLooper; |
|
||||||
// Singleton
|
|
||||||
PowerHintMonitor() : Thread(false), mLooper(new Looper(true)) {} |
|
||||||
}; |
|
||||||
|
|
||||||
} // namespace pixel
|
|
||||||
} // namespace impl
|
|
||||||
} // namespace power
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace google
|
|
||||||
} // namespace aidl
|
|
@ -1,28 +0,0 @@ |
|||||||
service vendor.power-hal-aidl /vendor/bin/hw/android.hardware.power-service.sm7125-libperfmgr |
|
||||||
class hal |
|
||||||
user root |
|
||||||
group system radio |
|
||||||
priority -20 |
|
||||||
|
|
||||||
on late-fs |
|
||||||
start vendor.power-hal-aidl |
|
||||||
|
|
||||||
# restart powerHAL when framework died |
|
||||||
on property:init.svc.zygote=restarting && property:vendor.powerhal.state=* |
|
||||||
setprop vendor.powerhal.state "" |
|
||||||
setprop vendor.powerhal.audio "" |
|
||||||
setprop vendor.powerhal.rendering "" |
|
||||||
restart vendor.power-hal-aidl |
|
||||||
|
|
||||||
# Clean up after b/163539793 resolved |
|
||||||
on property:vendor.powerhal.dalvik.vm.dex2oat-threads=* |
|
||||||
setprop dalvik.vm.dex2oat-threads ${vendor.powerhal.dalvik.vm.dex2oat-threads} |
|
||||||
setprop dalvik.vm.restore-dex2oat-threads ${vendor.powerhal.dalvik.vm.dex2oat-threads} |
|
||||||
|
|
||||||
on property:vendor.powerhal.dalvik.vm.dex2oat-cpu-set=* |
|
||||||
setprop dalvik.vm.dex2oat-cpu-set ${vendor.powerhal.dalvik.vm.dex2oat-cpu-set} |
|
||||||
setprop dalvik.vm.restore-dex2oat-cpu-set ${vendor.powerhal.dalvik.vm.dex2oat-cpu-set} |
|
||||||
|
|
||||||
# initialize powerHAL when boot is completed |
|
||||||
on property:sys.boot_completed=1 |
|
||||||
setprop vendor.powerhal.init 1 |
|
@ -1,7 +0,0 @@ |
|||||||
<manifest version="1.0" type="device"> |
|
||||||
<hal format="aidl" override="true"> |
|
||||||
<name>android.hardware.power</name> |
|
||||||
<version>2</version> |
|
||||||
<fqname>IPower/default</fqname> |
|
||||||
</hal> |
|
||||||
</manifest> |
|
@ -1,441 +0,0 @@ |
|||||||
{ |
|
||||||
"Nodes": [ |
|
||||||
{ |
|
||||||
"Name": "CPULittleClusterMaxFreq", |
|
||||||
"Path": "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", |
|
||||||
"Values": [ |
|
||||||
"9999999", |
|
||||||
"1113600" |
|
||||||
], |
|
||||||
"DefaultIndex": 0, |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "CPULittleClusterMinFreq", |
|
||||||
"Path": "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", |
|
||||||
"Values": [ |
|
||||||
"9999999", |
|
||||||
"1113600", |
|
||||||
"576000" |
|
||||||
], |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "CPUBigClusterMaxFreq", |
|
||||||
"Path": "/sys/devices/system/cpu/cpu4/cpufreq/scaling_max_freq", |
|
||||||
"Values": [ |
|
||||||
"9999999", |
|
||||||
"2016000", |
|
||||||
"1497600", |
|
||||||
"1401600" |
|
||||||
], |
|
||||||
"DefaultIndex": 0, |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "CPUBigClusterMinFreq", |
|
||||||
"Path": "/sys/devices/system/cpu/cpu4/cpufreq/scaling_min_freq", |
|
||||||
"Values": [ |
|
||||||
"9999999", |
|
||||||
"1497600", |
|
||||||
"1401600", |
|
||||||
"1286400", |
|
||||||
"0" |
|
||||||
], |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "CPUBigPlusClusterMaxFreq", |
|
||||||
"Path": "/sys/devices/system/cpu/cpu7/cpufreq/scaling_max_freq", |
|
||||||
"Values": [ |
|
||||||
"9999999", |
|
||||||
"2016000", |
|
||||||
"1497600", |
|
||||||
"1401600" |
|
||||||
], |
|
||||||
"DefaultIndex": 0, |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "CPUBigPlusClusterMinFreq", |
|
||||||
"Path": "/sys/devices/system/cpu/cpu7/cpufreq/scaling_min_freq", |
|
||||||
"Values": [ |
|
||||||
"9999999", |
|
||||||
"1497600", |
|
||||||
"1401600", |
|
||||||
"1286400", |
|
||||||
"0" |
|
||||||
], |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "GPUMaxFreq", |
|
||||||
"Path": "/sys/class/kgsl/kgsl-3d0/devfreq/max_freq", |
|
||||||
"Values": [ |
|
||||||
"585000000", |
|
||||||
"427000000" |
|
||||||
], |
|
||||||
"DefaultIndex": 0, |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "GPUMinFreq", |
|
||||||
"Path": "/sys/class/kgsl/kgsl-3d0/devfreq/min_freq", |
|
||||||
"Values": [ |
|
||||||
"585000000", |
|
||||||
"427000000", |
|
||||||
"345000000", |
|
||||||
"257000000" |
|
||||||
], |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "TASchedtuneBoost", |
|
||||||
"Path": "/dev/stune/top-app/schedtune.boost", |
|
||||||
"Values": [ |
|
||||||
"30", |
|
||||||
"10" |
|
||||||
], |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "PMQoSCpuDmaLatency", |
|
||||||
"Path": "/dev/cpu_dma_latency", |
|
||||||
"Values": [ |
|
||||||
"44", |
|
||||||
"100" |
|
||||||
], |
|
||||||
"HoldFd": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "TouchscreenEnable", |
|
||||||
"Path": "/sys/class/input/input3/enabled", |
|
||||||
"Values": [ |
|
||||||
"1", |
|
||||||
"0" |
|
||||||
], |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "DoubleTapToWakeEnable", |
|
||||||
"Path": "/sys/class/sec/tsp/cmd", |
|
||||||
"Values": [ |
|
||||||
"aot_enable,0", |
|
||||||
"aot_enable,1" |
|
||||||
], |
|
||||||
"DefaultIndex": 0 |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "PowerHALMainState", |
|
||||||
"Path": "vendor.powerhal.state", |
|
||||||
"Values": [ |
|
||||||
"SUSTAINED_PERFORMANCE", |
|
||||||
"VR_MODE", |
|
||||||
"VR_SUSTAINED_PERFORMANCE", |
|
||||||
"" |
|
||||||
], |
|
||||||
"Type": "Property" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "PowerHALAudioState", |
|
||||||
"Path": "vendor.powerhal.audio", |
|
||||||
"Values": [ |
|
||||||
"AUDIO_STREAMING_LOW_LATENCY", |
|
||||||
"" |
|
||||||
], |
|
||||||
"Type": "Property" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "PowerHALRenderingState", |
|
||||||
"Path": "vendor.powerhal.rendering", |
|
||||||
"Values": [ |
|
||||||
"EXPENSIVE_RENDERING", |
|
||||||
"" |
|
||||||
], |
|
||||||
"Type": "Property" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "PowerHALPerfProfileState", |
|
||||||
"Path": "vendor.powerhal.perf_profile", |
|
||||||
"Values": [ |
|
||||||
"POWER_SAVE", |
|
||||||
"BIAS_POWER_SAVE", |
|
||||||
"BIAS_PERFORMANCE", |
|
||||||
"HIGH_PERFORMANCE" |
|
||||||
], |
|
||||||
"Type": "Property" |
|
||||||
} |
|
||||||
], |
|
||||||
"Actions": [ |
|
||||||
{ |
|
||||||
"PowerHint": "INTERACTION", |
|
||||||
"Node": "CPUBigClusterMinFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "1286400" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "INTERACTION", |
|
||||||
"Node": "CPUBigPlusClusterMinFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "1286400" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "INTERACTION", |
|
||||||
"Node": "CPULittleClusterMinFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "1113600" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "INTERACTION", |
|
||||||
"Node": "TASchedtuneBoost", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "30" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "LAUNCH", |
|
||||||
"Node": "CPUBigClusterMaxFreq", |
|
||||||
"Duration": 5000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "LAUNCH", |
|
||||||
"Node": "CPUBigPlusClusterMaxFreq", |
|
||||||
"Duration": 5000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "LAUNCH", |
|
||||||
"Node": "CPUBigClusterMinFreq", |
|
||||||
"Duration": 5000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "LAUNCH", |
|
||||||
"Node": "CPUBigPlusClusterMinFreq", |
|
||||||
"Duration": 5000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "LAUNCH", |
|
||||||
"Node": "CPULittleClusterMinFreq", |
|
||||||
"Duration": 5000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "LAUNCH", |
|
||||||
"Node": "PMQoSCpuDmaLatency", |
|
||||||
"Duration": 5000, |
|
||||||
"Value": "44" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_LAUNCH", |
|
||||||
"Node": "CPUBigClusterMaxFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_LAUNCH", |
|
||||||
"Node": "CPUBigPlusClusterMaxFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_LAUNCH", |
|
||||||
"Node": "CPUBigClusterMinFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_LAUNCH", |
|
||||||
"Node": "CPUBigPlusClusterMinFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_LAUNCH", |
|
||||||
"Node": "CPULittleClusterMaxFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_LAUNCH", |
|
||||||
"Node": "CPULittleClusterMinFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_LAUNCH", |
|
||||||
"Node": "PMQoSCpuDmaLatency", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "44" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_STREAMING_MID", |
|
||||||
"Node": "CPUBigClusterMaxFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "2016000" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_STREAMING_MID", |
|
||||||
"Node": "CPUBigPlusClusterMaxFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "2016000" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_SHOT", |
|
||||||
"Node": "CPUBigClusterMaxFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_SHOT", |
|
||||||
"Node": "CPUBigPlusClusterMaxFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_SHOT", |
|
||||||
"Node": "CPUBigClusterMinFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_SHOT", |
|
||||||
"Node": "CPUBigPlusClusterMinFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_SHOT", |
|
||||||
"Node": "CPULittleClusterMaxFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_SHOT", |
|
||||||
"Node": "CPULittleClusterMinFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_SHOT", |
|
||||||
"Node": "PMQoSCpuDmaLatency", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "44" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "AUDIO_LAUNCH", |
|
||||||
"Node": "PMQoSCpuDmaLatency", |
|
||||||
"Duration": 2000, |
|
||||||
"Value": "44" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "AUDIO_STREAMING_LOW_LATENCY", |
|
||||||
"Node": "PowerHALAudioState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "AUDIO_STREAMING_LOW_LATENCY" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "AUDIO_STREAMING_LOW_LATENCY", |
|
||||||
"Node": "PMQoSCpuDmaLatency", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "44" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "SUSTAINED_PERFORMANCE", |
|
||||||
"Node": "PowerHALMainState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "SUSTAINED_PERFORMANCE" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "SUSTAINED_PERFORMANCE", |
|
||||||
"Node": "CPUBigClusterMaxFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "1401600" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "SUSTAINED_PERFORMANCE", |
|
||||||
"Node": "CPUBigPlusClusterMaxFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "1401600" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "SUSTAINED_PERFORMANCE", |
|
||||||
"Node": "CPULittleClusterMaxFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "1113600" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "SUSTAINED_PERFORMANCE", |
|
||||||
"Node": "GPUMaxFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "427000000" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "VR_MODE", |
|
||||||
"Node": "PowerHALMainState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "VR_MODE" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "VR_SUSTAINED_PERFORMANCE", |
|
||||||
"Node": "PowerHALMainState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "VR_SUSTAINED_PERFORMANCE" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "EXPENSIVE_RENDERING", |
|
||||||
"Node": "PowerHALRenderingState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "EXPENSIVE_RENDERING" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "EXPENSIVE_RENDERING", |
|
||||||
"Node": "GPUMinFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "427000000" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "EXPENSIVE_RENDERING", |
|
||||||
"Node": "GPUMaxFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "585000000" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "INTERACTIVE", |
|
||||||
"Node": "TouchscreenEnable", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "1" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "DOUBLE_TAP_TO_WAKE", |
|
||||||
"Node": "DoubleTapToWakeEnable", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "aot_enable,1" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "PROFILE_POWER_SAVE", |
|
||||||
"Node": "PowerHALPerfProfileState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "POWER_SAVE" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "PROFILE_BIAS_POWER_SAVE", |
|
||||||
"Node": "PowerHALPerfProfileState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "BIAS_POWER_SAVE" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "PROFILE_BIAS_PERFORMANCE", |
|
||||||
"Node": "PowerHALPerfProfileState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "BIAS_PERFORMANCE" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "PROFILE_HIGH_PERFORMANCE", |
|
||||||
"Node": "PowerHALPerfProfileState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "HIGH_PERFORMANCE" |
|
||||||
} |
|
||||||
] |
|
||||||
} |
|
@ -1,87 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2020 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#define LOG_TAG "powerhal-libperfmgr" |
|
||||||
|
|
||||||
#include <thread> |
|
||||||
|
|
||||||
#include <android-base/logging.h> |
|
||||||
#include <android-base/properties.h> |
|
||||||
#include <android/binder_manager.h> |
|
||||||
#include <android/binder_process.h> |
|
||||||
|
|
||||||
#include "Power.h" |
|
||||||
#include "PowerExt.h" |
|
||||||
#include "PowerSessionManager.h" |
|
||||||
|
|
||||||
using aidl::google::hardware::power::impl::pixel::Power; |
|
||||||
using aidl::google::hardware::power::impl::pixel::PowerExt; |
|
||||||
using aidl::google::hardware::power::impl::pixel::PowerHintMonitor; |
|
||||||
using aidl::google::hardware::power::impl::pixel::PowerSessionManager; |
|
||||||
using ::android::perfmgr::HintManager; |
|
||||||
|
|
||||||
constexpr std::string_view kPowerHalInitProp("vendor.powerhal.init"); |
|
||||||
constexpr std::string_view kConfigProperty("vendor.powerhal.config"); |
|
||||||
constexpr std::string_view kConfigDefaultFileName("powerhint.json"); |
|
||||||
|
|
||||||
int main() { |
|
||||||
const std::string config_path = |
|
||||||
"/vendor/etc/" + |
|
||||||
android::base::GetProperty(kConfigProperty.data(), kConfigDefaultFileName.data()); |
|
||||||
LOG(INFO) << "Pixel Power HAL AIDL Service with Extension is starting with config: " |
|
||||||
<< config_path; |
|
||||||
|
|
||||||
// Parse config but do not start the looper
|
|
||||||
std::shared_ptr<HintManager> hm = HintManager::GetFromJSON(config_path, false); |
|
||||||
if (!hm) { |
|
||||||
LOG(FATAL) << "Invalid config: " << config_path; |
|
||||||
} |
|
||||||
|
|
||||||
// single thread
|
|
||||||
ABinderProcess_setThreadPoolMaxThreadCount(0); |
|
||||||
|
|
||||||
// core service
|
|
||||||
std::shared_ptr<Power> pw = ndk::SharedRefBase::make<Power>(hm); |
|
||||||
ndk::SpAIBinder pwBinder = pw->asBinder(); |
|
||||||
|
|
||||||
// extension service
|
|
||||||
std::shared_ptr<PowerExt> pwExt = ndk::SharedRefBase::make<PowerExt>(hm); |
|
||||||
|
|
||||||
// attach the extension to the same binder we will be registering
|
|
||||||
CHECK(STATUS_OK == AIBinder_setExtension(pwBinder.get(), pwExt->asBinder().get())); |
|
||||||
|
|
||||||
const std::string instance = std::string() + Power::descriptor + "/default"; |
|
||||||
binder_status_t status = AServiceManager_addService(pw->asBinder().get(), instance.c_str()); |
|
||||||
CHECK(status == STATUS_OK); |
|
||||||
LOG(INFO) << "Pixel Power HAL AIDL Service with Extension is started."; |
|
||||||
|
|
||||||
if (::android::base::GetIntProperty("vendor.powerhal.adpf.rate", -1) != -1) { |
|
||||||
PowerHintMonitor::getInstance()->start(); |
|
||||||
PowerSessionManager::getInstance()->setHintManager(hm); |
|
||||||
} |
|
||||||
|
|
||||||
std::thread initThread([&]() { |
|
||||||
::android::base::WaitForProperty(kPowerHalInitProp.data(), "1"); |
|
||||||
hm->Start(); |
|
||||||
}); |
|
||||||
initThread.detach(); |
|
||||||
|
|
||||||
ABinderProcess_joinThreadPool(); |
|
||||||
|
|
||||||
// should not reach
|
|
||||||
LOG(ERROR) << "Pixel Power HAL AIDL Service with Extension just died."; |
|
||||||
return EXIT_FAILURE; |
|
||||||
} |
|
@ -1,53 +0,0 @@ |
|||||||
// |
|
||||||
// Copyright (C) 2020 The Android Open Source Project |
|
||||||
// |
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
// you may not use this file except in compliance with the License. |
|
||||||
// You may obtain a copy of the License at |
|
||||||
// |
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0 |
|
||||||
// |
|
||||||
// Unless required by applicable law or agreed to in writing, software |
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
// See the License for the specific language governing permissions and |
|
||||||
// limitations under the License. |
|
||||||
|
|
||||||
cc_binary { |
|
||||||
name: "android.hardware.sensors-service.sm7125-multihal", |
|
||||||
defaults: [ |
|
||||||
"hidl_defaults", |
|
||||||
], |
|
||||||
vendor: true, |
|
||||||
relative_install_path: "hw", |
|
||||||
srcs: [ |
|
||||||
"ConvertUtils.cpp", |
|
||||||
"HalProxyAidl.cpp", |
|
||||||
"service.cpp", |
|
||||||
], |
|
||||||
local_include_dirs: ["include"], |
|
||||||
init_rc: ["android.hardware.sensors-service.sm7125-multihal.rc"], |
|
||||||
vintf_fragments: ["android.hardware.sensors-sm7125-multihal.xml"], |
|
||||||
header_libs: [ |
|
||||||
"android.hardware.sensors@2.X-shared-utils", |
|
||||||
], |
|
||||||
shared_libs: [ |
|
||||||
"android.hardware.sensors@2.0", |
|
||||||
"android.hardware.sensors@2.0-ScopedWakelock", |
|
||||||
"android.hardware.sensors@2.1", |
|
||||||
"android.hardware.sensors-V1-ndk", |
|
||||||
"libbase", |
|
||||||
"libbinder_ndk", |
|
||||||
"libcutils", |
|
||||||
"libfmq", |
|
||||||
"libhidlbase", |
|
||||||
"liblog", |
|
||||||
"libpower", |
|
||||||
"libutils", |
|
||||||
], |
|
||||||
static_libs: [ |
|
||||||
"android.hardware.sensors@1.0-convert", |
|
||||||
"android.hardware.sensors@2.X-multihal", |
|
||||||
"libaidlcommonsupport", |
|
||||||
], |
|
||||||
} |
|
@ -1,363 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2021 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include "ConvertUtils.h" |
|
||||||
#include <android-base/logging.h> |
|
||||||
#include <log/log.h> |
|
||||||
|
|
||||||
using AidlSensorInfo = ::aidl::android::hardware::sensors::SensorInfo; |
|
||||||
using AidlSensorType = ::aidl::android::hardware::sensors::SensorType; |
|
||||||
using AidlEvent = ::aidl::android::hardware::sensors::Event; |
|
||||||
using AidlSensorStatus = ::aidl::android::hardware::sensors::SensorStatus; |
|
||||||
using ::aidl::android::hardware::sensors::AdditionalInfo; |
|
||||||
using ::aidl::android::hardware::sensors::DynamicSensorInfo; |
|
||||||
using ::android::hardware::sensors::V1_0::MetaDataEventType; |
|
||||||
using V1_0SensorStatus = ::android::hardware::sensors::V1_0::SensorStatus; |
|
||||||
using ::android::hardware::sensors::V1_0::AdditionalInfoType; |
|
||||||
using V2_1SensorInfo = ::android::hardware::sensors::V2_1::SensorInfo; |
|
||||||
using V2_1Event = ::android::hardware::sensors::V2_1::Event; |
|
||||||
using V2_1SensorType = ::android::hardware::sensors::V2_1::SensorType; |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace android { |
|
||||||
namespace hardware { |
|
||||||
namespace sensors { |
|
||||||
namespace implementation { |
|
||||||
|
|
||||||
AidlSensorInfo convertSensorInfo(const V2_1SensorInfo& sensorInfo) { |
|
||||||
AidlSensorInfo aidlSensorInfo; |
|
||||||
aidlSensorInfo.sensorHandle = sensorInfo.sensorHandle; |
|
||||||
aidlSensorInfo.name = sensorInfo.name; |
|
||||||
aidlSensorInfo.vendor = sensorInfo.vendor; |
|
||||||
aidlSensorInfo.version = sensorInfo.version; |
|
||||||
aidlSensorInfo.type = (AidlSensorType)sensorInfo.type; |
|
||||||
aidlSensorInfo.typeAsString = sensorInfo.typeAsString; |
|
||||||
aidlSensorInfo.maxRange = sensorInfo.maxRange; |
|
||||||
aidlSensorInfo.resolution = sensorInfo.resolution; |
|
||||||
aidlSensorInfo.power = sensorInfo.power; |
|
||||||
aidlSensorInfo.minDelayUs = sensorInfo.minDelay; |
|
||||||
aidlSensorInfo.fifoReservedEventCount = sensorInfo.fifoReservedEventCount; |
|
||||||
aidlSensorInfo.fifoMaxEventCount = sensorInfo.fifoMaxEventCount; |
|
||||||
aidlSensorInfo.requiredPermission = sensorInfo.requiredPermission; |
|
||||||
aidlSensorInfo.maxDelayUs = sensorInfo.maxDelay; |
|
||||||
aidlSensorInfo.flags = sensorInfo.flags; |
|
||||||
return aidlSensorInfo; |
|
||||||
} |
|
||||||
|
|
||||||
void convertToHidlEvent(const AidlEvent& aidlEvent, V2_1Event* hidlEvent) { |
|
||||||
static_assert(decltype(hidlEvent->u.data)::elementCount() == 16); |
|
||||||
hidlEvent->timestamp = aidlEvent.timestamp; |
|
||||||
hidlEvent->sensorHandle = aidlEvent.sensorHandle; |
|
||||||
hidlEvent->sensorType = (V2_1SensorType)aidlEvent.sensorType; |
|
||||||
|
|
||||||
switch (aidlEvent.sensorType) { |
|
||||||
case AidlSensorType::META_DATA: |
|
||||||
hidlEvent->u.meta.what = |
|
||||||
(MetaDataEventType)aidlEvent.payload.get<Event::EventPayload::meta>().what; |
|
||||||
break; |
|
||||||
case AidlSensorType::ACCELEROMETER: |
|
||||||
case AidlSensorType::MAGNETIC_FIELD: |
|
||||||
case AidlSensorType::ORIENTATION: |
|
||||||
case AidlSensorType::GYROSCOPE: |
|
||||||
case AidlSensorType::GRAVITY: |
|
||||||
case AidlSensorType::LINEAR_ACCELERATION: |
|
||||||
hidlEvent->u.vec3.x = aidlEvent.payload.get<Event::EventPayload::vec3>().x; |
|
||||||
hidlEvent->u.vec3.y = aidlEvent.payload.get<Event::EventPayload::vec3>().y; |
|
||||||
hidlEvent->u.vec3.z = aidlEvent.payload.get<Event::EventPayload::vec3>().z; |
|
||||||
hidlEvent->u.vec3.status = |
|
||||||
(V1_0SensorStatus)aidlEvent.payload.get<Event::EventPayload::vec3>().status; |
|
||||||
break; |
|
||||||
case AidlSensorType::GAME_ROTATION_VECTOR: |
|
||||||
hidlEvent->u.vec4.x = aidlEvent.payload.get<Event::EventPayload::vec4>().x; |
|
||||||
hidlEvent->u.vec4.y = aidlEvent.payload.get<Event::EventPayload::vec4>().y; |
|
||||||
hidlEvent->u.vec4.z = aidlEvent.payload.get<Event::EventPayload::vec4>().z; |
|
||||||
hidlEvent->u.vec4.w = aidlEvent.payload.get<Event::EventPayload::vec4>().w; |
|
||||||
break; |
|
||||||
case AidlSensorType::ROTATION_VECTOR: |
|
||||||
case AidlSensorType::GEOMAGNETIC_ROTATION_VECTOR: |
|
||||||
std::copy(aidlEvent.payload.get<Event::EventPayload::data>().values.data(), |
|
||||||
aidlEvent.payload.get<Event::EventPayload::data>().values.data() + 5, |
|
||||||
hidlEvent->u.data.data()); |
|
||||||
break; |
|
||||||
case AidlSensorType::ACCELEROMETER_UNCALIBRATED: |
|
||||||
case AidlSensorType::MAGNETIC_FIELD_UNCALIBRATED: |
|
||||||
case AidlSensorType::GYROSCOPE_UNCALIBRATED: |
|
||||||
hidlEvent->u.uncal.x = aidlEvent.payload.get<Event::EventPayload::uncal>().x; |
|
||||||
hidlEvent->u.uncal.y = aidlEvent.payload.get<Event::EventPayload::uncal>().y; |
|
||||||
hidlEvent->u.uncal.z = aidlEvent.payload.get<Event::EventPayload::uncal>().z; |
|
||||||
hidlEvent->u.uncal.x_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().xBias; |
|
||||||
hidlEvent->u.uncal.y_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().yBias; |
|
||||||
hidlEvent->u.uncal.z_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().zBias; |
|
||||||
break; |
|
||||||
case AidlSensorType::DEVICE_ORIENTATION: |
|
||||||
case AidlSensorType::LIGHT: |
|
||||||
case AidlSensorType::PRESSURE: |
|
||||||
case AidlSensorType::PROXIMITY: |
|
||||||
case AidlSensorType::RELATIVE_HUMIDITY: |
|
||||||
case AidlSensorType::AMBIENT_TEMPERATURE: |
|
||||||
case AidlSensorType::SIGNIFICANT_MOTION: |
|
||||||
case AidlSensorType::STEP_DETECTOR: |
|
||||||
case AidlSensorType::TILT_DETECTOR: |
|
||||||
case AidlSensorType::WAKE_GESTURE: |
|
||||||
case AidlSensorType::GLANCE_GESTURE: |
|
||||||
case AidlSensorType::PICK_UP_GESTURE: |
|
||||||
case AidlSensorType::WRIST_TILT_GESTURE: |
|
||||||
case AidlSensorType::STATIONARY_DETECT: |
|
||||||
case AidlSensorType::MOTION_DETECT: |
|
||||||
case AidlSensorType::HEART_BEAT: |
|
||||||
case AidlSensorType::LOW_LATENCY_OFFBODY_DETECT: |
|
||||||
case AidlSensorType::HINGE_ANGLE: |
|
||||||
hidlEvent->u.scalar = aidlEvent.payload.get<Event::EventPayload::scalar>(); |
|
||||||
break; |
|
||||||
case AidlSensorType::STEP_COUNTER: |
|
||||||
hidlEvent->u.stepCount = aidlEvent.payload.get<AidlEvent::EventPayload::stepCount>(); |
|
||||||
break; |
|
||||||
case AidlSensorType::HEART_RATE: |
|
||||||
hidlEvent->u.heartRate.bpm = |
|
||||||
aidlEvent.payload.get<AidlEvent::EventPayload::heartRate>().bpm; |
|
||||||
hidlEvent->u.heartRate.status = |
|
||||||
(V1_0SensorStatus)aidlEvent.payload.get<Event::EventPayload::heartRate>() |
|
||||||
.status; |
|
||||||
break; |
|
||||||
case AidlSensorType::POSE_6DOF: |
|
||||||
std::copy(std::begin(aidlEvent.payload.get<AidlEvent::EventPayload::pose6DOF>().values), |
|
||||||
std::end(aidlEvent.payload.get<AidlEvent::EventPayload::pose6DOF>().values), |
|
||||||
hidlEvent->u.pose6DOF.data()); |
|
||||||
break; |
|
||||||
case AidlSensorType::DYNAMIC_SENSOR_META: |
|
||||||
hidlEvent->u.dynamic.connected = |
|
||||||
aidlEvent.payload.get<Event::EventPayload::dynamic>().connected; |
|
||||||
hidlEvent->u.dynamic.sensorHandle = |
|
||||||
aidlEvent.payload.get<Event::EventPayload::dynamic>().sensorHandle; |
|
||||||
std::copy( |
|
||||||
std::begin( |
|
||||||
aidlEvent.payload.get<AidlEvent::EventPayload::dynamic>().uuid.values), |
|
||||||
std::end(aidlEvent.payload.get<AidlEvent::EventPayload::dynamic>().uuid.values), |
|
||||||
hidlEvent->u.dynamic.uuid.data()); |
|
||||||
break; |
|
||||||
case AidlSensorType::ADDITIONAL_INFO: { |
|
||||||
const AdditionalInfo& additionalInfo = |
|
||||||
aidlEvent.payload.get<AidlEvent::EventPayload::additional>(); |
|
||||||
hidlEvent->u.additional.type = (AdditionalInfoType)additionalInfo.type; |
|
||||||
hidlEvent->u.additional.serial = additionalInfo.serial; |
|
||||||
|
|
||||||
switch (additionalInfo.payload.getTag()) { |
|
||||||
case AdditionalInfo::AdditionalInfoPayload::Tag::dataInt32: { |
|
||||||
const auto& aidlData = |
|
||||||
additionalInfo.payload |
|
||||||
.get<AdditionalInfo::AdditionalInfoPayload::dataInt32>() |
|
||||||
.values; |
|
||||||
std::copy(std::begin(aidlData), std::end(aidlData), |
|
||||||
hidlEvent->u.additional.u.data_int32.data()); |
|
||||||
break; |
|
||||||
} |
|
||||||
case AdditionalInfo::AdditionalInfoPayload::Tag::dataFloat: { |
|
||||||
const auto& aidlData = |
|
||||||
additionalInfo.payload |
|
||||||
.get<AdditionalInfo::AdditionalInfoPayload::dataFloat>() |
|
||||||
.values; |
|
||||||
std::copy(std::begin(aidlData), std::end(aidlData), |
|
||||||
hidlEvent->u.additional.u.data_float.data()); |
|
||||||
break; |
|
||||||
} |
|
||||||
default: |
|
||||||
ALOGE("Invalid sensor additioanl info tag: %d", |
|
||||||
static_cast<int32_t>(additionalInfo.payload.getTag())); |
|
||||||
break; |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
case AidlSensorType::HEAD_TRACKER: { |
|
||||||
const auto& ht = aidlEvent.payload.get<Event::EventPayload::headTracker>(); |
|
||||||
hidlEvent->u.data[0] = ht.rx; |
|
||||||
hidlEvent->u.data[1] = ht.ry; |
|
||||||
hidlEvent->u.data[2] = ht.rz; |
|
||||||
hidlEvent->u.data[3] = ht.vx; |
|
||||||
hidlEvent->u.data[4] = ht.vy; |
|
||||||
hidlEvent->u.data[5] = ht.vz; |
|
||||||
|
|
||||||
// IMPORTANT: Because we want to preserve the data range of discontinuityCount,
|
|
||||||
// we assume the data can be interpreted as an int32_t directly (e.g. the underlying
|
|
||||||
// HIDL HAL must be using memcpy or equivalent to store this value).
|
|
||||||
*(reinterpret_cast<int32_t*>(&hidlEvent->u.data[6])) = ht.discontinuityCount; |
|
||||||
break; |
|
||||||
} |
|
||||||
default: { |
|
||||||
CHECK_GE((int32_t)aidlEvent.sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE); |
|
||||||
std::copy(std::begin(aidlEvent.payload.get<AidlEvent::EventPayload::data>().values), |
|
||||||
std::end(aidlEvent.payload.get<AidlEvent::EventPayload::data>().values), |
|
||||||
hidlEvent->u.data.data()); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void convertToAidlEvent(const V2_1Event& hidlEvent, AidlEvent* aidlEvent) { |
|
||||||
static_assert(decltype(hidlEvent.u.data)::elementCount() == 16); |
|
||||||
aidlEvent->timestamp = hidlEvent.timestamp; |
|
||||||
aidlEvent->sensorHandle = hidlEvent.sensorHandle; |
|
||||||
aidlEvent->sensorType = (AidlSensorType)hidlEvent.sensorType; |
|
||||||
switch (hidlEvent.sensorType) { |
|
||||||
case V2_1SensorType::META_DATA: { |
|
||||||
AidlEvent::EventPayload::MetaData meta; |
|
||||||
meta.what = (Event::EventPayload::MetaData::MetaDataEventType)hidlEvent.u.meta.what; |
|
||||||
aidlEvent->payload.set<Event::EventPayload::meta>(meta); |
|
||||||
break; |
|
||||||
} |
|
||||||
case V2_1SensorType::ACCELEROMETER: |
|
||||||
case V2_1SensorType::MAGNETIC_FIELD: |
|
||||||
case V2_1SensorType::ORIENTATION: |
|
||||||
case V2_1SensorType::GYROSCOPE: |
|
||||||
case V2_1SensorType::GRAVITY: |
|
||||||
case V2_1SensorType::LINEAR_ACCELERATION: { |
|
||||||
AidlEvent::EventPayload::Vec3 vec3; |
|
||||||
vec3.x = hidlEvent.u.vec3.x; |
|
||||||
vec3.y = hidlEvent.u.vec3.y; |
|
||||||
vec3.z = hidlEvent.u.vec3.z; |
|
||||||
vec3.status = (SensorStatus)hidlEvent.u.vec3.status; |
|
||||||
aidlEvent->payload.set<Event::EventPayload::vec3>(vec3); |
|
||||||
break; |
|
||||||
} |
|
||||||
case V2_1SensorType::GAME_ROTATION_VECTOR: { |
|
||||||
AidlEvent::EventPayload::Vec4 vec4; |
|
||||||
vec4.x = hidlEvent.u.vec4.x; |
|
||||||
vec4.y = hidlEvent.u.vec4.y; |
|
||||||
vec4.z = hidlEvent.u.vec4.z; |
|
||||||
vec4.w = hidlEvent.u.vec4.w; |
|
||||||
aidlEvent->payload.set<Event::EventPayload::vec4>(vec4); |
|
||||||
break; |
|
||||||
} |
|
||||||
case V2_1SensorType::ROTATION_VECTOR: |
|
||||||
case V2_1SensorType::GEOMAGNETIC_ROTATION_VECTOR: { |
|
||||||
AidlEvent::EventPayload::Data data; |
|
||||||
std::copy(hidlEvent.u.data.data(), hidlEvent.u.data.data() + 5, |
|
||||||
std::begin(data.values)); |
|
||||||
aidlEvent->payload.set<Event::EventPayload::data>(data); |
|
||||||
break; |
|
||||||
} |
|
||||||
case V2_1SensorType::MAGNETIC_FIELD_UNCALIBRATED: |
|
||||||
case V2_1SensorType::GYROSCOPE_UNCALIBRATED: |
|
||||||
case V2_1SensorType::ACCELEROMETER_UNCALIBRATED: { |
|
||||||
AidlEvent::EventPayload::Uncal uncal; |
|
||||||
uncal.x = hidlEvent.u.uncal.x; |
|
||||||
uncal.y = hidlEvent.u.uncal.y; |
|
||||||
uncal.z = hidlEvent.u.uncal.z; |
|
||||||
uncal.xBias = hidlEvent.u.uncal.x_bias; |
|
||||||
uncal.yBias = hidlEvent.u.uncal.y_bias; |
|
||||||
uncal.zBias = hidlEvent.u.uncal.z_bias; |
|
||||||
aidlEvent->payload.set<Event::EventPayload::uncal>(uncal); |
|
||||||
break; |
|
||||||
} |
|
||||||
case V2_1SensorType::DEVICE_ORIENTATION: |
|
||||||
case V2_1SensorType::LIGHT: |
|
||||||
case V2_1SensorType::PRESSURE: |
|
||||||
case V2_1SensorType::PROXIMITY: |
|
||||||
case V2_1SensorType::RELATIVE_HUMIDITY: |
|
||||||
case V2_1SensorType::AMBIENT_TEMPERATURE: |
|
||||||
case V2_1SensorType::SIGNIFICANT_MOTION: |
|
||||||
case V2_1SensorType::STEP_DETECTOR: |
|
||||||
case V2_1SensorType::TILT_DETECTOR: |
|
||||||
case V2_1SensorType::WAKE_GESTURE: |
|
||||||
case V2_1SensorType::GLANCE_GESTURE: |
|
||||||
case V2_1SensorType::PICK_UP_GESTURE: |
|
||||||
case V2_1SensorType::WRIST_TILT_GESTURE: |
|
||||||
case V2_1SensorType::STATIONARY_DETECT: |
|
||||||
case V2_1SensorType::MOTION_DETECT: |
|
||||||
case V2_1SensorType::HEART_BEAT: |
|
||||||
case V2_1SensorType::LOW_LATENCY_OFFBODY_DETECT: |
|
||||||
case V2_1SensorType::HINGE_ANGLE: |
|
||||||
aidlEvent->payload.set<Event::EventPayload::scalar>(hidlEvent.u.scalar); |
|
||||||
break; |
|
||||||
case V2_1SensorType::STEP_COUNTER: |
|
||||||
aidlEvent->payload.set<Event::EventPayload::stepCount>(hidlEvent.u.stepCount); |
|
||||||
break; |
|
||||||
case V2_1SensorType::HEART_RATE: { |
|
||||||
AidlEvent::EventPayload::HeartRate heartRate; |
|
||||||
heartRate.bpm = hidlEvent.u.heartRate.bpm; |
|
||||||
heartRate.status = (SensorStatus)hidlEvent.u.heartRate.status; |
|
||||||
aidlEvent->payload.set<Event::EventPayload::heartRate>(heartRate); |
|
||||||
break; |
|
||||||
} |
|
||||||
case V2_1SensorType::POSE_6DOF: { |
|
||||||
AidlEvent::EventPayload::Pose6Dof pose6Dof; |
|
||||||
std::copy(hidlEvent.u.pose6DOF.data(), |
|
||||||
hidlEvent.u.pose6DOF.data() + hidlEvent.u.pose6DOF.size(), |
|
||||||
std::begin(pose6Dof.values)); |
|
||||||
aidlEvent->payload.set<Event::EventPayload::pose6DOF>(pose6Dof); |
|
||||||
break; |
|
||||||
} |
|
||||||
case V2_1SensorType::DYNAMIC_SENSOR_META: { |
|
||||||
DynamicSensorInfo dynamicSensorInfo; |
|
||||||
dynamicSensorInfo.connected = hidlEvent.u.dynamic.connected; |
|
||||||
dynamicSensorInfo.sensorHandle = hidlEvent.u.dynamic.sensorHandle; |
|
||||||
std::copy(hidlEvent.u.dynamic.uuid.data(), |
|
||||||
hidlEvent.u.dynamic.uuid.data() + hidlEvent.u.dynamic.uuid.size(), |
|
||||||
std::begin(dynamicSensorInfo.uuid.values)); |
|
||||||
aidlEvent->payload.set<Event::EventPayload::dynamic>(dynamicSensorInfo); |
|
||||||
break; |
|
||||||
} |
|
||||||
case V2_1SensorType::ADDITIONAL_INFO: { |
|
||||||
AdditionalInfo additionalInfo; |
|
||||||
additionalInfo.type = (AdditionalInfo::AdditionalInfoType)hidlEvent.u.additional.type; |
|
||||||
additionalInfo.serial = hidlEvent.u.additional.serial; |
|
||||||
|
|
||||||
AdditionalInfo::AdditionalInfoPayload::Int32Values int32Values; |
|
||||||
std::copy(hidlEvent.u.additional.u.data_int32.data(), |
|
||||||
hidlEvent.u.additional.u.data_int32.data() + |
|
||||||
hidlEvent.u.additional.u.data_int32.size(), |
|
||||||
std::begin(int32Values.values)); |
|
||||||
additionalInfo.payload.set<AdditionalInfo::AdditionalInfoPayload::dataInt32>( |
|
||||||
int32Values); |
|
||||||
aidlEvent->payload.set<Event::EventPayload::additional>(additionalInfo); |
|
||||||
break; |
|
||||||
} |
|
||||||
default: { |
|
||||||
if (static_cast<int32_t>(hidlEvent.sensorType) == |
|
||||||
static_cast<int32_t>(AidlSensorType::HEAD_TRACKER)) { |
|
||||||
Event::EventPayload::HeadTracker headTracker; |
|
||||||
headTracker.rx = hidlEvent.u.data[0]; |
|
||||||
headTracker.ry = hidlEvent.u.data[1]; |
|
||||||
headTracker.rz = hidlEvent.u.data[2]; |
|
||||||
headTracker.vx = hidlEvent.u.data[3]; |
|
||||||
headTracker.vy = hidlEvent.u.data[4]; |
|
||||||
headTracker.vz = hidlEvent.u.data[5]; |
|
||||||
|
|
||||||
// IMPORTANT: Because we want to preserve the data range of discontinuityCount,
|
|
||||||
// we assume the data can be interpreted as an int32_t directly (e.g. the underlying
|
|
||||||
// HIDL HAL must be using memcpy or equivalent to store this value).
|
|
||||||
headTracker.discontinuityCount = |
|
||||||
*(reinterpret_cast<const int32_t*>(&hidlEvent.u.data[6])); |
|
||||||
|
|
||||||
aidlEvent->payload.set<Event::EventPayload::Tag::headTracker>(headTracker); |
|
||||||
} else { |
|
||||||
CHECK_GE((int32_t)hidlEvent.sensorType, |
|
||||||
(int32_t)V2_1SensorType::DEVICE_PRIVATE_BASE); |
|
||||||
AidlEvent::EventPayload::Data data; |
|
||||||
std::copy(hidlEvent.u.data.data(), |
|
||||||
hidlEvent.u.data.data() + hidlEvent.u.data.size(), |
|
||||||
std::begin(data.values)); |
|
||||||
aidlEvent->payload.set<Event::EventPayload::data>(data); |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace implementation
|
|
||||||
} // namespace sensors
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace android
|
|
||||||
} // namespace aidl
|
|
@ -1,269 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2021 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
//#define VERBOSE
|
|
||||||
|
|
||||||
#include "HalProxyAidl.h" |
|
||||||
#include <aidlcommonsupport/NativeHandle.h> |
|
||||||
#include <fmq/AidlMessageQueue.h> |
|
||||||
#include <hidl/Status.h> |
|
||||||
#include "ConvertUtils.h" |
|
||||||
#include "EventMessageQueueWrapperAidl.h" |
|
||||||
#include "ISensorsCallbackWrapperAidl.h" |
|
||||||
#include "WakeLockMessageQueueWrapperAidl.h" |
|
||||||
#include "convertV2_1.h" |
|
||||||
|
|
||||||
using ::aidl::android::hardware::common::fmq::MQDescriptor; |
|
||||||
using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; |
|
||||||
using ::aidl::android::hardware::sensors::ISensors; |
|
||||||
using ::aidl::android::hardware::sensors::ISensorsCallback; |
|
||||||
using ::aidl::android::hardware::sensors::SensorInfo; |
|
||||||
using ::android::hardware::sensors::V2_1::implementation::convertToOldEvent; |
|
||||||
using ::ndk::ScopedAStatus; |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace android { |
|
||||||
namespace hardware { |
|
||||||
namespace sensors { |
|
||||||
namespace implementation { |
|
||||||
|
|
||||||
static ScopedAStatus |
|
||||||
resultToAStatus(::android::hardware::sensors::V1_0::Result result) { |
|
||||||
switch (result) { |
|
||||||
case ::android::hardware::sensors::V1_0::Result::OK: |
|
||||||
return ScopedAStatus::ok(); |
|
||||||
case ::android::hardware::sensors::V1_0::Result::PERMISSION_DENIED: |
|
||||||
return ScopedAStatus::fromExceptionCode(EX_SECURITY); |
|
||||||
case ::android::hardware::sensors::V1_0::Result::NO_MEMORY: |
|
||||||
return ScopedAStatus::fromServiceSpecificError(ISensors::ERROR_NO_MEMORY); |
|
||||||
case ::android::hardware::sensors::V1_0::Result::BAD_VALUE: |
|
||||||
return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); |
|
||||||
case ::android::hardware::sensors::V1_0::Result::INVALID_OPERATION: |
|
||||||
return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); |
|
||||||
default: |
|
||||||
return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static ::android::hardware::sensors::V1_0::RateLevel convertRateLevel( |
|
||||||
ISensors::RateLevel rateLevel) { |
|
||||||
switch (rateLevel) { |
|
||||||
case ISensors::RateLevel::STOP: |
|
||||||
return ::android::hardware::sensors::V1_0::RateLevel::STOP; |
|
||||||
case ISensors::RateLevel::NORMAL: |
|
||||||
return ::android::hardware::sensors::V1_0::RateLevel::NORMAL; |
|
||||||
case ISensors::RateLevel::FAST: |
|
||||||
return ::android::hardware::sensors::V1_0::RateLevel::FAST; |
|
||||||
case ISensors::RateLevel::VERY_FAST: |
|
||||||
return ::android::hardware::sensors::V1_0::RateLevel::VERY_FAST; |
|
||||||
default: |
|
||||||
assert(false); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static ::android::hardware::sensors::V1_0::OperationMode convertOperationMode( |
|
||||||
ISensors::OperationMode operationMode) { |
|
||||||
switch (operationMode) { |
|
||||||
case ISensors::OperationMode::NORMAL: |
|
||||||
return ::android::hardware::sensors::V1_0::OperationMode::NORMAL; |
|
||||||
case ISensors::OperationMode::DATA_INJECTION: |
|
||||||
return ::android::hardware::sensors::V1_0::OperationMode::DATA_INJECTION; |
|
||||||
default: |
|
||||||
assert(false); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static ::android::hardware::sensors::V1_0::SharedMemType convertSharedMemType( |
|
||||||
ISensors::SharedMemInfo::SharedMemType sharedMemType) { |
|
||||||
switch (sharedMemType) { |
|
||||||
case ISensors::SharedMemInfo::SharedMemType::ASHMEM: |
|
||||||
return ::android::hardware::sensors::V1_0::SharedMemType::ASHMEM; |
|
||||||
case ISensors::SharedMemInfo::SharedMemType::GRALLOC: |
|
||||||
return ::android::hardware::sensors::V1_0::SharedMemType::GRALLOC; |
|
||||||
default: |
|
||||||
assert(false); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static ::android::hardware::sensors::V1_0::SharedMemFormat convertSharedMemFormat( |
|
||||||
ISensors::SharedMemInfo::SharedMemFormat sharedMemFormat) { |
|
||||||
switch (sharedMemFormat) { |
|
||||||
case ISensors::SharedMemInfo::SharedMemFormat::SENSORS_EVENT: |
|
||||||
return ::android::hardware::sensors::V1_0::SharedMemFormat::SENSORS_EVENT; |
|
||||||
default: |
|
||||||
assert(false); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static ::android::hardware::sensors::V1_0::SharedMemInfo convertSharedMemInfo( |
|
||||||
const ISensors::SharedMemInfo& sharedMemInfo) { |
|
||||||
::android::hardware::sensors::V1_0::SharedMemInfo v1SharedMemInfo; |
|
||||||
v1SharedMemInfo.type = convertSharedMemType(sharedMemInfo.type); |
|
||||||
v1SharedMemInfo.format = convertSharedMemFormat(sharedMemInfo.format); |
|
||||||
v1SharedMemInfo.size = sharedMemInfo.size; |
|
||||||
v1SharedMemInfo.memoryHandle = |
|
||||||
::android::hardware::hidl_handle(::android::makeFromAidl(sharedMemInfo.memoryHandle)); |
|
||||||
return v1SharedMemInfo; |
|
||||||
} |
|
||||||
|
|
||||||
ScopedAStatus HalProxyAidl::activate(int32_t in_sensorHandle, bool in_enabled) { |
|
||||||
return resultToAStatus(HalProxy::activate(in_sensorHandle, in_enabled)); |
|
||||||
} |
|
||||||
|
|
||||||
ScopedAStatus HalProxyAidl::batch(int32_t in_sensorHandle, |
|
||||||
int64_t in_samplingPeriodNs, |
|
||||||
int64_t in_maxReportLatencyNs) { |
|
||||||
return resultToAStatus(HalProxy::batch(in_sensorHandle, in_samplingPeriodNs, |
|
||||||
in_maxReportLatencyNs)); |
|
||||||
} |
|
||||||
|
|
||||||
ScopedAStatus HalProxyAidl::configDirectReport(int32_t in_sensorHandle, |
|
||||||
int32_t in_channelHandle, |
|
||||||
ISensors::RateLevel in_rate, |
|
||||||
int32_t *_aidl_return) { |
|
||||||
ScopedAStatus status = |
|
||||||
ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); |
|
||||||
HalProxy::configDirectReport( |
|
||||||
in_sensorHandle, in_channelHandle, convertRateLevel(in_rate), |
|
||||||
[&status, _aidl_return](::android::hardware::sensors::V1_0::Result result, |
|
||||||
int32_t reportToken) { |
|
||||||
status = resultToAStatus(result); |
|
||||||
*_aidl_return = reportToken; |
|
||||||
}); |
|
||||||
|
|
||||||
return status; |
|
||||||
} |
|
||||||
|
|
||||||
ScopedAStatus HalProxyAidl::flush(int32_t in_sensorHandle) { |
|
||||||
return resultToAStatus(HalProxy::flush(in_sensorHandle)); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
ScopedAStatus HalProxyAidl::getSensorsList( |
|
||||||
std::vector<::aidl::android::hardware::sensors::SensorInfo> *_aidl_return) { |
|
||||||
for (const auto &sensor : HalProxy::getSensors()) { |
|
||||||
SensorInfo dst = sensor.second; |
|
||||||
|
|
||||||
if (dst.requiredPermission == "com.samsung.permission.SSENSOR") { |
|
||||||
dst.requiredPermission = ""; |
|
||||||
} |
|
||||||
|
|
||||||
if (dst.typeAsString == "com.samsung.sensor.physical_proximity" || |
|
||||||
dst.typeAsString == "com.samsung.sensor.hover_proximity") { |
|
||||||
ALOGI("Fixing %s", dst.typeAsString.c_str()); |
|
||||||
dst.type = ::android::hardware::sensors::V2_1::SensorType::PROXIMITY; |
|
||||||
dst.typeAsString = SENSOR_STRING_TYPE_PROXIMITY; |
|
||||||
dst.maxRange = 1; |
|
||||||
} |
|
||||||
|
|
||||||
#ifdef VERBOSE |
|
||||||
ALOGI( "SENSOR NAME:%s ", dst.name.c_str()); |
|
||||||
ALOGI( " VENDOR:%s ", dst.name.c_str()); |
|
||||||
ALOGI( " TYPE:%d ", (uint32_t)dst.type); |
|
||||||
ALOGI( " TYPE_AS_STRING:%s ", dst.typeAsString.c_str()); |
|
||||||
#endif |
|
||||||
|
|
||||||
_aidl_return->push_back(convertSensorInfo(dst)); |
|
||||||
} |
|
||||||
return ScopedAStatus::ok(); |
|
||||||
} |
|
||||||
|
|
||||||
ScopedAStatus HalProxyAidl::initialize( |
|
||||||
const MQDescriptor<::aidl::android::hardware::sensors::Event, |
|
||||||
SynchronizedReadWrite> &in_eventQueueDescriptor, |
|
||||||
const MQDescriptor<int32_t, SynchronizedReadWrite> &in_wakeLockDescriptor, |
|
||||||
const std::shared_ptr<ISensorsCallback> &in_sensorsCallback) { |
|
||||||
::android::sp<::android::hardware::sensors::V2_1::implementation:: |
|
||||||
ISensorsCallbackWrapperBase> |
|
||||||
dynamicCallback = new ISensorsCallbackWrapperAidl(in_sensorsCallback); |
|
||||||
|
|
||||||
auto aidlEventQueue = std::make_unique<::android::AidlMessageQueue< |
|
||||||
::aidl::android::hardware::sensors::Event, SynchronizedReadWrite>>( |
|
||||||
in_eventQueueDescriptor, true /* resetPointers */); |
|
||||||
std::unique_ptr<::android::hardware::sensors::V2_1::implementation:: |
|
||||||
EventMessageQueueWrapperBase> |
|
||||||
eventQueue = |
|
||||||
std::make_unique<EventMessageQueueWrapperAidl>(aidlEventQueue); |
|
||||||
|
|
||||||
auto aidlWakeLockQueue = std::make_unique< |
|
||||||
::android::AidlMessageQueue<int32_t, SynchronizedReadWrite>>( |
|
||||||
in_wakeLockDescriptor, true /* resetPointers */); |
|
||||||
std::unique_ptr<::android::hardware::sensors::V2_1::implementation:: |
|
||||||
WakeLockMessageQueueWrapperBase> |
|
||||||
wakeLockQueue = |
|
||||||
std::make_unique<WakeLockMessageQueueWrapperAidl>(aidlWakeLockQueue); |
|
||||||
|
|
||||||
return resultToAStatus( |
|
||||||
initializeCommon(eventQueue, wakeLockQueue, dynamicCallback)); |
|
||||||
} |
|
||||||
|
|
||||||
ScopedAStatus HalProxyAidl::injectSensorData( |
|
||||||
const ::aidl::android::hardware::sensors::Event &in_event) { |
|
||||||
::android::hardware::sensors::V2_1::Event hidlEvent; |
|
||||||
convertToHidlEvent(in_event, &hidlEvent); |
|
||||||
return resultToAStatus( |
|
||||||
HalProxy::injectSensorData(convertToOldEvent(hidlEvent))); |
|
||||||
} |
|
||||||
|
|
||||||
ScopedAStatus |
|
||||||
HalProxyAidl::registerDirectChannel(const ISensors::SharedMemInfo &in_mem, |
|
||||||
int32_t *_aidl_return) { |
|
||||||
ScopedAStatus status = |
|
||||||
ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); |
|
||||||
::android::hardware::sensors::V1_0::SharedMemInfo sharedMemInfo = |
|
||||||
convertSharedMemInfo(in_mem); |
|
||||||
|
|
||||||
HalProxy::registerDirectChannel( |
|
||||||
sharedMemInfo, |
|
||||||
[&status, _aidl_return](::android::hardware::sensors::V1_0::Result result, |
|
||||||
int32_t reportToken) { |
|
||||||
status = resultToAStatus(result); |
|
||||||
*_aidl_return = reportToken; |
|
||||||
}); |
|
||||||
|
|
||||||
native_handle_delete(const_cast<native_handle_t *>( |
|
||||||
sharedMemInfo.memoryHandle.getNativeHandle())); |
|
||||||
|
|
||||||
return status; |
|
||||||
} |
|
||||||
|
|
||||||
ScopedAStatus HalProxyAidl::setOperationMode( |
|
||||||
::aidl::android::hardware::sensors::ISensors::OperationMode in_mode) { |
|
||||||
return resultToAStatus( |
|
||||||
HalProxy::setOperationMode(convertOperationMode(in_mode))); |
|
||||||
} |
|
||||||
|
|
||||||
ScopedAStatus HalProxyAidl::unregisterDirectChannel(int32_t in_channelHandle) { |
|
||||||
return resultToAStatus(HalProxy::unregisterDirectChannel(in_channelHandle)); |
|
||||||
} |
|
||||||
|
|
||||||
binder_status_t HalProxyAidl::dump(int fd, const char ** /* args */, |
|
||||||
uint32_t /* numArgs */) { |
|
||||||
native_handle_t *nativeHandle = |
|
||||||
native_handle_create(1 /* numFds */, 0 /* numInts */); |
|
||||||
nativeHandle->data[0] = fd; |
|
||||||
|
|
||||||
HalProxy::debug(nativeHandle, {} /* args */); |
|
||||||
|
|
||||||
native_handle_delete(nativeHandle); |
|
||||||
return STATUS_OK; |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace implementation
|
|
||||||
} // namespace sensors
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace android
|
|
||||||
} // namespace aidl
|
|
@ -1,7 +0,0 @@ |
|||||||
service vendor.sensors-hal-multihal /vendor/bin/hw/android.hardware.sensors-service.sm7125-multihal |
|
||||||
class hal |
|
||||||
user system |
|
||||||
group system wakelock context_hub input |
|
||||||
task_profiles ServiceCapacityLow |
|
||||||
capabilities BLOCK_SUSPEND |
|
||||||
rlimit rtprio 10 10 |
|
@ -1,23 +0,0 @@ |
|||||||
<!-- |
|
||||||
~ Copyright (C) 2021 The Android Open Source Project |
|
||||||
~ |
|
||||||
~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
~ you may not use this file except in compliance with the License. |
|
||||||
~ You may obtain a copy of the License at |
|
||||||
~ |
|
||||||
~ http://www.apache.org/licenses/LICENSE-2.0 |
|
||||||
~ |
|
||||||
~ Unless required by applicable law or agreed to in writing, software |
|
||||||
~ distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
~ See the License for the specific language governing permissions and |
|
||||||
~ limitations under the License. |
|
||||||
--> |
|
||||||
|
|
||||||
<manifest version="1.0" type="device"> |
|
||||||
<hal format="aidl" override="true"> |
|
||||||
<name>android.hardware.sensors</name> |
|
||||||
<version>1</version> |
|
||||||
<fqname>ISensors/default</fqname> |
|
||||||
</hal> |
|
||||||
</manifest> |
|
@ -1,50 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2021 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include <aidl/android/hardware/sensors/BnSensors.h> |
|
||||||
#include <android/hardware/sensors/2.1/types.h> |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace android { |
|
||||||
namespace hardware { |
|
||||||
namespace sensors { |
|
||||||
namespace implementation { |
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates an AIDL SensorInfo instance from the passed HIDL V2.1 SensorInfo instance. |
|
||||||
*/ |
|
||||||
::aidl::android::hardware::sensors::SensorInfo convertSensorInfo( |
|
||||||
const ::android::hardware::sensors::V2_1::SensorInfo& sensorInfo); |
|
||||||
|
|
||||||
/**
|
|
||||||
* Populates a HIDL V2.1 Event instance based on an AIDL Event instance. |
|
||||||
*/ |
|
||||||
void convertToHidlEvent(const ::aidl::android::hardware::sensors::Event& aidlEvent, |
|
||||||
::android::hardware::sensors::V2_1::Event* hidlEvent); |
|
||||||
|
|
||||||
/**
|
|
||||||
* Populates an AIDL Event instance based on a HIDL V2.1 Event instance. |
|
||||||
*/ |
|
||||||
void convertToAidlEvent(const ::android::hardware::sensors::V2_1::Event& hidlEvent, |
|
||||||
::aidl::android::hardware::sensors::Event* aidlEvent); |
|
||||||
|
|
||||||
} // namespace implementation
|
|
||||||
} // namespace sensors
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace android
|
|
||||||
} // namespace aidl
|
|
@ -1,99 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2021 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include <android/hardware/sensors/2.1/types.h> |
|
||||||
#include <fmq/AidlMessageQueue.h> |
|
||||||
#include "ConvertUtils.h" |
|
||||||
#include "EventMessageQueueWrapper.h" |
|
||||||
#include "ISensorsWrapper.h" |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace android { |
|
||||||
namespace hardware { |
|
||||||
namespace sensors { |
|
||||||
namespace implementation { |
|
||||||
|
|
||||||
class EventMessageQueueWrapperAidl |
|
||||||
: public ::android::hardware::sensors::V2_1::implementation::EventMessageQueueWrapperBase { |
|
||||||
public: |
|
||||||
EventMessageQueueWrapperAidl( |
|
||||||
std::unique_ptr<::android::AidlMessageQueue< |
|
||||||
::aidl::android::hardware::sensors::Event, |
|
||||||
::aidl::android::hardware::common::fmq::SynchronizedReadWrite>>& queue) |
|
||||||
: mQueue(std::move(queue)) {} |
|
||||||
|
|
||||||
virtual std::atomic<uint32_t>* getEventFlagWord() override { |
|
||||||
return mQueue->getEventFlagWord(); |
|
||||||
} |
|
||||||
|
|
||||||
virtual size_t availableToRead() override { return mQueue->availableToRead(); } |
|
||||||
|
|
||||||
size_t availableToWrite() override { return mQueue->availableToWrite(); } |
|
||||||
|
|
||||||
virtual bool read(::android::hardware::sensors::V2_1::Event* events, |
|
||||||
size_t numToRead) override { |
|
||||||
bool success = mQueue->read(mIntermediateEventBuffer.data(), numToRead); |
|
||||||
for (int i = 0; i < numToRead; ++i) { |
|
||||||
convertToHidlEvent(mIntermediateEventBuffer[i], &events[i]); |
|
||||||
} |
|
||||||
return success; |
|
||||||
} |
|
||||||
|
|
||||||
bool write(const ::android::hardware::sensors::V2_1::Event* events, |
|
||||||
size_t numToWrite) override { |
|
||||||
for (int i = 0; i < numToWrite; ++i) { |
|
||||||
convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]); |
|
||||||
} |
|
||||||
return mQueue->write(mIntermediateEventBuffer.data(), numToWrite); |
|
||||||
} |
|
||||||
|
|
||||||
virtual bool write( |
|
||||||
const std::vector<::android::hardware::sensors::V2_1::Event>& events) override { |
|
||||||
for (int i = 0; i < events.size(); ++i) { |
|
||||||
convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]); |
|
||||||
} |
|
||||||
return mQueue->write(mIntermediateEventBuffer.data(), events.size()); |
|
||||||
} |
|
||||||
|
|
||||||
bool writeBlocking(const ::android::hardware::sensors::V2_1::Event* events, size_t count, |
|
||||||
uint32_t readNotification, uint32_t writeNotification, int64_t timeOutNanos, |
|
||||||
::android::hardware::EventFlag* evFlag) override { |
|
||||||
for (int i = 0; i < count; ++i) { |
|
||||||
convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]); |
|
||||||
} |
|
||||||
return mQueue->writeBlocking(mIntermediateEventBuffer.data(), count, readNotification, |
|
||||||
writeNotification, timeOutNanos, evFlag); |
|
||||||
} |
|
||||||
|
|
||||||
size_t getQuantumCount() override { return mQueue->getQuantumCount(); } |
|
||||||
|
|
||||||
private: |
|
||||||
std::unique_ptr<::android::AidlMessageQueue< |
|
||||||
::aidl::android::hardware::sensors::Event, |
|
||||||
::aidl::android::hardware::common::fmq::SynchronizedReadWrite>> |
|
||||||
mQueue; |
|
||||||
std::array<::aidl::android::hardware::sensors::Event, |
|
||||||
::android::hardware::sensors::V2_1::implementation::MAX_RECEIVE_BUFFER_EVENT_COUNT> |
|
||||||
mIntermediateEventBuffer; |
|
||||||
}; |
|
||||||
|
|
||||||
} // namespace implementation
|
|
||||||
} // namespace sensors
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace android
|
|
||||||
} // namespace aidl
|
|
@ -1,66 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2021 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include <aidl/android/hardware/sensors/BnSensors.h> |
|
||||||
#include "HalProxy.h" |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace android { |
|
||||||
namespace hardware { |
|
||||||
namespace sensors { |
|
||||||
namespace implementation { |
|
||||||
|
|
||||||
class HalProxyAidl : public ::android::hardware::sensors::V2_1::implementation::HalProxy, |
|
||||||
public ::aidl::android::hardware::sensors::BnSensors { |
|
||||||
::ndk::ScopedAStatus activate(int32_t in_sensorHandle, bool in_enabled) override; |
|
||||||
::ndk::ScopedAStatus batch(int32_t in_sensorHandle, int64_t in_samplingPeriodNs, |
|
||||||
int64_t in_maxReportLatencyNs) override; |
|
||||||
::ndk::ScopedAStatus configDirectReport( |
|
||||||
int32_t in_sensorHandle, int32_t in_channelHandle, |
|
||||||
::aidl::android::hardware::sensors::ISensors::RateLevel in_rate, |
|
||||||
int32_t* _aidl_return) override; |
|
||||||
::ndk::ScopedAStatus flush(int32_t in_sensorHandle) override; |
|
||||||
::ndk::ScopedAStatus getSensorsList( |
|
||||||
std::vector<::aidl::android::hardware::sensors::SensorInfo>* _aidl_return) override; |
|
||||||
::ndk::ScopedAStatus initialize( |
|
||||||
const ::aidl::android::hardware::common::fmq::MQDescriptor< |
|
||||||
::aidl::android::hardware::sensors::Event, |
|
||||||
::aidl::android::hardware::common::fmq::SynchronizedReadWrite>& |
|
||||||
in_eventQueueDescriptor, |
|
||||||
const ::aidl::android::hardware::common::fmq::MQDescriptor< |
|
||||||
int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>& |
|
||||||
in_wakeLockDescriptor, |
|
||||||
const std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback>& |
|
||||||
in_sensorsCallback) override; |
|
||||||
::ndk::ScopedAStatus injectSensorData( |
|
||||||
const ::aidl::android::hardware::sensors::Event& in_event) override; |
|
||||||
::ndk::ScopedAStatus registerDirectChannel( |
|
||||||
const ::aidl::android::hardware::sensors::ISensors::SharedMemInfo& in_mem, |
|
||||||
int32_t* _aidl_return) override; |
|
||||||
::ndk::ScopedAStatus setOperationMode( |
|
||||||
::aidl::android::hardware::sensors::ISensors::OperationMode in_mode) override; |
|
||||||
::ndk::ScopedAStatus unregisterDirectChannel(int32_t in_channelHandle) override; |
|
||||||
|
|
||||||
binder_status_t dump(int fd, const char **args, uint32_t numArgs) override; |
|
||||||
}; |
|
||||||
|
|
||||||
} // namespace implementation
|
|
||||||
} // namespace sensors
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace android
|
|
||||||
} // namespace aidl
|
|
@ -1,66 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2021 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include "ConvertUtils.h" |
|
||||||
#include "ISensorsCallbackWrapper.h" |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace android { |
|
||||||
namespace hardware { |
|
||||||
namespace sensors { |
|
||||||
namespace implementation { |
|
||||||
|
|
||||||
static std::vector<::aidl::android::hardware::sensors::SensorInfo> convertToAidlSensorInfos( |
|
||||||
const ::android::hardware::hidl_vec<::android::hardware::sensors::V2_1::SensorInfo>& |
|
||||||
sensorInfos) { |
|
||||||
std::vector<::aidl::android::hardware::sensors::SensorInfo> aidlSensorInfos; |
|
||||||
for (const auto& sensorInfo : sensorInfos) { |
|
||||||
aidlSensorInfos.push_back(convertSensorInfo(sensorInfo)); |
|
||||||
} |
|
||||||
return aidlSensorInfos; |
|
||||||
} |
|
||||||
|
|
||||||
class ISensorsCallbackWrapperAidl |
|
||||||
: public ::android::hardware::sensors::V2_1::implementation::ISensorsCallbackWrapperBase { |
|
||||||
public: |
|
||||||
ISensorsCallbackWrapperAidl( |
|
||||||
std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback> sensorsCallback) |
|
||||||
: mSensorsCallback(sensorsCallback) {} |
|
||||||
|
|
||||||
::android::hardware::Return<void> onDynamicSensorsConnected( |
|
||||||
const ::android::hardware::hidl_vec<::android::hardware::sensors::V2_1::SensorInfo>& |
|
||||||
sensorInfos) override { |
|
||||||
mSensorsCallback->onDynamicSensorsConnected(convertToAidlSensorInfos(sensorInfos)); |
|
||||||
return ::android::hardware::Void(); |
|
||||||
} |
|
||||||
|
|
||||||
::android::hardware::Return<void> onDynamicSensorsDisconnected( |
|
||||||
const ::android::hardware::hidl_vec<int32_t>& sensorHandles) override { |
|
||||||
mSensorsCallback->onDynamicSensorsDisconnected(sensorHandles); |
|
||||||
return ::android::hardware::Void(); |
|
||||||
} |
|
||||||
|
|
||||||
private: |
|
||||||
std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback> mSensorsCallback; |
|
||||||
}; |
|
||||||
|
|
||||||
} // namespace implementation
|
|
||||||
} // namespace sensors
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace android
|
|
||||||
} // namespace aidl
|
|
@ -1,62 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2021 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include <android/hardware/sensors/2.1/types.h> |
|
||||||
#include <fmq/AidlMessageQueue.h> |
|
||||||
#include "WakeLockMessageQueueWrapper.h" |
|
||||||
|
|
||||||
namespace aidl { |
|
||||||
namespace android { |
|
||||||
namespace hardware { |
|
||||||
namespace sensors { |
|
||||||
namespace implementation { |
|
||||||
|
|
||||||
class WakeLockMessageQueueWrapperAidl |
|
||||||
: public ::android::hardware::sensors::V2_1::implementation::WakeLockMessageQueueWrapperBase { |
|
||||||
public: |
|
||||||
WakeLockMessageQueueWrapperAidl( |
|
||||||
std::unique_ptr<::android::AidlMessageQueue< |
|
||||||
int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>>& queue) |
|
||||||
: mQueue(std::move(queue)) {} |
|
||||||
|
|
||||||
virtual std::atomic<uint32_t>* getEventFlagWord() override { |
|
||||||
return mQueue->getEventFlagWord(); |
|
||||||
} |
|
||||||
|
|
||||||
bool readBlocking(uint32_t* wakeLocks, size_t numToRead, uint32_t readNotification, |
|
||||||
uint32_t writeNotification, int64_t timeOutNanos, |
|
||||||
::android::hardware::EventFlag* evFlag) override { |
|
||||||
return mQueue->readBlocking(reinterpret_cast<int32_t*>(wakeLocks), numToRead, |
|
||||||
readNotification, writeNotification, timeOutNanos, evFlag); |
|
||||||
} |
|
||||||
|
|
||||||
bool write(const uint32_t* wakeLock) override { |
|
||||||
return mQueue->write(reinterpret_cast<const int32_t*>(wakeLock)); |
|
||||||
} |
|
||||||
|
|
||||||
private: |
|
||||||
std::unique_ptr<::android::AidlMessageQueue< |
|
||||||
int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>> |
|
||||||
mQueue; |
|
||||||
}; |
|
||||||
|
|
||||||
} // namespace implementation
|
|
||||||
} // namespace sensors
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace android
|
|
||||||
} // namespace aidl
|
|
@ -1,36 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2021 The Android Open Source Project |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <android-base/logging.h> |
|
||||||
#include <android/binder_manager.h> |
|
||||||
#include <android/binder_process.h> |
|
||||||
#include "HalProxyAidl.h" |
|
||||||
|
|
||||||
using ::aidl::android::hardware::sensors::implementation::HalProxyAidl; |
|
||||||
|
|
||||||
int main() { |
|
||||||
ABinderProcess_setThreadPoolMaxThreadCount(0); |
|
||||||
|
|
||||||
// Make a default multihal sensors service
|
|
||||||
auto halProxy = ndk::SharedRefBase::make<HalProxyAidl>(); |
|
||||||
const std::string halProxyName = std::string() + HalProxyAidl::descriptor + "/default"; |
|
||||||
binder_status_t status = |
|
||||||
AServiceManager_addService(halProxy->asBinder().get(), halProxyName.c_str()); |
|
||||||
CHECK_EQ(status, STATUS_OK); |
|
||||||
|
|
||||||
ABinderProcess_joinThreadPool(); |
|
||||||
return EXIT_FAILURE; // should not reach
|
|
||||||
} |
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,48 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<!-- |
||||||
|
Copyright (C) 2012-2014 The CyanogenMod Project |
||||||
|
Copyright (C) 2018 The LineageOS Project |
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
you may not use this file except in compliance with the License. |
||||||
|
You may obtain a copy of the License at |
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software |
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
See the License for the specific language governing permissions and |
||||||
|
limitations under the License. |
||||||
|
--> |
||||||
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> |
||||||
|
<string-array name="mdnie_scenario_entries" translatable="false"> |
||||||
|
<item>LineageOS (default)</item> |
||||||
|
<item>Video</item> |
||||||
|
<item>Video warm</item> |
||||||
|
<item>Video cold</item> |
||||||
|
<item>Camera</item> |
||||||
|
<item>Navigation</item> |
||||||
|
<item>Gallery</item> |
||||||
|
<item>Video call</item> |
||||||
|
<item>Browser</item> |
||||||
|
<item>eBook</item> |
||||||
|
<item>E-mail</item> |
||||||
|
<item>Digital television</item> |
||||||
|
</string-array> |
||||||
|
|
||||||
|
<string-array name="mdnie_scenario_entries_values" translatable="false"> |
||||||
|
<item>0</item> |
||||||
|
<item>1</item> |
||||||
|
<item>2</item> |
||||||
|
<item>3</item> |
||||||
|
<item>4</item> |
||||||
|
<item>5</item> |
||||||
|
<item>6</item> |
||||||
|
<item>7</item> |
||||||
|
<item>8</item> |
||||||
|
<item>9</item> |
||||||
|
<item>10</item> |
||||||
|
<item>16</item> |
||||||
|
</string-array> |
||||||
|
</resources> |
@ -1,23 +0,0 @@ |
|||||||
<!-- |
|
||||||
~ Copyright (C) 2021 The Android Open Source Project |
|
||||||
~ |
|
||||||
~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
~ you may not use this file except in compliance with the License. |
|
||||||
~ You may obtain a copy of the License at |
|
||||||
~ |
|
||||||
~ http://www.apache.org/licenses/LICENSE-2.0 |
|
||||||
~ |
|
||||||
~ Unless required by applicable law or agreed to in writing, software |
|
||||||
~ distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
~ See the License for the specific language governing permissions and |
|
||||||
~ limitations under the License. |
|
||||||
--> |
|
||||||
|
|
||||||
<manifest version="1.0" type="device"> |
|
||||||
<hal format="aidl" override="true"> |
|
||||||
<name>android.hardware.sensors</name> |
|
||||||
<version>1</version> |
|
||||||
<fqname>ISensors/default</fqname> |
|
||||||
</hal> |
|
||||||
</manifest> |
|
@ -1,7 +0,0 @@ |
|||||||
service vendor.sensors-hal-multihal /vendor/bin/hw/android.hardware.sensors-service.samsung-multihal |
|
||||||
class hal |
|
||||||
user system |
|
||||||
group system wakelock context_hub input |
|
||||||
task_profiles ServiceCapacityLow |
|
||||||
capabilities BLOCK_SUSPEND |
|
||||||
rlimit rtprio 10 10 |
|
@ -0,0 +1,22 @@ |
|||||||
|
// |
||||||
|
// Copyright (C) 2023-2024 The LineageOS Project |
||||||
|
// |
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
// you may not use this file except in compliance with the License. |
||||||
|
// You may obtain a copy of the License at |
||||||
|
// |
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
// |
||||||
|
// Unless required by applicable law or agreed to in writing, software |
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
// See the License for the specific language governing permissions and |
||||||
|
// limitations under the License. |
||||||
|
|
||||||
|
cc_library_shared { |
||||||
|
name: "libshim_crypto", |
||||||
|
srcs: ["crypto.c"], |
||||||
|
compile_multilib: "64", |
||||||
|
shared_libs: ["libcrypto-v33"], |
||||||
|
vendor: true, |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 The LineageOS Project |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <stddef.h> |
||||||
|
|
||||||
|
extern void *sk_new_null(void); |
||||||
|
void *OPENSSL_sk_new_null(void) { |
||||||
|
return sk_new_null(); |
||||||
|
} |
||||||
|
|
||||||
|
extern size_t sk_num(void *sk); |
||||||
|
size_t OPENSSL_sk_num(void *sk) { |
||||||
|
return sk_num(sk); |
||||||
|
} |
||||||
|
|
||||||
|
extern size_t sk_push(void *sk, void *p); |
||||||
|
size_t OPENSSL_sk_push(void *sk, void *p) { |
||||||
|
return sk_push(sk, p); |
||||||
|
} |
||||||
|
|
||||||
|
extern void *sk_value(const void *sk, size_t i); |
||||||
|
void* OPENSSL_sk_value(const void *sk, size_t i) { |
||||||
|
return sk_value(sk, i); |
||||||
|
} |
@ -0,0 +1 @@ |
|||||||
|
../../../../prebuilts/vndk/v33/arm64/arch-arm64-armv8-a/shared/vndk-core/libssl.so |
Loading…
Reference in new issue