// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Implementation based on sample code from
// http://developer.apple.com/library/mac/#qa/qa1340/_index.html.

#include "base/power_monitor/power_monitor_device_source.h"

#include "base/mac/foundation_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_source.h"

#include <IOKit/IOMessage.h>
#include <IOKit/ps/IOPSKeys.h>
#include <IOKit/ps/IOPowerSources.h>
#include <IOKit/pwr_mgt/IOPMLib.h>

namespace base {

void ProcessPowerEventHelper(PowerMonitorSource::PowerEvent event) {
  PowerMonitorSource::ProcessPowerEvent(event);
}

bool PowerMonitorDeviceSource::IsOnBatteryPower() {
  base::ScopedCFTypeRef<CFTypeRef> info(IOPSCopyPowerSourcesInfo());
  if (!info)
    return false;
  base::ScopedCFTypeRef<CFArrayRef> power_sources_list(
      IOPSCopyPowerSourcesList(info));
  if (!power_sources_list)
    return false;

  bool found_battery = false;
  const CFIndex count = CFArrayGetCount(power_sources_list);
  for (CFIndex i = 0; i < count; ++i) {
    const CFDictionaryRef description = IOPSGetPowerSourceDescription(
        info, CFArrayGetValueAtIndex(power_sources_list, i));
    if (!description)
      continue;

    CFStringRef current_state = base::mac::GetValueFromDictionary<CFStringRef>(
        description, CFSTR(kIOPSPowerSourceStateKey));
    if (!current_state)
      continue;

    // We only report "on battery power" if no source is on AC power.
    if (CFStringCompare(current_state, CFSTR(kIOPSOffLineValue), 0) ==
        kCFCompareEqualTo) {
      continue;
    } else if (CFStringCompare(current_state, CFSTR(kIOPSACPowerValue), 0) ==
               kCFCompareEqualTo) {
      return false;
    }

    DCHECK_EQ(CFStringCompare(current_state, CFSTR(kIOPSBatteryPowerValue), 0),
              kCFCompareEqualTo)
        << "Power source state is not one of 3 documented values";

    found_battery = true;
  }

  // At this point, either there were no readable batteries found, in which case
  // this Mac is not on battery power, or all the readable batteries were on
  // battery power, in which case, count this as being on battery power.
  return found_battery;
}

PowerThermalObserver::DeviceThermalState
PowerMonitorDeviceSource::GetCurrentThermalState() {
  return thermal_state_observer_->GetCurrentThermalState();
}

int PowerMonitorDeviceSource::GetInitialSpeedLimit() {
  return thermal_state_observer_->GetCurrentSpeedLimit();
}

namespace {

void BatteryEventCallback(void*) {
  ProcessPowerEventHelper(PowerMonitorSource::POWER_STATE_EVENT);
}

}  // namespace

void PowerMonitorDeviceSource::PlatformInit() {
  power_manager_port_ = IORegisterForSystemPower(
      this,
      mac::ScopedIONotificationPortRef::Receiver(notification_port_).get(),
      &SystemPowerEventCallback, &notifier_);
  DCHECK_NE(power_manager_port_, IO_OBJECT_NULL);

  // Add the sleep/wake notification event source to the runloop.
  CFRunLoopAddSource(
      CFRunLoopGetCurrent(),
      IONotificationPortGetRunLoopSource(notification_port_.get()),
      kCFRunLoopCommonModes);

  // Create and add the power-source-change event source to the runloop.
  power_source_run_loop_source_.reset(
      IOPSNotificationCreateRunLoopSource(&BatteryEventCallback, nullptr));
  // Verify that the source was created. This may fail if the sandbox does not
  // permit the process to access the underlying system service. See
  // https://crbug.com/897557 for an example of such a configuration bug.
  DCHECK(power_source_run_loop_source_);

  CFRunLoopAddSource(CFRunLoopGetCurrent(), power_source_run_loop_source_,
                     kCFRunLoopDefaultMode);

  thermal_state_observer_ = std::make_unique<ThermalStateObserverMac>(
      BindRepeating(&PowerMonitorSource::ProcessThermalEvent),
      BindRepeating(&PowerMonitorSource::ProcessSpeedLimitEvent));
}

void PowerMonitorDeviceSource::PlatformDestroy() {
  CFRunLoopRemoveSource(
      CFRunLoopGetCurrent(),
      IONotificationPortGetRunLoopSource(notification_port_.get()),
      kCFRunLoopCommonModes);

  CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
                        power_source_run_loop_source_.get(),
                        kCFRunLoopDefaultMode);

  // Deregister for system power notifications.
  IODeregisterForSystemPower(&notifier_);

  // Close the connection to the IOPMrootDomain that was opened in
  // PlatformInit().
  IOServiceClose(power_manager_port_);
  power_manager_port_ = IO_OBJECT_NULL;
}

void PowerMonitorDeviceSource::SystemPowerEventCallback(
    void* refcon,
    io_service_t service,
    natural_t message_type,
    void* message_argument) {
  auto* thiz = static_cast<PowerMonitorDeviceSource*>(refcon);

  switch (message_type) {
    // If this message is not handled the system may delay sleep for 30 seconds.
    case kIOMessageCanSystemSleep:
      IOAllowPowerChange(thiz->power_manager_port_,
                         reinterpret_cast<intptr_t>(message_argument));
      break;
    case kIOMessageSystemWillSleep:
      ProcessPowerEventHelper(PowerMonitorSource::SUSPEND_EVENT);
      IOAllowPowerChange(thiz->power_manager_port_,
                         reinterpret_cast<intptr_t>(message_argument));
      break;

    case kIOMessageSystemWillPowerOn:
      ProcessPowerEventHelper(PowerMonitorSource::RESUME_EVENT);
      break;
  }
}

}  // namespace base
