/****************************************************************************** * * Copyright 2021 Google, Inc. * * 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 "BtGdWakelockNative" #include "os/internal/wakelock_native.h" #include #include #include #include #include #include "os/log.h" namespace bluetooth { namespace os { namespace internal { using android::sp; using android::system::suspend::V1_0::ISystemSuspend; using android::system::suspend::V1_0::IWakeLock; using android::system::suspend::V1_0::WakeLockType; struct WakelockNative::Impl { sp suspend_service = nullptr; sp current_wakelock = nullptr; class SystemSuspendDeathRecipient : public ::android::hardware::hidl_death_recipient { public: explicit SystemSuspendDeathRecipient(WakelockNative::Impl* impl) : impl_(impl) {} void serviceDied(uint64_t /*cookie*/, const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) override { LOG_ERROR("ISystemSuspend HAL service died!"); impl_->suspend_service = nullptr; } private: WakelockNative::Impl* impl_ = nullptr; }; sp suspend_death_recipient; }; void WakelockNative::Initialize() { LOG_INFO("Initializing native wake locks"); pimpl_->suspend_service = ISystemSuspend::getService(); ASSERT_LOG(pimpl_->suspend_service, "Cannot get ISystemSuspend service"); pimpl_->suspend_death_recipient = new Impl::SystemSuspendDeathRecipient(pimpl_.get()); pimpl_->suspend_service->linkToDeath(pimpl_->suspend_death_recipient, 0 /* cookie */); } WakelockNative::StatusCode WakelockNative::Acquire(const std::string& lock_name) { if (!pimpl_->suspend_service) { LOG_ERROR("lock not acquired, ISystemService is not available"); return StatusCode::NATIVE_SERVICE_NOT_AVAILABLE; } if (pimpl_->current_wakelock) { LOG_INFO("wakelock is already acquired"); return StatusCode::SUCCESS; } pimpl_->current_wakelock = pimpl_->suspend_service->acquireWakeLock(WakeLockType::PARTIAL, lock_name); if (!pimpl_->current_wakelock) { LOG_ERROR("wake lock not acquired: %s", strerror(errno)); return StatusCode::NATIVE_API_ERROR; } return StatusCode::SUCCESS; } WakelockNative::StatusCode WakelockNative::Release(const std::string& lock_name) { if (!pimpl_->current_wakelock) { LOG_WARN("no lock is currently acquired"); return StatusCode::SUCCESS; } pimpl_->current_wakelock->release(); pimpl_->current_wakelock.clear(); return StatusCode::SUCCESS; } void WakelockNative::CleanUp() { LOG_INFO("Cleaning up native wake locks"); if (pimpl_->current_wakelock) { LOG_INFO("releasing current wakelock during clean up"); pimpl_->current_wakelock->release(); pimpl_->current_wakelock.clear(); } if (pimpl_->suspend_service) { LOG_INFO("Unlink death recipient"); pimpl_->suspend_service->unlinkToDeath(pimpl_->suspend_death_recipient); pimpl_->suspend_death_recipient.clear(); pimpl_->suspend_service.clear(); } } WakelockNative::WakelockNative() : pimpl_(std::make_unique()) {} WakelockNative::~WakelockNative() = default; } // namespace internal } // namespace os } // namespace bluetooth