| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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_manager.h" | 5 #include "media/midi/midi_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 | 45 |
| 46 void ReportUsage(Usage usage) { | 46 void ReportUsage(Usage usage) { |
| 47 UMA_HISTOGRAM_ENUMERATION("Media.Midi.Usage", | 47 UMA_HISTOGRAM_ENUMERATION("Media.Midi.Usage", |
| 48 static_cast<Sample>(usage), | 48 static_cast<Sample>(usage), |
| 49 static_cast<Sample>(Usage::MAX) + 1); | 49 static_cast<Sample>(Usage::MAX) + 1); |
| 50 } | 50 } |
| 51 | 51 |
| 52 } // namespace | 52 } // namespace |
| 53 | 53 |
| 54 MidiManager::MidiManager() | 54 MidiManager::MidiManager() |
| 55 : initialized_(false), finalized_(false), result_(Result::NOT_INITIALIZED) { | 55 : initialized_(false), |
| 56 finalized_(false), |
| 57 result_(mojom::Result::NOT_INITIALIZED) { |
| 56 ReportUsage(Usage::CREATED); | 58 ReportUsage(Usage::CREATED); |
| 57 } | 59 } |
| 58 | 60 |
| 59 MidiManager::~MidiManager() { | 61 MidiManager::~MidiManager() { |
| 60 // Make sure that Finalize() is called to clean up resources allocated on | 62 // Make sure that Finalize() is called to clean up resources allocated on |
| 61 // the Chrome_IOThread. | 63 // the Chrome_IOThread. |
| 62 base::AutoLock auto_lock(lock_); | 64 base::AutoLock auto_lock(lock_); |
| 63 CHECK(finalized_); | 65 CHECK(finalized_); |
| 64 } | 66 } |
| 65 | 67 |
| 66 #if !defined(OS_MACOSX) && !defined(OS_WIN) && \ | 68 #if !defined(OS_MACOSX) && !defined(OS_WIN) && \ |
| 67 !(defined(USE_ALSA) && defined(USE_UDEV)) && !defined(OS_ANDROID) | 69 !(defined(USE_ALSA) && defined(USE_UDEV)) && !defined(OS_ANDROID) |
| 68 MidiManager* MidiManager::Create() { | 70 MidiManager* MidiManager::Create() { |
| 69 ReportUsage(Usage::CREATED_ON_UNSUPPORTED_PLATFORMS); | 71 ReportUsage(Usage::CREATED_ON_UNSUPPORTED_PLATFORMS); |
| 70 return new MidiManager; | 72 return new MidiManager; |
| 71 } | 73 } |
| 72 #endif | 74 #endif |
| 73 | 75 |
| 74 void MidiManager::Shutdown() { | 76 void MidiManager::Shutdown() { |
| 75 UMA_HISTOGRAM_ENUMERATION("Media.Midi.ResultOnShutdown", | 77 UMA_HISTOGRAM_ENUMERATION("Media.Midi.ResultOnShutdown", |
| 76 static_cast<int>(result_), | 78 static_cast<int>(result_), |
| 77 static_cast<int>(Result::MAX) + 1); | 79 static_cast<int>(mojom::Result::MAX) + 1); |
| 78 base::AutoLock auto_lock(lock_); | 80 base::AutoLock auto_lock(lock_); |
| 79 if (session_thread_runner_) { | 81 if (session_thread_runner_) { |
| 80 session_thread_runner_->PostTask( | 82 session_thread_runner_->PostTask( |
| 81 FROM_HERE, base::Bind(&MidiManager::ShutdownOnSessionThread, | 83 FROM_HERE, base::Bind(&MidiManager::ShutdownOnSessionThread, |
| 82 base::Unretained(this))); | 84 base::Unretained(this))); |
| 83 session_thread_runner_ = nullptr; | 85 session_thread_runner_ = nullptr; |
| 84 } else { | 86 } else { |
| 85 finalized_ = true; | 87 finalized_ = true; |
| 86 } | 88 } |
| 87 } | 89 } |
| 88 | 90 |
| 89 void MidiManager::StartSession(MidiManagerClient* client) { | 91 void MidiManager::StartSession(MidiManagerClient* client) { |
| 90 ReportUsage(Usage::SESSION_STARTED); | 92 ReportUsage(Usage::SESSION_STARTED); |
| 91 | 93 |
| 92 Completion completion = Completion::COMPLETE_SYNCHRONOUSLY; | 94 Completion completion = Completion::COMPLETE_SYNCHRONOUSLY; |
| 93 Result result = Result::NOT_INITIALIZED; | 95 mojom::Result result = mojom::Result::NOT_INITIALIZED; |
| 94 | 96 |
| 95 { | 97 { |
| 96 base::AutoLock auto_lock(lock_); | 98 base::AutoLock auto_lock(lock_); |
| 97 if (clients_.find(client) != clients_.end() || | 99 if (clients_.find(client) != clients_.end() || |
| 98 pending_clients_.find(client) != pending_clients_.end()) { | 100 pending_clients_.find(client) != pending_clients_.end()) { |
| 99 // Should not happen. But just in case the renderer is compromised. | 101 // Should not happen. But just in case the renderer is compromised. |
| 100 NOTREACHED(); | 102 NOTREACHED(); |
| 101 return; | 103 return; |
| 102 } | 104 } |
| 103 | 105 |
| 104 if (initialized_) { | 106 if (initialized_) { |
| 105 // Platform dependent initialization was already finished for previously | 107 // Platform dependent initialization was already finished for previously |
| 106 // initialized clients. | 108 // initialized clients. |
| 107 if (result_ == Result::OK) { | 109 if (result_ == mojom::Result::OK) { |
| 108 AddInitialPorts(client); | 110 AddInitialPorts(client); |
| 109 clients_.insert(client); | 111 clients_.insert(client); |
| 110 } | 112 } |
| 111 // Complete synchronously with |result_|; | 113 // Complete synchronously with |result_|; |
| 112 result = result_; | 114 result = result_; |
| 113 } else { | 115 } else { |
| 114 bool too_many_pending_clients_exist = | 116 bool too_many_pending_clients_exist = |
| 115 pending_clients_.size() >= kMaxPendingClientCount; | 117 pending_clients_.size() >= kMaxPendingClientCount; |
| 116 // Do not accept a new request if the pending client list contains too | 118 // Do not accept a new request if the pending client list contains too |
| 117 // many clients, or Shutdown() was already called. | 119 // many clients, or Shutdown() was already called. |
| 118 if (too_many_pending_clients_exist || finalized_) { | 120 if (too_many_pending_clients_exist || finalized_) { |
| 119 result = Result::INITIALIZATION_ERROR; | 121 result = mojom::Result::INITIALIZATION_ERROR; |
| 120 } else { | 122 } else { |
| 121 // Call StartInitialization() only for the first request. | 123 // Call StartInitialization() only for the first request. |
| 122 if (pending_clients_.empty()) { | 124 if (pending_clients_.empty()) { |
| 123 completion = Completion::INVOKE_INITIALIZATION; | 125 completion = Completion::INVOKE_INITIALIZATION; |
| 124 session_thread_runner_ = base::ThreadTaskRunnerHandle::Get(); | 126 session_thread_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 125 } else { | 127 } else { |
| 126 completion = Completion::COMPLETE_ASYNCHRONOUSLY; | 128 completion = Completion::COMPLETE_ASYNCHRONOUSLY; |
| 127 } | 129 } |
| 128 pending_clients_.insert(client); | 130 pending_clients_.insert(client); |
| 129 } | 131 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 } | 168 } |
| 167 | 169 |
| 168 void MidiManager::DispatchSendMidiData(MidiManagerClient* client, | 170 void MidiManager::DispatchSendMidiData(MidiManagerClient* client, |
| 169 uint32_t port_index, | 171 uint32_t port_index, |
| 170 const std::vector<uint8_t>& data, | 172 const std::vector<uint8_t>& data, |
| 171 double timestamp) { | 173 double timestamp) { |
| 172 NOTREACHED(); | 174 NOTREACHED(); |
| 173 } | 175 } |
| 174 | 176 |
| 175 void MidiManager::StartInitialization() { | 177 void MidiManager::StartInitialization() { |
| 176 CompleteInitialization(Result::NOT_SUPPORTED); | 178 CompleteInitialization(mojom::Result::NOT_SUPPORTED); |
| 177 } | 179 } |
| 178 | 180 |
| 179 void MidiManager::CompleteInitialization(Result result) { | 181 void MidiManager::CompleteInitialization(mojom::Result result) { |
| 180 base::AutoLock auto_lock(lock_); | 182 base::AutoLock auto_lock(lock_); |
| 181 if (session_thread_runner_) { | 183 if (session_thread_runner_) { |
| 182 session_thread_runner_->PostTask( | 184 session_thread_runner_->PostTask( |
| 183 FROM_HERE, base::Bind(&MidiManager::CompleteInitializationInternal, | 185 FROM_HERE, base::Bind(&MidiManager::CompleteInitializationInternal, |
| 184 base::Unretained(this), result)); | 186 base::Unretained(this), result)); |
| 185 } | 187 } |
| 186 } | 188 } |
| 187 | 189 |
| 188 void MidiManager::AddInputPort(const MidiPortInfo& info) { | 190 void MidiManager::AddInputPort(const MidiPortInfo& info) { |
| 189 ReportUsage(Usage::INPUT_PORT_ADDED); | 191 ReportUsage(Usage::INPUT_PORT_ADDED); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 220 void MidiManager::ReceiveMidiData(uint32_t port_index, | 222 void MidiManager::ReceiveMidiData(uint32_t port_index, |
| 221 const uint8_t* data, | 223 const uint8_t* data, |
| 222 size_t length, | 224 size_t length, |
| 223 double timestamp) { | 225 double timestamp) { |
| 224 base::AutoLock auto_lock(lock_); | 226 base::AutoLock auto_lock(lock_); |
| 225 | 227 |
| 226 for (auto* client : clients_) | 228 for (auto* client : clients_) |
| 227 client->ReceiveMidiData(port_index, data, length, timestamp); | 229 client->ReceiveMidiData(port_index, data, length, timestamp); |
| 228 } | 230 } |
| 229 | 231 |
| 230 void MidiManager::CompleteInitializationInternal(Result result) { | 232 void MidiManager::CompleteInitializationInternal(mojom::Result result) { |
| 231 TRACE_EVENT0("midi", "MidiManager::CompleteInitialization"); | 233 TRACE_EVENT0("midi", "MidiManager::CompleteInitialization"); |
| 232 ReportUsage(Usage::INITIALIZED); | 234 ReportUsage(Usage::INITIALIZED); |
| 233 UMA_HISTOGRAM_ENUMERATION("Media.Midi.InputPorts", | 235 UMA_HISTOGRAM_ENUMERATION("Media.Midi.InputPorts", |
| 234 static_cast<Sample>(input_ports_.size()), | 236 static_cast<Sample>(input_ports_.size()), |
| 235 kMaxUmaDevices + 1); | 237 kMaxUmaDevices + 1); |
| 236 UMA_HISTOGRAM_ENUMERATION("Media.Midi.OutputPorts", | 238 UMA_HISTOGRAM_ENUMERATION("Media.Midi.OutputPorts", |
| 237 static_cast<Sample>(output_ports_.size()), | 239 static_cast<Sample>(output_ports_.size()), |
| 238 kMaxUmaDevices + 1); | 240 kMaxUmaDevices + 1); |
| 239 | 241 |
| 240 base::AutoLock auto_lock(lock_); | 242 base::AutoLock auto_lock(lock_); |
| 241 DCHECK(clients_.empty()); | 243 DCHECK(clients_.empty()); |
| 242 DCHECK(!initialized_); | 244 DCHECK(!initialized_); |
| 243 initialized_ = true; | 245 initialized_ = true; |
| 244 result_ = result; | 246 result_ = result; |
| 245 | 247 |
| 246 for (auto* client : pending_clients_) { | 248 for (auto* client : pending_clients_) { |
| 247 if (result_ == Result::OK) { | 249 if (result_ == mojom::Result::OK) { |
| 248 AddInitialPorts(client); | 250 AddInitialPorts(client); |
| 249 clients_.insert(client); | 251 clients_.insert(client); |
| 250 } | 252 } |
| 251 client->CompleteStartSession(result_); | 253 client->CompleteStartSession(result_); |
| 252 } | 254 } |
| 253 pending_clients_.clear(); | 255 pending_clients_.clear(); |
| 254 } | 256 } |
| 255 | 257 |
| 256 void MidiManager::AddInitialPorts(MidiManagerClient* client) { | 258 void MidiManager::AddInitialPorts(MidiManagerClient* client) { |
| 257 lock_.AssertAcquired(); | 259 lock_.AssertAcquired(); |
| 258 | 260 |
| 259 for (const auto& info : input_ports_) | 261 for (const auto& info : input_ports_) |
| 260 client->AddInputPort(info); | 262 client->AddInputPort(info); |
| 261 for (const auto& info : output_ports_) | 263 for (const auto& info : output_ports_) |
| 262 client->AddOutputPort(info); | 264 client->AddOutputPort(info); |
| 263 } | 265 } |
| 264 | 266 |
| 265 void MidiManager::ShutdownOnSessionThread() { | 267 void MidiManager::ShutdownOnSessionThread() { |
| 266 Finalize(); | 268 Finalize(); |
| 267 base::AutoLock auto_lock(lock_); | 269 base::AutoLock auto_lock(lock_); |
| 268 finalized_ = true; | 270 finalized_ = true; |
| 269 | 271 |
| 270 // Detach all clients so that they do not call MidiManager methods any more. | 272 // Detach all clients so that they do not call MidiManager methods any more. |
| 271 for (auto* client : clients_) | 273 for (auto* client : clients_) |
| 272 client->Detach(); | 274 client->Detach(); |
| 273 } | 275 } |
| 274 | 276 |
| 275 } // namespace midi | 277 } // namespace midi |
| OLD | NEW |