Chromium Code Reviews| 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/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 | 36 |
| 37 void ReportUsage(Usage usage) { | 37 void ReportUsage(Usage usage) { |
| 38 UMA_HISTOGRAM_ENUMERATION("Media.Midi.Usage", | 38 UMA_HISTOGRAM_ENUMERATION("Media.Midi.Usage", |
| 39 static_cast<Sample>(usage), | 39 static_cast<Sample>(usage), |
| 40 static_cast<Sample>(Usage::MAX) + 1); | 40 static_cast<Sample>(Usage::MAX) + 1); |
| 41 } | 41 } |
| 42 | 42 |
| 43 } // namespace | 43 } // namespace |
| 44 | 44 |
| 45 MidiManager::MidiManager() | 45 MidiManager::MidiManager() |
| 46 : initialized_(false), result_(Result::NOT_INITIALIZED) { | 46 : initialized_(false), finalized_(false), result_(Result::NOT_INITIALIZED) { |
| 47 ReportUsage(Usage::CREATED); | 47 ReportUsage(Usage::CREATED); |
| 48 } | 48 } |
| 49 | 49 |
| 50 MidiManager::~MidiManager() { | 50 MidiManager::~MidiManager() { |
| 51 UMA_HISTOGRAM_ENUMERATION("Media.Midi.ResultOnShutdown", | 51 // Make sure that Finalize() is called to clean up resources allocated on |
| 52 static_cast<Sample>(result_), | 52 // the Chrome_IOThread. |
| 53 static_cast<Sample>(Result::MAX) + 1); | 53 DCHECK(finalized_); |
| 54 } | 54 } |
| 55 | 55 |
| 56 #if !defined(OS_MACOSX) && !defined(OS_WIN) && \ | 56 #if !defined(OS_MACOSX) && !defined(OS_WIN) && \ |
| 57 !(defined(USE_ALSA) && defined(USE_UDEV)) && !defined(OS_ANDROID) | 57 !(defined(USE_ALSA) && defined(USE_UDEV)) && !defined(OS_ANDROID) |
| 58 MidiManager* MidiManager::Create() { | 58 MidiManager* MidiManager::Create() { |
| 59 ReportUsage(Usage::CREATED_ON_UNSUPPORTED_PLATFORMS); | 59 ReportUsage(Usage::CREATED_ON_UNSUPPORTED_PLATFORMS); |
| 60 return new MidiManager; | 60 return new MidiManager; |
| 61 } | 61 } |
| 62 #endif | 62 #endif |
| 63 | 63 |
| 64 void MidiManager::Shutdown() { | |
| 65 UMA_HISTOGRAM_ENUMERATION("Media.Midi.ResultOnShutdown", | |
| 66 static_cast<int>(result_), | |
| 67 static_cast<int>(Result::MAX) + 1); | |
| 68 base::AutoLock auto_lock(lock_); | |
| 69 if (session_thread_runner_) { | |
| 70 session_thread_runner_->PostTask( | |
| 71 FROM_HERE, base::Bind(&MidiManager::ShutdownOnSessionThread, | |
| 72 base::Unretained(this))); | |
| 73 session_thread_runner_ = nullptr; | |
| 74 } else { | |
| 75 finalized_ = true; | |
| 76 } | |
| 77 } | |
| 78 | |
| 64 void MidiManager::StartSession(MidiManagerClient* client) { | 79 void MidiManager::StartSession(MidiManagerClient* client) { |
| 65 ReportUsage(Usage::SESSION_STARTED); | 80 ReportUsage(Usage::SESSION_STARTED); |
| 66 | 81 |
| 67 bool session_is_ready; | 82 bool session_is_ready; |
| 68 bool session_needs_initialization = false; | 83 bool session_needs_initialization = false; |
| 69 bool too_many_pending_clients_exist = false; | 84 bool too_many_pending_clients_exist = false; |
| 70 | 85 |
| 71 { | 86 { |
| 72 base::AutoLock auto_lock(lock_); | 87 base::AutoLock auto_lock(lock_); |
| 73 session_is_ready = initialized_; | 88 session_is_ready = initialized_; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 88 session_needs_initialization = pending_clients_.empty(); | 103 session_needs_initialization = pending_clients_.empty(); |
| 89 pending_clients_.insert(client); | 104 pending_clients_.insert(client); |
| 90 } | 105 } |
| 91 } | 106 } |
| 92 } | 107 } |
| 93 | 108 |
| 94 // Lazily initialize the MIDI back-end. | 109 // Lazily initialize the MIDI back-end. |
| 95 if (!session_is_ready) { | 110 if (!session_is_ready) { |
| 96 if (session_needs_initialization) { | 111 if (session_needs_initialization) { |
| 97 TRACE_EVENT0("midi", "MidiManager::StartInitialization"); | 112 TRACE_EVENT0("midi", "MidiManager::StartInitialization"); |
| 98 session_thread_runner_ = | 113 { |
| 99 base::MessageLoop::current()->task_runner(); | 114 base::AutoLock auto_lock(lock_); |
| 115 // Stop calling StartInitialization() if Shutdown() was already called. | |
| 116 if (finalized_) | |
|
yhirano
2015/09/11 15:59:47
Should we call CompleteStartSession with INITIALIZ
Takashi Toyoshima
2015/09/17 07:30:49
This isn't easy because I do not want to call clie
| |
| 117 return; | |
| 118 session_thread_runner_ = base::MessageLoop::current()->task_runner(); | |
| 119 } | |
| 100 StartInitialization(); | 120 StartInitialization(); |
| 101 } | 121 } |
| 102 if (too_many_pending_clients_exist) { | 122 if (too_many_pending_clients_exist) { |
| 103 // Return an error immediately if there are too many requests. | 123 // Return an error immediately if there are too many requests. |
| 104 client->CompleteStartSession(Result::INITIALIZATION_ERROR); | 124 client->CompleteStartSession(Result::INITIALIZATION_ERROR); |
| 105 return; | 125 return; |
| 106 } | 126 } |
| 107 // CompleteInitialization() will be called asynchronously when platform | 127 // CompleteInitialization() will be called asynchronously when platform |
| 108 // dependent initialization is finished. | 128 // dependent initialization is finished. |
| 109 return; | 129 return; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 147 const std::vector<uint8>& data, | 167 const std::vector<uint8>& data, |
| 148 double timestamp) { | 168 double timestamp) { |
| 149 NOTREACHED(); | 169 NOTREACHED(); |
| 150 } | 170 } |
| 151 | 171 |
| 152 void MidiManager::StartInitialization() { | 172 void MidiManager::StartInitialization() { |
| 153 CompleteInitialization(Result::NOT_SUPPORTED); | 173 CompleteInitialization(Result::NOT_SUPPORTED); |
| 154 } | 174 } |
| 155 | 175 |
| 156 void MidiManager::CompleteInitialization(Result result) { | 176 void MidiManager::CompleteInitialization(Result result) { |
| 157 DCHECK(session_thread_runner_.get()); | 177 base::AutoLock auto_lock(lock_); |
| 158 // It is safe to post a task to the IO thread from here because the IO thread | 178 if (session_thread_runner_) { |
| 159 // should have stopped if the MidiManager is going to be destructed. | 179 session_thread_runner_->PostTask( |
| 160 session_thread_runner_->PostTask( | 180 FROM_HERE, base::Bind(&MidiManager::CompleteInitializationInternal, |
| 161 FROM_HERE, | 181 base::Unretained(this), result)); |
| 162 base::Bind(&MidiManager::CompleteInitializationInternal, | 182 } |
| 163 base::Unretained(this), | |
| 164 result)); | |
| 165 } | 183 } |
| 166 | 184 |
| 167 void MidiManager::AddInputPort(const MidiPortInfo& info) { | 185 void MidiManager::AddInputPort(const MidiPortInfo& info) { |
| 168 ReportUsage(Usage::INPUT_PORT_ADDED); | 186 ReportUsage(Usage::INPUT_PORT_ADDED); |
| 169 base::AutoLock auto_lock(lock_); | 187 base::AutoLock auto_lock(lock_); |
| 170 input_ports_.push_back(info); | 188 input_ports_.push_back(info); |
| 171 for (auto client : clients_) | 189 for (auto client : clients_) |
| 172 client->AddInputPort(info); | 190 client->AddInputPort(info); |
| 173 } | 191 } |
| 174 | 192 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 | 253 |
| 236 void MidiManager::AddInitialPorts(MidiManagerClient* client) { | 254 void MidiManager::AddInitialPorts(MidiManagerClient* client) { |
| 237 lock_.AssertAcquired(); | 255 lock_.AssertAcquired(); |
| 238 | 256 |
| 239 for (const auto& info : input_ports_) | 257 for (const auto& info : input_ports_) |
| 240 client->AddInputPort(info); | 258 client->AddInputPort(info); |
| 241 for (const auto& info : output_ports_) | 259 for (const auto& info : output_ports_) |
| 242 client->AddOutputPort(info); | 260 client->AddOutputPort(info); |
| 243 } | 261 } |
| 244 | 262 |
| 263 void MidiManager::ShutdownOnSessionThread() { | |
| 264 Finalize(); | |
| 265 base::AutoLock auto_lock(lock_); | |
| 266 finalized_ = true; | |
| 267 } | |
| 268 | |
| 245 } // namespace midi | 269 } // namespace midi |
| 246 } // namespace media | 270 } // namespace media |
| OLD | NEW |