blob: 8490b62dcd5ebc69e61b262b2e95acc9356ba55a [file] [log] [blame]
Wei Wang61c2a332020-01-08 16:51:47 -08001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "Power.h"
Peiyong Lin5851c3a2022-10-18 20:47:56 +000018#include "PowerHintSession.h"
Wei Wang61c2a332020-01-08 16:51:47 -080019
20#include <android-base/logging.h>
Matt Buckleycaac1472023-12-12 03:55:50 +000021#include <fmq/AidlMessageQueue.h>
22#include <fmq/EventFlag.h>
Matt Buckleyf7c36d42024-02-27 01:31:43 +000023#include <thread>
Wei Wang61c2a332020-01-08 16:51:47 -080024
25namespace aidl {
26namespace android {
27namespace hardware {
28namespace power {
29namespace impl {
30namespace example {
31
Peiyong Lin5851c3a2022-10-18 20:47:56 +000032using namespace std::chrono_literals;
Matt Buckleycaac1472023-12-12 03:55:50 +000033using ::aidl::android::hardware::common::fmq::MQDescriptor;
34using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
35using ::aidl::android::hardware::power::ChannelMessage;
Matt Buckley0efc7482024-10-29 18:39:20 +000036using ::aidl::android::hardware::power::CompositionData;
37using ::aidl::android::hardware::power::CompositionUpdate;
Matt Buckleycaac1472023-12-12 03:55:50 +000038using ::android::AidlMessageQueue;
Peiyong Lin5851c3a2022-10-18 20:47:56 +000039
40using ndk::ScopedAStatus;
41
Wei Wang05003412021-04-01 10:44:29 -070042const std::vector<Boost> BOOST_RANGE{ndk::enum_range<Boost>().begin(),
43 ndk::enum_range<Boost>().end()};
44const std::vector<Mode> MODE_RANGE{ndk::enum_range<Mode>().begin(), ndk::enum_range<Mode>().end()};
45
Matt Buckley607720e2024-10-28 19:21:37 +000046template <class T>
47constexpr size_t enum_size() {
48 return static_cast<size_t>(*(ndk::enum_range<T>().end() - 1)) + 1;
49}
50
Peiyong Lin5851c3a2022-10-18 20:47:56 +000051ScopedAStatus Power::setMode(Mode type, bool enabled) {
Wei Wang61c2a332020-01-08 16:51:47 -080052 LOG(VERBOSE) << "Power setMode: " << static_cast<int32_t>(type) << " to: " << enabled;
Peiyong Lin5851c3a2022-10-18 20:47:56 +000053 return ScopedAStatus::ok();
Wei Wang61c2a332020-01-08 16:51:47 -080054}
55
Peiyong Lin5851c3a2022-10-18 20:47:56 +000056ScopedAStatus Power::isModeSupported(Mode type, bool* _aidl_return) {
Wei Wang61c2a332020-01-08 16:51:47 -080057 LOG(INFO) << "Power isModeSupported: " << static_cast<int32_t>(type);
Wei Wang05003412021-04-01 10:44:29 -070058 *_aidl_return = type >= MODE_RANGE.front() && type <= MODE_RANGE.back();
Peiyong Lin5851c3a2022-10-18 20:47:56 +000059 return ScopedAStatus::ok();
Wei Wang61c2a332020-01-08 16:51:47 -080060}
61
Peiyong Lin5851c3a2022-10-18 20:47:56 +000062ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
Wei Wang61c2a332020-01-08 16:51:47 -080063 LOG(VERBOSE) << "Power setBoost: " << static_cast<int32_t>(type)
64 << ", duration: " << durationMs;
Peiyong Lin5851c3a2022-10-18 20:47:56 +000065 return ScopedAStatus::ok();
Wei Wang61c2a332020-01-08 16:51:47 -080066}
67
Peiyong Lin5851c3a2022-10-18 20:47:56 +000068ScopedAStatus Power::isBoostSupported(Boost type, bool* _aidl_return) {
Wei Wang61c2a332020-01-08 16:51:47 -080069 LOG(INFO) << "Power isBoostSupported: " << static_cast<int32_t>(type);
Wei Wang05003412021-04-01 10:44:29 -070070 *_aidl_return = type >= BOOST_RANGE.front() && type <= BOOST_RANGE.back();
Peiyong Lin5851c3a2022-10-18 20:47:56 +000071 return ScopedAStatus::ok();
Wei Wang61c2a332020-01-08 16:51:47 -080072}
73
Xiang Wangb0d667e2024-11-16 06:19:21 +000074ndk::ScopedAStatus Power::getCpuHeadroom(const CpuHeadroomParams& params,
75 CpuHeadroomResult* _aidl_return) {
76 if (params.selectionType == CpuHeadroomParams::SelectionType::ALL) {
77 _aidl_return->set<CpuHeadroomResult::globalHeadroom>(100.0f);
78 return ndk::ScopedAStatus::ok();
79 } else if (params.selectionType == CpuHeadroomParams::SelectionType::PER_CORE) {
80 std::vector<float> headroom = {50.0f, 100.0f};
81 _aidl_return->set<CpuHeadroomResult::perCoreHeadroom>(headroom);
82 return ndk::ScopedAStatus::ok();
83 }
84 return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
Xiang Wangaf052822024-10-21 23:18:29 +000085}
86
Xiang Wangb0d667e2024-11-16 06:19:21 +000087ndk::ScopedAStatus Power::getGpuHeadroom(const GpuHeadroomParams& _,
88 GpuHeadroomResult* _aidl_return) {
89 _aidl_return->set<GpuHeadroomResult::globalHeadroom>(100.0f);
Xiang Wangaf052822024-10-21 23:18:29 +000090 return ndk::ScopedAStatus::ok();
91}
92
93ndk::ScopedAStatus Power::getCpuHeadroomMinIntervalMillis(int64_t* _aidl_return) {
94 *_aidl_return = 1000;
95 return ndk::ScopedAStatus::ok();
96}
97
98ndk::ScopedAStatus Power::getGpuHeadroomMinIntervalMillis(int64_t* _aidl_return) {
99 *_aidl_return = 1000;
100 return ndk::ScopedAStatus::ok();
101}
102
Peiyong Lin5851c3a2022-10-18 20:47:56 +0000103ScopedAStatus Power::createHintSession(int32_t, int32_t, const std::vector<int32_t>& tids, int64_t,
104 std::shared_ptr<IPowerHintSession>* _aidl_return) {
105 if (tids.size() == 0) {
106 *_aidl_return = nullptr;
107 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
108 }
109 std::shared_ptr<IPowerHintSession> powerHintSession =
110 ndk::SharedRefBase::make<PowerHintSession>();
111 mPowerHintSessions.push_back(powerHintSession);
112 *_aidl_return = powerHintSession;
113 return ScopedAStatus::ok();
Wei Wang05003412021-04-01 10:44:29 -0700114}
115
Matt Buckleycaac1472023-12-12 03:55:50 +0000116ndk::ScopedAStatus Power::createHintSessionWithConfig(
117 int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds, int64_t durationNanos,
118 SessionTag, SessionConfig* config, std::shared_ptr<IPowerHintSession>* _aidl_return) {
119 auto out = createHintSession(tgid, uid, threadIds, durationNanos, _aidl_return);
120 static_cast<PowerHintSession*>(_aidl_return->get())->getSessionConfig(config);
121 return out;
122}
123
124ndk::ScopedAStatus Power::getSessionChannel(int32_t, int32_t, ChannelConfig* _aidl_return) {
Matt Buckleyf7c36d42024-02-27 01:31:43 +0000125 static AidlMessageQueue<ChannelMessage, SynchronizedReadWrite> stubQueue{20, true};
126 static std::thread stubThread([&] {
127 ChannelMessage data;
128 // This loop will only run while there is data waiting
129 // to be processed, and blocks on a futex all other times
130 while (stubQueue.readBlocking(&data, 1, 0)) {
131 }
132 });
Matt Buckleycaac1472023-12-12 03:55:50 +0000133 _aidl_return->channelDescriptor = stubQueue.dupeDesc();
Matt Buckleyf7c36d42024-02-27 01:31:43 +0000134 _aidl_return->readFlagBitmask = 0x01;
135 _aidl_return->writeFlagBitmask = 0x02;
Matt Buckleycaac1472023-12-12 03:55:50 +0000136 _aidl_return->eventFlagDescriptor = std::nullopt;
137 return ndk::ScopedAStatus::ok();
138}
139
140ndk::ScopedAStatus Power::closeSessionChannel(int32_t, int32_t) {
141 return ndk::ScopedAStatus::ok();
142}
143
Matt Buckley607720e2024-10-28 19:21:37 +0000144ndk::ScopedAStatus Power::getHintSessionPreferredRate(int64_t* outNanoseconds) {
Peiyong Lin5851c3a2022-10-18 20:47:56 +0000145 *outNanoseconds = std::chrono::nanoseconds(1ms).count();
146 return ScopedAStatus::ok();
Wei Wang05003412021-04-01 10:44:29 -0700147}
148
Matt Buckley607720e2024-10-28 19:21:37 +0000149template <class E>
150int64_t bitsForEnum() {
151 return static_cast<int64_t>(std::bitset<enum_size<E>()>().set().to_ullong());
152}
153
154ndk::ScopedAStatus Power::getSupportInfo(SupportInfo* _aidl_return) {
Matt Buckley0efc7482024-10-29 18:39:20 +0000155 static SupportInfo supportInfo = {.usesSessions = false,
156 .modes = bitsForEnum<Mode>(),
157 .boosts = bitsForEnum<Boost>(),
158 .sessionHints = 0,
159 .sessionModes = 0,
160 .sessionTags = 0,
161 .compositionData = {
162 .isSupported = false,
163 .disableGpuFences = false,
164 .maxBatchSize = 1,
165 .alwaysBatch = false,
166 }};
Matt Buckley607720e2024-10-28 19:21:37 +0000167 // Copy the support object into the binder
168 *_aidl_return = supportInfo;
169 return ndk::ScopedAStatus::ok();
170}
171
Matt Buckley0efc7482024-10-29 18:39:20 +0000172ndk::ScopedAStatus Power::sendCompositionData(const std::vector<CompositionData>&) {
173 LOG(INFO) << "Composition data received!";
174 return ndk::ScopedAStatus::ok();
175}
176
177ndk::ScopedAStatus Power::sendCompositionUpdate(const CompositionUpdate&) {
178 LOG(INFO) << "Composition update received!";
179 return ndk::ScopedAStatus::ok();
180}
181
Wei Wang61c2a332020-01-08 16:51:47 -0800182} // namespace example
183} // namespace impl
184} // namespace power
185} // namespace hardware
186} // namespace android
187} // namespace aidl