/* * 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. */ #include "Power.h" #include "PowerHintSession.h" #include #include #include #include namespace aidl { namespace android { namespace hardware { namespace power { namespace impl { namespace example { using namespace std::chrono_literals; using ::aidl::android::hardware::common::fmq::MQDescriptor; using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; using ::aidl::android::hardware::power::ChannelMessage; using ::aidl::android::hardware::power::CompositionData; using ::aidl::android::hardware::power::CompositionUpdate; using ::android::AidlMessageQueue; using ndk::ScopedAStatus; const std::vector BOOST_RANGE{ndk::enum_range().begin(), ndk::enum_range().end()}; const std::vector MODE_RANGE{ndk::enum_range().begin(), ndk::enum_range().end()}; template constexpr size_t enum_size() { return static_cast(*(ndk::enum_range().end() - 1)) + 1; } ScopedAStatus Power::setMode(Mode type, bool enabled) { LOG(VERBOSE) << "Power setMode: " << static_cast(type) << " to: " << enabled; return ScopedAStatus::ok(); } ScopedAStatus Power::isModeSupported(Mode type, bool* _aidl_return) { LOG(INFO) << "Power isModeSupported: " << static_cast(type); *_aidl_return = type >= MODE_RANGE.front() && type <= MODE_RANGE.back(); return ScopedAStatus::ok(); } ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) { LOG(VERBOSE) << "Power setBoost: " << static_cast(type) << ", duration: " << durationMs; return ScopedAStatus::ok(); } ScopedAStatus Power::isBoostSupported(Boost type, bool* _aidl_return) { LOG(INFO) << "Power isBoostSupported: " << static_cast(type); *_aidl_return = type >= BOOST_RANGE.front() && type <= BOOST_RANGE.back(); return ScopedAStatus::ok(); } ndk::ScopedAStatus Power::getCpuHeadroom(const CpuHeadroomParams&, CpuHeadroomResult*) { return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } ndk::ScopedAStatus Power::getGpuHeadroom(const GpuHeadroomParams&, GpuHeadroomResult*) { return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } ScopedAStatus Power::createHintSession(int32_t, int32_t, const std::vector& tids, int64_t, std::shared_ptr* _aidl_return) { if (tids.size() == 0) { *_aidl_return = nullptr; return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } std::shared_ptr powerHintSession = ndk::SharedRefBase::make(); mPowerHintSessions.push_back(powerHintSession); *_aidl_return = powerHintSession; return ScopedAStatus::ok(); } ndk::ScopedAStatus Power::createHintSessionWithConfig( int32_t tgid, int32_t uid, const std::vector& threadIds, int64_t durationNanos, SessionTag, SessionConfig* config, std::shared_ptr* _aidl_return) { auto out = createHintSession(tgid, uid, threadIds, durationNanos, _aidl_return); static_cast(_aidl_return->get())->getSessionConfig(config); return out; } ndk::ScopedAStatus Power::getSessionChannel(int32_t, int32_t, ChannelConfig* _aidl_return) { static AidlMessageQueue stubQueue{20, true}; static std::thread stubThread([&] { ChannelMessage data; // This loop will only run while there is data waiting // to be processed, and blocks on a futex all other times while (stubQueue.readBlocking(&data, 1, 0)) { } }); _aidl_return->channelDescriptor = stubQueue.dupeDesc(); _aidl_return->readFlagBitmask = 0x01; _aidl_return->writeFlagBitmask = 0x02; _aidl_return->eventFlagDescriptor = std::nullopt; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Power::closeSessionChannel(int32_t, int32_t) { return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Power::getHintSessionPreferredRate(int64_t* outNanoseconds) { *outNanoseconds = std::chrono::nanoseconds(1ms).count(); return ScopedAStatus::ok(); } template int64_t bitsForEnum() { return static_cast(std::bitset()>().set().to_ullong()); } ndk::ScopedAStatus Power::getSupportInfo(SupportInfo* _aidl_return) { static SupportInfo supportInfo = {.usesSessions = false, .modes = bitsForEnum(), .boosts = bitsForEnum(), .sessionHints = 0, .sessionModes = 0, .sessionTags = 0, .compositionData = { .isSupported = false, .disableGpuFences = false, .maxBatchSize = 1, .alwaysBatch = false, }, .headroom = { .isCpuSupported = false, .isGpuSupported = false, .cpuMinIntervalMillis = 0, .gpuMinIntervalMillis = 0, }}; // Copy the support object into the binder *_aidl_return = supportInfo; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Power::sendCompositionData(const std::vector&) { LOG(INFO) << "Composition data received!"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Power::sendCompositionUpdate(const CompositionUpdate&) { LOG(INFO) << "Composition update received!"; return ndk::ScopedAStatus::ok(); } } // namespace example } // namespace impl } // namespace power } // namespace hardware } // namespace android } // namespace aidl