Chromium Code Reviews| Index: device/usb/usb_service.cc |
| diff --git a/device/usb/usb_service.cc b/device/usb/usb_service.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..70f054d0b228e2736f5131a171e05f1170951b53 |
| --- /dev/null |
| +++ b/device/usb/usb_service.cc |
| @@ -0,0 +1,90 @@ |
| +// Copyright 2015 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/usb/usb_service.h" |
| + |
| +#include "base/message_loop/message_loop.h" |
| +#include "device/usb/usb_device.h" |
| +#include "device/usb/usb_service_impl.h" |
| + |
| +namespace device { |
| + |
| +namespace { |
| + |
| +UsbService* g_service; |
| + |
| +} // namespace |
| + |
| +// This class manages the lifetime of the global UsbService instance so that |
| +// it is destroyed when the current message loop is destroyed. A lazy instance |
| +// cannot be used because this object does not live on the main thread. |
| +class UsbService::Destroyer : private base::MessageLoop::DestructionObserver { |
| + public: |
| + explicit Destroyer(UsbService* usb_service) : usb_service_(usb_service) { |
| + base::MessageLoop::current()->AddDestructionObserver(this); |
| + } |
| + ~Destroyer() override {} |
| + |
| + private: |
| + // base::MessageLoop::DestructionObserver implementation. |
| + void WillDestroyCurrentMessageLoop() override { |
| + base::MessageLoop::current()->RemoveDestructionObserver(this); |
| + delete usb_service_; |
| + delete this; |
| + g_service = nullptr; |
| + } |
| + |
| + UsbService* usb_service_; |
| +}; |
| + |
| +void UsbService::Observer::OnDeviceAdded(scoped_refptr<UsbDevice> device) { |
| +} |
| + |
| +void UsbService::Observer::OnDeviceRemoved(scoped_refptr<UsbDevice> device) { |
| +} |
| + |
| +// static |
| +UsbService* UsbService::GetInstance( |
| + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
| + if (!g_service) { |
| + g_service = UsbServiceImpl::Create(ui_task_runner); |
|
Yoyo Zhou
2015/01/21 06:57:43
It is odd for UsbService to depend on UsbServiceIm
Reilly Grant (use Gerrit)
2015/01/22 00:45:01
There's a similar pattern in HidService::GetInstan
|
| + // This object will clean itself up when the message loop is destroyed. |
| + new Destroyer(g_service); |
| + } |
| + return g_service; |
| +} |
| + |
| +// static |
| +void UsbService::SetInstanceForTest(UsbService* instance) { |
| + g_service = instance; |
| + new Destroyer(instance); |
| +} |
| + |
| +UsbService::UsbService() { |
| +} |
| + |
| +UsbService::~UsbService() { |
| +} |
| + |
| +void UsbService::AddObserver(Observer* observer) { |
| + DCHECK(CalledOnValidThread()); |
| + observer_list_.AddObserver(observer); |
| +} |
| + |
| +void UsbService::RemoveObserver(Observer* observer) { |
| + DCHECK(CalledOnValidThread()); |
| + observer_list_.RemoveObserver(observer); |
| +} |
| + |
| +void UsbService::NotifyDeviceAdded(scoped_refptr<UsbDevice> device) { |
| + DCHECK(CalledOnValidThread()); |
| + FOR_EACH_OBSERVER(Observer, observer_list_, OnDeviceAdded(device)); |
| +} |
| + |
| +void UsbService::NotifyDeviceRemoved(scoped_refptr<UsbDevice> device) { |
| + DCHECK(CalledOnValidThread()); |
| + FOR_EACH_OBSERVER(Observer, observer_list_, OnDeviceRemoved(device)); |
| +} |
| + |
| +} // namespace device |