12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Custom binding for the Permissions API. 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var binding = require('binding').Binding.create('permissions'); 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)var Event = require('event_bindings').Event; 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var sendRequest = require('sendRequest').sendRequest; 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// These custom binding are only necessary because it is not currently 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// possible to have a union of types as the type of the items in an array. 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Once that is fixed, this entire file should go away. 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// See, 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// https://code.google.com/p/chromium/issues/detail?id=162044 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// https://code.google.com/p/chromium/issues/detail?id=162042 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(bryeung): delete this file. 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)binding.registerCustomHook(function(api) { 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var apiFunctions = api.apiFunctions; 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var permissions = api.compiledApi; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function maybeConvertToObject(str) { 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch var parts = $String.split(str, '|'); 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (parts.length != 2) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return str; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var ret = {}; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ret[parts[0]] = JSON.parse(parts[1]); 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ret; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function convertObjectPermissionsToStrings() { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (arguments.length < 1) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return arguments; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var args = arguments[0].permissions; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!args) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return arguments; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (var i = 0; i < args.length; i += 1) { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (typeof(args[i]) == 'object') { 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var a = args[i]; 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch var keys = $Object.keys(a); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (keys.length != 1) { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throw new Error("Too many keys in object-style permission."); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) arguments[0].permissions[i] = keys[0] + '|' + 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JSON.stringify(a[keys[0]]); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return arguments; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Convert complex permissions to strings so they validate against the schema 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiFunctions.setUpdateArgumentsPreValidate( 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'contains', convertObjectPermissionsToStrings); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiFunctions.setUpdateArgumentsPreValidate( 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'remove', convertObjectPermissionsToStrings); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiFunctions.setUpdateArgumentsPreValidate( 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'request', convertObjectPermissionsToStrings); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Convert complex permissions back to objects 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiFunctions.setCustomCallback('getAll', 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function(name, request, response) { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (var i = 0; i < response.permissions.length; i += 1) { 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) response.permissions[i] = 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) maybeConvertToObject(response.permissions[i]); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Since the schema says Permissions.permissions contains strings and 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // not objects, validation will fail after the for-loop above. This 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // skips validation and calls the callback directly, then clears it so 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that handleResponse doesn't call it again. 767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) try { 777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (request.callback) 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch $Function.apply(request.callback, request, [response]); 797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } finally { 807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) delete request.callback; 817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Also convert complex permissions back to objects for events. The 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dispatchToListener call happens after argument validation, which works 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // around the problem that Permissions.permissions is supposed to be a list 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of strings. 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) permissions.onAdded.dispatchToListener = function(callback, args) { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (var i = 0; i < args[0].permissions.length; i += 1) { 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args[0].permissions[i] = maybeConvertToObject(args[0].permissions[i]); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Event.prototype.dispatchToListener(callback, args); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) permissions.onRemoved.dispatchToListener = 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) permissions.onAdded.dispatchToListener; 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)exports.binding = binding.generate(); 99