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. AudioVolumeHandler handles events
17 // only for volume key presses.
18 
19 #ifndef BRILLO_AUDIO_AUDIOSERVICE_AUDIO_VOLUME_HANDLER_H_
20 #define BRILLO_AUDIO_AUDIOSERVICE_AUDIO_VOLUME_HANDLER_H_
21 
22 #include <base/bind.h>
23 #include <base/files/file_path.h>
24 #include <brillo/key_value_store.h>
25 #include <gtest/gtest_prod.h>
26 #include <linux/input.h>
27 #include <media/IAudioPolicyService.h>
28 #include <system/audio.h>
29 
30 #include "audio_daemon_handler.h"
31 
32 namespace brillo {
33 
34 class AudioVolumeHandler : public AudioDaemonHandler {
35  public:
36   AudioVolumeHandler();
37   virtual ~AudioVolumeHandler();
38 
39   // Get the current state of the headset jack and update AudioSystem based on
40   // the initial state.
41   //
42   // |aps| is a pointer to the binder object.
43   virtual void Init(android::sp<android::IAudioPolicyService> aps) override;
44 
45   // Process input events from the kernel. Connecting/disconnecting an audio
46   // device will result in multiple calls to this method.
47   //
48   // |event| is a pointer to an input_event. This function should be able to
49   // gracefully handle input events that are not relevant to the functionality
50   // provided by this class.
51   virtual void ProcessEvent(const struct input_event& event) override;
52 
53   // Inform the handler that the audio policy service has been disconnected.
54   virtual void APSDisconnect() override;
55 
56   // Inform the handler that the audio policy service is reconnected.
57   //
58   // |aps| is a pointer to the binder object.
59   virtual void APSConnect(
60       android::sp<android::IAudioPolicyService> aps) override;
61 
62   // Get the stream used when volume buttons are pressed.
63   //
64   // Returns an audio_stream_t representing the stream. If
65   // SetVolumeControlStream isn't called before calling this method,
66   // STREAM_DEFAULT is returned.
67   audio_stream_type_t GetVolumeControlStream();
68 
69   // Set the stream to use when volume buttons are pressed.
70   //
71   // |stream| is an int representing the stream. Passing STREAM_DEFAULT to this
72   // method can be used to reset selected_stream_.
73   void SetVolumeControlStream(audio_stream_type_t stream);
74 
75   // Register a callback to be triggered when keys are pressed.
76   //
77   // |callback| is an object of type base::Callback.
78   void RegisterCallback(
79       base::Callback<void(audio_stream_type_t, int, int)>& callback);
80 
81   // Set the max steps for an audio stream.
82   //
83   // |stream| is an int representing the stream.
84   // |max_index| is an int representing the maximum index to set for |stream|.
85   //
86   // Returns 0 on success and errno on failure.
87   int SetVolumeMaxSteps(audio_stream_type_t stream, int max_steps);
88 
89   // Get the max steps for an audio stream.
90   //
91   // |stream| is an int representing the stream.
92   //
93   // Returns the maximum possible index for |stream|.
94   int GetVolumeMaxSteps(audio_stream_type_t stream);
95 
96   // Get the volume of a given key.
97   //
98   // |stream| is an int representing the stream.
99   // |device| is an int representing the device.
100   //
101   // Returns an int which corresponds to the current index.
102   int GetVolumeCurrentIndex(audio_stream_type_t stream, audio_devices_t device);
103 
104   // Set the volume for a given (stream, device) tuple.
105   //
106   // |stream| is an int representing the stream.
107   // |device| is an int representing the device.
108   // |index| is an int representing the volume.
109   //
110   // Returns 0 on success and errno on failure.
111   int SetVolumeIndex(audio_stream_type_t stream,
112                      audio_devices_t device,
113                      int index);
114 
115   // Get the volume for a given (stream, device) tuple.
116   //
117   // |stream| is an int representing the stream.
118   // |device| is an int representing the device.
119   //
120   // Returns the index for the (stream, device) tuple. This index is between 0
121   // and the user defined maximum value.
122   int GetVolumeIndex(audio_stream_type_t stream, audio_devices_t device);
123 
124   // Update the volume index for a given stream.
125   //
126   // |previous_index| is the current index of the stream/device tuple before the
127   // volume button is pressed.
128   // |direction| is an int which is multiplied to step_. +1 for volume up and -1
129   // for volume down.
130   // |stream| is an int representing the stream.
131   //
132   // Returns the new volume index.
133   int GetNewVolumeIndex(int previous_index, int direction,
134                         audio_stream_type_t stream);
135 
136   // Adjust the volume of the active streams in the direction indicated. If
137   // SetDefaultStream() is called, then only the volume for that stream will be
138   // changed. Calling this method always triggers a callback.
139   //
140   // |direction| is an int which is multiplied to step_. +1 for volume up and -1
141   // for volume down.
142   virtual void AdjustVolumeActiveStreams(int direction);
143 
144  private:
145   friend class AudioVolumeHandlerTest;
146   FRIEND_TEST(AudioVolumeHandlerTest, FileGeneration);
147   FRIEND_TEST(AudioVolumeHandlerTest, GetVolumeForStreamDeviceTuple);
148   FRIEND_TEST(AudioVolumeHandlerTest, SetVolumeForStreamDeviceTuple);
149   FRIEND_TEST(AudioVolumeHandlerTest, InitNoFile);
150   FRIEND_TEST(AudioVolumeHandlerTest, InitFilePresent);
151   FRIEND_TEST(AudioVolumeHandlerTest, ProcessEventEmpty);
152   FRIEND_TEST(AudioVolumeHandlerTest, ProcessEventKeyUp);
153   FRIEND_TEST(AudioVolumeHandlerTest, ProcessEventKeyDown);
154   FRIEND_TEST(AudioVolumeHandlerTest, SelectStream);
155   FRIEND_TEST(AudioVolumeHandlerTest, ComputeNewVolume);
156   FRIEND_TEST(AudioVolumeHandlerTest, GetSetVolumeIndex);
157 
158   // Save the volume for a given (stream, device) tuple.
159   //
160   // |stream| is an int representing the stream.
161   // |device| is an int representing the device.
162   // |index| is an int representing the volume.
163   void PersistVolumeConfiguration(audio_stream_type_t stream,
164                                   audio_devices_t device,
165                                   int index);
166 
167   // Read the initial volume of audio streams.
168   //
169   // |path| is the file that contains the initial volume state.
170   void GetInitialVolumeState(const base::FilePath& path);
171 
172   // Adjust the volume of a given stream in the direction specified.
173   //
174   // |stream| is an int representing the stream.
175   // |direction| is an int which is multiplied to step_. +1 for volume up and -1
176   // for volume down.
177   void AdjustStreamVolume(audio_stream_type_t stream, int direction);
178 
179   // Set the file path for testing.
180   //
181   // |path| to use while running tests.
182   void SetVolumeFilePathForTesting(const base::FilePath& path);
183 
184   // Initialize all the streams in the audio policy service.
185   virtual void InitAPSAllStreams();
186 
187   // Generate the volume config file.
188   void GenerateVolumeFile();
189 
190   // Trigger a callback when a volume button is pressed.
191   //
192   // |stream| is an audio_stream_t representing the stream.
193   // |previous_index| is the volume index before the key press. This is an
194   // absolute index from 0 - 100.
195   // |current_index| is the volume index after the key press. This is an
196   // absolute index from 0 - 100.
197   virtual void TriggerCallback(audio_stream_type_t stream,
198                                int previous_index,
199                                int current_index);
200 
201   // Convert internal index to user defined index scale.
202   //
203   // |stream| is an audio_stream_t representing the stream.
204   // |index| is the volume index before the key press. This is an absolute
205   // index from 0 - 100.
206   //
207   // Returns an int between 0 and the user defined max.
208   int ConvertToUserDefinedIndex(audio_stream_type_t stream, int index);
209 
210   // Convert user defined index to internal index scale.
211   //
212   // |stream| is an audio_stream_t representing the stream.
213   // |index| is the volume index before the key press. This is an index from 0
214   // and the user defined max.
215   //
216   // Returns an int between 0 and 100.
217   int ConvertToInternalIndex(audio_stream_type_t stream, int index);
218 
219   // Stream to use for volume control.
220   audio_stream_type_t selected_stream_;
221   // File backed key-value store of the current index (as seen by the audio
222   // policy service).
223   std::unique_ptr<KeyValueStore> kv_store_;
224   // Supported stream names. The order of this vector defines the priority from
225   // high to low.
226   std::vector<audio_stream_type_t> kSupportedStreams_{
227       AUDIO_STREAM_ALARM, AUDIO_STREAM_NOTIFICATION, AUDIO_STREAM_SYSTEM,
228       AUDIO_STREAM_MUSIC};
229   // Step size for each stream. This is used to translate between user defined
230   // stream ranges and the range as seen by audio policy service. This value is
231   // not file-backed and is intended to be re-applied by the user on reboots and
232   // brilloaudioservice crashes.
233   std::map<audio_stream_type_t, double> step_sizes_;
234   // Callback to call when volume buttons are pressed.
235   base::Callback<void(audio_stream_type_t, int, int)> callback_;
236   // Key indicies.
237   const std::string kCurrentIndexKey_ = "current_index";
238   // Default values.
239   const int kMinIndex_ = 0;
240   const int kDefaultCurrentIndex_ = 30;
241   const int kMaxIndex_ = 100;
242   const int kDefaultStepSize_ = 1;
243   base::FilePath volume_state_file_;
244 };
245 
246 }  // namespace brillo
247 
248 #endif  // BRILLO_AUDIO_AUDIOSERVICE_AUDIO_VOLUME_HANDLER_H_
249