summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/crx_installer.cc5
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc4
-rw-r--r--chrome/browser/extensions/extension_module.cc23
-rw-r--r--chrome/browser/extensions/extension_module.h20
-rw-r--r--chrome/browser/extensions/extension_module_apitest.cc12
-rw-r--r--chrome/browser/extensions/extension_prefs.cc25
-rw-r--r--chrome/browser/extensions/extension_prefs.h7
-rw-r--r--chrome/browser/extensions/extension_updater.cc32
-rw-r--r--chrome/browser/extensions/extension_updater.h6
-rw-r--r--chrome/browser/extensions/extension_updater_unittest.cc99
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/common/extensions/api/extension_api.json8
-rw-r--r--chrome/common/extensions/docs/extension.html123
-rw-r--r--chrome/common/extensions/extension.cc8
-rw-r--r--chrome/common/extensions/extension.h4
-rw-r--r--chrome/renderer/resources/renderer_extension_bindings.js3
-rw-r--r--chrome/test/data/extensions/api_test/extension_module/manifest.json6
-rw-r--r--chrome/test/data/extensions/api_test/extension_module/test.html1
-rw-r--r--chrome/test/data/extensions/api_test/extension_module/test.js43
20 files changed, 409 insertions, 23 deletions
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index a0dd960..d90bbbd 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -204,10 +204,7 @@ bool CrxInstaller::AllowInstall(const Extension* extension,
// For apps with a gallery update URL, require that they be installed
// from the gallery.
// TODO(erikkay) Apply this rule for paid extensions and themes as well.
- if ((extension->update_url() ==
- GURL(extension_urls::kGalleryUpdateHttpsUrl)) ||
- (extension->update_url() ==
- GURL(extension_urls::kGalleryUpdateHttpUrl))) {
+ if (extension->UpdatesFromGallery()) {
*error = l10n_util::GetStringFUTF8(
IDS_EXTENSION_DISALLOW_NON_DOWNLOADED_GALLERY_INSTALLS,
l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE));
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 4f53b48..47531f4 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -36,6 +36,7 @@
#include "chrome/browser/extensions/extension_management_api.h"
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/extensions/extension_metrics_module.h"
+#include "chrome/browser/extensions/extension_module.h"
#include "chrome/browser/extensions/extension_omnibox_api.h"
#include "chrome/browser/extensions/extension_page_actions_module.h"
#include "chrome/browser/extensions/extension_popup_api.h"
@@ -279,6 +280,9 @@ void FactoryRegistry::ResetFunctions() {
RegisterFunction<SetEnabledFunction>();
RegisterFunction<UninstallFunction>();
+ // Extension module.
+ RegisterFunction<SetUpdateUrlDataFunction>();
+
// WebstorePrivate.
RegisterFunction<GetBrowserLoginFunction>();
RegisterFunction<GetStoreLoginFunction>();
diff --git a/chrome/browser/extensions/extension_module.cc b/chrome/browser/extensions/extension_module.cc
new file mode 100644
index 0000000..84c3789
--- /dev/null
+++ b/chrome/browser/extensions/extension_module.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2010 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_module.h"
+
+#include <string>
+
+#include "chrome/browser/extensions/extension_prefs.h"
+#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/profile.h"
+
+ExtensionPrefs* SetUpdateUrlDataFunction::extension_prefs() {
+ return profile()->GetExtensionsService()->extension_prefs();
+}
+
+bool SetUpdateUrlDataFunction::RunImpl() {
+ std::string data;
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &data));
+
+ extension_prefs()->SetUpdateUrlData(extension_id(), data);
+ return true;
+}
diff --git a/chrome/browser/extensions/extension_module.h b/chrome/browser/extensions/extension_module.h
new file mode 100644
index 0000000..21227a2
--- /dev/null
+++ b/chrome/browser/extensions/extension_module.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2010 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_EXTENSION_MODULE_H__
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_MODULE_H__
+#pragma once
+
+#include "chrome/browser/extensions/extension_function.h"
+
+class ExtensionPrefs;
+
+class SetUpdateUrlDataFunction : public SyncExtensionFunction {
+ protected:
+ ExtensionPrefs* extension_prefs();
+ virtual bool RunImpl();
+ DECLARE_EXTENSION_FUNCTION_NAME("extension.setUpdateUrlData");
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_MODULE_H__
diff --git a/chrome/browser/extensions/extension_module_apitest.cc b/chrome/browser/extensions/extension_module_apitest.cc
new file mode 100644
index 0000000..718c422
--- /dev/null
+++ b/chrome/browser/extensions/extension_module_apitest.cc
@@ -0,0 +1,12 @@
+// Copyright (c) 2010 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"
+
+class ExtensionModuleApiTest : public ExtensionApiTest {
+};
+
+IN_PROC_BROWSER_TEST_F(ExtensionModuleApiTest, Basics) {
+ ASSERT_TRUE(RunExtensionTest("extension_module")) << message_;
+}
diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc
index bf80550..3c789b0 100644
--- a/chrome/browser/extensions/extension_prefs.cc
+++ b/chrome/browser/extensions/extension_prefs.cc
@@ -75,6 +75,9 @@ const char kPrefLaunchType[] = "launchType";
// A preference determining the order of which the apps appear on the NTP.
const char kPrefAppLaunchIndex[] = "app_launcher_index";
+// "A preference for storing extra data sent in update checks for an extension.
+const char kUpdateUrlData[] = "update_url_data";
+
} // namespace
////////////////////////////////////////////////////////////////////////////////
@@ -895,6 +898,28 @@ int ExtensionPrefs::GetNextAppLaunchIndex() {
return max_value + 1;
}
+void ExtensionPrefs::SetUpdateUrlData(const std::string& extension_id,
+ const std::string& data) {
+ DictionaryValue* dictionary = GetExtensionPref(extension_id);
+ if (!dictionary) {
+ NOTREACHED();
+ return;
+ }
+
+ dictionary->SetString(kUpdateUrlData, data);
+ SavePrefsAndNotify();
+}
+
+std::string ExtensionPrefs::GetUpdateUrlData(const std::string& extension_id) {
+ DictionaryValue* dictionary = GetExtensionPref(extension_id);
+ if (!dictionary)
+ return std::string();
+
+ std::string data;
+ dictionary->GetString(kUpdateUrlData, &data);
+ return data;
+}
+
// static
void ExtensionPrefs::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterDictionaryPref(kExtensionsPref);
diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h
index eb16329..298d03c 100644
--- a/chrome/browser/extensions/extension_prefs.h
+++ b/chrome/browser/extensions/extension_prefs.h
@@ -187,6 +187,13 @@ class ExtensionPrefs {
// highest current application launch index found.
int GetNextAppLaunchIndex();
+ // The extension's update URL data. If not empty, the ExtensionUpdater
+ // will append a ap= parameter to the URL when checking if a new version
+ // of the extension is available.
+ void SetUpdateUrlData(const std::string& extension_id,
+ const std::string& data);
+ std::string GetUpdateUrlData(const std::string& extension_id);
+
static void RegisterUserPrefs(PrefService* prefs);
// The underlying PrefService.
diff --git a/chrome/browser/extensions/extension_updater.cc b/chrome/browser/extensions/extension_updater.cc
index a3f81ef..573da94 100644
--- a/chrome/browser/extensions/extension_updater.cc
+++ b/chrome/browser/extensions/extension_updater.cc
@@ -97,7 +97,8 @@ ManifestFetchData::~ManifestFetchData() {}
//
// (Note that '=' is %3D and '&' is %26 when urlencoded.)
bool ManifestFetchData::AddExtension(std::string id, std::string version,
- int days) {
+ int days,
+ const std::string& update_url_data) {
if (extension_ids_.find(id) != extension_ids_.end()) {
NOTREACHED() << "Duplicate extension id " << id;
return false;
@@ -109,6 +110,13 @@ bool ManifestFetchData::AddExtension(std::string id, std::string version,
parts.push_back("v=" + version);
parts.push_back("uc");
+ if (!update_url_data.empty()) {
+ // Make sure the update_url_data string is escaped before using it so that
+ // there is no chance of overriding the id or v other parameter value
+ // we place into the x= value.
+ parts.push_back("ap=" + EscapeQueryParamValue(update_url_data, true));
+ }
+
if (ShouldPing(days)) {
parts.push_back("ping=" +
EscapeQueryParamValue("r=" + base::IntToString(days), true));
@@ -177,12 +185,20 @@ void ManifestFetchesBuilder::AddExtension(const Extension& extension) {
return;
}
+ // If the extension updates itself from the gallery, ignore any update URL
+ // data. At the moment there is no extra data that an extension can
+ // communicate to the the gallery update servers.
+ std::string update_url_data;
+ if (!extension.UpdatesFromGallery())
+ update_url_data = service_->extension_prefs()->
+ GetUpdateUrlData(extension.id());
+
AddExtensionData(extension.location(),
extension.id(),
*extension.version(),
(extension.is_theme() ? PendingExtensionInfo::THEME
: PendingExtensionInfo::EXTENSION),
- extension.update_url());
+ extension.update_url(), update_url_data);
}
void ManifestFetchesBuilder::AddPendingExtension(
@@ -195,7 +211,7 @@ void ManifestFetchesBuilder::AddPendingExtension(
Version::GetVersionFromString("0.0.0.0"));
AddExtensionData(info.install_source, id, *version,
- info.expected_crx_type, info.update_url);
+ info.expected_crx_type, info.update_url, "");
}
void ManifestFetchesBuilder::ReportStats() const {
@@ -230,7 +246,8 @@ void ManifestFetchesBuilder::AddExtensionData(
const std::string& id,
const Version& version,
PendingExtensionInfo::ExpectedCrxType crx_type,
- GURL update_url) {
+ GURL update_url,
+ const std::string& update_url_data) {
if (!Extension::IsAutoUpdateableLocation(location)) {
return;
@@ -277,7 +294,7 @@ void ManifestFetchesBuilder::AddExtensionData(
CalculatePingDays(service_->extension_prefs()->LastPingDay(id));
while (existing_iter != fetches_.end()) {
if (existing_iter->second->AddExtension(id, version.GetString(),
- ping_days)) {
+ ping_days, update_url_data)) {
fetch = existing_iter->second;
break;
}
@@ -286,7 +303,8 @@ void ManifestFetchesBuilder::AddExtensionData(
if (!fetch) {
fetch = new ManifestFetchData(update_url);
fetches_.insert(std::pair<GURL, ManifestFetchData*>(update_url, fetch));
- bool added = fetch->AddExtension(id, version.GetString(), ping_days);
+ bool added = fetch->AddExtension(id, version.GetString(), ping_days,
+ update_url_data);
DCHECK(added);
}
}
@@ -736,7 +754,7 @@ void ExtensionUpdater::CheckNow() {
std::string version = prefs_->GetString(kExtensionBlacklistUpdateVersion);
int ping_days =
CalculatePingDays(service_->extension_prefs()->BlacklistLastPingDay());
- blacklist_fetch->AddExtension(kBlacklistAppID, version, ping_days);
+ blacklist_fetch->AddExtension(kBlacklistAppID, version, ping_days, "");
StartUpdateCheck(blacklist_fetch);
}
diff --git a/chrome/browser/extensions/extension_updater.h b/chrome/browser/extensions/extension_updater.h
index 1a28a4d..1e99649 100644
--- a/chrome/browser/extensions/extension_updater.h
+++ b/chrome/browser/extensions/extension_updater.h
@@ -43,7 +43,8 @@ class ManifestFetchData {
// Returns true if this extension information was successfully added. If the
// return value is false it means the full_url would have become too long, and
// this ManifestFetchData object remains unchanged.
- bool AddExtension(std::string id, std::string version, int ping_days);
+ bool AddExtension(std::string id, std::string version, int ping_days,
+ const std::string& update_url_data);
const GURL& base_url() const { return base_url_; }
const GURL& full_url() const { return full_url_; }
@@ -112,7 +113,8 @@ class ManifestFetchesBuilder {
const std::string& id,
const Version& version,
PendingExtensionInfo::ExpectedCrxType crx_type,
- GURL update_url);
+ GURL update_url,
+ const std::string& update_url_data);
ExtensionUpdateService* service_;
// List of data on fetches we're going to do. We limit the number of
diff --git a/chrome/browser/extensions/extension_updater_unittest.cc b/chrome/browser/extensions/extension_updater_unittest.cc
index 53975d0..bc1a6ff 100644
--- a/chrome/browser/extensions/extension_updater_unittest.cc
+++ b/chrome/browser/extensions/extension_updater_unittest.cc
@@ -32,11 +32,17 @@
using base::Time;
using base::TimeDelta;
-static int expected_load_flags =
+namespace {
+
+const char kEmptyUpdateUrlData[] = "";
+
+int expected_load_flags =
net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SAVE_COOKIES |
net::LOAD_DISABLE_CACHE;
+} // namespace
+
// Base class for further specialized test classes.
class MockService : public ExtensionUpdateService {
public:
@@ -402,6 +408,70 @@ class ExtensionUpdaterTest : public testing::Test {
EXPECT_TRUE(ContainsKey(params, "ping"));
}
+ static void TestUpdateUrlDataEmpty() {
+ const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ const std::string version = "1.0";
+
+ // Make sure that an empty update URL data string does not cause a ap=
+ // option to appear in the x= parameter.
+ ManifestFetchData fetch_data(GURL("http://localhost/foo"));
+ fetch_data.AddExtension(id, version,
+ ManifestFetchData::kNeverPinged, "");
+ EXPECT_EQ("http://localhost/foo\?x=id%3Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "%26v%3D1.0%26uc",
+ fetch_data.full_url().spec());
+ }
+
+ static void TestUpdateUrlDataSimple() {
+ const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ const std::string version = "1.0";
+
+ // Make sure that an update URL data string causes an appropriate ap=
+ // option to appear in the x= parameter.
+ ManifestFetchData fetch_data(GURL("http://localhost/foo"));
+ fetch_data.AddExtension(id, version,
+ ManifestFetchData::kNeverPinged, "bar");
+ EXPECT_EQ("http://localhost/foo\?x=id%3Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "%26v%3D1.0%26uc%26ap%3Dbar",
+ fetch_data.full_url().spec());
+ }
+
+ static void TestUpdateUrlDataCompound() {
+ const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ const std::string version = "1.0";
+
+ // Make sure that an update URL data string causes an appropriate ap=
+ // option to appear in the x= parameter.
+ ManifestFetchData fetch_data(GURL("http://localhost/foo"));
+ fetch_data.AddExtension(id, version,
+ ManifestFetchData::kNeverPinged, "a=1&b=2&c");
+ EXPECT_EQ("http://localhost/foo\?x=id%3Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "%26v%3D1.0%26uc%26ap%3Da%253D1%2526b%253D2%2526c",
+ fetch_data.full_url().spec());
+ }
+
+ static void TestUpdateUrlDataFromGallery(const char* gallery_url) {
+ MockService service;
+ ManifestFetchesBuilder builder(&service);
+ ExtensionList extensions;
+ std::string url(gallery_url);
+
+ service.CreateTestExtensions(1, &extensions, &url, Extension::INTERNAL);
+ builder.AddExtension(*extensions[0]);
+ std::vector<ManifestFetchData*> fetches = builder.GetFetches();
+ EXPECT_EQ(1u, fetches.size());
+ scoped_ptr<ManifestFetchData> fetch(fetches[0]);
+ fetches.clear();
+
+ // Make sure that extensions that update from the gallery ignore any
+ // update URL data.
+ const std::string& update_url = fetch->full_url().spec();
+ std::string::size_type x = update_url.find("x=");
+ EXPECT_NE(std::string::npos, x);
+ std::string::size_type ap = update_url.find("ap%3D", x);
+ EXPECT_EQ(std::string::npos, ap);
+ }
+
static void TestDetermineUpdates() {
// Create a set of test extensions
ServiceForManifestTests service;
@@ -428,11 +498,13 @@ class ExtensionUpdaterTest : public testing::Test {
scoped_ptr<Version> one(Version::GetVersionFromString("1.0"));
EXPECT_TRUE(tmp[0]->version()->Equals(*one));
fetch_data.AddExtension(tmp[0]->id(), tmp[0]->VersionString(),
- ManifestFetchData::kNeverPinged);
+ ManifestFetchData::kNeverPinged,
+ kEmptyUpdateUrlData);
AddParseResult(tmp[0]->id(),
"1.1", "http://localhost/e1_1.1.crx", &updates);
fetch_data.AddExtension(tmp[1]->id(), tmp[1]->VersionString(),
- ManifestFetchData::kNeverPinged);
+ ManifestFetchData::kNeverPinged,
+ kEmptyUpdateUrlData);
AddParseResult(tmp[1]->id(),
tmp[1]->VersionString(), "http://localhost/e2_2.0.crx", &updates);
updateable = updater->DetermineUpdates(fetch_data, updates);
@@ -458,7 +530,8 @@ class ExtensionUpdaterTest : public testing::Test {
for (PendingExtensionMap::const_iterator it = pending_extensions.begin();
it != pending_extensions.end(); ++it) {
fetch_data.AddExtension(it->first, "1.0.0.0",
- ManifestFetchData::kNeverPinged);
+ ManifestFetchData::kNeverPinged,
+ kEmptyUpdateUrlData);
AddParseResult(it->first,
"1.1", "http://localhost/e1_1.1.crx", &updates);
}
@@ -495,8 +568,9 @@ class ExtensionUpdaterTest : public testing::Test {
// second one should be queued up.
ManifestFetchData* fetch1 = new ManifestFetchData(url1);
ManifestFetchData* fetch2 = new ManifestFetchData(url2);
- fetch1->AddExtension("1111", "1.0", 0);
- fetch2->AddExtension("12345", "2.0", ManifestFetchData::kNeverPinged);
+ fetch1->AddExtension("1111", "1.0", 0, kEmptyUpdateUrlData);
+ fetch2->AddExtension("12345", "2.0", ManifestFetchData::kNeverPinged,
+ kEmptyUpdateUrlData);
updater->StartUpdateCheck(fetch1);
updater->StartUpdateCheck(fetch2);
@@ -814,7 +888,8 @@ class ExtensionUpdaterTest : public testing::Test {
ManifestFetchData fetch_data(update_url);
const Extension* extension = tmp[0];
fetch_data.AddExtension(extension->id(), extension->VersionString(),
- ManifestFetchData::kNeverPinged);
+ ManifestFetchData::kNeverPinged,
+ kEmptyUpdateUrlData);
UpdateManifest::Results results;
results.daystart_elapsed_seconds = 750;
@@ -844,6 +919,16 @@ TEST(ExtensionUpdaterTest, TestBlacklistUpdateCheckRequests) {
ExtensionUpdaterTest::TestBlacklistUpdateCheckRequests();
}
+TEST(ExtensionUpdaterTest, TestUpdateUrlData) {
+ ExtensionUpdaterTest::TestUpdateUrlDataEmpty();
+ ExtensionUpdaterTest::TestUpdateUrlDataSimple();
+ ExtensionUpdaterTest::TestUpdateUrlDataCompound();
+ ExtensionUpdaterTest::TestUpdateUrlDataFromGallery(
+ extension_urls::kGalleryUpdateHttpUrl);
+ ExtensionUpdaterTest::TestUpdateUrlDataFromGallery(
+ extension_urls::kGalleryUpdateHttpsUrl);
+}
+
TEST(ExtensionUpdaterTest, TestDetermineUpdates) {
ExtensionUpdaterTest::TestDetermineUpdates();
}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 6710a08..0cdca9a 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1539,6 +1539,8 @@
'browser/extensions/extension_message_service.h',
'browser/extensions/extension_metrics_module.cc',
'browser/extensions/extension_metrics_module.h',
+ 'browser/extensions/extension_module.cc',
+ 'browser/extensions/extension_module.h',
'browser/extensions/extension_omnibox_api.cc',
'browser/extensions/extension_omnibox_api.h',
'browser/extensions/extension_page_actions_module.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 148f254..1782ed1 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1998,6 +1998,7 @@
'browser/extensions/extension_messages_apitest.cc',
'browser/extensions/extension_messages_browsertest.cc',
'browser/extensions/extension_metrics_apitest.cc',
+ 'browser/extensions/extension_module_apitest.cc',
'browser/extensions/extension_omnibox_apitest.cc',
'browser/extensions/extension_override_apitest.cc',
'browser/extensions/extension_popup_apitest.cc',
diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json
index 68c9af0..ebc43a0f 100644
--- a/chrome/common/extensions/api/extension_api.json
+++ b/chrome/common/extensions/api/extension_api.json
@@ -188,6 +188,14 @@
"description": "Array of global window objects",
"items": { "type": "object", "isInstanceOf": "DOMWindow", "properties": {}, "additionalProperties": { "type": "any" } }
}
+ },
+ {
+ "name": "setUpdateUrlData",
+ "type": "function",
+ "description": "Sets the value of the ap CGI parameter used in the extension's update URL. This value is ignored for extensions that are hosted in the Chrome Extension Gallery.",
+ "parameters": [
+ {"type": "string", "name": "data", "maxLength": 1024}
+ ]
}
],
"events": [
diff --git a/chrome/common/extensions/docs/extension.html b/chrome/common/extensions/docs/extension.html
index 3f7dac6..7d301ac 100644
--- a/chrome/common/extensions/docs/extension.html
+++ b/chrome/common/extensions/docs/extension.html
@@ -284,6 +284,8 @@
<a href="#method-getViews">getViews</a>
</li><li>
<a href="#method-sendRequest">sendRequest</a>
+ </li><li>
+ <a href="#method-setUpdateUrlData">setUpdateUrlData</a>
</li>
</ol>
</li>
@@ -2008,6 +2010,127 @@ For details, see
</p>
</div> <!-- /description -->
+ </div><div class="apiItem">
+ <a name="method-setUpdateUrlData"></a> <!-- method-anchor -->
+ <h4>setUpdateUrlData</h4>
+
+ <div class="summary"><span style="display: none; ">void</span>
+ <!-- Note: intentionally longer 80 columns -->
+ <span>chrome.extension.setUpdateUrlData</span>(<span class="null"><span style="display: none; ">, </span><span>string</span>
+ <var><span>data</span></var></span>)</div>
+
+ <div class="description">
+ <p class="todo" style="display: none; ">Undocumented.</p>
+ <p>Sets the value of the ap CGI parameter used in the extension's update URL. This value is ignored for extensions that are hosted in the Chrome Extension Gallery.</p>
+
+ <!-- PARAMETERS -->
+ <h4>Parameters</h4>
+ <dl>
+ <div>
+ <div>
+ <dt>
+ <var>data</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional" style="display: none; ">optional</span>
+ <span class="enum" style="display: none; ">enumerated</span>
+ <span id="typeTemplate">
+ <span style="display: none; ">
+ <a> Type</a>
+ </span>
+ <span>
+ <span style="display: none; ">
+ array of <span><span></span></span>
+ </span>
+ <span>string</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo">
+ Undocumented.
+ </dd>
+ <dd style="display: none; ">
+ Description of this parameter from the json schema.
+ </dd>
+ <dd style="display: none; ">
+ This parameter was added in version
+ <b><span></span></b>.
+ You must omit this parameter in earlier versions,
+ and you may omit it in any version. If you require this
+ parameter, the manifest key
+ <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
+ can ensure that your extension won't be run in an earlier browser version.
+ </dd>
+
+ <!-- OBJECT PROPERTIES -->
+ <dd style="display: none; ">
+ <dl>
+ <div>
+ <div>
+ </div>
+ </div>
+ </dl>
+ </dd>
+
+ <!-- FUNCTION PARAMETERS -->
+ <dd style="display: none; ">
+ <div></div>
+ </dd>
+
+ </div>
+ </div>
+ </dl>
+
+ <!-- RETURNS -->
+ <h4 style="display: none; ">Returns</h4>
+ <dl>
+ <div style="display: none; ">
+ <div>
+ </div>
+ </div>
+ </dl>
+
+ <!-- CALLBACK -->
+ <div style="display: none; ">
+ <div>
+ <h4>Callback function</h4>
+ <p>
+ The callback <em>parameter</em> should specify a function
+ that looks like this:
+ </p>
+ <p>
+ If you specify the <em>callback</em> parameter, it should
+ specify a function that looks like this:
+ </p>
+
+ <!-- Note: intentionally longer 80 columns -->
+ <pre>function(<span>Type param1, Type param2</span>) <span class="subdued">{...}</span>;</pre>
+ <dl>
+ <div>
+ <div>
+ </div>
+ </div>
+ </dl>
+ </div>
+ </div>
+
+ <!-- MIN_VERSION -->
+ <p style="display: none; ">
+ This function was added in version <b><span></span></b>.
+ If you require this function, the manifest key
+ <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
+ can ensure that your extension won't be run in an earlier browser version.
+ </p>
+ </div> <!-- /description -->
+
</div> <!-- /apiItem -->
</div> <!-- /apiGroup -->
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index 8b9c39f..41c260e 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -1854,8 +1854,7 @@ GURL Extension::GetHomepageURL() const {
if (homepage_url_.is_valid())
return homepage_url_;
- if (update_url()!= GURL(extension_urls::kGalleryUpdateHttpsUrl) &&
- update_url()!= GURL(extension_urls::kGalleryUpdateHttpUrl))
+ if (!UpdatesFromGallery())
return GURL();
// TODO(erikkay): This may not be entirely correct with the webstore.
@@ -2193,6 +2192,11 @@ bool Extension::CanExecuteScriptEverywhere() const {
return false;
}
+bool Extension::UpdatesFromGallery() const {
+ return update_url() == GURL(extension_urls::kGalleryUpdateHttpsUrl) ||
+ update_url() == GURL(extension_urls::kGalleryUpdateHttpUrl);
+}
+
ExtensionInfo::ExtensionInfo(const DictionaryValue* manifest,
const std::string& id,
const FilePath& path,
diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h
index ce7e628..6c545e73 100644
--- a/chrome/common/extensions/extension.h
+++ b/chrome/common/extensions/extension.h
@@ -356,6 +356,10 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// on the whitelist of extensions that can script all pages.
bool CanExecuteScriptEverywhere() const;
+ // Returns true if this extension updates itself using the extension
+ // gallery.
+ bool UpdatesFromGallery() const;
+
// Accessors:
const FilePath& path() const { return path_; }
diff --git a/chrome/renderer/resources/renderer_extension_bindings.js b/chrome/renderer/resources/renderer_extension_bindings.js
index c470947..c583ca0 100644
--- a/chrome/renderer/resources/renderer_extension_bindings.js
+++ b/chrome/renderer/resources/renderer_extension_bindings.js
@@ -113,7 +113,7 @@ var chrome = chrome || {};
// Update the renderer's port bookkeeping, without notifying the browser.
CloseChannel(portId, false);
if (connectionInvalid) {
- var errorMsg =
+ var errorMsg =
"Could not establish connection. Receiving end does not exist.";
chrome.extension.lastError = {"message": errorMsg};
console.error("Port error: " + errorMsg);
@@ -302,6 +302,7 @@ var chrome = chrome || {};
"extension.lastError",
"extension.onConnectExternal",
"extension.onRequestExternal",
+ "extension.setUpdateUrlData",
"i18n.getAcceptLanguages"
];
for (var i = 0; i < privileged.length; i++) {
diff --git a/chrome/test/data/extensions/api_test/extension_module/manifest.json b/chrome/test/data/extensions/api_test/extension_module/manifest.json
new file mode 100644
index 0000000..4b3caa8
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/extension_module/manifest.json
@@ -0,0 +1,6 @@
+{
+ "name": "chrome.extension",
+ "version": "0.1",
+ "description": "end-to-end browser test for some chrome.extension API",
+ "background_page": "test.html"
+}
diff --git a/chrome/test/data/extensions/api_test/extension_module/test.html b/chrome/test/data/extensions/api_test/extension_module/test.html
new file mode 100644
index 0000000..46f4d74
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/extension_module/test.html
@@ -0,0 +1 @@
+<script src="test.js"></script>
diff --git a/chrome/test/data/extensions/api_test/extension_module/test.js b/chrome/test/data/extensions/api_test/extension_module/test.js
new file mode 100644
index 0000000..762ba45
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/extension_module/test.js
@@ -0,0 +1,43 @@
+// Copyright (c) 2010 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.
+
+// extension api test
+// browser_tests.exe --gtest_filter=ExtensionModuleApiTest.Basics
+
+chrome.test.runTests([
+ function testUpdateUrlData() {
+ // Data string must not be too long.
+ try {
+ var data =
+ '01234567890123456789012345678901234567890123456789' +
+ '01234567890123456789012345678901234567890123456789' + // 100
+ '01234567890123456789012345678901234567890123456789' +
+ '01234567890123456789012345678901234567890123456789' + // 200
+ '01234567890123456789012345678901234567890123456789' +
+ '01234567890123456789012345678901234567890123456789' + // 300
+ '01234567890123456789012345678901234567890123456789' +
+ '01234567890123456789012345678901234567890123456789' + // 400
+ '01234567890123456789012345678901234567890123456789' +
+ '01234567890123456789012345678901234567890123456789' + // 500
+ '01234567890123456789012345678901234567890123456789' +
+ '01234567890123456789012345678901234567890123456789' + // 600
+ '01234567890123456789012345678901234567890123456789' +
+ '01234567890123456789012345678901234567890123456789' + // 700
+ '01234567890123456789012345678901234567890123456789' +
+ '01234567890123456789012345678901234567890123456789' + // 800
+ '01234567890123456789012345678901234567890123456789' +
+ '01234567890123456789012345678901234567890123456789' + // 900
+ '01234567890123456789012345678901234567890123456789' +
+ '01234567890123456789012345678901234567890123456789' + // 1000
+ '01234567890123456789012345678901234567890123456789';
+ chrome.extension.setUpdateUrlData(data);
+ // Should not reach this line since the above call throws.
+ chrome.test.fail();
+ } catch(ex) {
+ }
+
+ chrome.extension.setUpdateUrlData('a=1&b=2&foo');
+ chrome.test.succeed();
+ }
+]);