summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-02 07:52:33 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-02 07:52:33 +0000
commit7713d63d41fad819b4031c2f30422489469ead95 (patch)
tree21bc0fe37980b49e1a2b03ca6726b695bd587f91 /chrome
parent527c739c43984bc49da5d0de4989e1d81d4a74d5 (diff)
downloadchromium_src-7713d63d41fad819b4031c2f30422489469ead95.zip
chromium_src-7713d63d41fad819b4031c2f30422489469ead95.tar.gz
chromium_src-7713d63d41fad819b4031c2f30422489469ead95.tar.bz2
Introduce Extension class that can serializer and deserialize from Value
instances. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6211 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser.scons1
-rw-r--r--chrome/browser/browser.vcproj12
-rw-r--r--chrome/browser/extensions/extension.cc115
-rw-r--r--chrome/browser/extensions/extension.h71
-rw-r--r--chrome/browser/extensions/extension_unittest.cc88
-rw-r--r--chrome/test/unit/unit_tests.scons1
-rw-r--r--chrome/test/unit/unittests.vcproj8
7 files changed, 296 insertions, 0 deletions
diff --git a/chrome/browser/browser.scons b/chrome/browser/browser.scons
index 1d56bdf..aeb213b 100644
--- a/chrome/browser/browser.scons
+++ b/chrome/browser/browser.scons
@@ -58,6 +58,7 @@ if env['PLATFORM'] in ('posix', 'win32'):
'chrome_thread.cc',
'cross_site_request_manager.cc',
'download/save_file.cc',
+ 'extensions/extension.cc',
'google_url_tracker.cc',
'google_util.cc',
'history/archived_database.cc',
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index 7d79e5d..9cb07f5 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -2154,6 +2154,18 @@
>
</File>
</Filter>
+ <Filter
+ Name="extensions"
+ >
+ <File
+ RelativePath=".\extensions\extension.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\extensions\extension.h"
+ >
+ </File>
+ </Filter>
<File
RelativePath=".\browser_trial.cc"
>
diff --git a/chrome/browser/extensions/extension.cc b/chrome/browser/extensions/extension.cc
new file mode 100644
index 0000000..d4fbe9f
--- /dev/null
+++ b/chrome/browser/extensions/extension.cc
@@ -0,0 +1,115 @@
+// Copyright (c) 2006-2008 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.h"
+
+#include "base/logging.h"
+#include "base/string_util.h"
+
+const std::wstring Extension::kFormatVersionKey(L"format_version");
+const std::wstring Extension::kIdKey(L"id");
+const std::wstring Extension::kNameKey(L"name");
+const std::wstring Extension::kDescriptionKey(L"description");
+const std::wstring Extension::kContentScriptsKey(L"content_scripts");
+
+const std::wstring Extension::kInvalidFormatVersionError(
+ StringPrintf(L"Required key '%ls' is missing or invalid",
+ kFormatVersionKey.c_str()));
+const std::wstring Extension::kInvalidIdError(
+ StringPrintf(L"Required key '%ls' is missing or invalid.",
+ kIdKey.c_str()));
+const std::wstring Extension::kInvalidNameError(
+ StringPrintf(L"Required key '%ls' is missing or has invalid type.",
+ kNameKey.c_str()));
+const std::wstring Extension::kInvalidDescriptionError(
+ StringPrintf(L"Invalid type for '%ls' key.",
+ kDescriptionKey.c_str()));
+const std::wstring Extension::kInvalidContentScriptsListError(
+ StringPrintf(L"Invalid type for '%ls' key.",
+ kContentScriptsKey.c_str()));
+const std::wstring Extension::kInvalidContentScriptError(
+ StringPrintf(L"Invalid type for %ls at index ",
+ kContentScriptsKey.c_str()));
+
+bool Extension::InitFromValue(const DictionaryValue& source,
+ std::wstring* error) {
+ // Check format version.
+ int format_version = 0;
+ if (!source.GetInteger(kFormatVersionKey, &format_version) ||
+ format_version != kExpectedFormatVersion) {
+ *error = kInvalidFormatVersionError;
+ return false;
+ }
+
+ // Initialize id.
+ if (!source.GetString(kIdKey, &id_)) {
+ *error = kInvalidIdError;
+ return false;
+ }
+
+ // Initialize name.
+ if (!source.GetString(kNameKey, &name_)) {
+ *error = kInvalidNameError;
+ return false;
+ }
+
+ // Initialize description (optional).
+ Value* value = NULL;
+ if (source.Get(kDescriptionKey, &value)) {
+ if (!value->GetAsString(&description_)) {
+ *error = kInvalidDescriptionError;
+ return false;
+ }
+ }
+
+ // Initialize content scripts (optional).
+ if (source.Get(kContentScriptsKey, &value)) {
+ ListValue* list_value = NULL;
+ if (value->GetType() != Value::TYPE_LIST) {
+ *error = kInvalidContentScriptsListError;
+ return false;
+ } else {
+ list_value = static_cast<ListValue*>(value);
+ }
+
+ for (size_t i = 0; i < list_value->GetSize(); ++i) {
+ std::wstring content_script;
+ if (!list_value->Get(i, &value) || !value->GetAsString(&content_script)) {
+ *error = kInvalidContentScriptError;
+ *error += IntToWString(i);
+ return false;
+ }
+
+ content_scripts_.push_back(content_script);
+ }
+ }
+
+ return true;
+}
+
+void Extension::CopyToValue(DictionaryValue* destination) {
+ // Set format version
+ destination->SetInteger(kFormatVersionKey,
+ kExpectedFormatVersion);
+
+ // Copy id.
+ destination->SetString(kIdKey, id_);
+
+ // Copy name.
+ destination->SetString(kNameKey, name_);
+
+ // Copy description (optional).
+ if (description_.size() > 0)
+ destination->SetString(kDescriptionKey, description_);
+
+ // Copy content scripts (optional).
+ if (content_scripts_.size() > 0) {
+ ListValue* list_value = new ListValue();
+ destination->Set(kContentScriptsKey, list_value);
+
+ for (size_t i = 0; i < content_scripts_.size(); ++i) {
+ list_value->Set(i, Value::CreateStringValue(content_scripts_[i]));
+ }
+ }
+}
diff --git a/chrome/browser/extensions/extension.h b/chrome/browser/extensions/extension.h
new file mode 100644
index 0000000..16260e0
--- /dev/null
+++ b/chrome/browser/extensions/extension.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2006-2008 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_H__
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_H__
+
+#include <string>
+#include <vector>
+
+#include "base/string16.h"
+#include "base/values.h"
+
+// Represents a Chromium extension.
+class Extension {
+ public:
+ Extension(){};
+
+ // The format for extension manifests that this code understands.
+ static const int kExpectedFormatVersion = 1;
+
+ // Keys used in JSON representation of extensions.
+ static const std::wstring kFormatVersionKey;
+ static const std::wstring kIdKey;
+ static const std::wstring kNameKey;
+ static const std::wstring kDescriptionKey;
+ static const std::wstring kContentScriptsKey;
+
+ // Error messages returned from InitFromValue().
+ static const std::wstring kInvalidFormatVersionError;
+ static const std::wstring kInvalidIdError;
+ static const std::wstring kInvalidNameError;
+ static const std::wstring kInvalidDescriptionError;
+ static const std::wstring kInvalidContentScriptsListError;
+ static const std::wstring kInvalidContentScriptError;
+
+ // A human-readable ID for the extension. The convention is to use something
+ // like 'com.example.myextension', but this is not currently enforced. An
+ // extension's ID is used in things like directory structures and URLs, and
+ // is expected to not change across versions. In the case of conflicts,
+ // updates will only be allowed if the extension can be validated using the
+ // previous version's update key.
+ const std::wstring& id() const { return id_; }
+
+ // A human-readable name of the extension.
+ const std::wstring& name() const { return name_; }
+
+ // An optional longer description of the extension.
+ const std::wstring& description() const { return description_; }
+
+ // Paths to the content scripts that the extension contains.
+ const std::vector<std::wstring>& content_scripts() const {
+ return content_scripts_;
+ }
+
+ // Initialize the extension from a parsed manifest.
+ bool InitFromValue(const DictionaryValue& value, std::wstring* error);
+
+ // Serialize the extension to a DictionaryValue.
+ void CopyToValue(DictionaryValue* value);
+
+ private:
+ std::wstring id_;
+ std::wstring name_;
+ std::wstring description_;
+ std::vector<std::wstring> content_scripts_;
+
+ DISALLOW_COPY_AND_ASSIGN(Extension);
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_H__
diff --git a/chrome/browser/extensions/extension_unittest.cc b/chrome/browser/extensions/extension_unittest.cc
new file mode 100644
index 0000000..2377dae
--- /dev/null
+++ b/chrome/browser/extensions/extension_unittest.cc
@@ -0,0 +1,88 @@
+// Copyright (c) 2006-2008 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 "base/string_util.h"
+#include "chrome/browser/extensions/extension.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class ExtensionTest : public testing::Test {
+};
+
+TEST(ExtensionTest, InitFromValueInvalid) {
+ Extension extension;
+ std::wstring error;
+
+ // Test invalid format version
+ DictionaryValue input_value;
+ input_value.SetInteger(Extension::kFormatVersionKey, 2);
+ EXPECT_FALSE(extension.InitFromValue(input_value, &error));
+ EXPECT_EQ(Extension::kInvalidFormatVersionError, error);
+ input_value.SetInteger(Extension::kFormatVersionKey, 1);
+
+ // Test missing and invalid ids
+ EXPECT_FALSE(extension.InitFromValue(input_value, &error));
+ EXPECT_EQ(Extension::kInvalidIdError, error);
+ input_value.SetInteger(Extension::kIdKey, 42);
+ EXPECT_FALSE(extension.InitFromValue(input_value, &error));
+ EXPECT_EQ(Extension::kInvalidIdError, error);
+ input_value.SetString(Extension::kIdKey, L"com.google.myextension");
+
+ // Test missing and invalid names
+ EXPECT_FALSE(extension.InitFromValue(input_value, &error));
+ EXPECT_EQ(Extension::kInvalidNameError, error);
+ input_value.SetInteger(Extension::kNameKey, 42);
+ EXPECT_FALSE(extension.InitFromValue(input_value, &error));
+ EXPECT_EQ(Extension::kInvalidNameError, error);
+ input_value.SetString(Extension::kNameKey, L"my extension");
+
+ // Test invalid description
+ input_value.SetInteger(Extension::kDescriptionKey, 42);
+ EXPECT_FALSE(extension.InitFromValue(input_value, &error));
+ EXPECT_EQ(Extension::kInvalidDescriptionError, error);
+ input_value.Remove(Extension::kDescriptionKey, NULL);
+
+ // Test invalid content scripts list
+ input_value.SetInteger(Extension::kContentScriptsKey, 42);
+ EXPECT_FALSE(extension.InitFromValue(input_value, &error));
+ EXPECT_EQ(Extension::kInvalidContentScriptsListError, error);
+
+ // Test invalid content script item
+ ListValue* content_scripts = new ListValue;
+ input_value.Set(Extension::kContentScriptsKey, content_scripts);
+ content_scripts->Set(0, Value::CreateIntegerValue(42));
+ EXPECT_FALSE(extension.InitFromValue(input_value, &error));
+ EXPECT_EQ(0u, error.find(Extension::kInvalidContentScriptError));
+}
+
+TEST(ExtensionTest, InitFromValueValid) {
+ Extension extension;
+ std::wstring error;
+ DictionaryValue input_value;
+ DictionaryValue output_value;
+
+ // Test minimal extension
+ input_value.SetInteger(Extension::kFormatVersionKey, 1);
+ input_value.SetString(Extension::kIdKey, L"com.google.myextension");
+ input_value.SetString(Extension::kNameKey, L"my extension");
+
+ EXPECT_TRUE(extension.InitFromValue(input_value, &error));
+ extension.CopyToValue(&output_value);
+ EXPECT_TRUE(input_value.Equals(&output_value));
+
+ // Test with a description
+ input_value.SetString(Extension::kDescriptionKey,
+ L"my extension does things");
+ EXPECT_TRUE(extension.InitFromValue(input_value, &error));
+ extension.CopyToValue(&output_value);
+ EXPECT_TRUE(input_value.Equals(&output_value));
+
+ // Test content_scripts
+ ListValue* content_scripts = new ListValue();
+ input_value.Set(Extension::kContentScriptsKey, content_scripts);
+ content_scripts->Set(0, Value::CreateStringValue(L"foo/bar.js"));
+ content_scripts->Set(1, Value::CreateStringValue(L"hot/dog.js"));
+ EXPECT_TRUE(extension.InitFromValue(input_value, &error));
+ extension.CopyToValue(&output_value);
+ EXPECT_TRUE(input_value.Equals(&output_value));
+}
diff --git a/chrome/test/unit/unit_tests.scons b/chrome/test/unit/unit_tests.scons
index c90a0be..320dc09 100644
--- a/chrome/test/unit/unit_tests.scons
+++ b/chrome/test/unit/unit_tests.scons
@@ -115,6 +115,7 @@ if env['PLATFORM'] in ('posix', 'win32'):
'run_all_unittests.cc',
'$CHROME_DIR/browser/chrome_thread_unittest.cc',
+ '$CHROME_DIR/browser/extensions/extension_unittest.cc',
'$CHROME_DIR/browser/history/history_types_unittest.cc',
'$CHROME_DIR/browser/history/snippet_unittest.cc',
'$CHROME_DIR/browser/history/text_database_unittest.cc',
diff --git a/chrome/test/unit/unittests.vcproj b/chrome/test/unit/unittests.vcproj
index 17b9dc29..e05354a 100644
--- a/chrome/test/unit/unittests.vcproj
+++ b/chrome/test/unit/unittests.vcproj
@@ -1026,6 +1026,14 @@
>
</File>
</Filter>
+ <Filter
+ Name="TestExtension"
+ >
+ <File
+ RelativePath="..\..\browser\extensions\extension_unittest.cc"
+ >
+ </File>
+ </Filter>
</Files>
<Globals>
</Globals>