// 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 "device/media_transfer_protocol/media_transfer_protocol_manager.h"

#include <algorithm>
#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/containers/queue.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/sequenced_task_runner.h"
#include "base/stl_util.h"
#include "base/threading/thread_checker.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "dbus/bus.h"
#include "device/media_transfer_protocol/media_transfer_protocol_daemon_client.h"
#include "device/media_transfer_protocol/mtp_storage_info.pb.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace device {

namespace {

#if DCHECK_IS_ON()
MediaTransferProtocolManager* g_media_transfer_protocol_manager = nullptr;
#endif

// When reading directory entries, this is the number of entries for
// GetFileInfo() to read in one operation. If set too low, efficiency goes down
// slightly due to the overhead of D-Bus calls. If set too high, then slow
// devices may trigger a D-Bus timeout.
// The value below is a good initial estimate.
const size_t kFileInfoToFetchChunkSize = 25;

// On the first call to GetFileInfo, the offset to use is 0.
const size_t kInitialOffset = 0;

// The MediaTransferProtocolManager implementation.
class MediaTransferProtocolManagerImpl : public MediaTransferProtocolManager {
 public:
  MediaTransferProtocolManagerImpl()
      : bus_(chromeos::DBusThreadManager::Get()->GetSystemBus()),
        weak_ptr_factory_(this) {
    // Listen for future mtpd service owner changes, in case it is not
    // available right now. There is no guarantee that mtpd is running already.
    mtpd_owner_changed_callback_ =
        base::Bind(&MediaTransferProtocolManagerImpl::FinishSetupOnOriginThread,
                   weak_ptr_factory_.GetWeakPtr());
    if (bus_) {
      bus_->ListenForServiceOwnerChange(mtpd::kMtpdServiceName,
                                        mtpd_owner_changed_callback_);
      bus_->GetServiceOwner(mtpd::kMtpdServiceName,
                            mtpd_owner_changed_callback_);
    }
  }

  ~MediaTransferProtocolManagerImpl() override {
#if DCHECK_IS_ON()
    DCHECK(g_media_transfer_protocol_manager);
    g_media_transfer_protocol_manager = nullptr;
#endif
    if (bus_) {
      bus_->UnlistenForServiceOwnerChange(mtpd::kMtpdServiceName,
                                          mtpd_owner_changed_callback_);
    }

    VLOG(1) << "MediaTransferProtocolManager Shutdown completed";
  }

  // MediaTransferProtocolManager override.
  void AddObserver(Observer* observer) override {
    DCHECK(thread_checker_.CalledOnValidThread());
    observers_.AddObserver(observer);
  }

  // MediaTransferProtocolManager override.
  void RemoveObserver(Observer* observer) override {
    DCHECK(thread_checker_.CalledOnValidThread());
    observers_.RemoveObserver(observer);
  }

  // MediaTransferProtocolManager override.
  void GetStorages(GetStoragesCallback callback) const override {
    DCHECK(thread_checker_.CalledOnValidThread());
    std::vector<std::string> storages;
    storages.reserve(storage_info_map_.size());
    for (const auto& info : storage_info_map_)
      storages.push_back(info.first);
    std::move(callback).Run(storages);
  }

  // MediaTransferProtocolManager override.
  const mojom::MtpStorageInfo* GetStorageInfo(
      const std::string& storage_name) const override {
    DCHECK(thread_checker_.CalledOnValidThread());
    const auto it = storage_info_map_.find(storage_name);
    return it != storage_info_map_.end() ? &it->second : nullptr;
  }

  // MediaTransferProtocolManager override.
  void GetStorageInfoFromDevice(
      const std::string& storage_name,
      const GetStorageInfoFromDeviceCallback& callback) override {
    DCHECK(thread_checker_.CalledOnValidThread());
    if (!base::ContainsKey(storage_info_map_, storage_name) || !mtp_client_) {
      mojom::MtpStorageInfo info;
      callback.Run(info, true /* error */);
      return;
    }
    get_storage_info_from_device_callbacks_.push(callback);
    mtp_client_->GetStorageInfoFromDevice(
        storage_name,
        base::Bind(
            &MediaTransferProtocolManagerImpl::OnGetStorageInfoFromDevice,
            weak_ptr_factory_.GetWeakPtr()),
        base::Bind(
            &MediaTransferProtocolManagerImpl::OnGetStorageInfoFromDeviceError,
            weak_ptr_factory_.GetWeakPtr()));
  }

  // MediaTransferProtocolManager override.
  void OpenStorage(const std::string& storage_name,
                   const std::string& mode,
                   const OpenStorageCallback& callback) override {
    DCHECK(thread_checker_.CalledOnValidThread());
    if (!base::ContainsKey(storage_info_map_, storage_name) || !mtp_client_) {
      callback.Run(std::string(), true);
      return;
    }
    open_storage_callbacks_.push(callback);
    mtp_client_->OpenStorage(
        storage_name,
        mode,
        base::Bind(&MediaTransferProtocolManagerImpl::OnOpenStorage,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&MediaTransferProtocolManagerImpl::OnOpenStorageError,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  // MediaTransferProtocolManager override.
  void CloseStorage(const std::string& storage_handle,
                    const CloseStorageCallback& callback) override {
    DCHECK(thread_checker_.CalledOnValidThread());
    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
      callback.Run(true);
      return;
    }
    close_storage_callbacks_.push(std::make_pair(callback, storage_handle));
    mtp_client_->CloseStorage(
        storage_handle,
        base::Bind(&MediaTransferProtocolManagerImpl::OnCloseStorage,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&MediaTransferProtocolManagerImpl::OnCloseStorageError,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  void CreateDirectory(const std::string& storage_handle,
                       const uint32_t parent_id,
                       const std::string& directory_name,
                       const CreateDirectoryCallback& callback) override {
    DCHECK(thread_checker_.CalledOnValidThread());
    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
      callback.Run(true /* error */);
      return;
    }
    create_directory_callbacks_.push(callback);
    mtp_client_->CreateDirectory(
        storage_handle, parent_id, directory_name,
        base::Bind(&MediaTransferProtocolManagerImpl::OnCreateDirectory,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&MediaTransferProtocolManagerImpl::OnCreateDirectoryError,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  // MediaTransferProtocolManager override.
  void ReadDirectory(const std::string& storage_handle,
                     const uint32_t file_id,
                     const size_t max_size,
                     const ReadDirectoryCallback& callback) override {
    DCHECK(thread_checker_.CalledOnValidThread());
    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
      callback.Run(std::vector<mojom::MtpFileEntry>(),
                   false /* no more entries */,
                   true /* error */);
      return;
    }
    read_directory_callbacks_.push(callback);
    mtp_client_->ReadDirectoryEntryIds(
        storage_handle, file_id,
        base::Bind(&MediaTransferProtocolManagerImpl::
                       OnReadDirectoryEntryIdsToReadDirectory,
                   weak_ptr_factory_.GetWeakPtr(), storage_handle, max_size),
        base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectoryError,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  // MediaTransferProtocolManager override.
  void ReadFileChunk(const std::string& storage_handle,
                     uint32_t file_id,
                     uint32_t offset,
                     uint32_t count,
                     const ReadFileCallback& callback) override {
    DCHECK(thread_checker_.CalledOnValidThread());
    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
      callback.Run(std::string(), true);
      return;
    }
    read_file_callbacks_.push(callback);
    mtp_client_->ReadFileChunk(
        storage_handle, file_id, offset, count,
        base::Bind(&MediaTransferProtocolManagerImpl::OnReadFile,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&MediaTransferProtocolManagerImpl::OnReadFileError,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  void GetFileInfo(const std::string& storage_handle,
                   uint32_t file_id,
                   const GetFileInfoCallback& callback) override {
    DCHECK(thread_checker_.CalledOnValidThread());
    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
      callback.Run(mojom::MtpFileEntry(), true);
      return;
    }
    std::vector<uint32_t> file_ids;
    file_ids.push_back(file_id);
    get_file_info_callbacks_.push(callback);
    mtp_client_->GetFileInfo(
        storage_handle,
        file_ids,
        kInitialOffset,
        file_ids.size(),
        base::Bind(&MediaTransferProtocolManagerImpl::OnGetFileInfo,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&MediaTransferProtocolManagerImpl::OnGetFileInfoError,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  void RenameObject(const std::string& storage_handle,
                    const uint32_t object_id,
                    const std::string& new_name,
                    const RenameObjectCallback& callback) override {
    DCHECK(thread_checker_.CalledOnValidThread());
    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
      callback.Run(true /* error */);
      return;
    }
    rename_object_callbacks_.push(callback);
    mtp_client_->RenameObject(
        storage_handle, object_id, new_name,
        base::Bind(&MediaTransferProtocolManagerImpl::OnRenameObject,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&MediaTransferProtocolManagerImpl::OnRenameObjectError,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  void CopyFileFromLocal(const std::string& storage_handle,
                         const int source_file_descriptor,
                         const uint32_t parent_id,
                         const std::string& file_name,
                         const CopyFileFromLocalCallback& callback) override {
    DCHECK(thread_checker_.CalledOnValidThread());
    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
      callback.Run(true /* error */);
      return;
    }
    copy_file_from_local_callbacks_.push(callback);
    mtp_client_->CopyFileFromLocal(
        storage_handle, source_file_descriptor, parent_id, file_name,
        base::Bind(&MediaTransferProtocolManagerImpl::OnCopyFileFromLocal,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&MediaTransferProtocolManagerImpl::OnCopyFileFromLocalError,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  void DeleteObject(const std::string& storage_handle,
                    const uint32_t object_id,
                    const DeleteObjectCallback& callback) override {
    DCHECK(thread_checker_.CalledOnValidThread());
    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
      callback.Run(true /* error */);
      return;
    }
    delete_object_callbacks_.push(callback);
    mtp_client_->DeleteObject(
        storage_handle, object_id,
        base::Bind(&MediaTransferProtocolManagerImpl::OnDeleteObject,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&MediaTransferProtocolManagerImpl::OnDeleteObjectError,
                   weak_ptr_factory_.GetWeakPtr()));
  }

 private:
  // Map of storage names to storage info.
  using GetStorageInfoFromDeviceCallbackQueue =
      base::queue<GetStorageInfoFromDeviceCallback>;
  // Callback queues - DBus communication is in-order, thus callbacks are
  // received in the same order as the requests.
  using OpenStorageCallbackQueue = base::queue<OpenStorageCallback>;
  // (callback, handle)
  using CloseStorageCallbackQueue =
      base::queue<std::pair<CloseStorageCallback, std::string>>;
  using CreateDirectoryCallbackQueue = base::queue<CreateDirectoryCallback>;
  using ReadDirectoryCallbackQueue = base::queue<ReadDirectoryCallback>;
  using ReadFileCallbackQueue = base::queue<ReadFileCallback>;
  using GetFileInfoCallbackQueue = base::queue<GetFileInfoCallback>;
  using RenameObjectCallbackQueue = base::queue<RenameObjectCallback>;
  using CopyFileFromLocalCallbackQueue = base::queue<CopyFileFromLocalCallback>;
  using DeleteObjectCallbackQueue = base::queue<DeleteObjectCallback>;

  void OnStorageAttached(const std::string& storage_name) {
    DCHECK(thread_checker_.CalledOnValidThread());
    mtp_client_->GetStorageInfo(
        storage_name,
        base::Bind(&MediaTransferProtocolManagerImpl::OnGetStorageInfo,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&base::DoNothing));
  }

  void OnStorageDetached(const std::string& storage_name) {
    DCHECK(thread_checker_.CalledOnValidThread());
    if (storage_info_map_.erase(storage_name) == 0) {
      // This can happen for a storage where
      // MediaTransferProtocolDaemonClient::GetStorageInfo() failed.
      // Return to avoid giving observers phantom detach events.
      return;
    }
    for (auto& observer : observers_)
      observer.StorageChanged(false /* detach */, storage_name);
  }

  void OnStorageChanged(bool is_attach, const std::string& storage_name) {
    DCHECK(thread_checker_.CalledOnValidThread());
    DCHECK(mtp_client_);
    if (is_attach)
      OnStorageAttached(storage_name);
    else
      OnStorageDetached(storage_name);
  }

  void OnEnumerateStorages(const std::vector<std::string>& storage_names) {
    DCHECK(thread_checker_.CalledOnValidThread());
    DCHECK(mtp_client_);
    for (const auto& name : storage_names) {
      if (base::ContainsKey(storage_info_map_, name)) {
        // OnStorageChanged() might have gotten called first.
        continue;
      }
      OnStorageAttached(name);
    }
  }

  void OnGetStorageInfo(const mojom::MtpStorageInfo& storage_info) {
    DCHECK(thread_checker_.CalledOnValidThread());
    const std::string& storage_name = storage_info.storage_name;
    if (base::ContainsKey(storage_info_map_, storage_name)) {
      // This should not happen, since MediaTransferProtocolManagerImpl should
      // only call EnumerateStorages() once, which populates |storage_info_map_|
      // with the already-attached devices.
      // After that, all incoming signals are either for new storage
      // attachments, which should not be in |storage_info_map_|, or for
      // storage detachments, which do not add to |storage_info_map_|.
      // Return to avoid giving observers phantom detach events.
      NOTREACHED();
      return;
    }

    // New storage. Add it and let the observers know.
    storage_info_map_.insert(std::make_pair(storage_name, storage_info));
    for (auto& observer : observers_)
      observer.StorageChanged(true /* is attach */, storage_name);
  }

  void OnGetStorageInfoFromDevice(const mojom::MtpStorageInfo& storage_info) {
    get_storage_info_from_device_callbacks_.front().Run(storage_info,
                                                        false /* no error */);
    get_storage_info_from_device_callbacks_.pop();
  }

  void OnGetStorageInfoFromDeviceError() {
    mojom::MtpStorageInfo info;
    get_storage_info_from_device_callbacks_.front().Run(info, true /* error */);
    get_storage_info_from_device_callbacks_.pop();
  }

  void OnOpenStorage(const std::string& handle) {
    DCHECK(thread_checker_.CalledOnValidThread());
    if (!base::ContainsKey(handles_, handle)) {
      handles_.insert(handle);
      open_storage_callbacks_.front().Run(handle, false);
    } else {
      NOTREACHED();
      open_storage_callbacks_.front().Run(std::string(), true);
    }
    open_storage_callbacks_.pop();
  }

  void OnOpenStorageError() {
    open_storage_callbacks_.front().Run(std::string(), true);
    open_storage_callbacks_.pop();
  }

  void OnCloseStorage() {
    DCHECK(thread_checker_.CalledOnValidThread());
    const std::string& handle = close_storage_callbacks_.front().second;
    if (base::ContainsKey(handles_, handle)) {
      handles_.erase(handle);
      close_storage_callbacks_.front().first.Run(false);
    } else {
      NOTREACHED();
      close_storage_callbacks_.front().first.Run(true);
    }
    close_storage_callbacks_.pop();
  }

  void OnCloseStorageError() {
    DCHECK(thread_checker_.CalledOnValidThread());
    close_storage_callbacks_.front().first.Run(true);
    close_storage_callbacks_.pop();
  }

  void OnCreateDirectory() {
    DCHECK(thread_checker_.CalledOnValidThread());
    create_directory_callbacks_.front().Run(false /* no error */);
    create_directory_callbacks_.pop();
  }

  void OnCreateDirectoryError() {
    DCHECK(thread_checker_.CalledOnValidThread());
    create_directory_callbacks_.front().Run(true /* error */);
    create_directory_callbacks_.pop();
  }

  void OnReadDirectoryEntryIdsToReadDirectory(
      const std::string& storage_handle,
      const size_t max_size,
      const std::vector<uint32_t>& file_ids) {
    DCHECK(thread_checker_.CalledOnValidThread());

    if (file_ids.empty()) {
      OnGotDirectoryEntries(storage_handle, file_ids, kInitialOffset, max_size,
                            file_ids, std::vector<mojom::MtpFileEntry>());
      return;
    }

    std::vector<uint32_t> sorted_file_ids = file_ids;
    std::sort(sorted_file_ids.begin(), sorted_file_ids.end());

    const size_t chunk_size =
        max_size == 0 ? kFileInfoToFetchChunkSize
                      : std::min(max_size, kFileInfoToFetchChunkSize);

    mtp_client_->GetFileInfo(
        storage_handle, file_ids, kInitialOffset, chunk_size,
        base::Bind(&MediaTransferProtocolManagerImpl::OnGotDirectoryEntries,
                   weak_ptr_factory_.GetWeakPtr(), storage_handle, file_ids,
                   kInitialOffset, max_size, sorted_file_ids),
        base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectoryError,
                   weak_ptr_factory_.GetWeakPtr()));
  }

  void OnGotDirectoryEntries(
      const std::string& storage_handle,
      const std::vector<uint32_t>& file_ids,
      const size_t offset,
      const size_t max_size,
      const std::vector<uint32_t>& sorted_file_ids,
      const std::vector<mojom::MtpFileEntry>& file_entries) {
    DCHECK(thread_checker_.CalledOnValidThread());
    DCHECK_EQ(file_ids.size(), sorted_file_ids.size());

    // Use |sorted_file_ids| to sanity check and make sure the results are a
    // subset of the requested file ids.
    for (const auto& entry : file_entries) {
      std::vector<uint32_t>::const_iterator it = std::lower_bound(
          sorted_file_ids.begin(), sorted_file_ids.end(), entry.item_id);
      if (it == sorted_file_ids.end()) {
        OnReadDirectoryError();
        return;
      }
    }

    const size_t directory_size =
        max_size == 0 ? file_ids.size() : std::min(file_ids.size(), max_size);
    size_t next_offset = directory_size;
    if (offset < SIZE_MAX - kFileInfoToFetchChunkSize)
      next_offset = std::min(next_offset, offset + kFileInfoToFetchChunkSize);
    bool has_more = next_offset < directory_size;
    read_directory_callbacks_.front().Run(file_entries,
                                          has_more,
                                          false /* no error */);

    if (has_more) {
      const size_t chunk_size =
          std::min(directory_size - next_offset, kFileInfoToFetchChunkSize);

      mtp_client_->GetFileInfo(
          storage_handle, file_ids, next_offset, chunk_size,
          base::Bind(&MediaTransferProtocolManagerImpl::OnGotDirectoryEntries,
                     weak_ptr_factory_.GetWeakPtr(), storage_handle, file_ids,
                     next_offset, max_size, sorted_file_ids),
          base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectoryError,
                     weak_ptr_factory_.GetWeakPtr()));
      return;
    }
    read_directory_callbacks_.pop();
  }

  void OnReadDirectoryError() {
    DCHECK(thread_checker_.CalledOnValidThread());
    read_directory_callbacks_.front().Run(std::vector<mojom::MtpFileEntry>(),
                                          false /* no more entries */,
                                          true /* error */);
    read_directory_callbacks_.pop();
  }

  void OnReadFile(const std::string& data) {
    DCHECK(thread_checker_.CalledOnValidThread());
    read_file_callbacks_.front().Run(data, false);
    read_file_callbacks_.pop();
  }

  void OnReadFileError() {
    DCHECK(thread_checker_.CalledOnValidThread());
    read_file_callbacks_.front().Run(std::string(), true);
    read_file_callbacks_.pop();
  }

  void OnGetFileInfo(const std::vector<mojom::MtpFileEntry>& entries) {
    DCHECK(thread_checker_.CalledOnValidThread());
    if (entries.size() == 1) {
      get_file_info_callbacks_.front().Run(entries[0], false /* no error */);
      get_file_info_callbacks_.pop();
    } else {
      OnGetFileInfoError();
    }
  }

  void OnGetFileInfoError() {
    DCHECK(thread_checker_.CalledOnValidThread());
    get_file_info_callbacks_.front().Run(mojom::MtpFileEntry(), true);
    get_file_info_callbacks_.pop();
  }

  void OnRenameObject() {
    DCHECK(thread_checker_.CalledOnValidThread());
    rename_object_callbacks_.front().Run(false /* no error */);
    rename_object_callbacks_.pop();
  }

  void OnRenameObjectError() {
    DCHECK(thread_checker_.CalledOnValidThread());
    rename_object_callbacks_.front().Run(true /* error */);
    rename_object_callbacks_.pop();
  }

  void OnCopyFileFromLocal() {
    DCHECK(thread_checker_.CalledOnValidThread());
    copy_file_from_local_callbacks_.front().Run(false /* no error */);
    copy_file_from_local_callbacks_.pop();
  }

  void OnCopyFileFromLocalError() {
    DCHECK(thread_checker_.CalledOnValidThread());
    copy_file_from_local_callbacks_.front().Run(true /* error */);
    copy_file_from_local_callbacks_.pop();
  }

  void OnDeleteObject() {
    DCHECK(thread_checker_.CalledOnValidThread());
    delete_object_callbacks_.front().Run(false /* no error */);
    delete_object_callbacks_.pop();
  }

  void OnDeleteObjectError() {
    DCHECK(thread_checker_.CalledOnValidThread());
    delete_object_callbacks_.front().Run(true /* error */);
    delete_object_callbacks_.pop();
  }

  // Callback to finish initialization after figuring out if the mtpd service
  // has an owner, or if the service owner has changed.
  // |mtpd_service_owner| contains the name of the current owner, if any.
  void FinishSetupOnOriginThread(const std::string& mtpd_service_owner) {
    DCHECK(thread_checker_.CalledOnValidThread());

    if (mtpd_service_owner == current_mtpd_owner_)
      return;

    // In the case of a new service owner, clear |storage_info_map_|.
    // Assume all storages have been disconnected. If there is a new service
    // owner, reconnecting to it will reconnect all the storages as well.

    // Save a copy of |storage_info_map_| keys as |storage_info_map_| can
    // change in OnStorageDetached().
    std::vector<std::string> storage_names;
    storage_names.reserve(storage_info_map_.size());
    for (const auto& info : storage_info_map_)
      storage_names.push_back(info.first);

    for (const auto& name : storage_names)
      OnStorageDetached(name);

    if (mtpd_service_owner.empty()) {
      current_mtpd_owner_.clear();
      mtp_client_.reset();
      return;
    }

    current_mtpd_owner_ = mtpd_service_owner;

    // |bus_| must be valid here. Otherwise, how did this method get called as a
    // callback in the first place?
    DCHECK(bus_);
    mtp_client_ = MediaTransferProtocolDaemonClient::Create(bus_.get());

    // Set up signals and start initializing |storage_info_map_|.
    mtp_client_->ListenForChanges(
        base::Bind(&MediaTransferProtocolManagerImpl::OnStorageChanged,
                   weak_ptr_factory_.GetWeakPtr()));
    mtp_client_->EnumerateStorages(
        base::Bind(&MediaTransferProtocolManagerImpl::OnEnumerateStorages,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&base::DoNothing));
  }

  // Mtpd DBus client.
  std::unique_ptr<MediaTransferProtocolDaemonClient> mtp_client_;

  // And a D-Bus session for talking to mtpd. Note: In production, this is never
  // a nullptr, but in tests it oftentimes is. It may be too much work for
  // DBusThreadManager to provide a bus in unit tests.
  scoped_refptr<dbus::Bus> const bus_;

  // Device attachment / detachment observers.
  base::ObserverList<Observer> observers_;

  // Map to keep track of attached storages by name.
  base::flat_map<std::string, mojom::MtpStorageInfo> storage_info_map_;

  // Set of open storage handles.
  base::flat_set<std::string> handles_;

  dbus::Bus::GetServiceOwnerCallback mtpd_owner_changed_callback_;

  std::string current_mtpd_owner_;

  // Queued callbacks.
  GetStorageInfoFromDeviceCallbackQueue get_storage_info_from_device_callbacks_;
  OpenStorageCallbackQueue open_storage_callbacks_;
  CloseStorageCallbackQueue close_storage_callbacks_;
  CreateDirectoryCallbackQueue create_directory_callbacks_;
  ReadDirectoryCallbackQueue read_directory_callbacks_;
  ReadFileCallbackQueue read_file_callbacks_;
  GetFileInfoCallbackQueue get_file_info_callbacks_;
  RenameObjectCallbackQueue rename_object_callbacks_;
  CopyFileFromLocalCallbackQueue copy_file_from_local_callbacks_;
  DeleteObjectCallbackQueue delete_object_callbacks_;

  base::ThreadChecker thread_checker_;

  base::WeakPtrFactory<MediaTransferProtocolManagerImpl> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(MediaTransferProtocolManagerImpl);
};

}  // namespace

// static
std::unique_ptr<MediaTransferProtocolManager>
MediaTransferProtocolManager::Initialize() {
  auto manager = std::make_unique<MediaTransferProtocolManagerImpl>();

  VLOG(1) << "MediaTransferProtocolManager initialized";

#if DCHECK_IS_ON()
  DCHECK(!g_media_transfer_protocol_manager);
  g_media_transfer_protocol_manager = manager.get();
#endif

  return manager;
}

}  // namespace device
