Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2012 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 
      5 // Custom binding for the app API.
      6 
      7 var GetAvailability = requireNative('v8_context').GetAvailability;
      8 if (!GetAvailability('app').is_available) {
      9   exports.chromeApp = {};
     10   exports.onInstallStateResponse = function(){};
     11   return;
     12 }
     13 
     14 var appNatives = requireNative('app');
     15 var process = requireNative('process');
     16 var extensionId = process.GetExtensionId();
     17 var logActivity = requireNative('activityLogger');
     18 
     19 function wrapForLogging(fun) {
     20   if (!extensionId)
     21     return fun;  // nothing interesting to log without an extension
     22 
     23   return function() {
     24     // TODO(ataly): We need to make sure we use the right prototype for
     25     // fun.apply. Array slice can either be rewritten or similarly defined.
     26     logActivity.LogAPICall(extensionId, "app." + fun.name,
     27         $Array.slice(arguments));
     28     return $Function.apply(fun, this, arguments);
     29   };
     30 }
     31 
     32 // This becomes chrome.app
     33 var app = {
     34   getIsInstalled: wrapForLogging(appNatives.GetIsInstalled),
     35   getDetails: wrapForLogging(appNatives.GetDetails),
     36   getDetailsForFrame: wrapForLogging(appNatives.GetDetailsForFrame),
     37   runningState: wrapForLogging(appNatives.GetRunningState)
     38 };
     39 
     40 // Tricky; "getIsInstalled" is actually exposed as the getter "isInstalled",
     41 // but we don't have a way to express this in the schema JSON (nor is it
     42 // worth it for this one special case).
     43 //
     44 // So, define it manually, and let the getIsInstalled function act as its
     45 // documentation.
     46 app.__defineGetter__('isInstalled', wrapForLogging(appNatives.GetIsInstalled));
     47 
     48 // Called by app_bindings.cc.
     49 function onInstallStateResponse(state, callbackId) {
     50   var callback = callbacks[callbackId];
     51   delete callbacks[callbackId];
     52   if (typeof(callback) == 'function') {
     53     try {
     54       callback(state);
     55     } catch (e) {
     56       console.error('Exception in chrome.app.installState response handler: ' +
     57                     e.stack);
     58     }
     59   }
     60 }
     61 
     62 // TODO(kalman): move this stuff to its own custom bindings.
     63 var callbacks = {};
     64 var nextCallbackId = 1;
     65 
     66 app.installState = function getInstallState(callback) {
     67   var callbackId = nextCallbackId++;
     68   callbacks[callbackId] = callback;
     69   appNatives.GetInstallState(callbackId);
     70 };
     71 if (extensionId)
     72   app.installState = wrapForLogging(app.installState);
     73 
     74 // This must match InstallAppBindings() in
     75 // chrome/renderer/extensions/dispatcher.cc.
     76 exports.chromeApp = app;
     77 exports.onInstallStateResponse = onInstallStateResponse;
     78