summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-19 18:05:56 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-19 18:05:56 +0000
commit8b8e7c9bce4198a4ee2865d9dfce6e8baa173ad3 (patch)
tree938304b8e1be417c1b9c73d7463dacbc1da79843 /chrome/browser/extensions
parentf2c4ee3627e6039fd42bd7c0c93e902b72653449 (diff)
downloadchromium_src-8b8e7c9bce4198a4ee2865d9dfce6e8baa173ad3.zip
chromium_src-8b8e7c9bce4198a4ee2865d9dfce6e8baa173ad3.tar.gz
chromium_src-8b8e7c9bce4198a4ee2865d9dfce6e8baa173ad3.tar.bz2
Initial version of chrome.experimental.sidebar extension API.
BUG=51084 TEST=Run interactive_ui_tests and browser_tests. New: - sidebar Extension API (design doc: https://docs.google.com/a/google.com/Doc?docid=0AV4Qg3xyZ8RQZGZtbWIydDJfNWc0eHJtbmRm&hl=en); - Sidebar panel in Chrome browser view; Original review=http://codereview.chromium.org/2836040/show Patch by alekseys@google.com git-svn-id: svn://svn.chromium.org/chrome/trunk/src@56716 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/extension_dom_ui.cc13
-rw-r--r--chrome/browser/extensions/extension_dom_ui.h7
-rw-r--r--chrome/browser/extensions/extension_function.h6
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc33
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.h4
-rw-r--r--chrome/browser/extensions/extension_host.cc10
-rw-r--r--chrome/browser/extensions/extension_host.h6
-rw-r--r--chrome/browser/extensions/extension_sidebar_api.cc270
-rw-r--r--chrome/browser/extensions/extension_sidebar_api.h117
-rw-r--r--chrome/browser/extensions/extension_sidebar_apitest.cc19
10 files changed, 445 insertions, 40 deletions
diff --git a/chrome/browser/extensions/extension_dom_ui.cc b/chrome/browser/extensions/extension_dom_ui.cc
index dd9d169..598e43b 100644
--- a/chrome/browser/extensions/extension_dom_ui.cc
+++ b/chrome/browser/extensions/extension_dom_ui.cc
@@ -162,16 +162,9 @@ void ExtensionDOMUI::RenderViewReused(RenderViewHost* render_view_host) {
ResetExtensionBookmarkManagerEventRouter();
}
-void ExtensionDOMUI::ProcessDOMUIMessage(const std::string& message,
- const ListValue* content,
- const GURL& source_url,
- int request_id,
- bool has_callback) {
- extension_function_dispatcher_->HandleRequest(message,
- content,
- source_url,
- request_id,
- has_callback);
+void ExtensionDOMUI::ProcessDOMUIMessage(
+ const ViewHostMsg_DomMessage_Params& params) {
+ extension_function_dispatcher_->HandleRequest(params);
}
Browser* ExtensionDOMUI::GetBrowser() const {
diff --git a/chrome/browser/extensions/extension_dom_ui.h b/chrome/browser/extensions/extension_dom_ui.h
index e0698e7..d5f146d 100644
--- a/chrome/browser/extensions/extension_dom_ui.h
+++ b/chrome/browser/extensions/extension_dom_ui.h
@@ -20,6 +20,7 @@ class PrefService;
class Profile;
class RenderViewHost;
class TabContents;
+struct ViewHostMsg_DomMessage_Params;
// This class implements DOMUI for extensions and allows extensions to put UI in
// the main tab contents area.
@@ -38,11 +39,7 @@ class ExtensionDOMUI
// DOMUI
virtual void RenderViewCreated(RenderViewHost* render_view_host);
virtual void RenderViewReused(RenderViewHost* render_view_host);
- virtual void ProcessDOMUIMessage(const std::string& message,
- const ListValue* content,
- const GURL& source_url,
- int request_id,
- bool has_callback);
+ virtual void ProcessDOMUIMessage(const ViewHostMsg_DomMessage_Params& params);
// ExtensionFunctionDispatcher::Delegate
virtual Browser* GetBrowser() const;
diff --git a/chrome/browser/extensions/extension_function.h b/chrome/browser/extensions/extension_function.h
index 44fde69..51f25fe 100644
--- a/chrome/browser/extensions/extension_function.h
+++ b/chrome/browser/extensions/extension_function.h
@@ -90,6 +90,9 @@ class ExtensionFunction : public base::RefCountedThreadSafe<ExtensionFunction> {
void set_include_incognito(bool include) { include_incognito_ = include; }
bool include_incognito() { return include_incognito_; }
+ void set_user_gesture(bool user_gesture) { user_gesture_ = user_gesture; }
+ bool user_gesture() const { return user_gesture_; }
+
// Execute the API. Clients should call set_raw_args() and
// set_request_id() before calling this method. Derived classes should be
// ready to return raw_result() and error() before returning from this
@@ -149,6 +152,9 @@ class ExtensionFunction : public base::RefCountedThreadSafe<ExtensionFunction> {
// True if this callback should include information from incognito contexts.
bool include_incognito_;
+ // True if the call was made in response of user gesture.
+ bool user_gesture_;
+
DISALLOW_COPY_AND_ASSIGN(ExtensionFunction);
};
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index cb9e126..a2b16ee 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -39,6 +39,7 @@
#include "chrome/browser/extensions/extension_processes_api.h"
#include "chrome/browser/extensions/extension_proxy_api.h"
#include "chrome/browser/extensions/extension_rlz_module.h"
+#include "chrome/browser/extensions/extension_sidebar_api.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/extensions/extension_test_api.h"
#if defined(OS_CHROMEOS)
@@ -249,6 +250,17 @@ void FactoryRegistry::ResetFunctions() {
// Proxies.
RegisterFunction<UseCustomProxySettingsFunction>();
+
+ // Sidebar.
+ RegisterFunction<CollapseSidebarFunction>();
+ RegisterFunction<ExpandSidebarFunction>();
+ RegisterFunction<GetStateSidebarFunction>();
+ RegisterFunction<HideSidebarFunction>();
+ RegisterFunction<NavigateSidebarFunction>();
+ RegisterFunction<SetBadgeTextSidebarFunction>();
+ RegisterFunction<SetIconSidebarFunction>();
+ RegisterFunction<SetTitleSidebarFunction>();
+ RegisterFunction<ShowSidebarFunction>();
}
void FactoryRegistry::GetAllNames(std::vector<std::string>* names) {
@@ -400,20 +412,18 @@ Browser* ExtensionFunctionDispatcher::GetCurrentBrowser(
return browser;
}
-void ExtensionFunctionDispatcher::HandleRequest(const std::string& name,
- const ListValue* args,
- const GURL& source_url,
- int request_id,
- bool has_callback) {
+void ExtensionFunctionDispatcher::HandleRequest(
+ const ViewHostMsg_DomMessage_Params& params) {
scoped_refptr<ExtensionFunction> function(
- FactoryRegistry::instance()->NewFunction(name));
+ FactoryRegistry::instance()->NewFunction(params.name));
function->set_dispatcher_peer(peer_);
function->set_profile(profile_);
function->set_extension_id(extension_id());
- function->SetArgs(args);
- function->set_source_url(source_url);
- function->set_request_id(request_id);
- function->set_has_callback(has_callback);
+ function->SetArgs(&params.arguments);
+ function->set_source_url(params.source_url);
+ function->set_request_id(params.request_id);
+ function->set_has_callback(params.has_callback);
+ function->set_user_gesture(params.user_gesture);
ExtensionsService* service = profile()->GetExtensionsService();
DCHECK(service);
Extension* extension = service->GetExtensionById(extension_id(), false);
@@ -421,7 +431,8 @@ void ExtensionFunctionDispatcher::HandleRequest(const std::string& name,
function->set_include_incognito(service->IsIncognitoEnabled(extension));
ExtensionsQuotaService* quota = service->quota_service();
- if (quota->Assess(extension_id(), function, args, base::TimeTicks::Now())) {
+ if (quota->Assess(extension_id(), function, &params.arguments,
+ base::TimeTicks::Now())) {
// See crbug.com/39178.
ExternalProtocolHandler::PermitLaunchUrl();
diff --git a/chrome/browser/extensions/extension_function_dispatcher.h b/chrome/browser/extensions/extension_function_dispatcher.h
index e089e29..9bddecf 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.h
+++ b/chrome/browser/extensions/extension_function_dispatcher.h
@@ -20,6 +20,7 @@ class ListValue;
class Profile;
class RenderViewHost;
class TabContents;
+struct ViewHostMsg_DomMessage_Params;
// A factory function for creating new ExtensionFunction instances.
typedef ExtensionFunction* (*ExtensionFunctionFactory)();
@@ -92,8 +93,7 @@ class ExtensionFunctionDispatcher {
Delegate* delegate() { return delegate_; }
// Handle a request to execute an extension function.
- void HandleRequest(const std::string& name, const ListValue* args,
- const GURL& source_url, int request_id, bool has_callback);
+ void HandleRequest(const ViewHostMsg_DomMessage_Params& params);
// Send a response to a function.
void SendResponse(ExtensionFunction* api, bool success);
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index 7e78619..0b3cc5a 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -493,14 +493,10 @@ WebPreferences ExtensionHost::GetWebkitPrefs() {
return webkit_prefs;
}
-void ExtensionHost::ProcessDOMUIMessage(const std::string& message,
- const ListValue* content,
- const GURL& source_url,
- int request_id,
- bool has_callback) {
+void ExtensionHost::ProcessDOMUIMessage(
+ const ViewHostMsg_DomMessage_Params& params) {
if (extension_function_dispatcher_.get()) {
- extension_function_dispatcher_->HandleRequest(
- message, content, source_url, request_id, has_callback);
+ extension_function_dispatcher_->HandleRequest(params);
}
}
diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h
index e8fd600..c473e87 100644
--- a/chrome/browser/extensions/extension_host.h
+++ b/chrome/browser/extensions/extension_host.h
@@ -125,11 +125,7 @@ class ExtensionHost : public RenderViewHostDelegate,
RenderViewHost* render_view_host);
virtual WebPreferences GetWebkitPrefs();
- virtual void ProcessDOMUIMessage(const std::string& message,
- const ListValue* content,
- const GURL& source_url,
- int request_id,
- bool has_callback);
+ virtual void ProcessDOMUIMessage(const ViewHostMsg_DomMessage_Params& params);
virtual void RunJavaScriptMessage(const std::wstring& message,
const std::wstring& default_prompt,
const GURL& frame_url,
diff --git a/chrome/browser/extensions/extension_sidebar_api.cc b/chrome/browser/extensions/extension_sidebar_api.cc
new file mode 100644
index 0000000..9453ac7
--- /dev/null
+++ b/chrome/browser/extensions/extension_sidebar_api.cc
@@ -0,0 +1,270 @@
+// 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_sidebar_api.h"
+
+#include "base/json/json_writer.h"
+#include "base/string_number_conversions.h"
+#include "base/string_util.h"
+#include "base/string16.h"
+#include "base/values.h"
+#include "chrome/browser/extensions/extension_message_service.h"
+#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_tabs_module.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/sidebar/sidebar_container.h"
+#include "chrome/browser/sidebar/sidebar_manager.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/extensions/extension_error_utils.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/common/url_constants.h"
+#include "ipc/ipc_message_utils.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+namespace {
+// Errors.
+const char kNoTabError[] = "No tab with id: *.";
+const char kInvalidUrlError[] = "Invalid url: \"*\".";
+const char kNoCurrentWindowError[] = "No current browser window was found";
+const char kNoDefaultTabError[] = "No default tab was found";
+const char kInvalidExpandContextError[] =
+ "Sidebar can be expanded only in response to an explicit user gesture";
+// Keys.
+const char kBadgeTextKey[] = "text";
+const char kImageDataKey[] = "imageData";
+const char kStateKey[] = "state";
+const char kTabIdKey[] = "tabId";
+const char kTitleKey[] = "title";
+const char kUrlKey[] = "url";
+// Events.
+const char kOnStateChanged[] = "experimental.sidebar.onStateChanged";
+} // namespace
+
+namespace extension_sidebar_constants {
+// Sidebar states.
+const char kActiveState[] = "active";
+const char kHiddenState[] = "hidden";
+const char kShownState[] = "shown";
+}
+
+static GURL ResolvePossiblyRelativeURL(const std::string& url_string,
+ Extension* extension) {
+ GURL url = GURL(url_string);
+ if (!url.is_valid())
+ url = extension->GetResourceURL(url_string);
+
+ return url;
+}
+
+static bool CanUseHost(Extension* extension,
+ const GURL& url,
+ std::string* error) {
+ if (extension->HasHostPermission(url))
+ return true;
+
+ if (error) {
+ *error = ExtensionErrorUtils::FormatErrorMessage(
+ extension_manifest_errors::kCannotAccessPage, url.spec());
+ }
+
+ return false;
+}
+
+
+// static
+void ExtensionSidebarEventRouter::OnStateChanged(
+ Profile* profile, int tab_id, const std::string& content_id,
+ const std::string& state) {
+ DictionaryValue* details = new DictionaryValue;
+ details->Set(kTabIdKey, Value::CreateIntegerValue(tab_id));
+ details->Set(kStateKey, Value::CreateStringValue(state));
+
+ ListValue args;
+ args.Set(0, details);
+ std::string json_args;
+ base::JSONWriter::Write(&args, false, &json_args);
+
+ const std::string& extension_id(content_id);
+ profile->GetExtensionMessageService()->DispatchEventToExtension(
+ extension_id, kOnStateChanged, json_args,
+ profile->IsOffTheRecord(), GURL());
+}
+
+
+bool SidebarFunction::RunImpl() {
+ if (!args_.get())
+ return false;
+
+ DictionaryValue* details = NULL;
+ DictionaryValue default_details;
+ if (args_->empty()) {
+ details = &default_details;
+ } else {
+ EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details));
+ }
+
+ int tab_id;
+ TabContents* tab_contents = NULL;
+ if (details->HasKey(kTabIdKey)) {
+ EXTENSION_FUNCTION_VALIDATE(details->GetInteger(kTabIdKey, &tab_id));
+ if (!ExtensionTabUtil::GetTabById(tab_id, profile(), include_incognito(),
+ NULL, NULL, &tab_contents, NULL)) {
+ error_ = ExtensionErrorUtils::FormatErrorMessage(
+ kNoTabError, base::IntToString(tab_id));
+ return false;
+ }
+ } else {
+ Browser* browser = GetCurrentBrowser();
+ if (!browser) {
+ error_ = kNoCurrentWindowError;
+ return false;
+ }
+ if (!ExtensionTabUtil::GetDefaultTab(browser, &tab_contents, &tab_id)) {
+ error_ = kNoDefaultTabError;
+ return false;
+ }
+ }
+ if (!tab_contents)
+ return false;
+
+ std::string content_id(GetExtension()->id());
+ return RunImpl(tab_contents, content_id, *details);
+}
+
+
+bool CollapseSidebarFunction::RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details) {
+ SidebarManager::GetInstance()->CollapseSidebar(tab, content_id);
+ return true;
+}
+
+bool ExpandSidebarFunction::RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details) {
+ // TODO(alekseys): enable this check back when WebKit's user gesture flag
+ // reporting for extension calls is fixed.
+ // if (!user_gesture()) {
+ // error_ = kInvalidExpandContextError;
+ // return false;
+ // }
+ SidebarManager::GetInstance()->ExpandSidebar(tab, content_id);
+ return true;
+}
+
+bool GetStateSidebarFunction::RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details) {
+ SidebarManager* manager = SidebarManager::GetInstance();
+
+ const char* result = extension_sidebar_constants::kHiddenState;
+ if (manager->GetSidebarTabContents(tab, content_id)) {
+ bool is_active = false;
+ // Sidebar is considered active only if tab is selected, sidebar UI
+ // is expanded and this extension's content is displayed on it.
+ SidebarContainer* active_sidebar =
+ manager->GetActiveSidebarContainerFor(tab);
+ // Check if sidebar UI is expanded and this extension's content
+ // is displayed on it.
+ if (active_sidebar && active_sidebar->content_id() == content_id) {
+ if (!details.HasKey(kTabIdKey)) {
+ is_active = NULL != GetCurrentBrowser();
+ } else {
+ int tab_id;
+ EXTENSION_FUNCTION_VALIDATE(details.GetInteger(kTabIdKey, &tab_id));
+
+ // Check if this tab is selected.
+ Browser* browser = GetCurrentBrowser();
+ TabContents* contents = NULL;
+ int default_tab_id = -1;
+ if (browser &&
+ ExtensionTabUtil::GetDefaultTab(browser, &contents,
+ &default_tab_id)) {
+ is_active = default_tab_id == tab_id;
+ }
+ }
+ }
+
+ result = is_active ? extension_sidebar_constants::kActiveState :
+ extension_sidebar_constants::kShownState;
+ }
+
+ result_.reset(Value::CreateStringValue(result));
+ return true;
+}
+
+bool HideSidebarFunction::RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details) {
+ SidebarManager::GetInstance()->HideSidebar(tab, content_id);
+ return true;
+}
+
+bool NavigateSidebarFunction::RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details) {
+ std::string url_string;
+ EXTENSION_FUNCTION_VALIDATE(details.GetString(kUrlKey, &url_string));
+ GURL url = ResolvePossiblyRelativeURL(url_string, GetExtension());
+ if (!url.is_valid()) {
+ error_ = ExtensionErrorUtils::FormatErrorMessage(kInvalidUrlError,
+ url_string);
+ return false;
+ }
+ if (!url.SchemeIs(chrome::kExtensionScheme) &&
+ !CanUseHost(GetExtension(), url, &error_)) {
+ return false;
+ }
+ // Disallow requests outside of the requesting extension view's extension.
+ if (url.SchemeIs(chrome::kExtensionScheme)) {
+ std::string extension_id(url.host());
+ if (extension_id != GetExtension()->id())
+ return false;
+ }
+
+ SidebarManager::GetInstance()->NavigateSidebar(tab, content_id, GURL(url));
+ return true;
+}
+
+bool SetBadgeTextSidebarFunction::RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details) {
+ string16 badge_text;
+ EXTENSION_FUNCTION_VALIDATE(details.GetString(kBadgeTextKey, &badge_text));
+ SidebarManager::GetInstance()->SetSidebarBadgeText(
+ tab, content_id, badge_text);
+ return true;
+}
+
+bool SetIconSidebarFunction::RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details) {
+ BinaryValue* binary;
+ EXTENSION_FUNCTION_VALIDATE(details.GetBinary(kImageDataKey, &binary));
+ IPC::Message bitmap_pickle(binary->GetBuffer(), binary->GetSize());
+ void* iter = NULL;
+ scoped_ptr<SkBitmap> bitmap(new SkBitmap);
+ EXTENSION_FUNCTION_VALIDATE(
+ IPC::ReadParam(&bitmap_pickle, &iter, bitmap.get()));
+ SidebarManager::GetInstance()->SetSidebarIcon(tab, content_id, *bitmap);
+ return true;
+}
+
+bool SetTitleSidebarFunction::RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details) {
+ string16 title;
+ EXTENSION_FUNCTION_VALIDATE(details.GetString(kTitleKey, &title));
+ SidebarManager::GetInstance()->SetSidebarTitle(tab, content_id, title);
+ return true;
+}
+
+bool ShowSidebarFunction::RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details) {
+ SidebarManager::GetInstance()->ShowSidebar(tab, content_id);
+ return true;
+}
diff --git a/chrome/browser/extensions/extension_sidebar_api.h b/chrome/browser/extensions/extension_sidebar_api.h
new file mode 100644
index 0000000..e4ab780
--- /dev/null
+++ b/chrome/browser/extensions/extension_sidebar_api.h
@@ -0,0 +1,117 @@
+// 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_SIDEBAR_API_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_SIDEBAR_API_H_
+
+#include <string>
+#include "chrome/browser/extensions/extension_function.h"
+
+class DictionaryValue;
+class Profile;
+class RenderViewHost;
+class TabContents;
+
+namespace extension_sidebar_constants {
+extern const char kActiveState[];
+extern const char kHiddenState[];
+extern const char kShownState[];
+} // namespace extension_sidebar_constants
+
+// Event router class for events related to the sidebar API.
+class ExtensionSidebarEventRouter {
+ public:
+ // Sidebar state changed.
+ static void OnStateChanged(
+ Profile* profile, int tab_id, const std::string& content_id,
+ const std::string& state);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ExtensionSidebarEventRouter);
+};
+
+// Base class for sidebar function APIs.
+class SidebarFunction : public SyncExtensionFunction {
+ public:
+ virtual bool RunImpl();
+ private:
+ virtual bool RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details) = 0;
+};
+
+class CollapseSidebarFunction : public SidebarFunction {
+ private:
+ virtual bool RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details);
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.sidebar.collapse");
+};
+
+class ExpandSidebarFunction : public SidebarFunction {
+ private:
+ virtual bool RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details);
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.sidebar.expand");
+};
+
+class GetStateSidebarFunction : public SidebarFunction {
+ private:
+ virtual bool RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details);
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.sidebar.getState");
+};
+
+class HideSidebarFunction : public SidebarFunction {
+ private:
+ virtual bool RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details);
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.sidebar.hide");
+};
+
+class NavigateSidebarFunction : public SidebarFunction {
+ private:
+ virtual bool RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details);
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.sidebar.navigate");
+};
+
+class SetBadgeTextSidebarFunction : public SidebarFunction {
+ private:
+ virtual bool RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details);
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.sidebar.setBadgeText");
+};
+
+class SetIconSidebarFunction : public SidebarFunction {
+ private:
+ virtual bool RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details);
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.sidebar.setIcon");
+};
+
+class SetTitleSidebarFunction : public SidebarFunction {
+ private:
+ virtual bool RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details);
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.sidebar.setTitle");
+};
+
+class ShowSidebarFunction : public SidebarFunction {
+ private:
+ virtual bool RunImpl(TabContents* tab,
+ const std::string& content_id,
+ const DictionaryValue& details);
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.sidebar.show");
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_SIDEBAR_API_H_
+
diff --git a/chrome/browser/extensions/extension_sidebar_apitest.cc b/chrome/browser/extensions/extension_sidebar_apitest.cc
new file mode 100644
index 0000000..9d33fa0
--- /dev/null
+++ b/chrome/browser/extensions/extension_sidebar_apitest.cc
@@ -0,0 +1,19 @@
+// 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 "base/command_line.h"
+#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/common/chrome_switches.h"
+
+class SidebarApiTest : public ExtensionApiTest {
+ public:
+ void SetUpCommandLine(CommandLine* command_line) {
+ ExtensionApiTest::SetUpCommandLine(command_line);
+ command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(SidebarApiTest, Sidebar) {
+ ASSERT_TRUE(RunExtensionTest("sidebar")) << message_;
+}