1 // 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 CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_OUTPUT_AUTHORIZATION_HANDLER_H_
6 #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_OUTPUT_AUTHORIZATION_HANDLER_H_
7 
8 #include <memory>
9 #include <string>
10 #include <utility>
11 
12 #include "base/callback_forward.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/time/time.h"
15 #include "content/browser/renderer_host/media/media_stream_manager.h"
16 #include "media/audio/audio_device_description.h"
17 #include "media/base/audio_parameters.h"
18 #include "media/base/output_device_info.h"
19 
20 namespace media {
21 class AudioSystem;
22 }
23 
24 namespace content {
25 
26 // This class, which lives on the IO thread, handles the logic of an IPC device
27 // request from the renderer. It checks which device to use (in case of using
28 // |session_id| to select device), verifies that the renderer is authorized to
29 // use the device, and gets the default device parameters for the selected audio
30 // device.
31 class CONTENT_EXPORT AudioOutputAuthorizationHandler {
32  public:
33   // Convention: Something named |device_id| is hashed and something named
34   // |raw_device_id| is not hashed.
35 
36   // The result of an authorization check. In addition to the status, it
37   // provides the default parameters of the device and the raw device id.
38   // |device_id_for_renderer| is either the hashed device id, if it should be
39   // sent to the renderer, or "", if it shouldn't.
40   using AuthorizationCompletedCallback =
41       base::OnceCallback<void(media::OutputDeviceStatus status,
42                               const media::AudioParameters& params,
43                               const std::string& raw_device_id,
44                               const std::string& device_id_for_renderer)>;
45 
46   AudioOutputAuthorizationHandler(media::AudioSystem* audio_system,
47                                   MediaStreamManager* media_stream_manager,
48                                   int render_process_id_);
49 
50   ~AudioOutputAuthorizationHandler();
51 
52   // Checks authorization of the device with the hashed id |device_id| for the
53   // given render frame id, or uses |session_id| for authorization. Looks up
54   // device id (if |session_id| is used for device selection) and default
55   // device parameters. This function will always call |cb|.
56   void RequestDeviceAuthorization(int render_frame_id,
57                                   const base::UnguessableToken& session_id,
58                                   const std::string& device_id,
59                                   AuthorizationCompletedCallback cb) const;
60 
61   // Calling this method will make the checks for permission from the user
62   // always return |override_value|.
63   void OverridePermissionsForTesting(bool override_value);
64 
65   static void UMALogDeviceAuthorizationTime(base::TimeTicks auth_start_time);
66 
67  private:
68   // Helper class for recording traces.
69   class TraceScope;
70 
71   void HashDeviceId(std::unique_ptr<TraceScope> trace_scope,
72                     AuthorizationCompletedCallback cb,
73                     const std::string& raw_device_id,
74                     const MediaDeviceSaltAndOrigin& salt_and_origin) const;
75 
76   void AccessChecked(std::unique_ptr<TraceScope> trace_scope,
77                      AuthorizationCompletedCallback cb,
78                      const std::string& device_id,
79                      std::string salt,
80                      url::Origin security_origin,
81                      bool has_access) const;
82 
83   void TranslateDeviceID(std::unique_ptr<TraceScope> trace_scope,
84                          AuthorizationCompletedCallback cb,
85                          const std::string& device_id,
86                          const std::string& salt,
87                          const url::Origin& security_origin,
88                          const MediaDeviceEnumeration& enumeration) const;
89 
90   void GetDeviceParameters(std::unique_ptr<TraceScope> trace_scope,
91                            AuthorizationCompletedCallback cb,
92                            const std::string& raw_device_id) const;
93 
94   void DeviceParametersReceived(
95       std::unique_ptr<TraceScope> trace_scope,
96       AuthorizationCompletedCallback cb,
97       const std::string& device_id_for_renderer,
98       const std::string& raw_device_id,
99       const base::Optional<media::AudioParameters>& params) const;
100 
101   media::AudioSystem* const audio_system_;
102   MediaStreamManager* const media_stream_manager_;
103   const int render_process_id_;
104   bool override_permissions_ = false;
105   bool permissions_override_value_ = false;
106 
107   // All access is on the IO thread, and taking a weak pointer to const looks
108   // const, so this can be mutable.
109   mutable base::WeakPtrFactory<const AudioOutputAuthorizationHandler>
110       weak_factory_{this};
111 
112   DISALLOW_COPY_AND_ASSIGN(AudioOutputAuthorizationHandler);
113 };
114 
115 }  // namespace content
116 
117 #endif  // CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_OUTPUT_AUTHORIZATION_HANDLER_H_
118