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 @@
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/common/extensions/api/copresence_private.h"
#include "components/copresence/public/copresence_constants.h"
#include "content/public/browser/browser_context.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_system.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
const char ChromeWhispernetClient::kWhispernetProxyExtensionId[] =
"bpfmnplchembfbdgieamdodgaencleal";
......@@ -73,14 +62,16 @@ void ChromeWhispernetClient::Shutdown() {
}
// 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(browser_context_);
DCHECK(extensions::EventRouter::Get(browser_context_));
scoped_ptr<extensions::Event> event(new extensions::Event(
extensions::api::copresence_private::OnEncodeTokenRequest::kEventName,
extensions::api::copresence_private::OnEncodeTokenRequest::Create(token),
extensions::api::copresence_private::OnEncodeTokenRequest::Create(
token, audible),
browser_context_));
extensions::EventRouter::Get(browser_context_)
......
......@@ -40,7 +40,7 @@ class ChromeWhispernetClient : public copresence::WhispernetClient {
virtual void Initialize(const SuccessCallback& init_callback) 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 DetectBroadcast() OVERRIDE;
......
......@@ -21,6 +21,8 @@
namespace {
const char kSixZeros[] = "MDAwMDAw";
copresence::WhispernetClient* GetWhispernetClient(
content::BrowserContext* context) {
extensions::CopresenceService* service =
......@@ -61,19 +63,16 @@ class ChromeWhispernetClientTest : public ExtensionBrowserTest {
EXPECT_TRUE(initialized_);
}
void EncodeTokenAndSaveSamples() {
void EncodeTokenAndSaveSamples(bool audible) {
copresence::WhispernetClient* client = GetWhispernetClient(context_);
ASSERT_TRUE(client);
// This is the base64 encoding for "000000".
const std::string kZeroToken = "MDAwMDAw";
run_loop_.reset(new base::RunLoop());
client->RegisterSamplesCallback(base::Bind(
&ChromeWhispernetClientTest::SamplesCallback, base::Unretained(this)));
expected_token_ = kZeroToken;
expected_token_ = kSixZeros;
client->EncodeToken(kZeroToken);
client->EncodeToken(kSixZeros, audible);
run_loop_->Run();
EXPECT_GT(saved_samples_->frames(), 0);
......@@ -83,12 +82,10 @@ class ChromeWhispernetClientTest : public ExtensionBrowserTest {
copresence::WhispernetClient* client = GetWhispernetClient(context_);
ASSERT_TRUE(client);
const std::string kZeroToken = "MDAwMDAw";
run_loop_.reset(new base::RunLoop());
client->RegisterTokensCallback(base::Bind(
&ChromeWhispernetClientTest::TokensCallback, base::Unretained(this)));
expected_token_ = kZeroToken;
expected_token_ = kSixZeros;
ASSERT_GT(saved_samples_->frames(), 0);
......@@ -167,18 +164,24 @@ IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, Initialize) {
IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, EncodeToken) {
InitializeWhispernet();
EncodeTokenAndSaveSamples();
EncodeTokenAndSaveSamples(false);
}
IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, DecodeSamples) {
InitializeWhispernet();
EncodeTokenAndSaveSamples();
EncodeTokenAndSaveSamples(false);
DecodeSamplesAndVerifyToken();
}
IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, DetectBroadcast) {
InitializeWhispernet();
EncodeTokenAndSaveSamples();
EncodeTokenAndSaveSamples(false);
DecodeSamplesAndVerifyToken();
DetectBroadcast();
}
IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, Audible) {
InitializeWhispernet();
EncodeTokenAndSaveSamples(true);
DecodeSamplesAndVerifyToken();
}
......@@ -38,10 +38,11 @@ function initialize(audioParams) {
/**
* Sends a request to whispernet to encode a token.
* @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) {
whisperEncoder.encode(atob(token), true);
whisperEncoder.encode(atob(token), audible, true);
} else {
console.error('encodeTokenRequest: Whisper not initialized!');
}
......
......@@ -44,22 +44,10 @@ function WhisperEncoder(params, whisperNacl) {
this.whisperNacl_ = whisperNacl;
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 = {
type: 'initialize_encoder',
symbol_coder: symbolCoder,
encoder_params: {
bytes_per_token: 6,
include_parity_symbol: true,
single_sideband: true
}
sample_rate: params.sampleRate || 48000.0,
upsampling_factor: params.bitsPerSample || 16,
};
this.whisperNacl_.send(JSON.stringify(msg));
}
......@@ -67,10 +55,11 @@ function WhisperEncoder(params, whisperNacl) {
/**
* Method to encode a token.
* @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
* format or as a Wave file.
*/
WhisperEncoder.prototype.encode = function(token, raw) {
WhisperEncoder.prototype.encode = function(token, audible, raw) {
var msg = {
type: 'encode_token',
// Trying to send the token in binary form to Nacl doesn't work correctly.
......@@ -79,6 +68,7 @@ WhisperEncoder.prototype.encode = function(token, raw) {
// forth by converting the bytes into an array of integers.
token: stringToArray(token),
repetitions: this.repetitions_,
use_dtmf: audible,
return_raw_samples: raw
};
this.whisperNacl_.send(JSON.stringify(msg));
......@@ -122,24 +112,11 @@ function WhisperDecoder(params, whisperNacl) {
var msg = {
type: 'initialize_decoder',
num_channels: params.channels,
symbol_coder: {
channels: params.channels || 1,
sample_rate: params.sampleRate || 48000.0,
upsampling_factor: params.bitsPerSample || 16,
desired_carrier_frequency: params.carrierFrequency || 18500.0,
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));
}
......
......@@ -1026,7 +1026,6 @@
'browser/chromeos/ui/idle_logout_dialog_view_browsertest.cc',
'browser/collected_cookies_browsertest.cc',
'browser/content_settings/content_settings_browsertest.cc',
'browser/copresence/chrome_whispernet_client_browsertest.cc',
'browser/crash_recovery_browsertest.cc',
'browser/custom_handlers/protocol_handler_registry_browsertest.cc',
'browser/devtools/device/adb/adb_client_socket_browsertest.cc',
......@@ -2003,7 +2002,11 @@
],
}],
['OS!="android" and OS!="ios"', {
'sources': [
'browser/copresence/chrome_whispernet_client_browsertest.cc',
],
'dependencies': [
'../components/components.gyp:copresence',
# build time dependency.
'../v8/src/d8.gyp:d8#host',
],
......
......@@ -40,7 +40,7 @@ namespace copresencePrivate {
// Fired to request initialization of the whisper.net library.
static void onInitialize(AudioParameters audioParams);
// 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.
static void onDecodeSamplesRequest(ArrayBuffer audioSamples);
// Fired to request a DetectBroadcast.
......
......@@ -40,7 +40,7 @@ class WhispernetClient {
virtual void Shutdown() = 0;
// 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.
virtual void DecodeSamples(const std::string& samples) = 0;
// 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