diff options
18 files changed, 269 insertions, 0 deletions
diff --git a/chrome/browser/extensions/api/gcm/OWNERS b/chrome/browser/extensions/api/gcm/OWNERS new file mode 100644 index 0000000..46bb266 --- /dev/null +++ b/chrome/browser/extensions/api/gcm/OWNERS @@ -0,0 +1,2 @@ +fgorski@chromium.org +jianli@chromium.org diff --git a/chrome/browser/extensions/api/gcm/gcm_api.cc b/chrome/browser/extensions/api/gcm/gcm_api.cc new file mode 100644 index 0000000..332c8d4 --- /dev/null +++ b/chrome/browser/extensions/api/gcm/gcm_api.cc @@ -0,0 +1,17 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/api/gcm/gcm_api.h" + +namespace extensions { + +bool GcmRegisterFunction::RunImpl() { + return true; +} + +bool GcmSendFunction::RunImpl() { + return true; +} + +} // namespace extensions diff --git a/chrome/browser/extensions/api/gcm/gcm_api.h b/chrome/browser/extensions/api/gcm/gcm_api.h new file mode 100644 index 0000000..8b4872b --- /dev/null +++ b/chrome/browser/extensions/api/gcm/gcm_api.h @@ -0,0 +1,40 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_API_GCM_GCM_API_H_ +#define CHROME_BROWSER_EXTENSIONS_API_GCM_GCM_API_H_ + +#include "extensions/browser/extension_function.h" + +namespace extensions { + +class GcmRegisterFunction : public AsyncExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("gcm.register", GCM_REGISTER); + + GcmRegisterFunction() {} + + protected: + virtual ~GcmRegisterFunction() {} + + // ExtensionFunction: + virtual bool RunImpl() OVERRIDE FINAL; +}; + +class GcmSendFunction : public AsyncExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("gcm.send", GCM_SEND); + + GcmSendFunction() {} + + protected: + virtual ~GcmSendFunction() {} + + // Send function implementation. + virtual bool RunImpl() OVERRIDE FINAL; +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_GCM_GCM_API_H_ diff --git a/chrome/browser/extensions/extension_function_histogram_value.h b/chrome/browser/extensions/extension_function_histogram_value.h index 23af274..489e47e 100644 --- a/chrome/browser/extensions/extension_function_histogram_value.h +++ b/chrome/browser/extensions/extension_function_histogram_value.h @@ -699,6 +699,8 @@ enum HistogramValue { SERIAL_GETINFO, SERIAL_GETCONNECTIONS, SERIAL_SEND, + GCM_REGISTER, + GCM_SEND, ENUM_BOUNDARY // Last entry: Add new entries above. }; diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index 770bc3a..0077c4a 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi @@ -274,6 +274,8 @@ 'browser/extensions/api/file_system/file_system_api.h', 'browser/extensions/api/font_settings/font_settings_api.cc', 'browser/extensions/api/font_settings/font_settings_api.h', + 'browser/extensions/api/gcm/gcm_api.cc', + 'browser/extensions/api/gcm/gcm_api.h', 'browser/extensions/api/history/history_api.h', 'browser/extensions/api/history/history_api.cc', 'browser/extensions/api/i18n/i18n_api.cc', diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index ae6c3c1..733d403 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -208,6 +208,7 @@ 'renderer/resources/extensions/file_browser_private_custom_bindings.js', 'renderer/resources/extensions/file_system_custom_bindings.js', 'renderer/resources/extensions/file_system_provider_custom_bindings.js', + 'renderer/resources/extensions/gcm_custom_bindings.js', 'renderer/resources/extensions/greasemonkey_api.js', 'renderer/resources/extensions/identity_custom_bindings.js', 'renderer/resources/extensions/input.ime_custom_bindings.js', diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index 07cc3a6..cab962e 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json @@ -317,6 +317,10 @@ "dependencies": ["permission:fontSettings"], "contexts": ["blessed_extension"] }, + "gcm": { + "dependencies": ["permission:gcm"], + "contexts": ["blessed_extension"] + }, "hangoutsPrivate": { "channel": "stable", "contexts": ["blessed_extension"], diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index bb81299..8e14b9b 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json @@ -372,6 +372,10 @@ "channel": "stable", "extension_types": ["platform_app"] }, + "gcm": { + "channel": "dev", + "extension_types": ["extension", "platform_app"] + }, "geolocation": { "channel": "stable", "extension_types": [ diff --git a/chrome/common/extensions/api/api.gyp b/chrome/common/extensions/api/api.gyp index 6b85815..225c553 100644 --- a/chrome/common/extensions/api/api.gyp +++ b/chrome/common/extensions/api/api.gyp @@ -72,6 +72,7 @@ 'file_system.idl', 'file_system_provider.idl', 'font_settings.json', + 'gcm.json', 'hangouts_private.idl', 'history.json', 'i18n.json', diff --git a/chrome/common/extensions/api/gcm.json b/chrome/common/extensions/api/gcm.json new file mode 100644 index 0000000..51f212a --- /dev/null +++ b/chrome/common/extensions/api/gcm.json @@ -0,0 +1,157 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + { + "namespace": "gcm", + "description": "Use <code>chrome.gcm</code> to enable apps and extensions to send and receive messages through <a href='http://developer.android.com/google/gcm/index.html'>Google Cloud Messaging for Android</a>.", + "properties": { + "MAX_MESSAGE_SIZE": { + "value": 4096, + "description": "The maximum size (in bytes) of all key/value pairs in a message." + } + }, + "functions": [ + { + "name": "register", + "type": "function", + "description": "Registers the application with GCM. The registration ID will be returned by the <code>callback</code>. If <code>register</code> is called again with the same list of <code>senderIds</code>, the same registration ID will be returned.", + "parameters": [ + { + "name": "senderIds", + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "maxItems": 100, + "description": "A list of server IDs that are allowed to send messages to the application. It should contain at least one and no more than 100 sender IDs." + }, + { + "name": "callback", + "type": "function", + "description": "Function called when registration completes. It should check $ref:runtime.lastError for error when <code>registrationId</code> is empty.", + "parameters": [ + { + "name": "registrationId", + "type": "string", + "description": "A registration ID assigned to the application by the GCM." + } + ] + } + ] + }, + { + "name": "send", + "type": "function", + "description": "Sends a message according to its contents.", + "parameters": [ + { + "name": "message", + "type": "object", + "description": "A message to send to the other party via GCM.", + "properties": { + "destinationId": { + "type": "string", + "description": "The ID of the server to send the message to as assigned by <a href='https://code.google.com/apis/console'>Google API Console</a>." + }, + "messageId": { + "type": "string", + "description": "The ID of the message. It must be unique for each message." + }, + "timeToLive": { + "type": "number", + "minimum": 0, + "maximum": 2419200, + "optional": true, + "description": "Time-to-live of the message in seconds. If it is not possible to send the message wihtin that time an error will be raised. A time-to-live of 0 indicates that the message should be sent immediately or fail if it's not possible. The maximum and a default value of time-to-live is 2419200 seconds (4 weeks)." + }, + "data": { + "type": "object", + "properties": {}, + "additionalProperties": { + "type": "string" + }, + "description": "Message data to send to the server. <code>goog.</code> and <code>google</code> are disallowed as key prefixes. Sum of all key/value pairs should not exceed $ref:MAX_MESSAGE_SIZE." + } + } + }, + { + "name": "callback", + "type": "function", + "description": "A function called after the message is successfully queued for sending. $ref:runtime.lastError should be checked, to ensure a message was sent without problems.", + "parameters": [ + { + "name": "messageId", + "type": "string", + "description": "The ID of the message that the callback was issued for." + } + ] + } + ] + } + ], + "events": [ + { + "name": "onMessage", + "type": "function", + "description": "Fired when a message is received through GCM.", + "parameters": [ + { + "name": "message", + "type": "object", + "description": "A message received from another party via GCM.", + "properties": { + "data": { + "type": "object", + "properties": {}, + "additionalProperties": { + "type": "string" + }, + "description": "The message data." + } + } + } + ] + }, + { + "name": "onMessagesDeleted", + "type": "function", + "description": "Fired when a GCM server had to delete messages to the application from its queue in order to manage its size. The app is expected to handle that case gracefully, e.g. by running a full sync with its server." + }, + { + "name": "onSendError", + "type": "function", + "description": "Fired when it was not possible to send a message to the GCM server.", + "parameters": [ + { + "name": "error", + "type": "object", + "description": "An error related to sending a message raised by GCM.", + "properties": { + "errorMessage": { + "type": "string", + "description": "The error message describing the problem." + }, + "messageId": { + "type": "string", + "optional": true, + "description": "The ID of the message with this error, if error is related to a specific message." + }, + "details": { + "type": "object", + "properties": {}, + "additionalProperties": { + "type": "string" + }, + "description": "Additional details related to the error, when available." + } + }, + "description": "An error that occured while trying to send the message either in Chrome or on the GCM server. Application can retry sending the message with a reasonable backoff and possibly longer time-to-live." + } + ] + } + ] + } +]
\ No newline at end of file diff --git a/chrome/common/extensions/docs/templates/public/apps/gcm.html b/chrome/common/extensions/docs/templates/public/apps/gcm.html new file mode 100644 index 0000000..15637c5 --- /dev/null +++ b/chrome/common/extensions/docs/templates/public/apps/gcm.html @@ -0,0 +1 @@ +{{+partials.standard_apps_api api:apis.gcm/}} diff --git a/chrome/common/extensions/docs/templates/public/extensions/gcm.html b/chrome/common/extensions/docs/templates/public/extensions/gcm.html new file mode 100644 index 0000000..500a6a4 --- /dev/null +++ b/chrome/common/extensions/docs/templates/public/extensions/gcm.html @@ -0,0 +1 @@ +{{+partials.standard_extensions_api api:apis.gcm/}} diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc index 3ccb48f..10dbaef1 100644 --- a/chrome/common/extensions/permissions/chrome_api_permissions.cc +++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc @@ -81,6 +81,7 @@ std::vector<APIPermissionInfo*> ChromeAPIPermissions::GetAllPermissions() { APIPermission::kNotification, "notifications" }, { APIPermission::kUnlimitedStorage, "unlimitedStorage", APIPermissionInfo::kFlagCannotBeOptional }, + { APIPermission::kGcm, "gcm" }, // Register extension permissions. { APIPermission::kActiveTab, "activeTab" }, diff --git a/chrome/common/extensions/permissions/permission_set_unittest.cc b/chrome/common/extensions/permissions/permission_set_unittest.cc index 58354137..4951782 100644 --- a/chrome/common/extensions/permissions/permission_set_unittest.cc +++ b/chrome/common/extensions/permissions/permission_set_unittest.cc @@ -664,6 +664,7 @@ TEST(PermissionsTest, PermissionMessages) { skip.insert(APIPermission::kDownloadsShelf); skip.insert(APIPermission::kFontSettings); skip.insert(APIPermission::kFullscreen); + skip.insert(APIPermission::kGcm); skip.insert(APIPermission::kIdle); skip.insert(APIPermission::kIdltest); skip.insert(APIPermission::kLogPrivate); diff --git a/chrome/renderer/extensions/dispatcher.cc b/chrome/renderer/extensions/dispatcher.cc index 11f1f3b..044c5af 100644 --- a/chrome/renderer/extensions/dispatcher.cc +++ b/chrome/renderer/extensions/dispatcher.cc @@ -989,6 +989,8 @@ void Dispatcher::PopulateSourceMap() { IDR_FILE_SYSTEM_CUSTOM_BINDINGS_JS); source_map_.RegisterSource("fileSystemProvider", IDR_FILE_SYSTEM_PROVIDER_CUSTOM_BINDINGS_JS); + source_map_.RegisterSource("gcm", + IDR_GCM_CUSTOM_BINDINGS_JS); source_map_.RegisterSource("i18n", IDR_I18N_CUSTOM_BINDINGS_JS); source_map_.RegisterSource("identity", IDR_IDENTITY_CUSTOM_BINDINGS_JS); source_map_.RegisterSource("input.ime", IDR_INPUT_IME_CUSTOM_BINDINGS_JS); diff --git a/chrome/renderer/resources/extensions/gcm_custom_bindings.js b/chrome/renderer/resources/extensions/gcm_custom_bindings.js new file mode 100644 index 0000000..9cd1764 --- /dev/null +++ b/chrome/renderer/resources/extensions/gcm_custom_bindings.js @@ -0,0 +1,31 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Custom binding for the GCM API. + +var binding = require('binding').Binding.create('gcm'); +var forEach = require('utils').forEach; + +binding.registerCustomHook(function(api) { + var gcm = api.compiledApi; + var apiFunctions = api.apiFunctions; + + apiFunctions.setUpdateArgumentsPostValidate( + 'send', function (message, callback) { + var payloadSize = 0; + forEach(message.data, function(property, value) { + // Issue error for forbidden prefixes of property names. + if (property.startsWith("goog.") || property.startsWith("google")) + throw new Error("Invalid key: " + property); + + payloadSize += property.length + value.length; + }); + + // Issue error for messages larger than allowed limit. + if (payloadSize > gcm.MAX_MESSAGE_SIZE) + throw new Error("Payload exceeded size limit"); + }); +}); + +exports.binding = binding.generate(); diff --git a/chrome/renderer/resources/renderer_resources.grd b/chrome/renderer/resources/renderer_resources.grd index a8ee5ef..53cef60 100644 --- a/chrome/renderer/resources/renderer_resources.grd +++ b/chrome/renderer/resources/renderer_resources.grd @@ -69,6 +69,7 @@ without changes to the corresponding grd file. fb9 --> <include name="IDR_FILE_BROWSER_PRIVATE_CUSTOM_BINDINGS_JS" file="extensions\file_browser_private_custom_bindings.js" type="BINDATA" /> <include name="IDR_FILE_SYSTEM_CUSTOM_BINDINGS_JS" file="extensions\file_system_custom_bindings.js" type="BINDATA" /> <include name="IDR_FILE_SYSTEM_PROVIDER_CUSTOM_BINDINGS_JS" file="extensions\file_system_provider_custom_bindings.js" type="BINDATA" /> + <include name="IDR_GCM_CUSTOM_BINDINGS_JS" file="extensions\gcm_custom_bindings.js" type="BINDATA" /> <include name="IDR_I18N_CUSTOM_BINDINGS_JS" file="extensions\i18n_custom_bindings.js" type="BINDATA" /> <include name="IDR_IDENTITY_CUSTOM_BINDINGS_JS" file="extensions\identity_custom_bindings.js" type="BINDATA" /> <include name="IDR_INPUT_IME_CUSTOM_BINDINGS_JS" file="extensions\input.ime_custom_bindings.js" type="BINDATA" /> diff --git a/extensions/common/permissions/api_permission.h b/extensions/common/permissions/api_permission.h index 601463c4..e0054ae 100644 --- a/extensions/common/permissions/api_permission.h +++ b/extensions/common/permissions/api_permission.h @@ -89,6 +89,7 @@ class APIPermission { kFileSystemWriteDirectory, kFontSettings, kFullscreen, + kGcm, kGeolocation, kHistory, kHomepage, |