12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 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 bindings for the notifications API. 646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var binding = require('binding').Binding.create('notifications'); 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var sendRequest = require('sendRequest').sendRequest; 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var imageUtil = require('imageUtil'); 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var lastError = require('lastError'); 1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)var notificationsPrivate = requireNative('notifications_private'); 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)function imageDataSetter(context, key) { 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var f = function(val) { 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this[key] = val; 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return $Function.bind(f, context); 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// A URL Spec is an object with the following keys: 2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// path: The resource to be downloaded. 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// width: (optional) The maximum width of the image to be downloaded in device 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// pixels. 2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// height: (optional) The maximum height of the image to be downloaded in 2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// device pixels. 2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// callback: A function to be called when the URL is complete. It 2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// should accept an ImageData object and set the appropriate 2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// field in |notificationDetails|. 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)function getUrlSpecs(imageSizes, notificationDetails) { 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) var urlSpecs = []; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 33558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // |iconUrl| might be optional for notification updates. 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (notificationDetails.iconUrl) { 3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) $Array.push(urlSpecs, { 3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) path: notificationDetails.iconUrl, 3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) width: imageSizes.icon.width * imageSizes.scaleFactor, 3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) height: imageSizes.icon.height * imageSizes.scaleFactor, 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback: imageDataSetter(notificationDetails, 'iconBitmap') 40558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch }); 41558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // |appIconMaskUrl| is optional. 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (notificationDetails.appIconMaskUrl) { 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) $Array.push(urlSpecs, { 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) path: notificationDetails.appIconMaskUrl, 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) width: imageSizes.appIconMask.width * imageSizes.scaleFactor, 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) height: imageSizes.appIconMask.height * imageSizes.scaleFactor, 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback: imageDataSetter(notificationDetails, 'appIconMaskBitmap') 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }); 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |imageUrl| is optional. 5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (notificationDetails.imageUrl) { 5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) $Array.push(urlSpecs, { 5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) path: notificationDetails.imageUrl, 5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) width: imageSizes.image.width * imageSizes.scaleFactor, 5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) height: imageSizes.image.height * imageSizes.scaleFactor, 5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback: imageDataSetter(notificationDetails, 'imageBitmap') 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Each button has an optional icon. 6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) var buttonList = notificationDetails.buttons; 6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (buttonList && typeof buttonList.length === 'number') { 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) var numButtons = buttonList.length; 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (var i = 0; i < numButtons; i++) { 6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (buttonList[i].iconUrl) { 6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) $Array.push(urlSpecs, { 7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) path: buttonList[i].iconUrl, 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) width: imageSizes.buttonIcon.width * imageSizes.scaleFactor, 7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) height: imageSizes.buttonIcon.height * imageSizes.scaleFactor, 7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback: imageDataSetter(buttonList[i], 'iconBitmap') 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return urlSpecs; 8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)function replaceNotificationOptionURLs(notification_details, callback) { 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) var imageSizes = notificationsPrivate.GetNotificationImageSizes(); 8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) var url_specs = getUrlSpecs(imageSizes, notification_details); 85558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!url_specs.length) { 86558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch callback(true); 87558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return; 88558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 89558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var errors = 0; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) imageUtil.loadAllImages(url_specs, { 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) onerror: function(index) { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errors++; 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) oncomplete: function(imageData) { 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (errors > 0) { 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback(false); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (var index = 0; index < url_specs.length; index++) { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var url_spec = url_specs[index]; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url_spec.callback(imageData[index]); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback(true); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)function genHandle(name, failure_function) { 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return function(id, input_notification_details, callback) { 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(dewittj): Remove this hack. This is used as a way to deep 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // copy a complex JSON object. 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var notification_details = JSON.parse( 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JSON.stringify(input_notification_details)); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var that = this; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replaceNotificationOptionURLs(notification_details, function(success) { 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (success) { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sendRequest(that.name, 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) [id, notification_details, callback], 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) that.definition.parameters); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) lastError.run(name, 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'Unable to download all specified images.', 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) null, 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) failure_function, [callback, id]) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)var handleCreate = genHandle('notifications.create', 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) function(callback, id) { callback(id); }); 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)var handleUpdate = genHandle('notifications.update', 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) function(callback, id) { callback(false); }); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var notificationsCustomHook = function(bindingsAPI, extensionId) { 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var apiFunctions = bindingsAPI.apiFunctions; 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiFunctions.setHandleRequest('create', handleCreate); 1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) apiFunctions.setHandleRequest('update', handleUpdate); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)binding.registerCustomHook(notificationsCustomHook); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)exports.binding = binding.generate(); 146