Extract code handling PrinterProviderAPI from PrintPreviewHandler
[chromium-blink-merge.git] / chrome / browser / resources / app_list / plugin_manager.js
blob6a025e0548a1b2cad873d5f16aac776f2512c9dc
1 // Copyright 2013 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 /**
6  * @fileoverview The manager of offline hotword speech recognizer plugin.
7  */
9 cr.define('speech', function() {
10   'use strict';
12   /** The timeout milliseconds to load the model file. */
13   var MODEL_LOAD_TIMEOUT = 2000;
15   /**
16    * The type of the plugin state.
17    ** @enum {number}
18    */
19   var PluginState = {
20     UNINITIALIZED: 0,
21     LOADED: 1,
22     READY: 2,
23     RECOGNIZING: 3
24   };
26   /**
27    * The command names of the plugin.
28    * @enum {string}
29    */
30   var pluginCommands = {
31     SET_SAMPLING_RATE: 'h',
32     SET_CONFIG: 'm',
33     START_RECOGNIZING: 'r',
34     STOP_RECOGNIZING: 's'
35   };
37   /**
38    * The regexp pattern of the hotword recognition result.
39    */
40   var recognitionPattern = /^(HotwordFiredEvent:|hotword)/;
42   /**
43    * @constructor
44    */
45   function PluginManager(prefix, onReady, onRecognized, onError) {
46     this.state = PluginState.UNINITIALIZED;
47     this.onReady_ = onReady;
48     this.onRecognized_ = onRecognized;
49     this.onError_ = onError;
50     this.samplingRate_ = null;
51     this.config_ = null;
52     this.modelLoadTimeoutId_ = null;
53     var recognizer = $('recognizer');
54     if (!recognizer) {
55       recognizer = document.createElement('EMBED');
56       recognizer.id = 'recognizer';
57       recognizer.type = 'application/x-nacl';
58       recognizer.src = 'chrome://app-list/hotword_' + prefix + '.nmf';
59       recognizer.width = '1';
60       recognizer.height = '1';
61       document.body.appendChild(recognizer);
62     }
63     recognizer.addEventListener('error', onError);
64     recognizer.addEventListener('message', this.onMessage_.bind(this));
65     recognizer.addEventListener('load', this.onLoad_.bind(this));
66   };
68   /**
69    * The event handler of the plugin status.
70    *
71    * @param {Event} messageEvent the event object from the plugin.
72    * @private
73    */
74   PluginManager.prototype.onMessage_ = function(messageEvent) {
75     if (messageEvent.data == 'audio') {
76       var wasNotReady = this.state < PluginState.READY;
77       this.state = PluginState.RECOGNIZING;
78       if (wasNotReady) {
79         window.clearTimeout(this.modelLoadTimeoutId_);
80         this.modelLoadTimeoutId_ = null;
81         this.onReady_(this);
82       }
83     } else if (messageEvent.data == 'stopped' &&
84                this.state == PluginState.RECOGNIZING) {
85       this.state = PluginState.READY;
86     } else if (recognitionPattern.exec(messageEvent.data)) {
87       this.onRecognized_();
88     }
89   };
91   /**
92    * The event handler when the plugin is loaded.
93    *
94    * @private
95    */
96   PluginManager.prototype.onLoad_ = function() {
97     if (this.state == PluginState.UNINITIALIZED) {
98       this.state = PluginState.LOADED;
99       if (this.samplingRate_ && this.config_)
100         this.initialize_(this.samplingRate_, this.config_);
101       // Sets the timeout for initialization in case that NaCl module failed to
102       // respond during the initialization.
103       this.modelLoadTimeoutId_ = window.setTimeout(
104           this.onError_, MODEL_LOAD_TIMEOUT);
105     }
106   };
108   /**
109    * Sends the initialization messages to the plugin. This method is private.
110    * The initialization will happen from onLoad_ or scheduleInitialize.
111    *
112    * @param {number} samplingRate the sampling rate the plugin accepts.
113    * @param {string} config the url of the config file.
114    * @private
115    */
116   PluginManager.prototype.initialize_ = function(samplingRate, config) {
117     $('recognizer').postMessage(
118         pluginCommands.SET_SAMPLING_RATE + samplingRate);
119     $('recognizer').postMessage(pluginCommands.SET_CONFIG + config);
120   };
122   /**
123    * Initializes the plugin with the specified parameter, or schedules the
124    * initialization if the plugin is not ready.
125    *
126    * @param {number} samplingRate the sampling rate the plugin accepts.
127    * @param {string} config the url of the config file.
128    */
129   PluginManager.prototype.scheduleInitialize = function(samplingRate, config) {
130     if (this.state == PluginState.UNINITIALIZED) {
131       this.samplingRate_ = samplingRate;
132       this.config_ = config;
133     } else {
134       this.initialize_(samplingRate, config);
135     }
136   };
138   /**
139    * Asks the plugin to start recognizing the hotword.
140    */
141   PluginManager.prototype.startRecognizer = function() {
142     if (this.state == PluginState.READY)
143       $('recognizer').postMessage(pluginCommands.START_RECOGNIZING);
144   };
146   /**
147    * Asks the plugin to stop recognizing the hotword.
148    */
149   PluginManager.prototype.stopRecognizer = function() {
150     if (this.state == PluginState.RECOGNIZING)
151       $('recognizer').postMessage(pluginCommands.STOP_RECOGNIZING);
152   };
154   /**
155    * Sends the actual audio wave data.
156    *
157    * @param {cr.event.Event} event The event for the audio data.
158    */
159   PluginManager.prototype.sendAudioData = function(event) {
160     if (this.state == PluginState.RECOGNIZING)
161       $('recognizer').postMessage(event.data.buffer);
162   };
164   return {
165     PluginManager: PluginManager,
166     PluginState: PluginState,
167   };