Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(644)

Side by Side Diff: extensions/browser/api/audio/audio_api.cc

Issue 2688773002: Restrict deprecated parts of audio API usage to whitelisted apps (Closed)
Patch Set: . Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "extensions/browser/api/audio/audio_api.h" 5 #include "extensions/browser/api/audio/audio_api.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/values.h" 10 #include "base/values.h"
11 #include "extensions/browser/event_router.h" 11 #include "extensions/browser/event_router.h"
12 #include "extensions/common/api/audio.h" 12 #include "extensions/common/api/audio.h"
13 #include "extensions/common/extension.h"
14 #include "extensions/common/features/behavior_feature.h"
15 #include "extensions/common/features/feature_provider.h"
13 16
14 namespace extensions { 17 namespace extensions {
15 18
16 namespace audio = api::audio; 19 namespace audio = api::audio;
17 20
21 namespace {
22
23 bool CanUseDeprecatedAudioApi(const Extension* extension) {
Devlin 2017/02/22 14:13:14 Add a TODO to remove this, preferably with a concr
tbarzic 2017/02/22 19:35:18 Done. I've pinged mnilsson about a reasonable tim
tbarzic 2017/03/01 17:36:24 I've added a comment to target removal of this for
24 if (!extension)
25 return false;
26
27 const Feature* allow_deprecated_audio_api_feature =
28 FeatureProvider::GetBehaviorFeatures()->GetFeature(
29 behavior_feature::kAllowDeprecatedAudioApi);
30 if (!allow_deprecated_audio_api_feature)
31 return false;
32
33 return allow_deprecated_audio_api_feature->IsAvailableToExtension(extension)
34 .is_available();
35 }
36
37 bool CanReceiveDeprecatedAudioEvent(content::BrowserContext* context,
38 const Extension* extension,
39 Event* event,
40 const base::DictionaryValue* filter) {
41 return CanUseDeprecatedAudioApi(extension);
42 }
43
44 } // namespace
45
18 static base::LazyInstance<BrowserContextKeyedAPIFactory<AudioAPI> > g_factory = 46 static base::LazyInstance<BrowserContextKeyedAPIFactory<AudioAPI> > g_factory =
19 LAZY_INSTANCE_INITIALIZER; 47 LAZY_INSTANCE_INITIALIZER;
20 48
21 // static 49 // static
22 BrowserContextKeyedAPIFactory<AudioAPI>* AudioAPI::GetFactoryInstance() { 50 BrowserContextKeyedAPIFactory<AudioAPI>* AudioAPI::GetFactoryInstance() {
23 return g_factory.Pointer(); 51 return g_factory.Pointer();
24 } 52 }
25 53
26 AudioAPI::AudioAPI(content::BrowserContext* context) 54 AudioAPI::AudioAPI(content::BrowserContext* context)
27 : browser_context_(context), service_(AudioService::CreateInstance()) { 55 : browser_context_(context), service_(AudioService::CreateInstance()) {
28 service_->AddObserver(this); 56 service_->AddObserver(this);
29 } 57 }
30 58
31 AudioAPI::~AudioAPI() { 59 AudioAPI::~AudioAPI() {
32 service_->RemoveObserver(this); 60 service_->RemoveObserver(this);
33 delete service_; 61 delete service_;
34 service_ = NULL; 62 service_ = NULL;
35 } 63 }
36 64
37 AudioService* AudioAPI::GetService() const { 65 AudioService* AudioAPI::GetService() const {
38 return service_; 66 return service_;
39 } 67 }
40 68
41 void AudioAPI::OnDeviceChanged() { 69 void AudioAPI::OnDeviceChanged() {
42 if (EventRouter::Get(browser_context_)) { 70 EventRouter* event_router = EventRouter::Get(browser_context_);
43 std::unique_ptr<Event> event(new Event( 71 if (!event_router)
44 events::AUDIO_ON_DEVICE_CHANGED, audio::OnDeviceChanged::kEventName, 72 return;
45 std::unique_ptr<base::ListValue>(new base::ListValue()))); 73
46 EventRouter::Get(browser_context_)->BroadcastEvent(std::move(event)); 74 std::unique_ptr<Event> event(new Event(
47 } 75 events::AUDIO_ON_DEVICE_CHANGED, audio::OnDeviceChanged::kEventName,
76 std::unique_ptr<base::ListValue>(new base::ListValue())));
77 event->will_dispatch_callback = base::Bind(&CanReceiveDeprecatedAudioEvent);
78 event_router->BroadcastEvent(std::move(event));
48 } 79 }
49 80
50 void AudioAPI::OnLevelChanged(const std::string& id, int level) { 81 void AudioAPI::OnLevelChanged(const std::string& id, int level) {
51 EventRouter* event_router = EventRouter::Get(browser_context_); 82 EventRouter* event_router = EventRouter::Get(browser_context_);
52 if (!event_router) 83 if (!event_router)
53 return; 84 return;
54 85
55 audio::LevelChangedEvent raw_event; 86 audio::LevelChangedEvent raw_event;
56 raw_event.device_id = id; 87 raw_event.device_id = id;
57 raw_event.level = level; 88 raw_event.level = level;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 audio::OnDeviceListChanged::Create(devices); 122 audio::OnDeviceListChanged::Create(devices);
92 std::unique_ptr<Event> event(new Event(events::AUDIO_ON_DEVICES_CHANGED, 123 std::unique_ptr<Event> event(new Event(events::AUDIO_ON_DEVICES_CHANGED,
93 audio::OnDeviceListChanged::kEventName, 124 audio::OnDeviceListChanged::kEventName,
94 std::move(args))); 125 std::move(args)));
95 event_router->BroadcastEvent(std::move(event)); 126 event_router->BroadcastEvent(std::move(event));
96 } 127 }
97 128
98 /////////////////////////////////////////////////////////////////////////////// 129 ///////////////////////////////////////////////////////////////////////////////
99 130
100 ExtensionFunction::ResponseAction AudioGetInfoFunction::Run() { 131 ExtensionFunction::ResponseAction AudioGetInfoFunction::Run() {
132 if (!CanUseDeprecatedAudioApi(extension()))
133 return RespondNow(Error("Not allowed."));
Devlin 2017/02/22 14:13:14 Should this be a little more detailed? E.g. "audi
tbarzic 2017/02/22 19:35:18 Done.
134
101 AudioService* service = 135 AudioService* service =
102 AudioAPI::GetFactoryInstance()->Get(browser_context())->GetService(); 136 AudioAPI::GetFactoryInstance()->Get(browser_context())->GetService();
103 DCHECK(service); 137 DCHECK(service);
104 OutputInfo output_info; 138 OutputInfo output_info;
105 InputInfo input_info; 139 InputInfo input_info;
106 if (!service->GetInfo(&output_info, &input_info)) { 140 if (!service->GetInfo(&output_info, &input_info)) {
107 return RespondNow( 141 return RespondNow(
108 Error("Error occurred when querying audio device information.")); 142 Error("Error occurred when querying audio device information."));
109 } 143 }
110 144
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 AudioAPI::GetFactoryInstance()->Get(browser_context())->GetService(); 177 AudioAPI::GetFactoryInstance()->Get(browser_context())->GetService();
144 DCHECK(service); 178 DCHECK(service);
145 179
146 if (params->ids.as_device_id_lists) { 180 if (params->ids.as_device_id_lists) {
147 if (!service->SetActiveDeviceLists( 181 if (!service->SetActiveDeviceLists(
148 params->ids.as_device_id_lists->input, 182 params->ids.as_device_id_lists->input,
149 params->ids.as_device_id_lists->output)) { 183 params->ids.as_device_id_lists->output)) {
150 return RespondNow(Error("Failed to set active devices.")); 184 return RespondNow(Error("Failed to set active devices."));
151 } 185 }
152 } else if (params->ids.as_strings) { 186 } else if (params->ids.as_strings) {
153 // TODO(tbarzic): This way of setting active devices is deprecated - have 187 if (!CanUseDeprecatedAudioApi(extension())) {
154 // this return error for apps that were not whitelisted for deprecated 188 return RespondNow(Error("|ids| should have DeviceIdLists type."));
155 // version of audio API. 189 }
156 service->SetActiveDevices(*params->ids.as_strings); 190 service->SetActiveDevices(*params->ids.as_strings);
157 } 191 }
158 return RespondNow(NoArguments()); 192 return RespondNow(NoArguments());
159 } 193 }
160 194
161 /////////////////////////////////////////////////////////////////////////////// 195 ///////////////////////////////////////////////////////////////////////////////
162 196
163 ExtensionFunction::ResponseAction AudioSetPropertiesFunction::Run() { 197 ExtensionFunction::ResponseAction AudioSetPropertiesFunction::Run() {
164 std::unique_ptr<audio::SetProperties::Params> params( 198 std::unique_ptr<audio::SetProperties::Params> params(
165 audio::SetProperties::Params::Create(*args_)); 199 audio::SetProperties::Params::Create(*args_));
166 EXTENSION_FUNCTION_VALIDATE(params.get()); 200 EXTENSION_FUNCTION_VALIDATE(params.get());
167 201
168 AudioService* service = 202 AudioService* service =
169 AudioAPI::GetFactoryInstance()->Get(browser_context())->GetService(); 203 AudioAPI::GetFactoryInstance()->Get(browser_context())->GetService();
170 DCHECK(service); 204 DCHECK(service);
171 205
206 if (!CanUseDeprecatedAudioApi(extension())) {
207 if (params->properties.volume)
208 return RespondNow(Error("|volume| property not allowed - use |level|."));
209
210 if (params->properties.gain)
211 return RespondNow(Error("|gain| property not allowed - use |level|."));
212
213 if (params->properties.is_muted) {
214 return RespondNow(
215 Error("|isMuted| property not allowed - use |audio.setMute|."));
216 }
217 }
218
172 bool level_set = !!params->properties.level; 219 bool level_set = !!params->properties.level;
173 int level_value = level_set ? *params->properties.level : -1; 220 int level_value = level_set ? *params->properties.level : -1;
174 221
175 int volume_value = params->properties.volume.get() ? 222 int volume_value = params->properties.volume.get() ?
176 *params->properties.volume : -1; 223 *params->properties.volume : -1;
177 224
178 int gain_value = params->properties.gain.get() ? 225 int gain_value = params->properties.gain.get() ?
179 *params->properties.gain : -1; 226 *params->properties.gain : -1;
180 227
181 // |volume_value| and |gain_value| are deprecated in favor of |level_value|; 228 // |volume_value| and |gain_value| are deprecated in favor of |level_value|;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 272
226 bool value = false; 273 bool value = false;
227 if (!service->GetMute(params->stream_type == audio::STREAM_TYPE_INPUT, 274 if (!service->GetMute(params->stream_type == audio::STREAM_TYPE_INPUT,
228 &value)) { 275 &value)) {
229 return RespondNow(Error("Could not get mute state.")); 276 return RespondNow(Error("Could not get mute state."));
230 } 277 }
231 return RespondNow(ArgumentList(audio::GetMute::Results::Create(value))); 278 return RespondNow(ArgumentList(audio::GetMute::Results::Create(value)));
232 } 279 }
233 280
234 } // namespace extensions 281 } // namespace extensions
OLDNEW
« no previous file with comments | « no previous file | extensions/browser/api/audio/audio_apitest.cc » ('j') | extensions/common/api/audio.idl » ('J')

Powered by Google App Engine
This is Rietveld 408576698