1 // Copyright 2016 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 
16 // Handler for input events in /dev/input. AudioDeviceHandler handles events
17 // only for audio devices being plugged in/removed from the system. Implements
18 // some of the functionality present in WiredAccessoryManager.java.
19 
20 #ifndef BRILLO_AUDIO_AUDIOSERVICE_AUDIO_DEVICE_HANDLER_H_
21 #define BRILLO_AUDIO_AUDIOSERVICE_AUDIO_DEVICE_HANDLER_H_
22 
23 #include <set>
24 #include <vector>
25 
26 #include <base/bind.h>
27 #include <base/files/file_path.h>
28 #include <gtest/gtest_prod.h>
29 #include <linux/input.h>
30 #include <media/IAudioPolicyService.h>
31 #include <system/audio.h>
32 #include <system/audio_policy.h>
33 
34 #include "audio_daemon_handler.h"
35 
36 namespace brillo {
37 
38 class AudioDeviceHandler : public AudioDaemonHandler {
39  public:
40   AudioDeviceHandler();
41   virtual ~AudioDeviceHandler();
42 
43   // Get the current state of the headset jack and update AudioSystem based on
44   // the initial state.
45   //
46   // |aps| is a pointer to the binder object.
47   virtual void Init(android::sp<android::IAudioPolicyService> aps) override;
48 
49   // Process input events from the kernel. Connecting/disconnecting an audio
50   // device will result in multiple calls to this method.
51   //
52   // |event| is a pointer to an input_event. This function should be able to
53   // gracefully handle input events that are not relevant to the functionality
54   // provided by this class.
55   virtual void ProcessEvent(const struct input_event& event) override;
56 
57   // Inform the handler that the audio policy service has been disconnected.
58   void APSDisconnect();
59 
60   // Inform the handler that the audio policy service is reconnected.
61   //
62   // |aps| is a pointer to the binder object.
63   virtual void APSConnect(
64       android::sp<android::IAudioPolicyService> aps) override;
65 
66   // Get the list of connected devices.
67   //
68   // |devices_list| is the vector to copy list of connected input devices to.
69   void GetInputDevices(std::vector<int>* devices_list);
70 
71   // Get the list of connected output devices.
72   //
73   // |devices_list| is the vector to copy the list of connected output devices
74   // to.
75   void GetOutputDevices(std::vector<int>* devices_list);
76 
77   // Set device.
78   //
79   // |usage| is an int of type audio_policy_force_use_t
80   // |config| is an int of type audio_policy_forced_cfg_t.
81   //
82   // Returns 0 on sucess and errno on failure.
83   int SetDevice(audio_policy_force_use_t usage,
84                 audio_policy_forced_cfg_t config);
85 
86   // Enum used to represent whether devices are being connected or not. This is
87   // used when triggering callbacks.
88   enum DeviceConnectionState {
89     kDevicesConnected,
90     kDevicesDisconnected
91   };
92 
93   // Register a callback function to call when device state changes.
94   //
95   // |callback| is an object of type base::Callback that accepts a
96   // DeviceConnectionState and a vector of ints. See DeviceCallback() in
97   // audio_daemon.h.
98   void RegisterDeviceCallback(
99       base::Callback<void(DeviceConnectionState,
100                           const std::vector<int>& )>& callback);
101 
102  private:
103   friend class AudioDeviceHandlerTest;
104   friend class AudioVolumeHandler;
105   friend class AudioVolumeHandlerTest;
106   FRIEND_TEST(AudioDeviceHandlerTest,
107               DisconnectAllSupportedDevicesCallsDisconnect);
108   FRIEND_TEST(AudioDeviceHandlerTest, InitCallsDisconnectAllSupportedDevices);
109   FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateMic);
110   FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateHeadphone);
111   FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateHeadset);
112   FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateNone);
113   FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateInvalid);
114   FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventEmpty);
115   FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventMicrophonePresent);
116   FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventHeadphonePresent);
117   FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventMicrophoneNotPresent);
118   FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventHeadphoneNotPresent);
119   FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventInvalid);
120   FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemNone);
121   FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemConnectMic);
122   FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemConnectHeadphone);
123   FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemConnectHeadset);
124   FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemDisconnectMic);
125   FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemDisconnectHeadphone);
126   FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemDisconnectHeadset);
127   FRIEND_TEST(AudioDeviceHandlerTest, ConnectAudioDeviceInput);
128   FRIEND_TEST(AudioDeviceHandlerTest, ConnectAudioDeviceOutput);
129   FRIEND_TEST(AudioDeviceHandlerTest, DisconnectAudioDeviceInput);
130   FRIEND_TEST(AudioDeviceHandlerTest, DisconnectAudioDeviceOutput);
131   FRIEND_TEST(AudioVolumeHandlerTest, FileGeneration);
132 
133   // Read the initial state of audio devices in /sys/class/* and update
134   // the audio policy service.
135   //
136   // |path| is the file that contains the initial audio jack state.
137   void GetInitialAudioDeviceState(const base::FilePath& path);
138 
139   // Update the audio policy service once an input_event has completed.
140   //
141   // |headphone| is true is headphones are connected.
142   // |microphone| is true is microphones are connected.
143   void UpdateAudioSystem(bool headphone, bool microphone);
144 
145   // Notify the audio policy service that this device has been removed.
146   //
147   // |device| is the audio device whose state is to be changed.
148   // |state| is the current state of |device|.
149   virtual void NotifyAudioPolicyService(audio_devices_t device,
150                                         audio_policy_dev_state_t state);
151 
152   // Connect an audio device by calling aps and add it to the appropriate set
153   // (either connected_input_devices_ or connected_output_devices_).
154   //
155   // |device| is the audio device that has been added.
156   void ConnectAudioDevice(audio_devices_t device);
157 
158   // Disconnect an audio device by calling aps and remove it from the
159   // appropriate set (either connected_input_devices_ or
160   // connected_output_devices_).
161   //
162   // |device| is the audio device that has been disconnected.
163   void DisconnectAudioDevice(audio_devices_t device);
164 
165   // Disconnected all connected audio devices.
166   void DisconnectAllConnectedDevices();
167 
168   // Disconnect all supported audio devices.
169   void DisconnectAllSupportedDevices();
170 
171   // Trigger a callback when a device is either connected or disconnected.
172   //
173   // |state| is kDevicesConnected when |devices| are being connected.
174   virtual void TriggerCallback(DeviceConnectionState state);
175 
176   // All input devices currently supported by AudioDeviceHandler.
177   static const std::vector<audio_devices_t> kSupportedInputDevices_;
178   // All output devices currently supported by AudioDeviceHandler.
179   static const std::vector<audio_devices_t> kSupportedOutputDevices_;
180 
181  protected:
182   // Set of connected input devices.
183   std::set<audio_devices_t> connected_input_devices_;
184   // Set of connected output devices.
185   std::set<audio_devices_t> connected_output_devices_;
186   // Vector of devices changed (used for callbacks to clients).
187   std::vector<int> changed_devices_;
188   // Keeps track of whether a headphone has been connected. Used by ProcessEvent
189   // and UpdateAudioSystem.
190   bool headphone_;
191   // Keeps track of whether a microphone has been connected. Used by
192   // ProcessEvent and UpdateAudioSystem.
193   bool microphone_;
194   // Callback object to call when device state changes.
195   base::Callback<void(DeviceConnectionState,
196                       const std::vector<int>& )> callback_;
197 };
198 
199 }  // namespace brillo
200 
201 #endif  // BRILLO_AUDIO_AUDIOSERVICE_AUDIO_DEVICE_HANDLER_H_
202