Commit 13abec32 authored by rkc@chromium.org's avatar rkc@chromium.org

Add Audible support to the whispernet client.

This CL adds the ability to do encoding/decoding of tokens in the audible range.
It also simplifies the parameters we send in to the whispernet pnacl wrapper.
All the parameters removed are now picked up as defaults in the wrapper itself.
There is literally no reason we'd ever touch those defaults hence it made no
sense to send them hardcoded from wrapper.js.

R=ckehoe@chromium.org
BUG=390393

Review URL: https://codereview.chromium.org/444373004

Cr-Commit-Position: refs/heads/master@{#288374}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288374 0039d316-1c4b-4281-b951-d872f2087c98
parent 0a9c0435
...@@ -8,23 +8,12 @@ ...@@ -8,23 +8,12 @@
#include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service.h"
#include "chrome/common/extensions/api/copresence_private.h" #include "chrome/common/extensions/api/copresence_private.h"
#include "components/copresence/public/copresence_constants.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "extensions/browser/event_router.h" #include "extensions/browser/event_router.h"
#include "extensions/browser/extension_system.h" #include "extensions/browser/extension_system.h"
#include "grit/browser_resources.h" #include "grit/browser_resources.h"
namespace copresence {
// Once the CL for the copresence component lands, these constants will be
// need to be picked up from components/copresence/copresence_constants.h
const int kDefaultRepetitions = 5;
const float kDefaultSampleRate = 48000.0;
const int kDefaultBitsPerSample = 16;
const float kDefaultCarrierFrequency = 18500.0;
const int kDefaultChannels = 2;
} // namespace copresence
// static // static
const char ChromeWhispernetClient::kWhispernetProxyExtensionId[] = const char ChromeWhispernetClient::kWhispernetProxyExtensionId[] =
"bpfmnplchembfbdgieamdodgaencleal"; "bpfmnplchembfbdgieamdodgaencleal";
...@@ -73,14 +62,16 @@ void ChromeWhispernetClient::Shutdown() { ...@@ -73,14 +62,16 @@ void ChromeWhispernetClient::Shutdown() {
} }
// Fire an event to request a token encode. // Fire an event to request a token encode.
void ChromeWhispernetClient::EncodeToken(const std::string& token) { void ChromeWhispernetClient::EncodeToken(const std::string& token,
bool audible) {
DCHECK(extension_loaded_); DCHECK(extension_loaded_);
DCHECK(browser_context_); DCHECK(browser_context_);
DCHECK(extensions::EventRouter::Get(browser_context_)); DCHECK(extensions::EventRouter::Get(browser_context_));
scoped_ptr<extensions::Event> event(new extensions::Event( scoped_ptr<extensions::Event> event(new extensions::Event(
extensions::api::copresence_private::OnEncodeTokenRequest::kEventName, extensions::api::copresence_private::OnEncodeTokenRequest::kEventName,
extensions::api::copresence_private::OnEncodeTokenRequest::Create(token), extensions::api::copresence_private::OnEncodeTokenRequest::Create(
token, audible),
browser_context_)); browser_context_));
extensions::EventRouter::Get(browser_context_) extensions::EventRouter::Get(browser_context_)
......
...@@ -40,7 +40,7 @@ class ChromeWhispernetClient : public copresence::WhispernetClient { ...@@ -40,7 +40,7 @@ class ChromeWhispernetClient : public copresence::WhispernetClient {
virtual void Initialize(const SuccessCallback& init_callback) OVERRIDE; virtual void Initialize(const SuccessCallback& init_callback) OVERRIDE;
virtual void Shutdown() OVERRIDE; virtual void Shutdown() OVERRIDE;
virtual void EncodeToken(const std::string& token) OVERRIDE; virtual void EncodeToken(const std::string& token, bool audible) OVERRIDE;
virtual void DecodeSamples(const std::string& samples) OVERRIDE; virtual void DecodeSamples(const std::string& samples) OVERRIDE;
virtual void DetectBroadcast() OVERRIDE; virtual void DetectBroadcast() OVERRIDE;
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace { namespace {
const char kSixZeros[] = "MDAwMDAw";
copresence::WhispernetClient* GetWhispernetClient( copresence::WhispernetClient* GetWhispernetClient(
content::BrowserContext* context) { content::BrowserContext* context) {
extensions::CopresenceService* service = extensions::CopresenceService* service =
...@@ -61,19 +63,16 @@ class ChromeWhispernetClientTest : public ExtensionBrowserTest { ...@@ -61,19 +63,16 @@ class ChromeWhispernetClientTest : public ExtensionBrowserTest {
EXPECT_TRUE(initialized_); EXPECT_TRUE(initialized_);
} }
void EncodeTokenAndSaveSamples() { void EncodeTokenAndSaveSamples(bool audible) {
copresence::WhispernetClient* client = GetWhispernetClient(context_); copresence::WhispernetClient* client = GetWhispernetClient(context_);
ASSERT_TRUE(client); ASSERT_TRUE(client);
// This is the base64 encoding for "000000".
const std::string kZeroToken = "MDAwMDAw";
run_loop_.reset(new base::RunLoop()); run_loop_.reset(new base::RunLoop());
client->RegisterSamplesCallback(base::Bind( client->RegisterSamplesCallback(base::Bind(
&ChromeWhispernetClientTest::SamplesCallback, base::Unretained(this))); &ChromeWhispernetClientTest::SamplesCallback, base::Unretained(this)));
expected_token_ = kZeroToken; expected_token_ = kSixZeros;
client->EncodeToken(kZeroToken); client->EncodeToken(kSixZeros, audible);
run_loop_->Run(); run_loop_->Run();
EXPECT_GT(saved_samples_->frames(), 0); EXPECT_GT(saved_samples_->frames(), 0);
...@@ -83,12 +82,10 @@ class ChromeWhispernetClientTest : public ExtensionBrowserTest { ...@@ -83,12 +82,10 @@ class ChromeWhispernetClientTest : public ExtensionBrowserTest {
copresence::WhispernetClient* client = GetWhispernetClient(context_); copresence::WhispernetClient* client = GetWhispernetClient(context_);
ASSERT_TRUE(client); ASSERT_TRUE(client);
const std::string kZeroToken = "MDAwMDAw";
run_loop_.reset(new base::RunLoop()); run_loop_.reset(new base::RunLoop());
client->RegisterTokensCallback(base::Bind( client->RegisterTokensCallback(base::Bind(
&ChromeWhispernetClientTest::TokensCallback, base::Unretained(this))); &ChromeWhispernetClientTest::TokensCallback, base::Unretained(this)));
expected_token_ = kZeroToken; expected_token_ = kSixZeros;
ASSERT_GT(saved_samples_->frames(), 0); ASSERT_GT(saved_samples_->frames(), 0);
...@@ -167,18 +164,24 @@ IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, Initialize) { ...@@ -167,18 +164,24 @@ IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, Initialize) {
IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, EncodeToken) { IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, EncodeToken) {
InitializeWhispernet(); InitializeWhispernet();
EncodeTokenAndSaveSamples(); EncodeTokenAndSaveSamples(false);
} }
IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, DecodeSamples) { IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, DecodeSamples) {
InitializeWhispernet(); InitializeWhispernet();
EncodeTokenAndSaveSamples(); EncodeTokenAndSaveSamples(false);
DecodeSamplesAndVerifyToken(); DecodeSamplesAndVerifyToken();
} }
IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, DetectBroadcast) { IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, DetectBroadcast) {
InitializeWhispernet(); InitializeWhispernet();
EncodeTokenAndSaveSamples(); EncodeTokenAndSaveSamples(false);
DecodeSamplesAndVerifyToken(); DecodeSamplesAndVerifyToken();
DetectBroadcast(); DetectBroadcast();
} }
IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, Audible) {
InitializeWhispernet();
EncodeTokenAndSaveSamples(true);
DecodeSamplesAndVerifyToken();
}
...@@ -38,10 +38,11 @@ function initialize(audioParams) { ...@@ -38,10 +38,11 @@ function initialize(audioParams) {
/** /**
* Sends a request to whispernet to encode a token. * Sends a request to whispernet to encode a token.
* @param {string} token Token to encode. This needs to be a base64 string. * @param {string} token Token to encode. This needs to be a base64 string.
* @param {boolean} audible Whether we should use encode audible samples.
*/ */
function encodeTokenRequest(token) { function encodeTokenRequest(token, audible) {
if (whisperEncoder) { if (whisperEncoder) {
whisperEncoder.encode(atob(token), true); whisperEncoder.encode(atob(token), audible, true);
} else { } else {
console.error('encodeTokenRequest: Whisper not initialized!'); console.error('encodeTokenRequest: Whisper not initialized!');
} }
......
...@@ -44,22 +44,10 @@ function WhisperEncoder(params, whisperNacl) { ...@@ -44,22 +44,10 @@ function WhisperEncoder(params, whisperNacl) {
this.whisperNacl_ = whisperNacl; this.whisperNacl_ = whisperNacl;
this.whisperNacl_.addListener(this.onNaclMessage_.bind(this)); this.whisperNacl_.addListener(this.onNaclMessage_.bind(this));
var symbolCoder = {};
symbolCoder.sample_rate = params.sampleRate || 48000.0;
symbolCoder.upsampling_factor = params.bitsPerSample || 16;
symbolCoder.desired_carrier_frequency = params.carrierFrequency || 18500.0;
symbolCoder.bits_per_symbol = 4;
symbolCoder.min_cycles_per_frame = 4;
symbolCoder.baseband_decimation_factor = 4;
var msg = { var msg = {
type: 'initialize_encoder', type: 'initialize_encoder',
symbol_coder: symbolCoder, sample_rate: params.sampleRate || 48000.0,
encoder_params: { upsampling_factor: params.bitsPerSample || 16,
bytes_per_token: 6,
include_parity_symbol: true,
single_sideband: true
}
}; };
this.whisperNacl_.send(JSON.stringify(msg)); this.whisperNacl_.send(JSON.stringify(msg));
} }
...@@ -67,10 +55,11 @@ function WhisperEncoder(params, whisperNacl) { ...@@ -67,10 +55,11 @@ function WhisperEncoder(params, whisperNacl) {
/** /**
* Method to encode a token. * Method to encode a token.
* @param {string} token Token to encode. * @param {string} token Token to encode.
* @param {boolean} audible Whether we should use encode audible samples.
* @param {boolean} raw Whether we should return the encoded samples in raw * @param {boolean} raw Whether we should return the encoded samples in raw
* format or as a Wave file. * format or as a Wave file.
*/ */
WhisperEncoder.prototype.encode = function(token, raw) { WhisperEncoder.prototype.encode = function(token, audible, raw) {
var msg = { var msg = {
type: 'encode_token', type: 'encode_token',
// Trying to send the token in binary form to Nacl doesn't work correctly. // Trying to send the token in binary form to Nacl doesn't work correctly.
...@@ -79,6 +68,7 @@ WhisperEncoder.prototype.encode = function(token, raw) { ...@@ -79,6 +68,7 @@ WhisperEncoder.prototype.encode = function(token, raw) {
// forth by converting the bytes into an array of integers. // forth by converting the bytes into an array of integers.
token: stringToArray(token), token: stringToArray(token),
repetitions: this.repetitions_, repetitions: this.repetitions_,
use_dtmf: audible,
return_raw_samples: raw return_raw_samples: raw
}; };
this.whisperNacl_.send(JSON.stringify(msg)); this.whisperNacl_.send(JSON.stringify(msg));
...@@ -122,24 +112,11 @@ function WhisperDecoder(params, whisperNacl) { ...@@ -122,24 +112,11 @@ function WhisperDecoder(params, whisperNacl) {
var msg = { var msg = {
type: 'initialize_decoder', type: 'initialize_decoder',
num_channels: params.channels, channels: params.channels || 1,
symbol_coder: { sample_rate: params.sampleRate || 48000.0,
sample_rate: params.sampleRate || 48000.0, upsampling_factor: params.bitsPerSample || 16,
upsampling_factor: params.bitsPerSample || 16, max_candidates: 1,
desired_carrier_frequency: params.carrierFrequency || 18500.0, max_buffer_duration_in_seconds: 3
bits_per_symbol: 4,
min_cycles_per_frame: 4,
baseband_decimation_factor: 4
},
decoder_params: {
bytes_per_token: 6,
include_parity_symbol: true,
max_candidates: 1,
broadcaster_stopped_threshold_in_seconds: 10
},
acquisition_params: {
max_buffer_duration_in_seconds: 3
}
}; };
this.whisperNacl_.send(JSON.stringify(msg)); this.whisperNacl_.send(JSON.stringify(msg));
} }
......
...@@ -1026,7 +1026,6 @@ ...@@ -1026,7 +1026,6 @@
'browser/chromeos/ui/idle_logout_dialog_view_browsertest.cc', 'browser/chromeos/ui/idle_logout_dialog_view_browsertest.cc',
'browser/collected_cookies_browsertest.cc', 'browser/collected_cookies_browsertest.cc',
'browser/content_settings/content_settings_browsertest.cc', 'browser/content_settings/content_settings_browsertest.cc',
'browser/copresence/chrome_whispernet_client_browsertest.cc',
'browser/crash_recovery_browsertest.cc', 'browser/crash_recovery_browsertest.cc',
'browser/custom_handlers/protocol_handler_registry_browsertest.cc', 'browser/custom_handlers/protocol_handler_registry_browsertest.cc',
'browser/devtools/device/adb/adb_client_socket_browsertest.cc', 'browser/devtools/device/adb/adb_client_socket_browsertest.cc',
...@@ -2003,7 +2002,11 @@ ...@@ -2003,7 +2002,11 @@
], ],
}], }],
['OS!="android" and OS!="ios"', { ['OS!="android" and OS!="ios"', {
'sources': [
'browser/copresence/chrome_whispernet_client_browsertest.cc',
],
'dependencies': [ 'dependencies': [
'../components/components.gyp:copresence',
# build time dependency. # build time dependency.
'../v8/src/d8.gyp:d8#host', '../v8/src/d8.gyp:d8#host',
], ],
......
...@@ -40,7 +40,7 @@ namespace copresencePrivate { ...@@ -40,7 +40,7 @@ namespace copresencePrivate {
// Fired to request initialization of the whisper.net library. // Fired to request initialization of the whisper.net library.
static void onInitialize(AudioParameters audioParams); static void onInitialize(AudioParameters audioParams);
// Fired to request encoding of the given token. // Fired to request encoding of the given token.
static void onEncodeTokenRequest(DOMString base64Token); static void onEncodeTokenRequest(DOMString base64Token, boolean audible);
// Fired when we have new samples to decode. // Fired when we have new samples to decode.
static void onDecodeSamplesRequest(ArrayBuffer audioSamples); static void onDecodeSamplesRequest(ArrayBuffer audioSamples);
// Fired to request a DetectBroadcast. // Fired to request a DetectBroadcast.
......
...@@ -40,7 +40,7 @@ class WhispernetClient { ...@@ -40,7 +40,7 @@ class WhispernetClient {
virtual void Shutdown() = 0; virtual void Shutdown() = 0;
// Fires an event to request a token encode. // Fires an event to request a token encode.
virtual void EncodeToken(const std::string& token) = 0; virtual void EncodeToken(const std::string& token, bool audible) = 0;
// Fires an event to request a decode for the given samples. // Fires an event to request a decode for the given samples.
virtual void DecodeSamples(const std::string& samples) = 0; virtual void DecodeSamples(const std::string& samples) = 0;
// Fires an event to request detection of a whispernet broadcast. // Fires an event to request detection of a whispernet broadcast.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment