root/components/storage_monitor/storage_monitor.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ReceiverImpl
  2. ReceiverImpl
  3. ProcessAttach
  4. ProcessDetach
  5. MarkInitialized
  6. Create
  7. Destroy
  8. GetInstance
  9. SetStorageMonitorForTesting
  10. GetAllAvailableStorages
  11. EnsureInitialized
  12. IsInitialized
  13. AddObserver
  14. RemoveObserver
  15. GetTransientIdForDeviceId
  16. GetDeviceIdForTransientId
  17. EjectDevice
  18. transient_device_ids_
  19. receiver
  20. MarkInitialized
  21. ProcessAttach
  22. ProcessDetach

// Copyright 2014 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 "components/storage_monitor/storage_monitor.h"

#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/storage_monitor/removable_storage_observer.h"
#include "components/storage_monitor/transient_device_ids.h"

namespace storage_monitor {

namespace {

StorageMonitor* g_storage_monitor = NULL;

}  // namespace

StorageMonitor::Receiver::~Receiver() {
}

class StorageMonitor::ReceiverImpl : public StorageMonitor::Receiver {
 public:
  explicit ReceiverImpl(StorageMonitor* notifications)
      : notifications_(notifications) {}

  virtual ~ReceiverImpl() {}

  virtual void ProcessAttach(const StorageInfo& info) OVERRIDE;

  virtual void ProcessDetach(const std::string& id) OVERRIDE;

  virtual void MarkInitialized() OVERRIDE;

 private:
  StorageMonitor* notifications_;
};

void StorageMonitor::ReceiverImpl::ProcessAttach(const StorageInfo& info) {
  notifications_->ProcessAttach(info);
}

void StorageMonitor::ReceiverImpl::ProcessDetach(const std::string& id) {
  notifications_->ProcessDetach(id);
}

void StorageMonitor::ReceiverImpl::MarkInitialized() {
  notifications_->MarkInitialized();
}

// static
void StorageMonitor::Create() {
  delete g_storage_monitor;
  g_storage_monitor = CreateInternal();
}

// static
void StorageMonitor::Destroy() {
  delete g_storage_monitor;
  g_storage_monitor = NULL;
}

StorageMonitor* StorageMonitor::GetInstance() {
  return g_storage_monitor;
}

void StorageMonitor::SetStorageMonitorForTesting(
    scoped_ptr<StorageMonitor> storage_monitor) {
  delete g_storage_monitor;
  g_storage_monitor = storage_monitor.release();
}

std::vector<StorageInfo> StorageMonitor::GetAllAvailableStorages() const {
  std::vector<StorageInfo> results;

  base::AutoLock lock(storage_lock_);
  for (StorageMap::const_iterator it = storage_map_.begin();
       it != storage_map_.end();
       ++it) {
    results.push_back(it->second);
  }
  return results;
}

void StorageMonitor::EnsureInitialized(base::Closure callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (initialized_) {
    if (!callback.is_null())
      callback.Run();
    return;
  }

  if (!callback.is_null()) {
    on_initialize_callbacks_.push_back(callback);
  }

  if (initializing_)
    return;

  initializing_ = true;
  Init();
}

bool StorageMonitor::IsInitialized() const {
  return initialized_;
}

void StorageMonitor::AddObserver(RemovableStorageObserver* obs) {
  observer_list_->AddObserver(obs);
}

void StorageMonitor::RemoveObserver(
    RemovableStorageObserver* obs) {
  observer_list_->RemoveObserver(obs);
}

std::string StorageMonitor::GetTransientIdForDeviceId(
    const std::string& device_id) {
  return transient_device_ids_->GetTransientIdForDeviceId(device_id);
}

std::string StorageMonitor::GetDeviceIdForTransientId(
    const std::string& transient_id) const {
  return transient_device_ids_->DeviceIdFromTransientId(transient_id);
}

void StorageMonitor::EjectDevice(
    const std::string& device_id,
    base::Callback<void(EjectStatus)> callback) {
  // Platform-specific implementations will override this method to
  // perform actual device ejection.
  callback.Run(EJECT_FAILURE);
}

StorageMonitor::StorageMonitor()
    : observer_list_(new ObserverListThreadSafe<RemovableStorageObserver>()),
      initializing_(false),
      initialized_(false),
      transient_device_ids_(new TransientDeviceIds) {
  receiver_.reset(new ReceiverImpl(this));
}

StorageMonitor::~StorageMonitor() {
}

StorageMonitor::Receiver* StorageMonitor::receiver() const {
  return receiver_.get();
}

void StorageMonitor::MarkInitialized() {
  initialized_ = true;
  for (std::vector<base::Closure>::iterator iter =
           on_initialize_callbacks_.begin();
       iter != on_initialize_callbacks_.end(); ++iter) {
    iter->Run();
  }
  on_initialize_callbacks_.clear();
}

void StorageMonitor::ProcessAttach(const StorageInfo& info) {
  {
    base::AutoLock lock(storage_lock_);
    if (ContainsKey(storage_map_, info.device_id())) {
      // This can happen if our unique id scheme fails. Ignore the incoming
      // non-unique attachment.
      return;
    }
    storage_map_.insert(std::make_pair(info.device_id(), info));
  }

  DVLOG(1) << "StorageAttached id " << info.device_id();
  if (StorageInfo::IsRemovableDevice(info.device_id())) {
    observer_list_->Notify(
        &RemovableStorageObserver::OnRemovableStorageAttached, info);
  }
}

void StorageMonitor::ProcessDetach(const std::string& id) {
  StorageInfo info;
  {
    base::AutoLock lock(storage_lock_);
    StorageMap::iterator it = storage_map_.find(id);
    if (it == storage_map_.end())
      return;
    info = it->second;
    storage_map_.erase(it);
  }

  DVLOG(1) << "StorageDetached for id " << id;
  if (StorageInfo::IsRemovableDevice(info.device_id())) {
    observer_list_->Notify(
        &RemovableStorageObserver::OnRemovableStorageDetached, info);
  }
}

}  // namespace storage_monitor

/* [<][>][^][v][top][bottom][index][help] */