OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The ChromeOS IME Authors. All Rights Reserved. |
| 2 // limitations under the License. |
| 3 // See the License for the specific language governing permissions and |
| 4 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 5 // distributed under the License is distributed on an "AS-IS" BASIS, |
| 6 // Unless required by applicable law or agreed to in writing, software |
| 7 // |
| 8 // http://www.apache.org/licenses/LICENSE-2.0 |
| 9 // |
| 10 // You may obtain a copy of the License at |
| 11 // you may not use this file except in compliance with the License. |
| 12 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 13 // |
| 14 goog.provide('i18n.input.chrome.Statistics'); |
| 15 |
| 16 goog.scope(function() { |
| 17 |
| 18 |
| 19 |
| 20 /** |
| 21 * The statistics util class for IME of ChromeOS. |
| 22 * |
| 23 * @constructor |
| 24 */ |
| 25 i18n.input.chrome.Statistics = function() { |
| 26 }; |
| 27 goog.addSingletonGetter(i18n.input.chrome.Statistics); |
| 28 var Statistics = i18n.input.chrome.Statistics; |
| 29 |
| 30 |
| 31 /** |
| 32 * The layout types for stats. |
| 33 * |
| 34 * @enum {number} |
| 35 */ |
| 36 Statistics.LayoutTypes = { |
| 37 COMPACT: 0, |
| 38 COMPACT_SYMBOL: 1, |
| 39 COMPACT_MORE: 2, |
| 40 FULL: 3, |
| 41 A11Y: 4, |
| 42 HANDWRITING: 5, |
| 43 EMOJI: 6, |
| 44 MAX: 7 |
| 45 }; |
| 46 |
| 47 |
| 48 /** |
| 49 * The commit type for stats. |
| 50 * |
| 51 * @enum {number} |
| 52 */ |
| 53 Statistics.CommitTypes = { |
| 54 X_X0: 0, // User types X, and chooses X as top suggestion. |
| 55 X_X1: 1, // User types X, and chooses X as non-top suggestion. |
| 56 X_Y0: 2, // User types X, and chooses Y as top suggestion. |
| 57 X_Y1: 3, // User types X, and chooses Y as non-top suggestion. |
| 58 PREDICTION: 4, |
| 59 REVERT: 5, |
| 60 MAX: 7 |
| 61 }; |
| 62 |
| 63 |
| 64 /** |
| 65 * The current input method id. |
| 66 * |
| 67 * @type {string} |
| 68 * @private |
| 69 */ |
| 70 Statistics.prototype.inputMethodId_ = ''; |
| 71 |
| 72 |
| 73 /** |
| 74 * The current auto correct level. |
| 75 * |
| 76 * @type {number} |
| 77 * @private |
| 78 */ |
| 79 Statistics.prototype.autoCorrectLevel_ = 0; |
| 80 |
| 81 |
| 82 /** |
| 83 * Sets the current input method id. |
| 84 * |
| 85 * @param {string} inputMethodId . |
| 86 */ |
| 87 Statistics.prototype.setInputMethodId = function( |
| 88 inputMethodId) { |
| 89 this.inputMethodId_ = inputMethodId; |
| 90 }; |
| 91 |
| 92 |
| 93 /** |
| 94 * Sets the current auto-correct level. |
| 95 * |
| 96 * @param {number} level . |
| 97 */ |
| 98 Statistics.prototype.setAutoCorrectLevel = function( |
| 99 level) { |
| 100 this.autoCorrectLevel_ = level; |
| 101 this.recordEnum('InputMethod.AutoCorrectLevel', level, 3); |
| 102 }; |
| 103 |
| 104 |
| 105 /** |
| 106 * Gets the commit target type based on the given source and target. |
| 107 * |
| 108 * @param {string} source . |
| 109 * @param {string} target . |
| 110 * @return {number} The target type number value. |
| 111 * 0: Source; 1: Correction; 2: Completion; 3: Prediction. |
| 112 * @private |
| 113 */ |
| 114 Statistics.prototype.getTargetType_ = function( |
| 115 source, target) { |
| 116 if (source == target) { |
| 117 return 0; |
| 118 } |
| 119 if (!source) { |
| 120 return 3; |
| 121 } |
| 122 if (target.length > source.length) { |
| 123 return 2; |
| 124 } |
| 125 return 1; |
| 126 }; |
| 127 |
| 128 |
| 129 /** |
| 130 * Records the metrics for each commit. |
| 131 * |
| 132 * @param {string} source . |
| 133 * @param {string} target . |
| 134 * @param {number} targetIndex The target index. |
| 135 * @param {number} triggerType The trigger type: |
| 136 * 0: BySpace; 1: ByReset; 2: ByCandidate; 3: BySymbolOrNumber; |
| 137 * 4: ByDoubleSpaceToPeriod; 5: ByRevert. |
| 138 */ |
| 139 Statistics.prototype.recordCommit = function( |
| 140 source, target, targetIndex, triggerType) { |
| 141 if (!this.inputMethodId_) { |
| 142 return; |
| 143 } |
| 144 var CommitTypes = Statistics.CommitTypes; |
| 145 var commitType = -1; |
| 146 if (targetIndex == 0 && source == target) { |
| 147 commitType = CommitTypes.X_X0; |
| 148 } else if (targetIndex == 0 && source != target) { |
| 149 commitType = CommitTypes.X_Y0; |
| 150 } else if (targetIndex > 0 && source == target) { |
| 151 commitType = CommitTypes.X_X1; |
| 152 } else if (targetIndex > 0 && source != target) { |
| 153 commitType = CommitTypes.X_Y1; |
| 154 } else if (!source && this.getTargetType_(source, target) == 3) { |
| 155 commitType = CommitTypes.PREDICTION; |
| 156 } else if (triggerType == 5) { |
| 157 commitType = CommitTypes.REVERT; |
| 158 } |
| 159 if (commitType < 0) { |
| 160 return; |
| 161 } |
| 162 |
| 163 var self = this; |
| 164 var record = function(suffix) { |
| 165 self.recordEnum('InputMethod.Commit.Index' + suffix, |
| 166 targetIndex + 1, 20); |
| 167 self.recordEnum('InputMethod.Commit.Type' + suffix, |
| 168 commitType, CommitTypes.MAX); |
| 169 }; |
| 170 |
| 171 record(''); |
| 172 |
| 173 if (/^pinyin/.test(this.inputMethodId_)) { |
| 174 record('.Pinyin'); |
| 175 } else if (/^xkb:us/.test(this.inputMethodId_)) { |
| 176 record('.US'); |
| 177 record('.US.AC' + this.autoCorrectLevel_); |
| 178 } else if (/^xkb:fr/.test(this.inputMethodId_)) { |
| 179 record('.FR'); |
| 180 record('.FR.AC' + this.autoCorrectLevel_); |
| 181 } |
| 182 }; |
| 183 |
| 184 |
| 185 /** |
| 186 * Records the latency value for stats. |
| 187 * |
| 188 * @param {string} name . |
| 189 * @param {number} timeInMs . |
| 190 */ |
| 191 Statistics.prototype.recordLatency = function( |
| 192 name, timeInMs) { |
| 193 this.recordValue(name, timeInMs, 1000, 50); |
| 194 }; |
| 195 |
| 196 |
| 197 /** |
| 198 * Gets the layout type for stats. |
| 199 * |
| 200 * @param {string} layoutCode . |
| 201 * @param {boolean} isA11yMode . |
| 202 * @return {Statistics.LayoutTypes} |
| 203 */ |
| 204 Statistics.prototype.getLayoutType = function(layoutCode, isA11yMode) { |
| 205 var LayoutTypes = Statistics.LayoutTypes; |
| 206 var layoutType = LayoutTypes.MAX; |
| 207 if (isA11yMode) { |
| 208 layoutType = LayoutTypes.A11Y; |
| 209 } else if (/compact/.test(layoutCode)) { |
| 210 if (/symbol/.test(layoutCode)) { |
| 211 layoutType = LayoutTypes.COMPACT_SYMBOL; |
| 212 } else if (/more/.test(layoutCode)) { |
| 213 layoutType = LayoutTypes.COMPACT_MORE; |
| 214 } else { |
| 215 layoutType = LayoutTypes.COMPACT; |
| 216 } |
| 217 } else if (/^hwt/.test(layoutCode)) { |
| 218 layoutType = LayoutTypes.HANDWRITING; |
| 219 } else if (/^emoji/.test(layoutCode)) { |
| 220 layoutType = LayoutTypes.EMOJI; |
| 221 } |
| 222 return layoutType; |
| 223 }; |
| 224 |
| 225 |
| 226 /** |
| 227 * Records the layout usage. |
| 228 * |
| 229 * @param {string} layoutCode The layout code to be switched to. |
| 230 * @param {boolean} isA11yMode . |
| 231 */ |
| 232 Statistics.prototype.recordLayout = function( |
| 233 layoutCode, isA11yMode) { |
| 234 this.recordEnum('InputMethod.VirtualKeyboard.Layout', |
| 235 this.getLayoutType(layoutCode, isA11yMode), Statistics.LayoutTypes.MAX); |
| 236 }; |
| 237 |
| 238 |
| 239 /** |
| 240 * Records the layout switching action. |
| 241 */ |
| 242 Statistics.prototype.recordLayoutSwitch = function() { |
| 243 this.recordValue('InputMethod.VirtualKeyboard.LayoutSwitch', 1, 1, 1); |
| 244 }; |
| 245 |
| 246 |
| 247 /** |
| 248 * Records enum value. |
| 249 * |
| 250 * @param {string} name . |
| 251 * @param {number} enumVal . |
| 252 * @param {number} enumCount . |
| 253 */ |
| 254 Statistics.prototype.recordEnum = function( |
| 255 name, enumVal, enumCount) { |
| 256 if (chrome.metricsPrivate && chrome.metricsPrivate.recordValue) { |
| 257 chrome.metricsPrivate.recordValue({ |
| 258 'metricName': name, |
| 259 'type': 'histogram-linear', |
| 260 'min': 0, |
| 261 'max': enumCount - 1, |
| 262 'buckets': enumCount |
| 263 }, enumVal); |
| 264 } |
| 265 }; |
| 266 |
| 267 |
| 268 /** |
| 269 * Records count value. |
| 270 * |
| 271 * @param {string} name . |
| 272 * @param {number} count . |
| 273 * @param {number} max . |
| 274 * @param {number} bucketCount . |
| 275 */ |
| 276 Statistics.prototype.recordValue = function( |
| 277 name, count, max, bucketCount) { |
| 278 if (chrome.metricsPrivate && chrome.metricsPrivate.recordValue) { |
| 279 chrome.metricsPrivate.recordValue({ |
| 280 'metricName': name, |
| 281 'type': 'histogram-log', |
| 282 'min': 0, |
| 283 'max': max, |
| 284 'buckets': bucketCount |
| 285 }, count); |
| 286 } |
| 287 }; |
| 288 }); // goog.scope |
OLD | NEW |