1// LICENSE_CODE ZON 2'use strict'; /*jslint node:true, browser:true*/ 3var define; 4var is_node = typeof module=='object' && module.exports; 5if (is_node) 6 define = require('../../../util/require_node.js').define(module, '..'); 7else 8 define = self.define; 9define(['/util/user_agent.js', '/util/etask.js', 'svc_versions', 10 '/util/version_util.js', '/www/hola/pub/lib/model.ts', '/svc/hola/pub/svc_ipc.js', 11 '/www/hola/pub/config.js', '/util/url.js', '/svc/vpn/pub/util.js'], 12 function(user_agent, etask, versions, version_util, hola_model, 13 svc_ipc, config, zurl, svc_vpn_util) 14 { 15var b = user_agent.guess_browser(); 16var g = user_agent.guess(); 17var is_ext_inited, is_svc_inited, is_reg_inited; 18var ext_etask, svc_etask, reg_etask; 19 20// XXX pavlo: not working for MP use case now 21function msg_post_recv(opt){ 22 var msg = opt.msg, on_msg; 23 return etask([function(){ 24 on_msg = function(e){ 25 if (e.source!=top || e.data.src==msg.src || e.data.id!=msg.id) 26 return; 27 this.continue(e.data); 28 }.bind(this); 29 try { 30 // will init exception on cross origin frame access 31 top.addEventListener('message', on_msg); 32 } catch(e){ 33 this.continue(); 34 return; 35 } 36 top.postMessage(msg, '*'); 37 return this.wait(opt.timeout||5000); 38 }, function finally$(){ 39 // will init exception on cross origin frame access 40 try { top.removeEventListener('message', on_msg); } catch(e){} 41 }]); 42} 43 44function check_ext(opt){ 45 opt = opt||{}; 46 return msg_post_recv({timeout: opt.timeout||2000, 47 msg: {src: 'hola_ccgi', id: 'callback'}}); 48} 49 50function lean_check_ext(){ return svc_ipc.ext.lean_ping(); } 51 52function is_plugin(exe){ return /\bhola_plugin/.test(exe); } 53 54function check_svc(){ 55 return etask([function(){ 56 return svc_ipc.ajax('callback.json'); 57 }, function catch$(ret){ 58 throw {status: ret}; 59 }, function(ret){ 60 var data = ret.ret; 61 var xhr = ret.xhr; 62 return {data: data, status: xhr.statusText}; 63 }]); 64} 65 66function get_registry(attrib){ 67 return etask([function(){ 68 return svc_ipc.ajax({cmd: 'get_registry.json', 69 data: {attrib: attrib}}); 70 }, function(ret){ 71 var data = ret.ret||{}; 72 return data.value; 73 }]); 74} 75 76var info_model = new hola_model.Model({ 77 on_svc_detected: [], 78 reset: function(){ 79 is_ext_inited = is_svc_inited = is_reg_inited = false; 80 ext_etask = svc_etask = reg_etask = undefined; 81 config.set_hola_extension_info(undefined); 82 this.set('ext_info', undefined); 83 this.set('svc_info', undefined); 84 this.set('agree_ts', undefined); 85 }, 86 is_latest_ext: function(){ 87 var _this = this; 88 return etask([function(){ 89 return _this.get_ext_info(); 90 }, function(info){ 91 if (!info || !info.build_info) 92 return false; 93 return version_util.cmp(info.ver, 94 versions[info.build_info.browser_build])>=0; 95 }]); 96 }, 97 get_ext_info: function(){ 98 var _this = this; 99 return etask([function(){ 100 if (is_ext_inited) 101 return; 102 return _this._check_ext(); 103 }, function(){ 104 is_ext_inited = true; 105 return _this.get('ext_info'); 106 }]); 107 }, 108 get_svc_info: function(){ 109 var _this = this; 110 return etask([function(){ 111 if (is_svc_inited) 112 return; 113 return _this._check_svc(); 114 }, function(){ 115 is_svc_inited = true; 116 return _this.get('svc_info'); 117 }]); 118 }, 119 get_registry_info: function(){ 120 // XXX sergeir: don't use agree_ts; use object for all keys 121 var _this = this; 122 return etask([function(){ 123 if (is_reg_inited) 124 return; 125 return _this._check_registry(); 126 }, function(){ 127 is_reg_inited = true; 128 return {agree_ts: _this.get('agree_ts')}; 129 }]); 130 }, 131 is_ext: function(){ 132 var _this = this; 133 return etask([function(){ 134 return _this.get_ext_info(); 135 }, function(info){ 136 return !!info; 137 }]); 138 }, 139 is_svc: function(){ 140 var _this = this; 141 return etask([function(){ 142 return _this.get_svc_info(); 143 }, function(info){ 144 return !!info && !info.err; 145 }]); 146 }, 147 is_latest_svc: function(){ 148 var _this = this; 149 return etask([function(){ 150 return _this.get_svc_info(); 151 }, function(info){ 152 if (!info) 153 return false;
154 var v_os = g.os=='macos' ? versions.mac_svc : 155 svc_vpn_util.pick_version(versions, 156 svc_vpn_util.get_product(info.appid), 'windows'); 157 return version_util.cmp(info.ver, v_os)>=0; 158 }]); 159 }, 160 /** 161 * Waits for svc. 162 * 163 * @param {number} [timeout] Timeout in seconds. 164 * @returns {etask} Etask with svc info. 165 */ 166 wait_for_svc: function(timeout){ 167 var _this = this; 168 var spent = 0; 169 return etask.for(null, function(){ return etask.sleep(1000); }, 170 [function try_catch$(){ 171 spent++; 172 // _check_svc() will not work if we are currently using 'https', so 173 // call both, _check_ext() can provide svc info too. 174 this.spawn(_this._check_ext()); 175 this.spawn(_this._check_svc()); 176 this.spawn(_this._check_registry()); 177 return this.wait_child('any'); 178 }, function(){ 179 return _this.get_svc_info(); 180 }, function(info){ 181 if (info || timeout && spent==timeout) 182 return this.break(info); 183 }]); 184 }, 185 /** 186 * Waits for latest svc. 187 * 188 * @returns {etask} Etask with svc info. 189 */ 190 wait_for_new_svc: function(){ 191 var _this = this; 192 return etask.for(null, function(){ return etask.sleep(1000); }, 193 [function try_catch$(){ 194 // _check_svc() will not work if we are currently using 'https', so 195 // call both, _check_ext() can provide svc info too. 196 return etask.all({ext: _this._check_ext(), svc: _this 197 ._check_svc()}); 198 }, function(){ 199 return _this.is_latest_svc(); 200 }, function(is_latest){ 201 if (is_latest) 202 return this.break(_this.get('svc_info')); 203 }]); 204 }, 205 /** 206 * Waits for latest extension. 207 * 208 * @param {boolean} [lean=false] Whether we should check using image 209 * {@link svc/hola/pub/svc_ipc.js:ext.lean_ping()}. 210 * @returns {etask} Etask with extension info. 211 */ 212 wait_for_new_ext: function(lean){ 213 var _this = this; 214 var previous_init_ts = (_this.get('ext_info')||{}).init_ts; 215 return etask.for(null, function(){ return etask.sleep(1000); }, 216 [function try_catch$(){ 217 if (lean) 218 return lean_check_ext(); 219 return _this._check_ext(); 220 }, function(e){ 221 if (lean) 222 { 223 if (!this.error) 224 return this.break(); 225 return; 226 } 227 var new_info = !this.error && e; 228 if (!new_info) 229 return; 230 // in chrome, chrome.webstore.install will succeed if extension is 231 // already the the latest version, but the extension will not be 232 // reinstalled (so init_ts will not change). 233 if (b.browser=='chrome' && new_info.init_ts) 234 return this.break(); 235 if (previous_init_ts==new_info.init_ts) 236 return; 237 return this.break(new_info); 238 }]); 239 }, 240 _set_ext_info: function(info){ 241 if (!info) 242 return; 243 this.set('ext_info', info); 244 if (info.svc_info && !info.svc_info.plugin) 245 this.set('svc_info', info.svc_info.raw); 246 }, 247 _check_ext: function(){ 248 var _this = this; 249 if (ext_etask) 250 return ext_etask; 251 this._set_ext_info(config.get_hola_extension_info()); 252 ext_etask = etask([function try_catch$(){ 253 return check_ext(); 254 }, function(e){ 255 ext_etask = null; 256 if (this.error || !e || !e.data) 257 return; 258 _this._set_ext_info(e.data); 259 return e.data; 260 }]); 261 return ext_etask; 262 }, 263 _check_svc: function(){ 264 var _this = this; 265 if (svc_etask) 266 return svc_etask; 267 if (window && window.no_svc_check) 268 { 269 _this.set('svc_info', undefined); 270 return; 271 } 272 if (window && window.location) 273 { 274 var qs = zurl.qs_parse(window.location.search.substr(1), 275 {safe: true}); 276 if (qs.debug_svc=='off') 277 { 278 _this.set('svc_info', undefined); 279 return; 280 } 281 else if (qs.debug_svc) 282 { 283 var svc_i_json; 284 try { 285 svc_i_json = JSON.parse(qs.debug_svc); 286 } catch(e){ 287 svc_i_json = {appid: qs.debug_svc}; 288 } 289 console.log('detect debug svc info'); 290 setTimeout(function(){ 291 console.log('set debug svc info'); 292 _this.set('svc_info', svc_i_json); 293 if (svc_i_json && svc_i_json.uuid) 294 _this.perr({id: 'www_detect_svc', info: svc_i_json}); 295 }, 1000); 296 return; 297 } 298 } 299 svc_etask = etask([function try_catch$(){ 300 return check_svc(); 301 }, function(e){ 302 svc_etask = null; 303 if (this.error || !e || !e.data) 304 return; 305 var info = e.data; 306 var v_os = g.os=='macos' ? versions.mac_svc : 307 svc_vpn_util.pick_version(versions, 308 svc_vpn_util.get_product(info.appid), 'windows'); 309 info.is_latest_svc = version_util.cmp(info.ver, v_os)>=0; 310 if (is_plugin(info.exe)) 311 return; 312 _this.set('svc_info', info); 313 if (info && info.uuid) 314 { 315 _this.perr({id: 'www_detect_svc', info: info}); 316 try { 317 _this.on_svc_detected.forEach(function(fn){ 318 fn({info: info}); 319 }); 320 } catch(e){} 321 } 322 }]); 323 return svc_etask; 324 }, 325 _check_registry: function(){ 326 var _this = this; 327 if (g.os!='windows') 328 return; 329 if (reg_etask) 330 return reg_etask; 331 return reg_etask = etask([function try_catch$(){ 332 return get_registry('agree_ts'); 333 }, function(e){ 334 reg_etask = null; 335 if (this.error || !e) 336 return; 337 _this.set('agree_ts', e); 338 }]); 339 }, 340 perr: function(){ 341 console.warn('not implemented'); 342 }, 343 set_perr_fn: function(fn){ 344 this.perr = fn; 345 } 346}); 347 348// Singleton. 349return info_model; 350});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.