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 |