summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/extensions')
-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
10 files changed, 213 insertions, 20 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();
}