146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 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) 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// These custom binding are only necessary because it is not currently 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// possible to have a union of types as the type of the items in an array. 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Once that is fixed, this entire file should go away. 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// See, 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// https://code.google.com/p/chromium/issues/detail?id=162044 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// https://code.google.com/p/chromium/issues/detail?id=162042 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(bryeung): delete this file. 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)binding.registerCustomHook(function(api) { 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var apiFunctions = api.apiFunctions; 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var permissions = api.compiledApi; 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function maybeConvertToObject(str) { 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch var parts = $String.split(str, '|'); 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (parts.length != 2) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return str; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var ret = {}; 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ret[parts[0]] = JSON.parse(parts[1]); 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ret; 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function convertObjectPermissionsToStrings() { 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (arguments.length < 1) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return arguments; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var args = arguments[0].permissions; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!args) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return arguments; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (var i = 0; i < args.length; i += 1) { 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (typeof(args[i]) == 'object') { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var a = args[i]; 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch var keys = $Object.keys(a); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (keys.length != 1) { 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throw new Error("Too many keys in object-style permission."); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) arguments[0].permissions[i] = keys[0] + '|' + 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JSON.stringify(a[keys[0]]); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return arguments; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Convert complex permissions to strings so they validate against the schema 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiFunctions.setUpdateArgumentsPreValidate( 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'contains', convertObjectPermissionsToStrings); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiFunctions.setUpdateArgumentsPreValidate( 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'remove', convertObjectPermissionsToStrings); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiFunctions.setUpdateArgumentsPreValidate( 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'request', convertObjectPermissionsToStrings); 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Convert complex permissions back to objects 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiFunctions.setCustomCallback('getAll', 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function(name, request, response) { 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (var i = 0; i < response.permissions.length; i += 1) { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) response.permissions[i] = 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) maybeConvertToObject(response.permissions[i]); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Since the schema says Permissions.permissions contains strings and 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // not objects, validation will fail after the for-loop above. This 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // skips validation and calls the callback directly, then clears it so 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that handleResponse doesn't call it again. 757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) try { 767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (request.callback) 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch $Function.apply(request.callback, request, [response]); 787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } finally { 797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) delete request.callback; 807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Also convert complex permissions back to objects for events. The 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dispatchToListener call happens after argument validation, which works 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // around the problem that Permissions.permissions is supposed to be a list 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of strings. 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) permissions.onAdded.dispatchToListener = function(callback, args) { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (var i = 0; i < args[0].permissions.length; i += 1) { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args[0].permissions[i] = maybeConvertToObject(args[0].permissions[i]); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) $Function.call(Event.prototype.dispatchToListener, this, callback, args); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) permissions.onRemoved.dispatchToListener = 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) permissions.onAdded.dispatchToListener; 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)exports.binding = binding.generate(); 98