// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. cr.define('gpu', function() { /** * This class provides a 'bridge' for communicating between javascript and the * browser. When run outside of WebUI, e.g. as a regular webpage, it provides * synthetic data to assist in testing. * @constructor */ function BrowserBridge() { // If we are not running inside WebUI, output chrome.send messages // to the console to help with quick-iteration debugging. this.debugMode_ = (chrome.send === undefined && console.log); if (this.debugMode_) { var browserBridgeTests = document.createElement('script'); browserBridgeTests.src = './gpu_internals/browser_bridge_tests.js'; document.body.appendChild(browserBridgeTests); } this.nextRequestId_ = 0; this.pendingCallbacks_ = []; this.logMessages_ = []; // Tell c++ code that we are ready to receive GPU Info. if (!this.debugMode_) { chrome.send('browserBridgeInitialized'); this.beginRequestClientInfo_(); this.beginRequestLogMessages_(); } } BrowserBridge.prototype = { __proto__: cr.EventTarget.prototype, applySimulatedData_: function applySimulatedData(data) { // set up things according to the simulated data this.gpuInfo_ = data.gpuInfo; this.clientInfo_ = data.clientInfo; this.logMessages_ = data.logMessages; cr.dispatchSimpleEvent(this, 'gpuInfoUpdate'); cr.dispatchSimpleEvent(this, 'clientInfoChange'); cr.dispatchSimpleEvent(this, 'logMessagesChange'); }, /** * Returns true if the page is hosted inside Chrome WebUI * Helps have behavior conditional to emulate_webui.py */ get debugMode() { return this.debugMode_; }, /** * Sends a message to the browser with specified args. The * browser will reply asynchronously via the provided callback. */ callAsync: function(submessage, args, callback) { var requestId = this.nextRequestId_; this.nextRequestId_ += 1; this.pendingCallbacks_[requestId] = callback; if (!args) { chrome.send('callAsync', [requestId.toString(), submessage]); } else { var allArgs = [requestId.toString(), submessage].concat(args); chrome.send('callAsync', allArgs); } }, /** * Called by gpu c++ code when client info is ready. */ onCallAsyncReply: function(requestId, args) { if (this.pendingCallbacks_[requestId] === undefined) { throw new Error('requestId ' + requestId + ' is not pending'); } var callback = this.pendingCallbacks_[requestId]; callback(args); delete this.pendingCallbacks_[requestId]; }, /** * Get gpuInfo data. */ get gpuInfo() { return this.gpuInfo_; }, /** * Called from gpu c++ code when GPU Info is updated. */ onGpuInfoUpdate: function(gpuInfo) { this.gpuInfo_ = gpuInfo; cr.dispatchSimpleEvent(this, 'gpuInfoUpdate'); }, /** * This function begins a request for the ClientInfo. If it comes back * as undefined, then we will issue the request again in 250ms. */ beginRequestClientInfo_: function() { this.callAsync('requestClientInfo', undefined, (function(data) { if (data === undefined) { // try again in 250 ms window.setTimeout(this.beginRequestClientInfo_.bind(this), 250); } else { this.clientInfo_ = data; cr.dispatchSimpleEvent(this, 'clientInfoChange'); } }).bind(this)); }, /** * Returns information about the currently running Chrome build. */ get clientInfo() { return this.clientInfo_; }, /** * This function checks for new GPU_LOG messages. * If any are found, a refresh is triggered. */ beginRequestLogMessages_: function() { this.callAsync('requestLogMessages', undefined, (function(messages) { if (messages.length != this.logMessages_.length) { this.logMessages_ = messages; cr.dispatchSimpleEvent(this, 'logMessagesChange'); } // check again in 250 ms window.setTimeout(this.beginRequestLogMessages_.bind(this), 250); }).bind(this)); }, /** * Returns an array of log messages issued by the GPU process, if any. */ get logMessages() { return this.logMessages_; }, }; return { BrowserBridge: BrowserBridge }; });