blob: 2869480304aad62f923aad357ddc3b381d9b3159 [file] [log] [blame]
toyoshim14a32342016-12-14 22:18:29 -08001// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef MEDIA_MIDI_MIDI_SERVICE_H_
6#define MEDIA_MIDI_MIDI_SERVICE_H_
7
8#include <stdint.h>
9
10#include <memory>
11#include <vector>
12
13#include "base/macros.h"
toyoshimf4d61522017-02-10 02:03:32 -080014#include "base/memory/ref_counted.h"
toyoshim14a32342016-12-14 22:18:29 -080015#include "base/synchronization/lock.h"
Patrick Monette54c53f42021-10-08 20:27:23 +000016#include "base/task/single_thread_task_runner_forward.h"
toyoshimf4d61522017-02-10 02:03:32 -080017#include "base/threading/thread.h"
Takashi Toyoshimaafb27d52017-09-13 11:50:41 +000018#include "base/time/time.h"
toyoshim14a32342016-12-14 22:18:29 -080019#include "media/midi/midi_export.h"
20#include "media/midi/midi_manager.h"
21
22namespace midi {
23
toyoshimccb8ff92017-06-13 05:31:46 -070024class TaskService;
25
toyoshim14a32342016-12-14 22:18:29 -080026// Manages MidiManager backends. This class expects to be constructed and
27// destructed on the browser main thread, but methods can be called on both
28// the main thread and the I/O thread.
29class MIDI_EXPORT MidiService final {
30 public:
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +000031 class MIDI_EXPORT ManagerFactory {
32 public:
33 ManagerFactory() = default;
Peter Boström53634032021-09-22 20:24:34 +000034
35 ManagerFactory(const ManagerFactory&) = delete;
36 ManagerFactory& operator=(const ManagerFactory&) = delete;
37
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +000038 virtual ~ManagerFactory() = default;
39 virtual std::unique_ptr<MidiManager> Create(MidiService* service);
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +000040 };
41
tzik925e2c62018-02-02 07:39:45 +000042 // Converts Web MIDI timestamp to base::TimeDelta delay for PostDelayedTask.
43 static base::TimeDelta TimestampToTimeDeltaDelay(base::TimeTicks timestamp);
Takashi Toyoshimaafb27d52017-09-13 11:50:41 +000044
toyoshimf4d61522017-02-10 02:03:32 -080045 MidiService();
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090046 // Customized ManagerFactory can be specified in the constructor for testing.
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +000047 explicit MidiService(std::unique_ptr<ManagerFactory> factory);
Peter Boström53634032021-09-22 20:24:34 +000048
49 MidiService(const MidiService&) = delete;
50 MidiService& operator=(const MidiService&) = delete;
51
toyoshim14a32342016-12-14 22:18:29 -080052 ~MidiService();
53
54 // Called on the browser main thread to notify the I/O thread will stop and
55 // the instance will be destructed on the main thread soon.
56 void Shutdown();
57
58 // A client calls StartSession() to receive and send MIDI data.
59 void StartSession(MidiManagerClient* client);
60
61 // A client calls EndSession() to stop receiving MIDI data.
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090062 // Returns false if |client| did not start a session.
63 bool EndSession(MidiManagerClient* client);
toyoshim14a32342016-12-14 22:18:29 -080064
65 // A client calls DispatchSendMidiData() to send MIDI data.
toyoshimf4d61522017-02-10 02:03:32 -080066 void DispatchSendMidiData(MidiManagerClient* client,
67 uint32_t port_index,
68 const std::vector<uint8_t>& data,
tzik925e2c62018-02-02 07:39:45 +000069 base::TimeTicks timestamp);
toyoshim14a32342016-12-14 22:18:29 -080070
toyoshimf4d61522017-02-10 02:03:32 -080071 // Returns a SingleThreadTaskRunner reference to serve MidiManager. Each
72 // TaskRunner will be constructed on demand.
73 // MidiManager that supports the dynamic instantiation feature will use this
74 // method to post tasks that should not run on I/O. Since TaskRunners outlive
75 // MidiManager, each task should ensure that MidiManager that posted the task
76 // is still alive while accessing |this|. TaskRunners will be reused when
77 // another MidiManager is instantiated.
toyoshimccb8ff92017-06-13 05:31:46 -070078 // TODO(toyoshim): Remove this interface.
toyoshimf4d61522017-02-10 02:03:32 -080079 scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(size_t runner_id);
80
toyoshimccb8ff92017-06-13 05:31:46 -070081 // Obtains a TaskService that lives with MidiService.
82 TaskService* task_service() { return task_service_.get(); }
83
toyoshimd28b59c2017-02-20 11:07:37 -080084 private:
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090085 // ManagerFactory passed in the constructor.
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +000086 std::unique_ptr<ManagerFactory> manager_factory_;
87
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090088 // Holds MidiManager instance. The MidiManager is constructed and destructed
89 // on the I/O thread, and all MidiManager methods should be called on the I/O
90 // thread.
toyoshim14a32342016-12-14 22:18:29 -080091 std::unique_ptr<MidiManager> manager_;
toyoshimf4d61522017-02-10 02:03:32 -080092
toyoshimccb8ff92017-06-13 05:31:46 -070093 // Holds TaskService instance.
94 std::unique_ptr<TaskService> task_service_;
95
Takashi Toyoshimaf563b612017-05-26 20:19:00 +090096 // TaskRunner to destruct |manager_| on the right thread.
97 scoped_refptr<base::SingleThreadTaskRunner> manager_destructor_runner_;
98
toyoshimf4d61522017-02-10 02:03:32 -080099 // Protects all members above.
toyoshim14a32342016-12-14 22:18:29 -0800100 base::Lock lock_;
101
toyoshimf4d61522017-02-10 02:03:32 -0800102 // Threads to host SingleThreadTaskRunners.
103 std::vector<std::unique_ptr<base::Thread>> threads_;
104
105 // Protects |threads_|.
106 base::Lock threads_lock_;
toyoshim14a32342016-12-14 22:18:29 -0800107};
108
109} // namespace midi
110
111#endif // MEDIA_MIDI_MIDI_SERVICE_H_