/* * Copyright (C) 2015 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 <nativepower/power_manager_client.h> #include <base/bind.h> #include <base/logging.h> #include <binder/IBinder.h> #include <binderwrapper/binder_wrapper.h> #include <nativepower/constants.h> #include <nativepower/wake_lock.h> #include <powermanager/PowerManager.h> namespace android { namespace { // Returns the string corresponding to |reason|. Values are hardcoded in // core/java/android/os/PowerManager.java. String16 ShutdownReasonToString16(ShutdownReason reason) { switch (reason) { case ShutdownReason::DEFAULT: return String16(); case ShutdownReason::USER_REQUESTED: return String16(kShutdownReasonUserRequested); default: LOG(ERROR) << "Unknown shutdown reason " << static_cast<int>(reason); return String16(); } } // Returns the string corresponding to |reason|. Values are hardcoded in // core/java/android/os/PowerManager.java. String16 RebootReasonToString16(RebootReason reason) { switch (reason) { case RebootReason::DEFAULT: return String16(); case RebootReason::RECOVERY: return String16(kRebootReasonRecovery); default: LOG(ERROR) << "Unknown reboot reason " << static_cast<int>(reason); return String16(); } } } // namespace PowerManagerClient::PowerManagerClient() : weak_ptr_factory_(this) {} PowerManagerClient::~PowerManagerClient() { if (power_manager_.get()) { BinderWrapper::Get()->UnregisterForDeathNotifications( IInterface::asBinder(power_manager_)); } } bool PowerManagerClient::Init() { sp<IBinder> power_manager_binder = BinderWrapper::Get()->GetService(kPowerManagerServiceName); if (!power_manager_binder.get()) { LOG(ERROR) << "Didn't get " << kPowerManagerServiceName << " service"; return false; } BinderWrapper::Get()->RegisterForDeathNotifications( power_manager_binder, base::Bind(&PowerManagerClient::OnPowerManagerDied, weak_ptr_factory_.GetWeakPtr())); power_manager_ = interface_cast<IPowerManager>(power_manager_binder); return true; } std::unique_ptr<WakeLock> PowerManagerClient::CreateWakeLock( const std::string& tag, const std::string& package) { std::unique_ptr<WakeLock> lock(new WakeLock(tag, package, this)); if (!lock->Init()) lock.reset(); return lock; } bool PowerManagerClient::Suspend(base::TimeDelta event_uptime, SuspendReason reason, int flags) { DCHECK(power_manager_.get()); status_t status = power_manager_->goToSleep( event_uptime.InMilliseconds(), static_cast<int>(reason), flags); if (status != OK) { LOG(ERROR) << "Suspend request failed with status " << status; return false; } return true; } bool PowerManagerClient::ShutDown(ShutdownReason reason) { DCHECK(power_manager_.get()); status_t status = power_manager_->shutdown(false /* confirm */, ShutdownReasonToString16(reason), false /* wait */); if (status != OK) { LOG(ERROR) << "Shutdown request failed with status " << status; return false; } return true; } bool PowerManagerClient::Reboot(RebootReason reason) { DCHECK(power_manager_.get()); status_t status = power_manager_->reboot(false /* confirm */, RebootReasonToString16(reason), false /* wait */); if (status != OK) { LOG(ERROR) << "Reboot request failed with status " << status; return false; } return true; } void PowerManagerClient::OnPowerManagerDied() { LOG(WARNING) << "Power manager died"; power_manager_.clear(); // TODO: Try to get a new handle periodically; also consider notifying // previously-created WakeLock objects so they can reacquire locks. } } // namespace android