1 // Copyright (c) 2011 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 cr.define('gpu', function() { 5 /** 6 * This class provides a 'bridge' for communicating between javascript and the 7 * browser. When run outside of WebUI, e.g. as a regular webpage, it provides 8 * synthetic data to assist in testing. 9 * @constructor 10 */ 11 function BrowserBridge() { 12 // If we are not running inside WebUI, output chrome.send messages 13 // to the console to help with quick-iteration debugging. 14 if (chrome.send === undefined && console.log) { 15 this.debugMode_ = true; 16 var browserBridgeTests = document.createElement('script'); 17 browserBridgeTests.src = './gpu_internals/browser_bridge_tests.js'; 18 document.body.appendChild(browserBridgeTests); 19 } else { 20 this.debugMode_ = false; 21 } 22 23 this.nextRequestId_ = 0; 24 this.pendingCallbacks_ = []; 25 this.logMessages_ = []; 26 27 // Tell c++ code that we are ready to receive GPU Info. 28 if (!this.debugMode_) { 29 chrome.send('browserBridgeInitialized'); 30 this.beginRequestClientInfo_(); 31 this.beginRequestLogMessages_(); 32 } 33 } 34 35 BrowserBridge.prototype = { 36 __proto__: cr.EventTarget.prototype, 37 38 applySimulatedData_: function applySimulatedData(data) { 39 // set up things according to the simulated data 40 this.gpuInfo_ = data.gpuInfo; 41 this.clientInfo_ = data.clientInfo; 42 this.logMessages_ = data.logMessages; 43 cr.dispatchSimpleEvent(this, 'gpuInfoUpdate'); 44 cr.dispatchSimpleEvent(this, 'clientInfoChange'); 45 cr.dispatchSimpleEvent(this, 'logMessagesChange'); 46 }, 47 48 /** 49 * Returns true if the page is hosted inside Chrome WebUI 50 * Helps have behavior conditional to emulate_webui.py 51 */ 52 get debugMode() { 53 return this.debugMode_; 54 }, 55 56 /** 57 * Sends a message to the browser with specified args. The 58 * browser will reply asynchronously via the provided callback. 59 */ 60 callAsync: function(submessage, args, callback) { 61 var requestId = this.nextRequestId_; 62 this.nextRequestId_ += 1; 63 this.pendingCallbacks_[requestId] = callback; 64 if (!args) { 65 chrome.send('callAsync', [requestId.toString(), submessage]); 66 } else { 67 var allArgs = [requestId.toString(), submessage].concat(args); 68 chrome.send('callAsync', allArgs); 69 } 70 }, 71 72 /** 73 * Called by gpu c++ code when client info is ready. 74 */ 75 onCallAsyncReply: function(requestId, args) { 76 if (this.pendingCallbacks_[requestId] === undefined) { 77 throw new Error('requestId ' + requestId + ' is not pending'); 78 } 79 var callback = this.pendingCallbacks_[requestId]; 80 callback(args); 81 delete this.pendingCallbacks_[requestId]; 82 }, 83 84 /** 85 * Get gpuInfo data. 86 */ 87 get gpuInfo() { 88 return this.gpuInfo_; 89 }, 90 91 /** 92 * Called from gpu c++ code when GPU Info is updated. 93 */ 94 onGpuInfoUpdate: function(gpuInfo) { 95 this.gpuInfo_ = gpuInfo; 96 cr.dispatchSimpleEvent(this, 'gpuInfoUpdate'); 97 }, 98 99 /** 100 * This function begins a request for the ClientInfo. If it comes back 101 * as undefined, then we will issue the request again in 250ms. 102 */ 103 beginRequestClientInfo_: function() { 104 this.callAsync('requestClientInfo', undefined, (function(data) { 105 if (data === undefined) { // try again in 250 ms 106 window.setTimeout(this.beginRequestClientInfo_.bind(this), 250); 107 } else { 108 this.clientInfo_ = data; 109 cr.dispatchSimpleEvent(this, 'clientInfoChange'); 110 } 111 }).bind(this)); 112 }, 113 114 /** 115 * Returns information about the currently runnign Chrome build. 116 */ 117 get clientInfo() { 118 return this.clientInfo_; 119 }, 120 121 /** 122 * This function checks for new GPU_LOG messages. 123 * If any are found, a refresh is triggered. 124 */ 125 beginRequestLogMessages_: function() { 126 this.callAsync('requestLogMessages', undefined, 127 (function(messages) { 128 if (messages.length != this.logMessages_.length) { 129 this.logMessages_ = messages; 130 cr.dispatchSimpleEvent(this, 'logMessagesChange'); 131 } 132 // check again in 250 ms 133 window.setTimeout(this.beginRequestLogMessages_.bind(this), 250); 134 }).bind(this)); 135 }, 136 137 /** 138 * Returns an array of log messages issued by the GPU process, if any. 139 */ 140 get logMessages() { 141 return this.logMessages_; 142 } 143 144 }; 145 146 return { 147 BrowserBridge: BrowserBridge 148 }; 149 }); 150