Remove inappropriate chrome.{extension,app} bindings for platform apps.
Also:
-Begin process of moving from chrome.extension.lastError to chrome.runtime.lastError.
-Add chrome.runtime.getManifest and chrome.runtime.getURL
BUG=131717
TEST=In platform apps, chrome.extension and chrome.app should not contain any
extension or legacy hosted app stuff on them.
Review URL: https://chromiumcodereview.appspot.com/10666027
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@145238 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/runtime_apitest.cc b/chrome/browser/extensions/runtime_apitest.cc
new file mode 100644
index 0000000..d8b449d
--- /dev/null
+++ b/chrome/browser/extensions/runtime_apitest.cc
@@ -0,0 +1,9 @@
+// Copyright (c) 2012 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/extension_apitest.h"
+
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntime) {
+ ASSERT_TRUE(RunExtensionTest("runtime")) << message_;
+}
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index 1171d28..e26075d 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -109,6 +109,8 @@
'renderer/extensions/page_actions_custom_bindings.h',
'renderer/extensions/page_capture_custom_bindings.cc',
'renderer/extensions/page_capture_custom_bindings.h',
+ 'renderer/extensions/runtime_custom_bindings.cc',
+ 'renderer/extensions/runtime_custom_bindings.h',
'renderer/extensions/send_request_natives.cc',
'renderer/extensions/send_request_natives.h',
'renderer/extensions/set_icon_natives.cc',
@@ -160,6 +162,7 @@
'renderer/resources/extensions/greasemonkey_api.js',
'renderer/resources/extensions/input.ime_custom_bindings.js',
'renderer/resources/extensions/json_schema.js',
+ 'renderer/resources/extensions/last_error.js',
'renderer/resources/extensions/miscellaneous_bindings.js',
'renderer/resources/extensions/omnibox_custom_bindings.js',
'renderer/resources/extensions/page_action_custom_bindings.js',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index b41ecfa..fc9b162 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -2831,6 +2831,7 @@
'browser/extensions/platform_app_browsertest_util.h',
'browser/extensions/plugin_apitest.cc',
'browser/extensions/process_management_browsertest.cc',
+ 'browser/extensions/runtime_apitest.cc',
'browser/extensions/sandboxed_pages_apitest.cc',
'browser/extensions/shadow_dom_apitest.cc',
'browser/extensions/settings/settings_apitest.cc',
diff --git a/chrome/common/extensions/api/extension_api.cc b/chrome/common/extensions/api/extension_api.cc
index e6298fab..83e3960 100644
--- a/chrome/common/extensions/api/extension_api.cc
+++ b/chrome/common/extensions/api/extension_api.cc
@@ -570,6 +570,34 @@
return result;
}
+namespace {
+
+bool IsFeatureAllowedForExtension(const std::string& feature,
+ const extensions::Extension& extension) {
+ if (extension.is_platform_app() &&
+ (feature == "app" || feature == "extension"))
+ return false;
+ return true;
+}
+
+// Removes APIs from |apis| that should not be allowed for |extension|.
+// TODO(kalman/asargent) - Make it possible to specify these rules
+// declaratively.
+void RemoveDisallowedAPIs(const Extension& extension,
+ std::set<std::string>* apis) {
+ CHECK(apis);
+ std::set<std::string>::iterator i = apis->begin();
+ while (i != apis->end()) {
+ if (!IsFeatureAllowedForExtension(*i, extension)) {
+ apis->erase(i++);
+ } else {
+ ++i;
+ }
+ }
+}
+
+} // namespace
+
scoped_ptr<std::set<std::string> > ExtensionAPI::GetAPIsForContext(
Feature::Context context, const Extension* extension, const GURL& url) {
// We're forced to load all schemas now because we need to know the metadata
@@ -601,6 +629,7 @@
// Availability is determined by the permissions of the extension.
GetAllowedAPIs(extension, &temp_result);
ResolveDependencies(&temp_result);
+ RemoveDisallowedAPIs(*extension, &temp_result);
}
break;
diff --git a/chrome/common/extensions/api/runtime.json b/chrome/common/extensions/api/runtime.json
index 1bae4fac..8428fee 100644
--- a/chrome/common/extensions/api/runtime.json
+++ b/chrome/common/extensions/api/runtime.json
@@ -6,6 +6,49 @@
{
"namespace": "runtime",
"documentation_permissions_required": ["runtime"],
+ "properties": {
+ "lastError": {
+ "type": "object",
+ "optional": true,
+ "description": "This will be defined during an API method callback if there was an error",
+ "properties": {
+ "message": {
+ "optional": true,
+ "type": "string",
+ "description": "Details about the error which occurred."
+ }
+ }
+ }
+ },
+ "types": [
+ {
+ "id": "ManifestDetails",
+ "description": "Details from the manifest for the current extension/app.",
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the extension/app"
+ },
+ "version": {
+ "type":"string",
+ "description": "The version of the extension/app"
+ },
+ "manifest_version": {
+ "optional": true,
+ "type": "integer"
+ },
+ "permissions": {
+ "optional": true,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": { "type": "any" }
+ }
+ ],
"functions": [
{
"name": "getBackgroundPage",
@@ -29,6 +72,33 @@
]
}
]
+ },
+ {
+ "name": "getManifest",
+ "description": "Returns details about the app or extension from the manifest",
+ "type": "function",
+ "parameters": [],
+ "returns": {
+ "$ref": "ManifestDetails",
+ "description": "The manifest details."
+ }
+ },
+ {
+ "name": "getURL",
+ "type": "function",
+ "unprivileged": true,
+ "description": "Converts a relative path within an app/extension install directory to a fully-qualified URL.",
+ "parameters": [
+ {
+ "type": "string",
+ "name": "path",
+ "description": "A path to a resource within an app/extension expressed relative to its install directory."
+ }
+ ],
+ "returns": {
+ "type": "string",
+ "description": "The fully-qualified URL to the resource."
+ }
}
],
"events": [
diff --git a/chrome/common/extensions/docs/extensions/runtime.html b/chrome/common/extensions/docs/extensions/runtime.html
index 8e07141..381ab2e 100644
--- a/chrome/common/extensions/docs/extensions/runtime.html
+++ b/chrome/common/extensions/docs/extensions/runtime.html
@@ -200,6 +200,10 @@
<ol>
<li>
<a href="#method-getBackgroundPage">getBackgroundPage</a>
+ </li><li>
+ <a href="#method-getManifest">getManifest</a>
+ </li><li>
+ <a href="#method-getURL">getURL</a>
</li>
</ol>
</li>
@@ -213,6 +217,16 @@
</li>
</ol>
</li>
+ <li>
+ <a href="#types">Types</a>
+ <ol>
+ <li>
+ <a href="#type-runtime.ManifestDetails">ManifestDetails</a>
+ <ol>
+ </ol>
+ </li>
+ </ol>
+ </li>
</ol>
</li>
</ol>
@@ -326,6 +340,115 @@
</div>
<!-- MIN_VERSION -->
</div> <!-- /description -->
+ </div><div class="apiItem">
+ <a name="method-getManifest"></a> <!-- method-anchor -->
+ <h4>getManifest</h4>
+ <div class="summary"><span>runtime.ManifestDetails</span>
+ <!-- Note: intentionally longer 80 columns -->
+ <span>chrome.runtime.getManifest</span>()</div>
+ <div class="description">
+ <p>Returns details about the app or extension from the manifest</p>
+ <!-- PARAMETERS -->
+ <dl>
+ </dl>
+ <!-- RETURNS -->
+ <h4>Returns</h4>
+ <dl>
+ <div>
+ <div>
+ <dt>
+ <em>
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional">optional</span>
+ <span id="typeTemplate">
+ <span>
+ <a href="runtime.html#type-runtime.ManifestDetails">runtime.ManifestDetails</a>
+ </span>
+ </span>
+ )
+ </div>
+ </em>
+ </dt>
+ <dd>The manifest details.</dd>
+ <!-- OBJECT PROPERTIES -->
+ <!-- OBJECT METHODS -->
+ <!-- OBJECT EVENT FIELDS -->
+ <!-- FUNCTION PARAMETERS -->
+ </div>
+ </div>
+ </dl>
+ <!-- CALLBACK -->
+ <!-- MIN_VERSION -->
+ </div> <!-- /description -->
+ </div><div class="apiItem">
+ <a name="method-getURL"></a> <!-- method-anchor -->
+ <h4>getURL</h4>
+ <div class="summary"><span>string</span>
+ <!-- Note: intentionally longer 80 columns -->
+ <span>chrome.runtime.getURL</span>(<span class="null"><span>string</span>
+ <var><span>path</span></var></span>)</div>
+ <div class="description">
+ <p>Converts a relative path within an app/extension install directory to a fully-qualified URL.</p>
+ <!-- PARAMETERS -->
+ <h4>Parameters</h4>
+ <dl>
+ <div>
+ <div>
+ <dt>
+ <var>path</var>
+ <em>
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span id="typeTemplate">
+ <span>
+ <span>string</span>
+ </span>
+ </span>
+ )
+ </div>
+ </em>
+ </dt>
+ <dd>A path to a resource within an app/extension expressed relative to its install directory.</dd>
+ <!-- OBJECT PROPERTIES -->
+ <!-- OBJECT METHODS -->
+ <!-- OBJECT EVENT FIELDS -->
+ <!-- FUNCTION PARAMETERS -->
+ </div>
+ </div>
+ </dl>
+ <!-- RETURNS -->
+ <h4>Returns</h4>
+ <dl>
+ <div>
+ <div>
+ <dt>
+ <em>
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span id="typeTemplate">
+ <span>
+ <span>string</span>
+ </span>
+ </span>
+ )
+ </div>
+ </em>
+ </dt>
+ <dd>The fully-qualified URL to the resource.</dd>
+ <!-- OBJECT PROPERTIES -->
+ <!-- OBJECT METHODS -->
+ <!-- OBJECT EVENT FIELDS -->
+ <!-- FUNCTION PARAMETERS -->
+ </div>
+ </div>
+ </dl>
+ <!-- CALLBACK -->
+ <!-- MIN_VERSION -->
+ </div> <!-- /description -->
</div> <!-- /apiItem -->
</div> <!-- /apiGroup -->
<!-- EVENTS -->
@@ -368,7 +491,147 @@
</div> <!-- /apiItem -->
</div> <!-- /apiGroup -->
<!-- TYPES -->
- <!-- /apiGroup -->
+ <div class="apiGroup">
+ <a name="types"></a>
+ <h3 id="types">Types</h3>
+ <!-- iterates over all types -->
+ <div class="apiItem">
+ <a name="type-runtime.ManifestDetails"></a>
+ <h4>runtime.ManifestDetails</h4>
+ <div>
+ <dt>
+ <em>
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span id="typeTemplate">
+ <span>
+ <span>object</span>
+ </span>
+ </span>
+ )
+ </div>
+ </em>
+ </dt>
+ <dd>Details from the manifest for the current extension/app.</dd>
+ <!-- OBJECT PROPERTIES -->
+ <dd>
+ <dl>
+ <div>
+ <div>
+ <dt>
+ <var>name</var>
+ <em>
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span id="typeTemplate">
+ <span>
+ <span>string</span>
+ </span>
+ </span>
+ )
+ </div>
+ </em>
+ </dt>
+ <dd>The name of the extension/app</dd>
+ <!-- OBJECT PROPERTIES -->
+ <!-- OBJECT METHODS -->
+ <!-- OBJECT EVENT FIELDS -->
+ <!-- FUNCTION PARAMETERS -->
+ </div>
+ </div><div>
+ <div>
+ <dt>
+ <var>version</var>
+ <em>
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span id="typeTemplate">
+ <span>
+ <span>string</span>
+ </span>
+ </span>
+ )
+ </div>
+ </em>
+ </dt>
+ <dd class="todo">
+ Undocumented.
+ </dd>
+ <!-- OBJECT PROPERTIES -->
+ <!-- OBJECT METHODS -->
+ <!-- OBJECT EVENT FIELDS -->
+ <!-- FUNCTION PARAMETERS -->
+ </div>
+ </div><div>
+ <div>
+ <dt>
+ <var>manifest_version</var>
+ <em>
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional">optional</span>
+ <span id="typeTemplate">
+ <span>
+ <span>integer</span>
+ </span>
+ </span>
+ )
+ </div>
+ </em>
+ </dt>
+ <dd class="todo">
+ Undocumented.
+ </dd>
+ <!-- OBJECT PROPERTIES -->
+ <!-- OBJECT METHODS -->
+ <!-- OBJECT EVENT FIELDS -->
+ <!-- FUNCTION PARAMETERS -->
+ </div>
+ </div><div>
+ <div>
+ <dt>
+ <var>permissions</var>
+ <em>
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional">optional</span>
+ <span id="typeTemplate">
+ <span>
+ <span>
+ array of <span><span>
+ <span>
+ <span>any</span>
+ </span>
+ </span></span>
+ </span>
+ </span>
+ </span>
+ )
+ </div>
+ </em>
+ </dt>
+ <dd class="todo">
+ Undocumented.
+ </dd>
+ <!-- OBJECT PROPERTIES -->
+ <!-- OBJECT METHODS -->
+ <!-- OBJECT EVENT FIELDS -->
+ <!-- FUNCTION PARAMETERS -->
+ </div>
+ </div>
+ </dl>
+ </dd>
+ <!-- OBJECT METHODS -->
+ <!-- OBJECT EVENT FIELDS -->
+ <!-- FUNCTION PARAMETERS -->
+ </div>
+ </div> <!-- /apiItem -->
+ </div> <!-- /apiGroup -->
</div> <!-- /apiPage -->
</div> <!-- /gc-pagecontent -->
</div> <!-- /g-section -->
diff --git a/chrome/common/extensions/docs/samples.json b/chrome/common/extensions/docs/samples.json
index 8c622d7..c7d1bcc 100644
--- a/chrome/common/extensions/docs/samples.json
+++ b/chrome/common/extensions/docs/samples.json
@@ -308,6 +308,8 @@
"chrome.permissions.request": "permissions.html#method-request",
"chrome.proxy.onProxyError": "proxy.html#event-onProxyError",
"chrome.runtime.getBackgroundPage": "runtime.html#method-getBackgroundPage",
+ "chrome.runtime.getManifest": "runtime.html#method-getManifest",
+ "chrome.runtime.getURL": "runtime.html#method-getURL",
"chrome.runtime.onInstalled": "runtime.html#event-onInstalled",
"chrome.runtime.onSuspend": "runtime.html#event-onSuspend",
"chrome.scriptBadge.getPopup": "scriptBadge.html#method-getPopup",
diff --git a/chrome/renderer/extensions/extension_dispatcher.cc b/chrome/renderer/extensions/extension_dispatcher.cc
index a7da8601..56d5c89 100644
--- a/chrome/renderer/extensions/extension_dispatcher.cc
+++ b/chrome/renderer/extensions/extension_dispatcher.cc
@@ -39,6 +39,7 @@
#include "chrome/renderer/extensions/miscellaneous_bindings.h"
#include "chrome/renderer/extensions/page_actions_custom_bindings.h"
#include "chrome/renderer/extensions/page_capture_custom_bindings.h"
+#include "chrome/renderer/extensions/runtime_custom_bindings.h"
#include "chrome/renderer/extensions/send_request_natives.h"
#include "chrome/renderer/extensions/set_icon_natives.h"
#include "chrome/renderer/extensions/tab_finder.h"
@@ -94,6 +95,7 @@
using extensions::PageActionsCustomBindings;
using extensions::PageCaptureCustomBindings;
using extensions::PermissionSet;
+using extensions::RuntimeCustomBindings;
using extensions::SendRequestNatives;
using extensions::SetIconNatives;
using extensions::TTSCustomBindings;
@@ -536,6 +538,8 @@
new PageActionsCustomBindings(this)));
module_system->RegisterNativeHandler("page_capture",
scoped_ptr<NativeHandler>(new PageCaptureCustomBindings()));
+ module_system->RegisterNativeHandler("runtime",
+ scoped_ptr<NativeHandler>(new RuntimeCustomBindings(context)));
module_system->RegisterNativeHandler("tabs",
scoped_ptr<NativeHandler>(new TabsCustomBindings()));
module_system->RegisterNativeHandler("tts",
@@ -556,6 +560,7 @@
source_map_.RegisterSource("apitest", IDR_EXTENSION_APITEST_JS);
// Libraries.
+ source_map_.RegisterSource("lastError", IDR_LAST_ERROR_JS);
source_map_.RegisterSource("schemaUtils", IDR_SCHEMA_UTILS_JS);
source_map_.RegisterSource("sendRequest", IDR_SEND_REQUEST_JS);
source_map_.RegisterSource("setIcon", IDR_SET_ICON_JS);
@@ -707,7 +712,9 @@
case Feature::BLESSED_EXTENSION_CONTEXT:
case Feature::UNBLESSED_EXTENSION_CONTEXT:
case Feature::CONTENT_SCRIPT_CONTEXT: {
- module_system->Require("miscellaneous_bindings");
+ CHECK(extension);
+ if (!extension->is_platform_app())
+ module_system->Require("miscellaneous_bindings");
module_system->Require("schema_generated_bindings");
module_system->Require("apitest");
@@ -725,8 +732,7 @@
}
}
- // Inject custom JS into the platform app context to block certain features
- // of the document and window.
+ // Inject custom JS into the platform app context.
if (IsWithinPlatformApp(frame))
module_system->Require("platformApp");
diff --git a/chrome/renderer/extensions/runtime_custom_bindings.cc b/chrome/renderer/extensions/runtime_custom_bindings.cc
new file mode 100644
index 0000000..abc15a1
--- /dev/null
+++ b/chrome/renderer/extensions/runtime_custom_bindings.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2012 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/renderer/extensions/runtime_custom_bindings.h"
+
+#include "base/bind.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest.h"
+#include "chrome/renderer/extensions/extension_dispatcher.h"
+#include "chrome/renderer/extensions/chrome_v8_context.h"
+#include "content/public/renderer/v8_value_converter.h"
+
+using content::V8ValueConverter;
+
+namespace extensions {
+
+RuntimeCustomBindings::RuntimeCustomBindings(ChromeV8Context* context)
+ : ChromeV8Extension(NULL), context_(context) {
+ RouteFunction("GetManifest",
+ base::Bind(&RuntimeCustomBindings::GetManifest, base::Unretained(this)));
+}
+
+RuntimeCustomBindings::~RuntimeCustomBindings() {}
+
+v8::Handle<v8::Value> RuntimeCustomBindings::GetManifest(
+ const v8::Arguments& args) {
+ CHECK(context_->extension());
+
+ scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
+ return converter->ToV8Value(context_->extension()->manifest()->value(),
+ context_->v8_context());
+}
+
+} // extensions
diff --git a/chrome/renderer/extensions/runtime_custom_bindings.h b/chrome/renderer/extensions/runtime_custom_bindings.h
new file mode 100644
index 0000000..56bf98e
--- /dev/null
+++ b/chrome/renderer/extensions/runtime_custom_bindings.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2012 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_RENDERER_EXTENSIONS_RUNTIME_CUSTOM_BINDINGS_H_
+#define CHROME_RENDERER_EXTENSIONS_RUNTIME_CUSTOM_BINDINGS_H_
+#pragma once
+
+#include "base/compiler_specific.h"
+#include "chrome/renderer/extensions/chrome_v8_extension.h"
+#include "v8/include/v8.h"
+
+class ExtensionDispatcher;
+class ChromeV8Context;
+
+namespace extensions {
+
+// The native component of custom bindings for the chrome.runtime API.
+class RuntimeCustomBindings : public ChromeV8Extension {
+ public:
+ explicit RuntimeCustomBindings(ChromeV8Context* context);
+
+ virtual ~RuntimeCustomBindings();
+
+ private:
+ v8::Handle<v8::Value> GetManifest(const v8::Arguments& args);
+
+ ChromeV8Context* context_;
+};
+
+} // extensions
+
+#endif // CHROME_RENDERER_EXTENSIONS_RUNTIME_CUSTOM_BINDINGS_H_
diff --git a/chrome/renderer/renderer_resources.grd b/chrome/renderer/renderer_resources.grd
index eb63855..3d90611 100644
--- a/chrome/renderer/renderer_resources.grd
+++ b/chrome/renderer/renderer_resources.grd
@@ -28,6 +28,7 @@
<include name="IDR_SCHEMA_GENERATED_BINDINGS_JS" file="resources\extensions\schema_generated_bindings.js" type="BINDATA" />
<!-- Libraries. -->
+ <include name="IDR_LAST_ERROR_JS" file="resources\extensions\last_error.js" type="BINDATA" />
<include name="IDR_SCHEMA_UTILS_JS" file="resources\extensions\schema_utils.js" type="BINDATA" />
<include name="IDR_SEND_REQUEST_JS" file="resources\extensions\send_request.js" type="BINDATA" />
<include name="IDR_SET_ICON_JS" file="resources\extensions\set_icon.js" type="BINDATA" />
diff --git a/chrome/renderer/resources/extensions/apitest.js b/chrome/renderer/resources/extensions/apitest.js
index 2f36dee..a29f0979 100644
--- a/chrome/renderer/resources/extensions/apitest.js
+++ b/chrome/renderer/resources/extensions/apitest.js
@@ -183,9 +183,9 @@
};
chrome.test.assertNoLastError = function() {
- if (chrome.extension.lastError != undefined) {
+ if (chrome.runtime.lastError != undefined) {
chrome.test.fail("lastError.message == " +
- chrome.extension.lastError.message);
+ chrome.runtime.lastError.message);
}
};
@@ -212,9 +212,9 @@
chrome.test.assertNoLastError();
} else {
chrome.test.assertEq(typeof(expectedError), 'string');
- chrome.test.assertTrue(chrome.extension.lastError != undefined,
+ chrome.test.assertTrue(chrome.runtime.lastError != undefined,
"No lastError, but expected " + expectedError);
- chrome.test.assertEq(expectedError, chrome.extension.lastError.message);
+ chrome.test.assertEq(expectedError, chrome.runtime.lastError.message);
}
if (func) {
diff --git a/chrome/renderer/resources/extensions/context_menus_custom_bindings.js b/chrome/renderer/resources/extensions/context_menus_custom_bindings.js
index c4e48bf..9e4016a 100644
--- a/chrome/renderer/resources/extensions/context_menus_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/context_menus_custom_bindings.js
@@ -56,7 +56,7 @@
});
apiFunctions.setCustomCallback('create', function(name, request, response) {
- if (chrome.extension.lastError) {
+ if (chrome.runtime.lastError) {
return;
}
@@ -72,7 +72,7 @@
});
apiFunctions.setCustomCallback('remove', function(name, request, response) {
- if (chrome.extension.lastError) {
+ if (chrome.runtime.lastError) {
return;
}
var id = request.args[0];
@@ -80,7 +80,7 @@
});
apiFunctions.setCustomCallback('update', function(name, request, response) {
- if (chrome.extension.lastError) {
+ if (chrome.runtime.lastError) {
return;
}
var id = request.args[0];
@@ -91,7 +91,7 @@
apiFunctions.setCustomCallback('removeAll',
function(name, request, response) {
- if (chrome.extension.lastError) {
+ if (chrome.runtime.lastError) {
return;
}
chromeHidden.contextMenus.generatedIdHandlers = {};
diff --git a/chrome/renderer/resources/extensions/file_system_custom_bindings.js b/chrome/renderer/resources/extensions/file_system_custom_bindings.js
index 548bedf..4248787 100644
--- a/chrome/renderer/resources/extensions/file_system_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/file_system_custom_bindings.js
@@ -7,6 +7,7 @@
var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
var fileSystemNatives = requireNative('file_system_natives');
var GetIsolatedFileSystem = fileSystemNatives.GetIsolatedFileSystem;
+var lastError = require('lastError');
chromeHidden.registerCustomHook('fileSystem', function(bindingsAPI) {
var apiFunctions = bindingsAPI.apiFunctions;
@@ -35,13 +36,11 @@
fs.root.getFile(baseName, {}, function(fileEntry) {
callback(fileEntry);
}, function(fileError) {
- chrome.extension.lastError = {"message":
- 'Error getting fileEntry, code: ' + fileError.code};
+ lastError.set('Error getting fileEntry, code: ' + fileError.code);
callback();
});
} catch (e) {
- chrome.extension.lastError = {"message":
- 'Error in event handler for onLaunched: ' + e.stack};
+ lastError.set('Error in event handler for onLaunched: ' + e.stack);
callback();
}
}
diff --git a/chrome/renderer/resources/extensions/last_error.js b/chrome/renderer/resources/extensions/last_error.js
new file mode 100644
index 0000000..66f69f51
--- /dev/null
+++ b/chrome/renderer/resources/extensions/last_error.js
@@ -0,0 +1,19 @@
+// Copyright (c) 2012 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.
+
+function set(message) {
+ var errorObject = { "message": message };
+ if (chrome.extension)
+ chrome.extension.lastError = errorObject;
+ chrome.runtime.lastError = errorObject;
+};
+
+function clear() {
+ if (chrome.extension)
+ delete chrome.extension.lastError;
+ delete chrome.runtime.lastError;
+};
+
+exports.clear = clear;
+exports.set = set;
diff --git a/chrome/renderer/resources/extensions/miscellaneous_bindings.js b/chrome/renderer/resources/extensions/miscellaneous_bindings.js
index 1c07de7..7a806055b 100644
--- a/chrome/renderer/resources/extensions/miscellaneous_bindings.js
+++ b/chrome/renderer/resources/extensions/miscellaneous_bindings.js
@@ -9,6 +9,7 @@
require('json_schema');
require('event_bindings');
+ var lastError = requireNative('lastError');
var miscNatives = requireNative('miscellaneous_bindings');
var CloseChannel = miscNatives.CloseChannel;
var PortAddRef = miscNatives.PortAddRef;
@@ -116,7 +117,7 @@
if (sourceExtensionId != targetExtensionId)
errorMsg += " for extension " + targetExtensionId;
errorMsg += ").";
- chrome.extension.lastError = {"message": errorMsg};
+ lastError.set(errorMsg);
console.error("Could not send response: " + errorMsg);
}
@@ -228,14 +229,14 @@
if (connectionInvalid) {
var errorMsg =
"Could not establish connection. Receiving end does not exist.";
- chrome.extension.lastError = {"message": errorMsg};
+ lastError.set(errorMsg);
console.error("Port error: " + errorMsg);
}
try {
port.onDisconnect.dispatch(port);
} finally {
port.destroy_();
- delete chrome.extension.lastError;
+ lastError.clear();
}
}
};
@@ -272,7 +273,7 @@
port.onDisconnect.addListener(function() {
// For onDisconnects, we only notify the callback if there was an error
try {
- if (chrome.extension.lastError)
+ if (chrome.runtime.lastError)
responseCallback();
} finally {
port = null;
diff --git a/chrome/renderer/resources/extensions/runtime_custom_bindings.js b/chrome/renderer/resources/extensions/runtime_custom_bindings.js
index 8fb713fe..3c4c28e 100644
--- a/chrome/renderer/resources/extensions/runtime_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/runtime_custom_bindings.js
@@ -4,12 +4,12 @@
// Custom bindings for the runtime API.
+var runtimeNatives = requireNative('runtime');
var extensionNatives = requireNative('extension');
var GetExtensionViews = extensionNatives.GetExtensionViews;
var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
-var sendRequest = require('sendRequest').sendRequest;
-chromeHidden.registerCustomHook('runtime', function(bindingsAPI) {
+chromeHidden.registerCustomHook('runtime', function(bindingsAPI, extensionId) {
var apiFunctions = bindingsAPI.apiFunctions;
apiFunctions.setCustomCallback('getBackgroundPage',
@@ -20,4 +20,16 @@
}
request.callback = null;
});
+
+ apiFunctions.setHandleRequest('getManifest', function() {
+ return runtimeNatives.GetManifest();
+ });
+
+ apiFunctions.setHandleRequest('getURL', function(path) {
+ path = String(path);
+ if (!path.length || path[0] != '/')
+ path = '/' + path;
+ return 'chrome-extension://' + extensionId + path;
+ });
+
});
diff --git a/chrome/renderer/resources/extensions/send_request.js b/chrome/renderer/resources/extensions/send_request.js
index abb582a..2ea6545d 100644
--- a/chrome/renderer/resources/extensions/send_request.js
+++ b/chrome/renderer/resources/extensions/send_request.js
@@ -3,6 +3,7 @@
// found in the LICENSE file.
var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
+var lastError = require('lastError');
var natives = requireNative('sendRequest');
var validate = require('schemaUtils').validate;
@@ -13,15 +14,13 @@
try {
var request = requests[requestId];
if (success) {
- delete chrome.extension.lastError;
+ lastError.clear();
} else {
if (!error) {
error = "Unknown error.";
}
console.error("Error during " + name + ": " + error);
- chrome.extension.lastError = {
- "message": error
- };
+ lastError.set(error);
}
if (request.customCallback) {
@@ -60,7 +59,7 @@
}
} finally {
delete requests[requestId];
- delete chrome.extension.lastError;
+ lastError.clear();
}
return undefined;
diff --git a/chrome/test/data/extensions/api_test/runtime/manifest.json b/chrome/test/data/extensions/api_test/runtime/manifest.json
new file mode 100644
index 0000000..086f0890
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/runtime/manifest.json
@@ -0,0 +1,8 @@
+{
+ "name": "chrome.runtime API Test",
+ "version": "1",
+ "manifest_version": 2,
+ "background": {
+ "scripts": ["test.js"]
+ }
+}
diff --git a/chrome/test/data/extensions/api_test/runtime/test.js b/chrome/test/data/extensions/api_test/runtime/test.js
new file mode 100644
index 0000000..74de48c
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/runtime/test.js
@@ -0,0 +1,38 @@
+// Copyright (c) 2012 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.
+
+var assertEq = chrome.test.assertEq;
+var fail = chrome.test.fail;
+var succeed = chrome.test.succeed;
+
+chrome.test.runTests([
+
+ function testGetURL() {
+ if (!chrome.runtime || !chrome.runtime.getURL) {
+ fail("chrome.runtime.getURL not defined");
+ return;
+ }
+ var url = chrome.runtime.getURL("_generated_background_page.html");
+ assertEq(url, window.location.href);
+ succeed();
+ },
+
+ function testGetManifest() {
+ if (!chrome.runtime || !chrome.runtime.getManifest) {
+ fail("chrome.runtime.getManifest not defined");
+ return;
+ }
+ var manifest = chrome.runtime.getManifest();
+ if (!manifest || !manifest.background || !manifest.background.scripts) {
+ fail();
+ return;
+ }
+ assertEq(manifest.name, "chrome.runtime API Test");
+ assertEq(manifest.version, "1");
+ assertEq(manifest.manifest_version, 2);
+ assertEq(manifest.background.scripts, ["test.js"]);
+ succeed();
+ }
+
+]);
diff --git a/chrome/test/data/extensions/platform_apps/restrictions/main.js b/chrome/test/data/extensions/platform_apps/restrictions/main.js
index fb695c7..78d5873 100644
--- a/chrome/test/data/extensions/platform_apps/restrictions/main.js
+++ b/chrome/test/data/extensions/platform_apps/restrictions/main.js
@@ -150,5 +150,19 @@
var iframe = document.createElement('iframe');
iframe.src = 'sandboxed_iframe.html';
document.body.appendChild(iframe);
+ },
+
+ function testLegacyApis() {
+ if (chrome.app) {
+ assertEq("undefined", typeof(chrome.app.getIsInstalled));
+ assertEq("undefined", typeof(chrome.app.install));
+ assertEq("undefined", typeof(chrome.app.isInstalled));
+ assertEq("undefined", typeof(chrome.app.getDetails));
+ assertEq("undefined", typeof(chrome.app.getDetailsForFrame));
+ assertEq("undefined", typeof(chrome.app.runningState));
+ }
+ assertEq("undefined", typeof(chrome.appNotifications));
+ assertEq("undefined", typeof(chrome.extension));
+ succeed();
}
]);
diff --git a/chrome/test/data/extensions/platform_apps/restrictions/manifest.json b/chrome/test/data/extensions/platform_apps/restrictions/manifest.json
index 814775f2..65e676a 100644
--- a/chrome/test/data/extensions/platform_apps/restrictions/manifest.json
+++ b/chrome/test/data/extensions/platform_apps/restrictions/manifest.json
@@ -1,5 +1,5 @@
{
- "name": "Platform App Test: various document and window restrictions",
+ "name": "Platform App Test: various document, window, and API restrictions",
"version": "1",
"manifest_version": 2,
"permissions": [