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 Permissions API. 6 7 var binding = require('binding').Binding.create('permissions'); 8 9 var Event = require('event_bindings').Event; 10 var sendRequest = require('sendRequest').sendRequest; 11 12 // These custom binding are only necessary because it is not currently 13 // possible to have a union of types as the type of the items in an array. 14 // Once that is fixed, this entire file should go away. 15 // See, 16 // https://code.google.com/p/chromium/issues/detail?id=162044 17 // https://code.google.com/p/chromium/issues/detail?id=162042 18 // TODO(bryeung): delete this file. 19 binding.registerCustomHook(function(api) { 20 var apiFunctions = api.apiFunctions; 21 var permissions = api.compiledApi; 22 23 function maybeConvertToObject(str) { 24 var parts = $String.split(str, '|'); 25 if (parts.length != 2) 26 return str; 27 28 var ret = {}; 29 ret[parts[0]] = JSON.parse(parts[1]); 30 return ret; 31 } 32 33 function convertObjectPermissionsToStrings() { 34 if (arguments.length < 1) 35 return arguments; 36 37 var args = arguments[0].permissions; 38 if (!args) 39 return arguments; 40 41 for (var i = 0; i < args.length; i += 1) { 42 if (typeof(args[i]) == 'object') { 43 var a = args[i]; 44 var keys = $Object.keys(a); 45 if (keys.length != 1) { 46 throw new Error("Too many keys in object-style permission."); 47 } 48 arguments[0].permissions[i] = keys[0] + '|' + 49 JSON.stringify(a[keys[0]]); 50 } 51 } 52 53 return arguments; 54 } 55 56 // Convert complex permissions to strings so they validate against the schema 57 apiFunctions.setUpdateArgumentsPreValidate( 58 'contains', convertObjectPermissionsToStrings); 59 apiFunctions.setUpdateArgumentsPreValidate( 60 'remove', convertObjectPermissionsToStrings); 61 apiFunctions.setUpdateArgumentsPreValidate( 62 'request', convertObjectPermissionsToStrings); 63 64 // Convert complex permissions back to objects 65 apiFunctions.setCustomCallback('getAll', 66 function(name, request, response) { 67 for (var i = 0; i < response.permissions.length; i += 1) { 68 response.permissions[i] = 69 maybeConvertToObject(response.permissions[i]); 70 } 71 72 // Since the schema says Permissions.permissions contains strings and 73 // not objects, validation will fail after the for-loop above. This 74 // skips validation and calls the callback directly, then clears it so 75 // that handleResponse doesn't call it again. 76 try { 77 if (request.callback) 78 $Function.apply(request.callback, request, [response]); 79 } finally { 80 delete request.callback; 81 } 82 }); 83 84 // Also convert complex permissions back to objects for events. The 85 // dispatchToListener call happens after argument validation, which works 86 // around the problem that Permissions.permissions is supposed to be a list 87 // of strings. 88 permissions.onAdded.dispatchToListener = function(callback, args) { 89 for (var i = 0; i < args[0].permissions.length; i += 1) { 90 args[0].permissions[i] = maybeConvertToObject(args[0].permissions[i]); 91 } 92 Event.prototype.dispatchToListener(callback, args); 93 }; 94 permissions.onRemoved.dispatchToListener = 95 permissions.onAdded.dispatchToListener; 96 }); 97 98 exports.binding = binding.generate(); 99