Give names to all utility processes.
[chromium-blink-merge.git] / chrome / browser / copresence / chrome_whispernet_client.cc
blob2023196c7c61387c63e63cc8ebcdcf3a3295f286
1 // Copyright 2014 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.
5 #include "chrome/browser/copresence/chrome_whispernet_client.h"
7 #include "base/stl_util.h"
8 #include "chrome/browser/copresence/chrome_whispernet_config.h"
9 #include "chrome/browser/extensions/api/copresence_private/copresence_private_api.h"
10 #include "chrome/browser/extensions/component_loader.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/common/extensions/api/copresence_private.h"
13 #include "content/public/browser/browser_context.h"
14 #include "extensions/browser/event_router.h"
15 #include "extensions/browser/extension_system.h"
16 #include "grit/browser_resources.h"
17 #include "media/audio/audio_manager.h"
18 #include "media/audio/audio_manager_base.h"
19 #include "media/audio/audio_parameters.h"
21 using audio_modem::AUDIBLE;
22 using audio_modem::AudioType;
23 using audio_modem::BOTH;
24 using audio_modem::INAUDIBLE;
25 using audio_modem::SamplesCallback;
26 using audio_modem::SuccessCallback;
27 using audio_modem::TokensCallback;
28 using audio_modem::TokenParameters;
30 using extensions::api::copresence_private::AudioParameters;
31 using extensions::api::copresence_private::DecodeSamplesParameters;
32 using extensions::api::copresence_private::EncodeTokenParameters;
33 using ApiTokenParams = extensions::api::copresence_private::TokenParameters;
35 namespace OnConfigAudio =
36 extensions::api::copresence_private::OnConfigAudio;
37 namespace OnDecodeSamplesRequest =
38 extensions::api::copresence_private::OnDecodeSamplesRequest;
39 namespace OnEncodeTokenRequest =
40 extensions::api::copresence_private::OnEncodeTokenRequest;
42 using extensions::Event;
43 using extensions::copresence_private::RegisterWhispernetClient;
45 namespace {
47 AudioParamData GetDefaultAudioConfig() {
48 media::AudioParameters params =
49 media::AudioManager::Get()->GetInputStreamParameters(
50 media::AudioManagerBase::kDefaultDeviceId);
52 AudioParamData config_data = {};
54 config_data.audio_dtmf.coder_sample_rate =
55 config_data.audio_dsss.coder_sample_rate =
56 audio_modem::kDefaultSampleRate;
58 config_data.audio_dtmf.recording_sample_rate =
59 config_data.audio_dsss.recording_sample_rate = params.sample_rate();
61 config_data.audio_dtmf.num_repetitions_to_play =
62 config_data.audio_dsss.num_repetitions_to_play =
63 audio_modem::kDefaultRepetitions;
65 config_data.audio_dsss.upsampling_factor = audio_modem::kDefaultBitsPerSample;
66 config_data.audio_dsss.desired_carrier_frequency =
67 audio_modem::kDefaultCarrierFrequency;
69 config_data.recording_channels = params.channels();
71 return config_data;
74 // ApiTokenParams is not copyable, so we must take it as an output argument.
75 // TODO(ckehoe): Pass protos to Whispernet to avoid all these conversions.
76 void ConvertTokenParams(const TokenParameters& in, ApiTokenParams* out) {
77 out->length = in.length;
78 out->crc = in.crc;
79 out->parity = in.parity;
82 } // namespace
84 // static
85 const char ChromeWhispernetClient::kWhispernetProxyExtensionId[] =
86 "bpfmnplchembfbdgieamdodgaencleal";
89 // Public functions.
91 ChromeWhispernetClient::ChromeWhispernetClient(
92 content::BrowserContext* browser_context)
93 : browser_context_(browser_context),
94 event_router_(extensions::EventRouter::Get(browser_context)),
95 extension_loaded_(false) {
96 DCHECK(browser_context_);
99 ChromeWhispernetClient::~ChromeWhispernetClient() {}
101 void ChromeWhispernetClient::Initialize(
102 const SuccessCallback& init_callback) {
103 DVLOG(3) << "Initializing whispernet proxy client.";
105 DCHECK(!init_callback.is_null());
106 init_callback_ = init_callback;
108 extensions::ComponentLoader* loader =
109 extensions::ExtensionSystem::Get(browser_context_)
110 ->extension_service()->component_loader();
111 DCHECK(loader);
113 if (!loader->Exists(kWhispernetProxyExtensionId)) {
114 DVLOG(3) << "Loading Whispernet proxy.";
115 loader->Add(IDR_WHISPERNET_PROXY_MANIFEST,
116 base::FilePath(FILE_PATH_LITERAL("whispernet_proxy")));
119 client_id_ = RegisterWhispernetClient(this);
120 AudioConfiguration(GetDefaultAudioConfig());
123 void ChromeWhispernetClient::EncodeToken(
124 const std::string& token_str,
125 AudioType type,
126 const TokenParameters token_params[2]) {
127 DCHECK(type == AUDIBLE || type == INAUDIBLE);
129 EncodeTokenParameters params;
130 params.token.token = token_str;
131 params.token.audible = (type == AUDIBLE);
132 ConvertTokenParams(token_params[type], &params.token_params);
134 SendEventIfLoaded(make_scoped_ptr(new Event(
135 OnEncodeTokenRequest::kEventName,
136 OnEncodeTokenRequest::Create(client_id_, params),
137 browser_context_)));
140 void ChromeWhispernetClient::DecodeSamples(
141 AudioType type,
142 const std::string& samples,
143 const TokenParameters token_params[2]) {
144 DecodeSamplesParameters params;
145 params.samples.assign(samples.begin(), samples.end());
146 params.decode_audible = (type == AUDIBLE || type == BOTH);
147 params.decode_inaudible = (type == INAUDIBLE || type == BOTH);
148 ConvertTokenParams(token_params[AUDIBLE], &params.audible_token_params);
149 ConvertTokenParams(token_params[INAUDIBLE], &params.inaudible_token_params);
151 SendEventIfLoaded(make_scoped_ptr(new Event(
152 OnDecodeSamplesRequest::kEventName,
153 OnDecodeSamplesRequest::Create(client_id_, params),
154 browser_context_)));
157 void ChromeWhispernetClient::RegisterTokensCallback(
158 const TokensCallback& tokens_callback) {
159 tokens_callback_ = tokens_callback;
162 void ChromeWhispernetClient::RegisterSamplesCallback(
163 const SamplesCallback& samples_callback) {
164 samples_callback_ = samples_callback;
167 TokensCallback ChromeWhispernetClient::GetTokensCallback() {
168 return tokens_callback_;
171 SamplesCallback ChromeWhispernetClient::GetSamplesCallback() {
172 return samples_callback_;
175 SuccessCallback ChromeWhispernetClient::GetInitializedCallback() {
176 return base::Bind(&ChromeWhispernetClient::OnExtensionLoaded,
177 base::Unretained(this));
181 // Private functions.
183 void ChromeWhispernetClient::AudioConfiguration(const AudioParamData& params) {
184 AudioParameters audio_params;
186 // We serialize AudioConfigData to a string and send it to the whispernet
187 // nacl wrapper.
188 const size_t params_size = sizeof(params);
189 audio_params.param_data.resize(params_size);
190 memcpy(vector_as_array(&audio_params.param_data), &params, params_size);
192 DVLOG(3) << "Configuring audio for client " << client_id_;
193 SendEventIfLoaded(make_scoped_ptr(new Event(
194 OnConfigAudio::kEventName,
195 OnConfigAudio::Create(client_id_, audio_params),
196 browser_context_)));
199 void ChromeWhispernetClient::SendEventIfLoaded(
200 scoped_ptr<extensions::Event> event) {
201 DCHECK(event_router_);
203 if (extension_loaded_) {
204 event_router_->DispatchEventToExtension(kWhispernetProxyExtensionId,
205 event.Pass());
206 } else {
207 DVLOG(2) << "Queueing event " << event->event_name
208 << " for client " << client_id_;
209 queued_events_.push_back(event.release());
213 void ChromeWhispernetClient::OnExtensionLoaded(bool success) {
214 DCHECK(!init_callback_.is_null());
215 init_callback_.Run(success);
217 DVLOG(3) << "Sending " << queued_events_.size()
218 << " queued requests to whispernet from client "
219 << client_id_;
221 // In this loop, ownership of each Event is passed to a scoped_ptr instead.
222 // Thus we can just discard the pointers at the end.
223 DCHECK(event_router_);
224 for (Event* event : queued_events_) {
225 event_router_->DispatchEventToExtension(kWhispernetProxyExtensionId,
226 make_scoped_ptr(event));
228 queued_events_.weak_clear();
230 extension_loaded_ = true;