summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/api
diff options
context:
space:
mode:
authorbeaudoin@chromium.org <beaudoin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-17 21:12:40 +0000
committerbeaudoin@chromium.org <beaudoin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-17 21:12:40 +0000
commitc311db8f32a10726568a978f279e1e2d86cf9fd6 (patch)
tree25e5ed8af663e64aa1090b0a14ec7183570613a6 /chrome/browser/extensions/api
parentbebfb2ed2025f1e0f99dbcf3aa9af48cc6e8ac0f (diff)
downloadchromium_src-c311db8f32a10726568a978f279e1e2d86cf9fd6.zip
chromium_src-c311db8f32a10726568a978f279e1e2d86cf9fd6.tar.gz
chromium_src-c311db8f32a10726568a978f279e1e2d86cf9fd6.tar.bz2
Scaffolding for an experimental discovery API letting users inject links in the recommended pane of the New Tab Page.
Documentation changes can be seen at: http://www.corp.google.com/~beaudoin/no_crawl/docs/experimental.discovery.html The following files don't have to be reviewed as they are generated by build.py: chrome/common/extensions/docs/experimental.discovery.html chrome/common/extensions/docs/experimental.html chrome/common/extensions/docs/samples.json BUG=none TEST=none Review URL: https://chromiumcodereview.appspot.com/10391034 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137735 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions/api')
-rw-r--r--chrome/browser/extensions/api/README.txt100
-rw-r--r--chrome/browser/extensions/api/app/app_api.cc1
-rw-r--r--chrome/browser/extensions/api/discovery/discovery_api.cc67
-rw-r--r--chrome/browser/extensions/api/discovery/discovery_api.h42
-rw-r--r--chrome/browser/extensions/api/discovery/suggested_link.cc18
-rw-r--r--chrome/browser/extensions/api/discovery/suggested_link.h43
-rw-r--r--chrome/browser/extensions/api/discovery/suggested_links_registry.cc64
-rw-r--r--chrome/browser/extensions/api/discovery/suggested_links_registry.h56
-rw-r--r--chrome/browser/extensions/api/discovery/suggested_links_registry_factory.cc47
-rw-r--r--chrome/browser/extensions/api/discovery/suggested_links_registry_factory.h42
10 files changed, 480 insertions, 0 deletions
diff --git a/chrome/browser/extensions/api/README.txt b/chrome/browser/extensions/api/README.txt
new file mode 100644
index 0000000..f15e243
--- /dev/null
+++ b/chrome/browser/extensions/api/README.txt
@@ -0,0 +1,100 @@
+This file describes steps and files needed when adding a new API to Chrome.
+Before you start coding your new API, though, make sure you follow the process
+described at:
+ http://www.chromium.org/developers/design-documents/extensions/proposed-changes/apis-under-development
+
+Two approaches are available for writing your API specification. The original
+approach relies on JSON specification files. The more recent and simpler system
+uses Web IDL files, but does not yet support all the features of the JSON files.
+Discuss with a member of the extensions team (aa@chromium.org) before you decide
+which approach is better suited to your API.
+
+The following steps suppose you're writing an experimental API called "Foo".
+
+--------------------------------------------------------------------------------
+APPROACH 1: JSON FILES
+
+1) Write your API specification.
+Create "chrome/common/extensions/api/experimental_foo.json". For inspiration
+look at the "app" API. Include descriptions fields to generate the
+documentation.
+
+2) Add your API specification to the project.
+Add an "<include ...>" line with your JSON specification file to
+"chrome/common/extensions_api_resources.grd".
+
+3) Write the API function handlers.
+Create foo_api.cc and foo_api.h under "chrome/browser/extensions/api/foo". You
+should use the JSON Schema Compiler. Look at the "alarms_api.cc" for details on
+how to do that.
+
+4) Register function handlers.
+In "chrome/browser/extensions/extension_function_registry.cc" include foo_api.h
+and instantiate a RegisterFunction for each function you created in (3).
+
+--------------------------------------------------------------------------------
+APPROACH 2: IDL FILES
+
+1) Write your API specification.
+Create "chrome/common/extensions/api/experimental_foo.idl". For inspiration look
+at "alarms.idl". Include comments, they will be used to automatically generate
+the documentation.
+
+2) Add your API specification to the project.
+Add "experimental_foo.idl" to the "idl_schema_files" section in
+"chrome/common/extensions/api/api.gyp".
+
+3) Write the API function handlers.
+Create foo_api.cc and foo_api.h under "chrome/browser/extensions/api/foo". You
+should use the JSON Schema Compiler. Look at the "alarms_api.cc" for details on
+how to do that.
+
+4) Nothing to do! Function handlers are automatically registered for you.
+
+--------------------------------------------------------------------------------
+STEPS COMMON TO BOTH APPROACHES
+
+5) Write support classes for your API
+If your API needs any support classes add them to
+"chrome/browser/extensions/api/foo". Some old APIs added their support classes
+directly to chrome/browser/extensions. Don't do that.
+
+6) Update the project with your new files.
+The files you created in (3) and (5) should be added to
+"chrome/chrome_browser_extensions.gypi".
+
+--------------------------------------------------------------------------------
+GENERATING DOCUMENTATION
+
+7) Build the project. (Only required if you used IDL files.)
+If you used IDL files, you need to build the project once in order for the
+documentation to be properly generated. Do this now. (This is required in order
+to generate the JSON file used to generate documentation.)
+
+8) Add your JSON file to the documentation controller
+Open "chrome/common/extensions/docs/js/api_page_generator.js" and add a line
+referring to "../api/experimental_foo.json". Do this even if you used the IDL
+approach as this JSON file has been generated in (7).
+
+9) Write the static HTML page.
+Write a small snippet of static HTML describing your API in
+"chrome/common/extensions/docs/static/experimental.foo.html". For the moment,
+just include the following in this file, adjusting it to describe your API:
+
+ <div id="pageData-name" class="pageData">Experimental Foo APIs</div>
+
+ <!-- BEGIN AUTHORED CONTENT -->
+ <p>The current methods allow applications to...</p>
+ <!-- END AUTHORED CONTENT -->
+
+10) Build the documentation.
+You will need to build DumpRenderTree once before you can build the
+documentation. Once this is done, from "chrome/common/extensions/docs" run
+"build/build.py". For more information on building documentation see README.txt
+in "chrome/common/extensions/docs".
+
+--------------------------------------------------------------------------------
+WRITING TESTS
+
+TODO(beaudoin)
+
diff --git a/chrome/browser/extensions/api/app/app_api.cc b/chrome/browser/extensions/api/app/app_api.cc
index d429710..14c9ece 100644
--- a/chrome/browser/extensions/api/app/app_api.cc
+++ b/chrome/browser/extensions/api/app/app_api.cc
@@ -86,6 +86,7 @@ bool AppNotifyFunction::RunImpl() {
AppNotificationManager* manager =
profile()->GetExtensionService()->app_notification_manager();
+ // TODO(beaudoin) We should probably report an error if Add returns false.
manager->Add(item.release());
return true;
diff --git a/chrome/browser/extensions/api/discovery/discovery_api.cc b/chrome/browser/extensions/api/discovery/discovery_api.cc
new file mode 100644
index 0000000..4392f2a8
--- /dev/null
+++ b/chrome/browser/extensions/api/discovery/discovery_api.cc
@@ -0,0 +1,67 @@
+// 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/api/discovery/discovery_api.h"
+
+#include "base/values.h"
+#include "chrome/browser/extensions/api/discovery/suggested_link.h"
+#include "chrome/browser/extensions/api/discovery/suggested_links_registry.h"
+#include "chrome/browser/extensions/api/discovery/suggested_links_registry_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/extensions/api/experimental_discovery.h"
+#include "chrome/common/extensions/extension_error_utils.h"
+
+namespace discovery = extensions::api::experimental_discovery;
+
+namespace {
+const char kInvalidScore[] = "Invalid score, must be between 0 and 1.";
+} // namespace
+
+namespace extensions {
+
+bool DiscoverySuggestFunction::RunImpl() {
+ scoped_ptr<discovery::Suggest::Params> params(
+ discovery::Suggest::Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params.get());
+
+ double score = 1.0;
+ if (params->details.score != NULL) {
+ score = *params->details.score;
+ if (score < 0.0 || score > 1.0) {
+ error_ = kInvalidScore;
+ return false;
+ }
+ }
+
+ extensions::SuggestedLinksRegistry* registry =
+ extensions::SuggestedLinksRegistryFactory::GetForProfile(profile());
+ scoped_ptr<extensions::SuggestedLink> suggested_link(
+ new extensions::SuggestedLink(params->details.link_url,
+ params->details.link_text, score));
+ registry->Add(extension_id(), suggested_link.Pass());
+ return true;
+}
+
+bool DiscoveryRemoveSuggestionFunction::RunImpl() {
+ scoped_ptr<discovery::RemoveSuggestion::Params> params(
+ discovery::RemoveSuggestion::Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params.get());
+
+ extensions::SuggestedLinksRegistry* registry =
+ extensions::SuggestedLinksRegistryFactory::GetForProfile(profile());
+ registry->Remove(extension_id(), params->link_url);
+
+ return true;
+}
+
+bool DiscoveryClearAllSuggestionsFunction::RunImpl() {
+ extensions::SuggestedLinksRegistry* registry =
+ extensions::SuggestedLinksRegistryFactory::GetForProfile(profile());
+ registry->ClearAll(extension_id());
+
+ return true;
+}
+
+} // namespace extensions
+
diff --git a/chrome/browser/extensions/api/discovery/discovery_api.h b/chrome/browser/extensions/api/discovery/discovery_api.h
new file mode 100644
index 0000000..3828dca
--- /dev/null
+++ b/chrome/browser/extensions/api/discovery/discovery_api.h
@@ -0,0 +1,42 @@
+// 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_BROWSER_EXTENSIONS_API_DISCOVERY_DISCOVERY_API_H_
+#define CHROME_BROWSER_EXTENSIONS_API_DISCOVERY_DISCOVERY_API_H_
+#pragma once
+
+#include "chrome/browser/extensions/extension_function.h"
+
+namespace extensions {
+
+class DiscoverySuggestFunction : public SyncExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.discovery.suggest");
+
+ protected:
+ virtual ~DiscoverySuggestFunction() {}
+ virtual bool RunImpl() OVERRIDE;
+};
+
+class DiscoveryRemoveSuggestionFunction : public SyncExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.discovery.removeSuggestion");
+
+ protected:
+ virtual ~DiscoveryRemoveSuggestionFunction() {}
+ virtual bool RunImpl() OVERRIDE;
+};
+
+class DiscoveryClearAllSuggestionsFunction : public SyncExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.discovery.clearAllSuggestions");
+
+ protected:
+ virtual ~DiscoveryClearAllSuggestionsFunction() {}
+ virtual bool RunImpl() OVERRIDE;
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_DISCOVERY_DISCOVERY_API_H_
diff --git a/chrome/browser/extensions/api/discovery/suggested_link.cc b/chrome/browser/extensions/api/discovery/suggested_link.cc
new file mode 100644
index 0000000..4e4c88e
--- /dev/null
+++ b/chrome/browser/extensions/api/discovery/suggested_link.cc
@@ -0,0 +1,18 @@
+// 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/api/discovery/suggested_link.h"
+
+namespace extensions {
+
+SuggestedLink::SuggestedLink(const std::string& link_url,
+ const std::string& link_text,
+ double score)
+ : link_url_(link_url),
+ link_text_(link_text),
+ score_(score) {}
+
+SuggestedLink::~SuggestedLink() {}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/api/discovery/suggested_link.h b/chrome/browser/extensions/api/discovery/suggested_link.h
new file mode 100644
index 0000000..7b208f6
--- /dev/null
+++ b/chrome/browser/extensions/api/discovery/suggested_link.h
@@ -0,0 +1,43 @@
+// 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_BROWSER_EXTENSIONS_API_DISCOVERY_SUGGESTED_LINK_H_
+#define CHROME_BROWSER_EXTENSIONS_API_DISCOVERY_SUGGESTED_LINK_H_
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "base/memory/linked_ptr.h"
+
+namespace extensions {
+
+// ExtensionSuggestedLinks contains a list of scored links that the extension
+// wants to inject in the NTP's recommended pane.
+class SuggestedLink {
+ public:
+ SuggestedLink(const std::string& link_url_, const std::string& link_text_,
+ double score);
+ ~SuggestedLink();
+
+ const std::string& link_url() const { return link_url_; }
+ const std::string& link_text() const { return link_text_; }
+ double score() const { return score_; }
+
+ private:
+ std::string link_url_;
+ std::string link_text_;
+
+ // |score_| is a value between 0 and 1 indicating the relative importance of
+ // this suggested link. A link with score 1 is twice as likely to be presented
+ // than one with score 0.5. Use a score of 1 if no information is available on
+ // the relative importance of the links.
+ double score_;
+
+ DISALLOW_COPY_AND_ASSIGN(SuggestedLink);
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_DISCOVERY_SUGGESTED_LINK_H_
diff --git a/chrome/browser/extensions/api/discovery/suggested_links_registry.cc b/chrome/browser/extensions/api/discovery/suggested_links_registry.cc
new file mode 100644
index 0000000..7c7f5fe
--- /dev/null
+++ b/chrome/browser/extensions/api/discovery/suggested_links_registry.cc
@@ -0,0 +1,64 @@
+// 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/api/discovery/suggested_links_registry.h"
+
+namespace {
+
+typedef extensions::SuggestedLinksRegistry::SuggestedLinkList SuggestedLinkList;
+
+void RemoveLinkFromList(const std::string& link_url, SuggestedLinkList* list) {
+ SuggestedLinkList::iterator found = list->begin();
+ for (; found != list->end(); ++found)
+ if (link_url.compare((*found)->link_url()) == 0) break;
+ if (found != list->end())
+ list->erase(found);
+}
+
+} // namespace
+
+namespace extensions {
+
+SuggestedLinksRegistry::SuggestedLinksRegistry() {}
+
+SuggestedLinksRegistry::~SuggestedLinksRegistry() {
+}
+
+void SuggestedLinksRegistry::Add(const std::string& extension_id,
+ scoped_ptr<extensions::SuggestedLink> item) {
+ SuggestedLinkList& list = GetAllInternal(extension_id);
+ list.push_back(linked_ptr<extensions::SuggestedLink>(item.release()));
+}
+
+const SuggestedLinkList* SuggestedLinksRegistry::GetAll(
+ const std::string& extension_id) const {
+ SuggestedLinksMap::const_iterator found = suggested_links_.find(extension_id);
+ if (found != suggested_links_.end())
+ return &found->second;
+ return NULL;
+}
+
+void SuggestedLinksRegistry::Remove(const std::string& extension_id,
+ const std::string& link_url) {
+ SuggestedLinksMap::iterator found = suggested_links_.find(extension_id);
+ if (found != suggested_links_.end())
+ RemoveLinkFromList(link_url, &found->second);
+}
+
+void SuggestedLinksRegistry::ClearAll(const std::string& extension_id) {
+ SuggestedLinksMap::iterator found = suggested_links_.find(extension_id);
+ if (found != suggested_links_.end())
+ suggested_links_.erase(found);
+}
+
+SuggestedLinkList& SuggestedLinksRegistry::GetAllInternal(
+ const std::string& extension_id) {
+ // |insert| returns the element if it's already in the map.
+ SuggestedLinksMap::iterator found = suggested_links_.insert(
+ SuggestedLinksMap::value_type(extension_id, SuggestedLinkList())).first;
+ CHECK(found != suggested_links_.end());
+ return found->second;
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/api/discovery/suggested_links_registry.h b/chrome/browser/extensions/api/discovery/suggested_links_registry.h
new file mode 100644
index 0000000..df850d8
--- /dev/null
+++ b/chrome/browser/extensions/api/discovery/suggested_links_registry.h
@@ -0,0 +1,56 @@
+// 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_BROWSER_EXTENSIONS_API_DISCOVERY_SUGGESTED_LINKS_REGISTRY_H_
+#define CHROME_BROWSER_EXTENSIONS_API_DISCOVERY_SUGGESTED_LINKS_REGISTRY_H_
+#pragma once
+
+#include <map>
+
+#include "chrome/browser/extensions/api/discovery/suggested_link.h"
+#include "chrome/browser/profiles/profile_keyed_service.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace extensions {
+
+// This class keeps track of links suggested by an extension using the discovery
+// API.
+class SuggestedLinksRegistry : public ProfileKeyedService {
+ public:
+ // A list of ExtensionSuggestedLink's.
+ typedef std::vector<linked_ptr<extensions::SuggestedLink> > SuggestedLinkList;
+
+ SuggestedLinksRegistry();
+
+ // Adds a suggested link from |extension_id|. Takes ownership of |item| in all
+ // cases.
+ void Add(const std::string& extension_id,
+ scoped_ptr<extensions::SuggestedLink> item);
+
+ // Returns all the links suggested by |extension_id|.
+ const SuggestedLinkList* GetAll(const std::string& extension_id) const;
+
+ // Remove a specific link suggested by |extension_id|.
+ void Remove(const std::string& extension_id, const std::string& link_url);
+
+ // Clears all suggested links for |extension_id|.
+ void ClearAll(const std::string& extension_id);
+
+ private:
+ // Maps extension id to a list of notifications for that extension.
+ typedef std::map<std::string, SuggestedLinkList> SuggestedLinksMap;
+
+ virtual ~SuggestedLinksRegistry();
+
+ // Gets suggested links for a given extension id.
+ SuggestedLinkList& GetAllInternal(const std::string& extension_id);
+
+ SuggestedLinksMap suggested_links_;
+
+ DISALLOW_COPY_AND_ASSIGN(SuggestedLinksRegistry);
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_DISCOVERY_SUGGESTED_LINKS_REGISTRY_H_
diff --git a/chrome/browser/extensions/api/discovery/suggested_links_registry_factory.cc b/chrome/browser/extensions/api/discovery/suggested_links_registry_factory.cc
new file mode 100644
index 0000000..d21c36c
--- /dev/null
+++ b/chrome/browser/extensions/api/discovery/suggested_links_registry_factory.cc
@@ -0,0 +1,47 @@
+// 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/api/discovery/suggested_links_registry_factory.h"
+
+#include "chrome/browser/extensions/api/discovery/suggested_links_registry.h"
+#include "chrome/browser/extensions/extension_system_factory.h"
+#include "chrome/browser/profiles/profile_dependency_manager.h"
+
+namespace extensions {
+
+// static
+SuggestedLinksRegistry* SuggestedLinksRegistryFactory::GetForProfile(
+ Profile* profile) {
+ return static_cast<SuggestedLinksRegistry*>(
+ GetInstance()->GetServiceForProfile(profile, true));
+}
+
+// static
+SuggestedLinksRegistryFactory* SuggestedLinksRegistryFactory::GetInstance() {
+ return Singleton<SuggestedLinksRegistryFactory>::get();
+}
+
+bool SuggestedLinksRegistryFactory::ServiceIsCreatedWithProfile() {
+ return true;
+}
+
+SuggestedLinksRegistryFactory::SuggestedLinksRegistryFactory()
+ : ProfileKeyedServiceFactory("SuggestedLinksRegistry",
+ ProfileDependencyManager::GetInstance()) {
+ DependsOn(ExtensionSystemFactory::GetInstance());
+}
+
+SuggestedLinksRegistryFactory::~SuggestedLinksRegistryFactory() {
+}
+
+ProfileKeyedService* SuggestedLinksRegistryFactory::BuildServiceInstanceFor(
+ Profile* profile) const {
+ return new SuggestedLinksRegistry();
+}
+
+bool SuggestedLinksRegistryFactory::ServiceRedirectedInIncognito() {
+ return true;
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/api/discovery/suggested_links_registry_factory.h b/chrome/browser/extensions/api/discovery/suggested_links_registry_factory.h
new file mode 100644
index 0000000..4063d26
--- /dev/null
+++ b/chrome/browser/extensions/api/discovery/suggested_links_registry_factory.h
@@ -0,0 +1,42 @@
+// 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_BROWSER_EXTENSIONS_API_DISCOVERY_SUGGESTED_LINKS_REGISTRY_FACTORY_H_
+#define CHROME_BROWSER_EXTENSIONS_API_DISCOVERY_SUGGESTED_LINKS_REGISTRY_FACTORY_H_
+#pragma once
+
+#include "base/memory/singleton.h"
+#include "chrome/browser/profiles/profile_keyed_service_factory.h"
+
+namespace extensions {
+
+class SuggestedLinksRegistry;
+
+// Singleton that associate SuggestedLinksRegistry objects with Profiles.
+class SuggestedLinksRegistryFactory : public ProfileKeyedServiceFactory {
+ public:
+ static SuggestedLinksRegistry* GetForProfile(Profile* profile);
+
+ static SuggestedLinksRegistryFactory* GetInstance();
+
+ // Overridden from ProfileKeyedBaseFactory:
+ virtual bool ServiceIsCreatedWithProfile() OVERRIDE;
+
+ private:
+ friend struct DefaultSingletonTraits<SuggestedLinksRegistryFactory>;
+
+ SuggestedLinksRegistryFactory();
+ virtual ~SuggestedLinksRegistryFactory();
+
+ // ProfileKeyedServiceFactory:
+ virtual ProfileKeyedService* BuildServiceInstanceFor(
+ Profile* profile) const OVERRIDE;
+ virtual bool ServiceRedirectedInIncognito() OVERRIDE;
+
+ DISALLOW_COPY_AND_ASSIGN(SuggestedLinksRegistryFactory);
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_DISCOVERY_SUGGESTED_LINKS_REGISTRY_FACTORY_H_