OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/midi/midi_service.h" | 5 #include "media/midi/midi_service.h" |
6 | 6 |
| 7 #include "base/feature_list.h" |
| 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/strings/stringprintf.h" |
7 #include "media/midi/midi_manager.h" | 10 #include "media/midi/midi_manager.h" |
| 11 #include "media/midi/midi_switches.h" |
8 | 12 |
9 namespace midi { | 13 namespace midi { |
10 | 14 |
11 MidiService::MidiService(std::unique_ptr<MidiManager> manager) { | 15 namespace { |
| 16 |
| 17 bool IsDynamicInstantiationEnabled() { |
| 18 // TODO(toyoshim): Support on all platforms. See https://crbug.com/672793. |
| 19 #if defined(OS_LINUX) |
| 20 return base::FeatureList::IsEnabled( |
| 21 features::kMidiManagerDynamicInstantiation); |
| 22 #else |
| 23 return false; |
| 24 #endif |
| 25 } |
| 26 |
| 27 } // namespace |
| 28 |
| 29 MidiService::MidiService(void) |
| 30 : is_dynamic_instantiation_enabled_(IsDynamicInstantiationEnabled()), |
| 31 active_clients_(0u) { |
12 base::AutoLock lock(lock_); | 32 base::AutoLock lock(lock_); |
13 if (manager.get()) | 33 |
14 manager_ = std::move(manager); | 34 if (!is_dynamic_instantiation_enabled_) |
15 else | 35 manager_ = base::WrapUnique(MidiManager::Create(this)); |
16 manager_.reset(MidiManager::Create()); | 36 } |
| 37 |
| 38 MidiService::MidiService(std::unique_ptr<MidiManager> manager) |
| 39 : is_dynamic_instantiation_enabled_(false), active_clients_(0u) { |
| 40 base::AutoLock lock(lock_); |
| 41 |
| 42 manager_ = std::move(manager); |
17 } | 43 } |
18 | 44 |
19 MidiService::~MidiService() { | 45 MidiService::~MidiService() { |
20 base::AutoLock lock(lock_); | 46 base::AutoLock lock(lock_); |
| 47 |
21 manager_.reset(); | 48 manager_.reset(); |
| 49 |
| 50 base::AutoLock threads_lock(threads_lock_); |
| 51 threads_.clear(); |
22 } | 52 } |
23 | 53 |
24 void MidiService::Shutdown() { | 54 void MidiService::Shutdown() { |
25 base::AutoLock lock(lock_); | 55 base::AutoLock lock(lock_); |
26 manager_->Shutdown(); | 56 if (manager_.get()) |
| 57 manager_->Shutdown(); |
27 } | 58 } |
28 | 59 |
29 void MidiService::StartSession(MidiManagerClient* client) { | 60 void MidiService::StartSession(MidiManagerClient* client) { |
30 base::AutoLock lock(lock_); | 61 base::AutoLock lock(lock_); |
| 62 if (!manager_.get()) { |
| 63 CHECK(is_dynamic_instantiation_enabled_); |
| 64 CHECK_EQ(0u, active_clients_); |
| 65 manager_.reset(MidiManager::Create(this)); |
| 66 } |
| 67 active_clients_++; |
31 manager_->StartSession(client); | 68 manager_->StartSession(client); |
32 } | 69 } |
33 | 70 |
34 void MidiService::EndSession(MidiManagerClient* client) { | 71 void MidiService::EndSession(MidiManagerClient* client) { |
35 base::AutoLock lock(lock_); | 72 base::AutoLock lock(lock_); |
| 73 CHECK(manager_.get()); |
| 74 CHECK_NE(0u, active_clients_); |
36 manager_->EndSession(client); | 75 manager_->EndSession(client); |
| 76 active_clients_--; |
| 77 if (is_dynamic_instantiation_enabled_ && !active_clients_) { |
| 78 // MidiManager for each platform should be able to shutdown correctly even |
| 79 // if following Shutdown() call happens in the middle of |
| 80 // StartInitialization() to support the dynamic instantiation feature. |
| 81 manager_->Shutdown(); |
| 82 manager_.reset(); |
| 83 } |
37 } | 84 } |
38 | 85 |
39 void MidiService::DispatchSendMidiData(MidiManagerClient* client, | 86 void MidiService::DispatchSendMidiData(MidiManagerClient* client, |
40 uint32_t port_index, | 87 uint32_t port_index, |
41 const std::vector<uint8_t>& data, | 88 const std::vector<uint8_t>& data, |
42 double timestamp) { | 89 double timestamp) { |
43 base::AutoLock lock(lock_); | 90 base::AutoLock lock(lock_); |
44 manager_->DispatchSendMidiData(client, port_index, data, timestamp); | 91 manager_->DispatchSendMidiData(client, port_index, data, timestamp); |
45 } | 92 } |
46 | 93 |
| 94 scoped_refptr<base::SingleThreadTaskRunner> MidiService::GetTaskRunner( |
| 95 size_t runner_id) { |
| 96 base::AutoLock lock(threads_lock_); |
| 97 if (threads_.size() <= runner_id) |
| 98 threads_.resize(runner_id + 1); |
| 99 if (!threads_[runner_id].get()) { |
| 100 threads_[runner_id] = base::MakeUnique<base::Thread>( |
| 101 base::StringPrintf("MidiServiceThread(%zu)", runner_id)); |
| 102 threads_[runner_id]->Start(); |
| 103 } |
| 104 return threads_[runner_id]->task_runner(); |
| 105 } |
| 106 |
47 } // namespace midi | 107 } // namespace midi |
OLD | NEW |