// Copyright (c) 2012 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 "media/device_monitors/device_monitor_mac.h"

#include <AVFoundation/AVFoundation.h>
#include <set>

#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/mac/bind_objc_block.h"
#include "base/mac/scoped_nsobject.h"
#include "base/macros.h"
#include "base/profiler/scoped_tracker.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_checker.h"

namespace {

// This class is used to keep track of system devices names and their types.
class DeviceInfo {
 public:
  enum DeviceType { kAudio, kVideo, kMuxed, kUnknown, kInvalid };

  DeviceInfo(const std::string& unique_id, DeviceType type)
      : unique_id_(unique_id), type_(type) {}

  // Operator== is needed here to use this class in a std::find. A given
  // |unique_id_| always has the same |type_| so for comparison purposes the
  // latter can be safely ignored.
  bool operator==(const DeviceInfo& device) const {
    return unique_id_ == device.unique_id_;
  }

  const std::string& unique_id() const { return unique_id_; }
  DeviceType type() const { return type_; }

 private:
  std::string unique_id_;
  DeviceType type_;
  // Allow generated copy constructor and assignment.
};

// Base abstract class used by DeviceMonitorMac.
class DeviceMonitorMacImpl {
 public:
  explicit DeviceMonitorMacImpl(media::DeviceMonitorMac* monitor)
      : monitor_(monitor),
        cached_devices_(),
        device_arrival_(nil),
        device_removal_(nil) {
    DCHECK(monitor);
    // Initialise the devices_cache_ with a not-valid entry. For the case in
    // which there is one single device in the system and we get notified when
    // it gets removed, this will prevent the system from thinking that no
    // devices were added nor removed and not notifying the |monitor_|.
    cached_devices_.push_back(DeviceInfo("invalid", DeviceInfo::kInvalid));
  }
  virtual ~DeviceMonitorMacImpl() {}

  virtual void OnDeviceChanged() = 0;

  // Method called by the default notification center when a device is removed
  // or added to the system. It will compare the |cached_devices_| with the
  // current situation, update it, and, if there's an update, signal to
  // |monitor_| with the appropriate device type.
  void ConsolidateDevicesListAndNotify(
      const std::vector<DeviceInfo>& snapshot_devices);

 protected:
  media::DeviceMonitorMac* monitor_;
  std::vector<DeviceInfo> cached_devices_;

  // Handles to NSNotificationCenter block observers.
  id device_arrival_;
  id device_removal_;

 private:
  DISALLOW_COPY_AND_ASSIGN(DeviceMonitorMacImpl);
};

void DeviceMonitorMacImpl::ConsolidateDevicesListAndNotify(
    const std::vector<DeviceInfo>& snapshot_devices) {
  bool video_device_added = false;
  bool audio_device_added = false;
  bool video_device_removed = false;
  bool audio_device_removed = false;

  // Compare the current system devices snapshot with the ones cached to detect
  // additions, present in the former but not in the latter. If we find a device
  // in snapshot_devices entry also present in cached_devices, we remove it from
  // the latter vector.
  std::vector<DeviceInfo>::const_iterator it;
  for (it = snapshot_devices.begin(); it != snapshot_devices.end(); ++it) {
    std::vector<DeviceInfo>::iterator cached_devices_iterator =
        std::find(cached_devices_.begin(), cached_devices_.end(), *it);
    if (cached_devices_iterator == cached_devices_.end()) {
      video_device_added |= ((it->type() == DeviceInfo::kVideo) ||
                             (it->type() == DeviceInfo::kMuxed));
      audio_device_added |= ((it->type() == DeviceInfo::kAudio) ||
                             (it->type() == DeviceInfo::kMuxed));
      DVLOG(1) << "Device has been added, id: " << it->unique_id();
    } else {
      cached_devices_.erase(cached_devices_iterator);
    }
  }
  // All the remaining entries in cached_devices are removed devices.
  for (it = cached_devices_.begin(); it != cached_devices_.end(); ++it) {
    video_device_removed |= ((it->type() == DeviceInfo::kVideo) ||
                             (it->type() == DeviceInfo::kMuxed) ||
                             (it->type() == DeviceInfo::kInvalid));
    audio_device_removed |= ((it->type() == DeviceInfo::kAudio) ||
                             (it->type() == DeviceInfo::kMuxed) ||
                             (it->type() == DeviceInfo::kInvalid));
    DVLOG(1) << "Device has been removed, id: " << it->unique_id();
  }
  // Update the cached devices with the current system snapshot.
  cached_devices_ = snapshot_devices;

  if (video_device_added || video_device_removed)
    monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
  if (audio_device_added || audio_device_removed)
    monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_AUDIO);
}

// Forward declaration for use by CrAVFoundationDeviceObserver.
class SuspendObserverDelegate;

}  // namespace

// This class is a Key-Value Observer (KVO) shim. It is needed because C++
// classes cannot observe Key-Values directly. Created, manipulated, and
// destroyed on the UI Thread by SuspendObserverDelegate.
@interface CrAVFoundationDeviceObserver : NSObject {
 @private
  // Callback for device changed, has to run on Device Thread.
  base::Closure onDeviceChangedCallback_;

  // Member to keep track of the devices we are already monitoring.
  std::set<base::scoped_nsobject<AVCaptureDevice>> monitoredDevices_;

  // Pegged to the "main" thread -- usually content::BrowserThread::UI.
  base::ThreadChecker mainThreadChecker_;
}

- (id)initWithOnChangedCallback:(const base::Closure&)callback;
- (void)startObserving:(base::scoped_nsobject<AVCaptureDevice>)device;
- (void)stopObserving:(AVCaptureDevice*)device;
- (void)clearOnDeviceChangedCallback;

@end

namespace {

// This class owns and manages the lifetime of a CrAVFoundationDeviceObserver.
// It is created and destroyed on AVFoundationMonitorImpl's main thread (usually
// browser's UI thread), and it operates on this thread except for the expensive
// device enumerations which are run on Device Thread.
class SuspendObserverDelegate
    : public base::RefCountedThreadSafe<SuspendObserverDelegate> {
 public:
  explicit SuspendObserverDelegate(DeviceMonitorMacImpl* monitor);

  // Create |suspend_observer_| for all devices and register OnDeviceChanged()
  // as its change callback. Schedule bottom half in DoStartObserver().
  void StartObserver(
      const scoped_refptr<base::SingleThreadTaskRunner>& device_thread);
  // Enumerate devices in |device_thread| and run the bottom half in
  // DoOnDeviceChange(). |suspend_observer_| calls back here on suspend event,
  // and our parent AVFoundationMonitorImpl calls on connect/disconnect device.
  void OnDeviceChanged(
      const scoped_refptr<base::SingleThreadTaskRunner>& device_thread);
  // Remove the device monitor's weak reference. Remove ourselves as suspend
  // notification observer from |suspend_observer_|.
  void ResetDeviceMonitor();

 private:
  friend class base::RefCountedThreadSafe<SuspendObserverDelegate>;

  virtual ~SuspendObserverDelegate();

  // Bottom half of StartObserver(), starts |suspend_observer_| for all devices.
  // Assumes that |devices| has been retained prior to being called, and
  // releases it internally.
  void DoStartObserver(NSArray* devices);
  // Bottom half of OnDeviceChanged(), starts |suspend_observer_| for current
  // devices and composes a snapshot of them to send it to
  // |avfoundation_monitor_impl_|. Assumes that |devices| has been retained
  // prior to being called, and releases it internally.
  void DoOnDeviceChanged(NSArray* devices);

  base::scoped_nsobject<CrAVFoundationDeviceObserver> suspend_observer_;
  DeviceMonitorMacImpl* avfoundation_monitor_impl_;

  // Pegged to the "main" thread -- usually content::BrowserThread::UI.
  base::ThreadChecker main_thread_checker_;
};

SuspendObserverDelegate::SuspendObserverDelegate(DeviceMonitorMacImpl* monitor)
    : avfoundation_monitor_impl_(monitor) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
}

void SuspendObserverDelegate::StartObserver(
    const scoped_refptr<base::SingleThreadTaskRunner>& device_thread) {
  DCHECK(main_thread_checker_.CalledOnValidThread());

  base::Closure on_device_changed_callback = base::Bind(
      &SuspendObserverDelegate::OnDeviceChanged, this, device_thread);
  suspend_observer_.reset([[CrAVFoundationDeviceObserver alloc]
      initWithOnChangedCallback:on_device_changed_callback]);

  // Enumerate the devices in Device thread and post the observers start to be
  // done on UI thread. The devices array is retained in |device_thread| and
  // released in DoStartObserver().
  base::PostTaskAndReplyWithResult(
      device_thread.get(), FROM_HERE, base::BindBlock(^{
        return [[AVCaptureDevice devices] retain];
      }),
      base::Bind(&SuspendObserverDelegate::DoStartObserver, this));
}

void SuspendObserverDelegate::OnDeviceChanged(
    const scoped_refptr<base::SingleThreadTaskRunner>& device_thread) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  // Enumerate the devices in Device thread and post the consolidation of the
  // new devices and the old ones to be done on main thread. The devices array
  // is retained in |device_thread| and released in DoOnDeviceChanged().
  PostTaskAndReplyWithResult(
      device_thread.get(), FROM_HERE, base::BindBlock(^{
        return [[AVCaptureDevice devices] retain];
      }),
      base::Bind(&SuspendObserverDelegate::DoOnDeviceChanged, this));
}

void SuspendObserverDelegate::ResetDeviceMonitor() {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  avfoundation_monitor_impl_ = NULL;
  [suspend_observer_ clearOnDeviceChangedCallback];
}

SuspendObserverDelegate::~SuspendObserverDelegate() {
  DCHECK(main_thread_checker_.CalledOnValidThread());
}

void SuspendObserverDelegate::DoStartObserver(NSArray* devices) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  base::scoped_nsobject<NSArray> auto_release(devices);
  for (AVCaptureDevice* device in devices) {
    base::scoped_nsobject<AVCaptureDevice> device_ptr([device retain]);
    [suspend_observer_ startObserving:device_ptr];
  }
}

void SuspendObserverDelegate::DoOnDeviceChanged(NSArray* devices) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  base::scoped_nsobject<NSArray> auto_release(devices);
  std::vector<DeviceInfo> snapshot_devices;
  for (AVCaptureDevice* device in devices) {
    base::scoped_nsobject<AVCaptureDevice> device_ptr([device retain]);
    [suspend_observer_ startObserving:device_ptr];

    BOOL suspended = [device respondsToSelector:@selector(isSuspended)] &&
                     [device isSuspended];
    DeviceInfo::DeviceType device_type = DeviceInfo::kUnknown;
    if ([device hasMediaType:AVMediaTypeVideo]) {
      if (suspended)
        continue;
      device_type = DeviceInfo::kVideo;
    } else if ([device hasMediaType:AVMediaTypeMuxed]) {
      device_type = suspended ? DeviceInfo::kAudio : DeviceInfo::kMuxed;
    } else if ([device hasMediaType:AVMediaTypeAudio]) {
      device_type = DeviceInfo::kAudio;
    }
    snapshot_devices.push_back(
        DeviceInfo([[device uniqueID] UTF8String], device_type));
  }
  // Make sure no references are held to |devices| when
  // ConsolidateDevicesListAndNotify is called since the VideoCaptureManager
  // and AudioCaptureManagers also enumerates the available devices but on
  // another thread.
  auto_release.reset();
  // |avfoundation_monitor_impl_| might have been NULLed asynchronously before
  // arriving at this line.
  if (avfoundation_monitor_impl_) {
    avfoundation_monitor_impl_->ConsolidateDevicesListAndNotify(
        snapshot_devices);
  }
}

// AVFoundation implementation of the Mac Device Monitor, registers as a global
// device connect/disconnect observer and plugs suspend/wake up device observers
// per device. This class is created and lives on the main Application thread
// (UI for content). Owns a SuspendObserverDelegate that notifies when a device
// is suspended/resumed.
class AVFoundationMonitorImpl : public DeviceMonitorMacImpl {
 public:
  AVFoundationMonitorImpl(
      media::DeviceMonitorMac* monitor,
      const scoped_refptr<base::SingleThreadTaskRunner>& device_task_runner);
  ~AVFoundationMonitorImpl() override;

  void OnDeviceChanged() override;

 private:
  // {Video,AudioInput}DeviceManager's "Device" thread task runner used for
  // posting tasks to |suspend_observer_delegate_|;
  const scoped_refptr<base::SingleThreadTaskRunner> device_task_runner_;

  // Pegged to the "main" thread -- usually content::BrowserThread::UI.
  base::ThreadChecker main_thread_checker_;

  scoped_refptr<SuspendObserverDelegate> suspend_observer_delegate_;

  DISALLOW_COPY_AND_ASSIGN(AVFoundationMonitorImpl);
};

AVFoundationMonitorImpl::AVFoundationMonitorImpl(
    media::DeviceMonitorMac* monitor,
    const scoped_refptr<base::SingleThreadTaskRunner>& device_task_runner)
    : DeviceMonitorMacImpl(monitor),
      device_task_runner_(device_task_runner),
      suspend_observer_delegate_(new SuspendObserverDelegate(this)) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
  device_arrival_ =
      [nc addObserverForName:AVCaptureDeviceWasConnectedNotification
                      object:nil
                       queue:nil
                  usingBlock:^(NSNotification* notification) {
                    OnDeviceChanged();
                  }];
  device_removal_ =
      [nc addObserverForName:AVCaptureDeviceWasDisconnectedNotification
                      object:nil
                       queue:nil
                  usingBlock:^(NSNotification* notification) {
                    OnDeviceChanged();
                  }];
  suspend_observer_delegate_->StartObserver(device_task_runner_);
}

AVFoundationMonitorImpl::~AVFoundationMonitorImpl() {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  suspend_observer_delegate_->ResetDeviceMonitor();
  NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
  [nc removeObserver:device_arrival_];
  [nc removeObserver:device_removal_];
}

void AVFoundationMonitorImpl::OnDeviceChanged() {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  suspend_observer_delegate_->OnDeviceChanged(device_task_runner_);
}

}  // namespace

@implementation CrAVFoundationDeviceObserver

- (id)initWithOnChangedCallback:(const base::Closure&)callback {
  DCHECK(mainThreadChecker_.CalledOnValidThread());
  if ((self = [super init])) {
    DCHECK(!callback.is_null());
    onDeviceChangedCallback_ = callback;
  }
  return self;
}

- (void)dealloc {
  DCHECK(mainThreadChecker_.CalledOnValidThread());
  std::set<base::scoped_nsobject<AVCaptureDevice>>::iterator it =
      monitoredDevices_.begin();
  while (it != monitoredDevices_.end())
    [self removeObservers:*(it++)];
  [super dealloc];
}

- (void)startObserving:(base::scoped_nsobject<AVCaptureDevice>)device {
  DCHECK(mainThreadChecker_.CalledOnValidThread());
  DCHECK(device != nil);
  // Skip this device if there are already observers connected to it.
  if (std::find(monitoredDevices_.begin(), monitoredDevices_.end(), device) !=
      monitoredDevices_.end()) {
    return;
  }
  [device addObserver:self
           forKeyPath:@"suspended"
              options:0
              context:device.get()];
  [device addObserver:self
           forKeyPath:@"connected"
              options:0
              context:device.get()];
  monitoredDevices_.insert(device);
}

- (void)stopObserving:(AVCaptureDevice*)device {
  DCHECK(mainThreadChecker_.CalledOnValidThread());
  DCHECK(device != nil);

  std::set<base::scoped_nsobject<AVCaptureDevice>>::iterator found =
      std::find(monitoredDevices_.begin(), monitoredDevices_.end(), device);
  DCHECK(found != monitoredDevices_.end());
  [self removeObservers:*found];
  monitoredDevices_.erase(found);
}

- (void)clearOnDeviceChangedCallback {
  DCHECK(mainThreadChecker_.CalledOnValidThread());
  onDeviceChangedCallback_.Reset();
}

- (void)removeObservers:(AVCaptureDevice*)device {
  DCHECK(mainThreadChecker_.CalledOnValidThread());
  // Check sanity of |device| via its -observationInfo. http://crbug.com/371271.
  if ([device observationInfo]) {
    [device removeObserver:self
                forKeyPath:@"suspended"];
    [device removeObserver:self
                forKeyPath:@"connected"];
  }
}

- (void)observeValueForKeyPath:(NSString*)keyPath
                      ofObject:(id)object
                        change:(NSDictionary*)change
                       context:(void*)context {
  DCHECK(mainThreadChecker_.CalledOnValidThread());
  if ([keyPath isEqual:@"suspended"])
    onDeviceChangedCallback_.Run();
  if ([keyPath isEqual:@"connected"])
    [self stopObserving:static_cast<AVCaptureDevice*>(context)];
}

@end  // @implementation CrAVFoundationDeviceObserver

namespace media {

DeviceMonitorMac::DeviceMonitorMac() {
  // AVFoundation do not need to be fired up until the user
  // exercises a GetUserMedia. Bringing up either library and enumerating the
  // devices in the system is an operation taking in the range of hundred of ms,
  // so it is triggered explicitly from MediaStreamManager::StartMonitoring().
}

DeviceMonitorMac::~DeviceMonitorMac() {}

void DeviceMonitorMac::StartMonitoring(
    const scoped_refptr<base::SingleThreadTaskRunner>& device_task_runner) {
  DCHECK(thread_checker_.CalledOnValidThread());

    // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/458404
    // is fixed.
    tracked_objects::ScopedTracker tracking_profile(
        FROM_HERE_WITH_EXPLICIT_FUNCTION(
            "458404 DeviceMonitorMac::StartMonitoring::AVFoundation"));
    DVLOG(1) << "Monitoring via AVFoundation";
    device_monitor_impl_.reset(
        new AVFoundationMonitorImpl(this, device_task_runner));
}

void DeviceMonitorMac::NotifyDeviceChanged(
    base::SystemMonitor::DeviceType type) {
  DCHECK(thread_checker_.CalledOnValidThread());
  // TODO(xians): Remove the global variable for SystemMonitor.
  base::SystemMonitor::Get()->ProcessDevicesChanged(type);
}

}  // namespace media
