Home | History | Annotate | Download | only in copresence
      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.
      4 
      5 #include "chrome/browser/copresence/chrome_whispernet_client.h"
      6 
      7 #include "chrome/browser/extensions/api/copresence_private/copresence_private_api.h"
      8 #include "chrome/browser/extensions/component_loader.h"
      9 #include "chrome/browser/extensions/extension_service.h"
     10 #include "chrome/common/extensions/api/copresence_private.h"
     11 #include "components/copresence/public/copresence_constants.h"
     12 #include "content/public/browser/browser_context.h"
     13 #include "extensions/browser/event_router.h"
     14 #include "extensions/browser/extension_system.h"
     15 #include "grit/browser_resources.h"
     16 
     17 // static
     18 const char ChromeWhispernetClient::kWhispernetProxyExtensionId[] =
     19     "bpfmnplchembfbdgieamdodgaencleal";
     20 
     21 // Public:
     22 
     23 ChromeWhispernetClient::ChromeWhispernetClient(
     24     content::BrowserContext* browser_context)
     25     : browser_context_(browser_context), extension_loaded_(false) {
     26 }
     27 
     28 ChromeWhispernetClient::~ChromeWhispernetClient() {
     29 }
     30 
     31 void ChromeWhispernetClient::Initialize(const SuccessCallback& init_callback) {
     32   DVLOG(3) << "Initializing whispernet proxy client.";
     33   init_callback_ = init_callback;
     34 
     35   extensions::ExtensionSystem* es =
     36       extensions::ExtensionSystem::Get(browser_context_);
     37   DCHECK(es);
     38   ExtensionService* service = es->extension_service();
     39   DCHECK(service);
     40   extensions::ComponentLoader* loader = service->component_loader();
     41   DCHECK(loader);
     42 
     43   // This callback is cancelled in Shutdown().
     44   extension_loaded_callback_ = base::Bind(
     45       &ChromeWhispernetClient::OnExtensionLoaded, base::Unretained(this));
     46 
     47   if (!loader->Exists(kWhispernetProxyExtensionId)) {
     48     DVLOG(3) << "Loading Whispernet proxy.";
     49     loader->Add(IDR_WHISPERNET_PROXY_MANIFEST,
     50                 base::FilePath(FILE_PATH_LITERAL("whispernet_proxy")));
     51   } else {
     52     init_callback_.Run(true);
     53   }
     54 }
     55 
     56 void ChromeWhispernetClient::Shutdown() {
     57   extension_loaded_callback_.Reset();
     58   init_callback_.Reset();
     59   tokens_callback_.Reset();
     60   samples_callback_.Reset();
     61   db_callback_.Reset();
     62 }
     63 
     64 // Fire an event to request a token encode.
     65 void ChromeWhispernetClient::EncodeToken(const std::string& token,
     66                                          bool audible) {
     67   DCHECK(extension_loaded_);
     68   DCHECK(browser_context_);
     69   DCHECK(extensions::EventRouter::Get(browser_context_));
     70 
     71   scoped_ptr<extensions::Event> event(new extensions::Event(
     72       extensions::api::copresence_private::OnEncodeTokenRequest::kEventName,
     73       extensions::api::copresence_private::OnEncodeTokenRequest::Create(
     74           token, audible),
     75       browser_context_));
     76 
     77   extensions::EventRouter::Get(browser_context_)
     78       ->DispatchEventToExtension(kWhispernetProxyExtensionId, event.Pass());
     79 }
     80 
     81 // Fire an event to request a decode for the given samples.
     82 void ChromeWhispernetClient::DecodeSamples(const std::string& samples) {
     83   DCHECK(extension_loaded_);
     84   DCHECK(browser_context_);
     85   DCHECK(extensions::EventRouter::Get(browser_context_));
     86 
     87   scoped_ptr<extensions::Event> event(new extensions::Event(
     88       extensions::api::copresence_private::OnDecodeSamplesRequest::kEventName,
     89       extensions::api::copresence_private::OnDecodeSamplesRequest::Create(
     90           samples),
     91       browser_context_));
     92 
     93   extensions::EventRouter::Get(browser_context_)
     94       ->DispatchEventToExtension(kWhispernetProxyExtensionId, event.Pass());
     95 }
     96 
     97 void ChromeWhispernetClient::DetectBroadcast() {
     98   DCHECK(extension_loaded_);
     99   DCHECK(browser_context_);
    100   DCHECK(extensions::EventRouter::Get(browser_context_));
    101 
    102   scoped_ptr<extensions::Event> event(new extensions::Event(
    103       extensions::api::copresence_private::OnDetectBroadcastRequest::kEventName,
    104       make_scoped_ptr(new base::ListValue()),
    105       browser_context_));
    106 
    107   extensions::EventRouter::Get(browser_context_)
    108       ->DispatchEventToExtension(kWhispernetProxyExtensionId, event.Pass());
    109 }
    110 
    111 void ChromeWhispernetClient::RegisterTokensCallback(
    112     const TokensCallback& tokens_callback) {
    113   tokens_callback_ = tokens_callback;
    114 }
    115 
    116 void ChromeWhispernetClient::RegisterSamplesCallback(
    117     const SamplesCallback& samples_callback) {
    118   samples_callback_ = samples_callback;
    119 }
    120 
    121 void ChromeWhispernetClient::RegisterDetectBroadcastCallback(
    122     const SuccessCallback& db_callback) {
    123   db_callback_ = db_callback;
    124 }
    125 
    126 ChromeWhispernetClient::TokensCallback
    127 ChromeWhispernetClient::GetTokensCallback() {
    128   return tokens_callback_;
    129 }
    130 
    131 ChromeWhispernetClient::SamplesCallback
    132 ChromeWhispernetClient::GetSamplesCallback() {
    133   return samples_callback_;
    134 }
    135 
    136 ChromeWhispernetClient::SuccessCallback
    137 ChromeWhispernetClient::GetDetectBroadcastCallback() {
    138   return db_callback_;
    139 }
    140 
    141 ChromeWhispernetClient::SuccessCallback
    142 ChromeWhispernetClient::GetInitializedCallback() {
    143   return extension_loaded_callback_;
    144 }
    145 
    146 // Private:
    147 
    148 // Fire an event to initialize whispernet with the given parameters.
    149 void ChromeWhispernetClient::InitializeWhispernet(
    150     const extensions::api::copresence_private::AudioParameters& params) {
    151   DCHECK(browser_context_);
    152   DCHECK(extensions::EventRouter::Get(browser_context_));
    153 
    154   scoped_ptr<extensions::Event> event(new extensions::Event(
    155       extensions::api::copresence_private::OnInitialize::kEventName,
    156       extensions::api::copresence_private::OnInitialize::Create(params),
    157       browser_context_));
    158 
    159   extensions::EventRouter::Get(browser_context_)
    160       ->DispatchEventToExtension(kWhispernetProxyExtensionId, event.Pass());
    161 }
    162 
    163 void ChromeWhispernetClient::OnExtensionLoaded(bool success) {
    164   if (extension_loaded_) {
    165     if (!init_callback_.is_null())
    166       init_callback_.Run(success);
    167     return;
    168   }
    169 
    170   // Our extension just got loaded, initialize whispernet.
    171   extension_loaded_ = true;
    172 
    173   // This will fire another OnExtensionLoaded call once the initialization is
    174   // done, which means we've initialized for realz, hence call the init
    175   // callback.
    176 
    177   // At this point, we have the same parameters for record and play. This
    178   // may change later though (ongoing discussion with research).
    179   extensions::api::copresence_private::AudioParameters params;
    180   params.play.sample_rate = copresence::kDefaultSampleRate;
    181   params.play.bits_per_sample = copresence::kDefaultBitsPerSample;
    182   params.play.carrier_frequency = copresence::kDefaultCarrierFrequency;
    183   params.play.repetitions = copresence::kDefaultRepetitions;
    184 
    185   params.record.sample_rate = copresence::kDefaultSampleRate;
    186   params.record.bits_per_sample = copresence::kDefaultBitsPerSample;
    187   params.record.carrier_frequency = copresence::kDefaultCarrierFrequency;
    188   params.record.channels = copresence::kDefaultChannels;
    189 
    190   InitializeWhispernet(params);
    191 }
    192