// Copyright 2018 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.

#include "ui/base/accelerators/media_keys_listener.h"

#include <ApplicationServices/ApplicationServices.h>
#include <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/hidsystem/ev_keymap.h>

#include "ui/base/accelerators/accelerator.h"

namespace ui {

namespace {

// The media keys subtype. No official docs found, but widely known.
// http://lists.apple.com/archives/cocoa-dev/2007/Aug/msg00499.html
const int kSystemDefinedEventMediaKeysSubtype = 8;

ui::KeyboardCode MediaKeyCodeToKeyboardCode(int key_code) {
  switch (key_code) {
    case NX_KEYTYPE_PLAY:
      return ui::VKEY_MEDIA_PLAY_PAUSE;
    case NX_KEYTYPE_PREVIOUS:
    case NX_KEYTYPE_REWIND:
      return ui::VKEY_MEDIA_PREV_TRACK;
    case NX_KEYTYPE_NEXT:
    case NX_KEYTYPE_FAST:
      return ui::VKEY_MEDIA_NEXT_TRACK;
  }
  return ui::VKEY_UNKNOWN;
}

class MediaKeysListenerImpl : public MediaKeysListener {
 public:
  MediaKeysListenerImpl(MediaKeysListener::Delegate* delegate, Scope scope);

  ~MediaKeysListenerImpl() override;

  // MediaKeysListener:
  void StartWatchingMediaKeys() override;
  void StopWatchingMediaKeys() override;
  bool IsWatchingMediaKeys() const override;

 private:
  // Callback on media key event.
  MediaKeysHandleResult OnMediaKeyEvent(int media_key_code);

  // The callback for when an event tap happens.
  static CGEventRef EventTapCallback(CGEventTapProxy proxy,
                                     CGEventType type,
                                     CGEventRef event,
                                     void* refcon);

  MediaKeysListener::Delegate* delegate_;
  const Scope scope_;
  // Event tap for intercepting mac media keys.
  CFMachPortRef event_tap_ = nullptr;
  CFRunLoopSourceRef event_tap_source_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(MediaKeysListenerImpl);
};

MediaKeysListenerImpl::MediaKeysListenerImpl(
    MediaKeysListener::Delegate* delegate,
    Scope scope)
    : delegate_(delegate), scope_(scope) {
  CHECK_NE(delegate_, nullptr);
}

MediaKeysListenerImpl::~MediaKeysListenerImpl() {
  if (event_tap_) {
    StopWatchingMediaKeys();
  }
}

void MediaKeysListenerImpl::StartWatchingMediaKeys() {
  // Make sure there's no existing event tap.
  if (event_tap_) {
    return;
  }
  DCHECK_EQ(event_tap_, nullptr);
  DCHECK_EQ(event_tap_source_, nullptr);

  // Add an event tap to intercept the system defined media key events.
  event_tap_ = CGEventTapCreate(
      kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault,
      CGEventMaskBit(NX_SYSDEFINED), EventTapCallback, this);
  if (event_tap_ == nullptr) {
    LOG(ERROR) << "Error: failed to create event tap.";
    return;
  }

  event_tap_source_ =
      CFMachPortCreateRunLoopSource(kCFAllocatorSystemDefault, event_tap_, 0);
  if (event_tap_source_ == nullptr) {
    LOG(ERROR) << "Error: failed to create new run loop source.";
    return;
  }

  CFRunLoopAddSource(CFRunLoopGetCurrent(), event_tap_source_,
                     kCFRunLoopCommonModes);

  // Notify the delegate that we're ready to receive key events.
  delegate_->OnStartedWatchingMediaKeys();
}

void MediaKeysListenerImpl::StopWatchingMediaKeys() {
  if (!event_tap_) {
    return;
  }
  CFRunLoopRemoveSource(CFRunLoopGetCurrent(), event_tap_source_,
                        kCFRunLoopCommonModes);
  // Ensure both event tap and source are initialized.
  DCHECK_NE(event_tap_, nullptr);
  DCHECK_NE(event_tap_source_, nullptr);

  // Invalidate the event tap.
  CFMachPortInvalidate(event_tap_);
  CFRelease(event_tap_);
  event_tap_ = nullptr;

  // Release the event tap source.
  CFRelease(event_tap_source_);
  event_tap_source_ = nullptr;
}

bool MediaKeysListenerImpl::IsWatchingMediaKeys() const {
  return event_tap_ != nullptr;
}

MediaKeysListener::MediaKeysHandleResult MediaKeysListenerImpl::OnMediaKeyEvent(
    int media_key_code) {
  const ui::KeyboardCode key_code = MediaKeyCodeToKeyboardCode(media_key_code);
  // Create an accelerator corresponding to the keyCode.
  const ui::Accelerator accelerator(key_code, 0);
  return delegate_->OnMediaKeysAccelerator(accelerator);
}

// Processed events should propagate if they aren't handled by any listeners.
// For events that don't matter, this handler should return as quickly as
// possible.
// Returning event causes the event to propagate to other applications.
// Returning nullptr prevents the event from propagating.
// static
CGEventRef MediaKeysListenerImpl::EventTapCallback(CGEventTapProxy proxy,
                                                   CGEventType type,
                                                   CGEventRef event,
                                                   void* refcon) {
  MediaKeysListenerImpl* shortcut_listener =
      static_cast<MediaKeysListenerImpl*>(refcon);

  const bool is_active = [NSApp isActive];

  if (shortcut_listener->scope_ == Scope::kFocused && !is_active) {
    return event;
  }

  // Handle the timeout case by re-enabling the tap.
  if (type == kCGEventTapDisabledByTimeout) {
    CGEventTapEnable(shortcut_listener->event_tap_, true);
    return event;
  }

  // Convert the CGEvent to an NSEvent for access to the data1 field.
  NSEvent* ns_event = [NSEvent eventWithCGEvent:event];
  if (ns_event == nil) {
    return event;
  }

  // Ignore events that are not system defined media keys.
  if (type != NX_SYSDEFINED || [ns_event type] != NSSystemDefined ||
      [ns_event subtype] != kSystemDefinedEventMediaKeysSubtype) {
    return event;
  }

  NSInteger data1 = [ns_event data1];
  // Ignore media keys that aren't previous, next and play/pause.
  // Magical constants are from http://weblog.rogueamoeba.com/2007/09/29/
  int key_code = (data1 & 0xFFFF0000) >> 16;
  if (key_code != NX_KEYTYPE_PLAY && key_code != NX_KEYTYPE_NEXT &&
      key_code != NX_KEYTYPE_PREVIOUS && key_code != NX_KEYTYPE_FAST &&
      key_code != NX_KEYTYPE_REWIND) {
    return event;
  }

  int key_flags = data1 & 0x0000FFFF;
  bool is_key_pressed = ((key_flags & 0xFF00) >> 8) == 0xA;

  // If the key wasn't pressed (eg. was released), ignore this event.
  if (!is_key_pressed)
    return event;

  // Now we have a media key that we care about. Send it to the caller.
  auto result = shortcut_listener->OnMediaKeyEvent(key_code);

  // Prevent event from proagating to other apps if handled by Chrome.
  if (result == MediaKeysHandleResult::kSuppressPropagation) {
    return nullptr;
  }

  // By default, pass the event through.
  return event;
}

}  // namespace

std::unique_ptr<MediaKeysListener> MediaKeysListener::Create(
    MediaKeysListener::Delegate* delegate,
    MediaKeysListener::Scope scope) {
  return std::make_unique<MediaKeysListenerImpl>(delegate, scope);
}

}  // namespace ui
