summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/api/tabs
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/extensions/api/tabs')
-rw-r--r--chrome/browser/extensions/api/tabs/ash_panel_contents.cc221
-rw-r--r--chrome/browser/extensions/api/tabs/ash_panel_contents.h66
-rw-r--r--chrome/browser/extensions/api/tabs/tabs_api.cc37
3 files changed, 315 insertions, 9 deletions
diff --git a/chrome/browser/extensions/api/tabs/ash_panel_contents.cc b/chrome/browser/extensions/api/tabs/ash_panel_contents.cc
new file mode 100644
index 0000000..cb21550
--- /dev/null
+++ b/chrome/browser/extensions/api/tabs/ash_panel_contents.cc
@@ -0,0 +1,221 @@
+// Copyright 2013 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/tabs/ash_panel_contents.h"
+
+#include "base/values.h"
+#include "chrome/browser/extensions/api/tabs/tabs_constants.h"
+#include "chrome/browser/extensions/api/tabs/tabs_windows_api.h"
+#include "chrome/browser/extensions/api/tabs/windows_event_router.h"
+#include "chrome/browser/extensions/extension_tab_util.h"
+#include "chrome/browser/extensions/window_controller_list.h"
+#include "chrome/browser/ui/extensions/native_app_window.h"
+#include "chrome/browser/ui/extensions/shell_window.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_messages.h"
+#include "content/public/browser/site_instance.h"
+#include "content/public/browser/web_contents.h"
+
+// AshPanelWindowController ----------------------------------------------------
+
+// This class enables a ShellWindow instance to be accessed (to a limited
+// extent) via the chrome.windows and chrome.tabs API. This is a temporary
+// bridge to support instantiating ShellWindows from v1 apps, specifically
+// for creating Panels in Ash. See crbug.com/160645.
+class AshPanelWindowController : public extensions::WindowController {
+ public:
+ AshPanelWindowController(ShellWindow* window, Profile* profile);
+ virtual ~AshPanelWindowController();
+
+ void NativeWindowChanged();
+
+ // Overridden from extensions::WindowController.
+ virtual int GetWindowId() const OVERRIDE;
+ virtual std::string GetWindowTypeText() const OVERRIDE;
+ virtual base::DictionaryValue* CreateWindowValueWithTabs(
+ const extensions::Extension* extension) const OVERRIDE;
+ virtual base::DictionaryValue* CreateTabValue(
+ const extensions::Extension* extension, int tab_index) const OVERRIDE;
+ virtual bool CanClose(Reason* reason) const OVERRIDE;
+ virtual void SetFullscreenMode(bool is_fullscreen,
+ const GURL& extension_url) const OVERRIDE;
+ virtual bool IsVisibleToExtension(
+ const extensions::Extension* extension) const OVERRIDE;
+
+ private:
+ ShellWindow* shell_window_; // Weak pointer; this is owned by shell_window_
+ bool is_active_;
+
+ DISALLOW_COPY_AND_ASSIGN(AshPanelWindowController);
+};
+
+AshPanelWindowController::AshPanelWindowController(
+ ShellWindow* shell_window, Profile* profile)
+ : extensions::WindowController(shell_window->GetBaseWindow(), profile),
+ shell_window_(shell_window),
+ is_active_(shell_window->GetBaseWindow()->IsActive()) {
+ extensions::WindowControllerList::GetInstance()->AddExtensionWindow(this);
+}
+
+AshPanelWindowController::~AshPanelWindowController() {
+ extensions::WindowControllerList::GetInstance()->RemoveExtensionWindow(this);
+}
+
+int AshPanelWindowController::GetWindowId() const {
+ return static_cast<int>(shell_window_->session_id().id());
+}
+
+std::string AshPanelWindowController::GetWindowTypeText() const {
+ return extensions::tabs_constants::kWindowTypeValuePanel;
+}
+
+base::DictionaryValue* AshPanelWindowController::CreateWindowValueWithTabs(
+ const extensions::Extension* extension) const {
+ DCHECK(IsVisibleToExtension(extension));
+ base::DictionaryValue* result = CreateWindowValue();
+ DictionaryValue* tab_value = CreateTabValue(extension, 0);
+ if (tab_value) {
+ base::ListValue* tab_list = new ListValue();
+ tab_list->Append(tab_value);
+ result->Set(extensions::tabs_constants::kTabsKey, tab_list);
+ }
+ return result;
+}
+
+base::DictionaryValue* AshPanelWindowController::CreateTabValue(
+ const extensions::Extension* extension, int tab_index) const {
+ if ((extension && !IsVisibleToExtension(extension)) ||
+ (tab_index > 0)) {
+ return NULL;
+ }
+ content::WebContents* web_contents = shell_window_->web_contents();
+ if (!web_contents)
+ return NULL;
+
+ DictionaryValue* tab_value = new DictionaryValue();
+ tab_value->SetInteger(extensions::tabs_constants::kIdKey,
+ SessionID::IdForTab(web_contents));
+ tab_value->SetInteger(extensions::tabs_constants::kIndexKey, 0);
+ const int window_id = GetWindowId();
+ tab_value->SetInteger(extensions::tabs_constants::kWindowIdKey, window_id);
+ tab_value->SetString(
+ extensions::tabs_constants::kUrlKey, web_contents->GetURL().spec());
+ tab_value->SetString(
+ extensions::tabs_constants::kStatusKey,
+ ExtensionTabUtil::GetTabStatusText(web_contents->IsLoading()));
+ tab_value->SetBoolean(
+ extensions::tabs_constants::kActiveKey,
+ shell_window_->GetBaseWindow()->IsActive());
+ // ShellWindow only ever contains one tab, so that tab is always effectively
+ // selcted and highlighted (for purposes of the chrome.tabs API).
+ tab_value->SetInteger(extensions::tabs_constants::kWindowIdKey, window_id);
+ tab_value->SetInteger(extensions::tabs_constants::kIdKey, window_id);
+ tab_value->SetBoolean(extensions::tabs_constants::kSelectedKey, true);
+ tab_value->SetBoolean(extensions::tabs_constants::kHighlightedKey, true);
+ tab_value->SetBoolean(extensions::tabs_constants::kPinnedKey, false);
+ tab_value->SetString(
+ extensions::tabs_constants::kTitleKey, web_contents->GetTitle());
+ tab_value->SetBoolean(
+ extensions::tabs_constants::kIncognitoKey,
+ web_contents->GetBrowserContext()->IsOffTheRecord());
+ return tab_value;
+}
+
+bool AshPanelWindowController::CanClose(Reason* reason) const {
+ return true;
+}
+
+void AshPanelWindowController::SetFullscreenMode(
+ bool is_fullscreen, const GURL& extension_url) const {
+ // Do nothing. Panels cannot be fullscreen.
+}
+
+bool AshPanelWindowController::IsVisibleToExtension(
+ const extensions::Extension* extension) const {
+ return shell_window_->extension() &&
+ extension->id() == shell_window_->extension()->id();
+}
+
+void AshPanelWindowController::NativeWindowChanged() {
+ bool active = shell_window_->GetBaseWindow()->IsActive();
+ if (active == is_active_)
+ return;
+ is_active_ = active;
+ // Let the extension API know that the active window changed.
+ extensions::TabsWindowsAPI* tabs_windows_api =
+ extensions::TabsWindowsAPI::Get(profile());
+ if (!tabs_windows_api)
+ return;
+ tabs_windows_api->windows_event_router()->OnActiveWindowChanged(
+ active ? this : NULL);
+}
+
+// AshPanelContents -----------------------------------------------------
+
+AshPanelContents::AshPanelContents(ShellWindow* host)
+ : host_(host) {
+}
+
+AshPanelContents::~AshPanelContents() {
+}
+
+void AshPanelContents::Initialize(Profile* profile, const GURL& url) {
+ url_ = url;
+
+ extension_function_dispatcher_.reset(
+ new ExtensionFunctionDispatcher(profile, this));
+
+ web_contents_.reset(content::WebContents::Create(
+ content::WebContents::CreateParams(
+ profile, content::SiteInstance::CreateForURL(profile, url_))));
+
+ content::WebContentsObserver::Observe(web_contents_.get());
+}
+
+void AshPanelContents::LoadContents(int32 creator_process_id) {
+ // This must be created after the native window has been created.
+ window_controller_.reset(
+ new AshPanelWindowController(host_, host_->profile()));
+
+ web_contents_->GetController().LoadURL(
+ url_, content::Referrer(), content::PAGE_TRANSITION_LINK,
+ std::string());
+}
+
+void AshPanelContents::NativeWindowChanged(NativeAppWindow* native_app_window) {
+ if (window_controller_)
+ window_controller_->NativeWindowChanged();
+}
+
+void AshPanelContents::NativeWindowClosed() {
+}
+
+content::WebContents* AshPanelContents::GetWebContents() const {
+ return web_contents_.get();
+}
+
+bool AshPanelContents::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(AshPanelContents, message)
+ IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+extensions::WindowController*
+AshPanelContents::GetExtensionWindowController() const {
+ return window_controller_.get();
+}
+
+content::WebContents* AshPanelContents::GetAssociatedWebContents() const {
+ return web_contents_.get();
+}
+
+void AshPanelContents::OnRequest(
+ const ExtensionHostMsg_Request_Params& params) {
+ extension_function_dispatcher_->Dispatch(
+ params, web_contents_->GetRenderViewHost());
+}
diff --git a/chrome/browser/extensions/api/tabs/ash_panel_contents.h b/chrome/browser/extensions/api/tabs/ash_panel_contents.h
new file mode 100644
index 0000000..871139b
--- /dev/null
+++ b/chrome/browser/extensions/api/tabs/ash_panel_contents.h
@@ -0,0 +1,66 @@
+// Copyright 2013 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_TABS_ASH_PANEL_CONTENTS_H_
+#define CHROME_BROWSER_EXTENSIONS_API_TABS_ASH_PANEL_CONTENTS_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/extensions/extension_function_dispatcher.h"
+#include "chrome/browser/ui/extensions/shell_window.h"
+#include "content/public/browser/web_contents_observer.h"
+
+class AshPanelWindowController;
+class GURL;
+
+namespace content {
+class RenderViewHost;
+}
+
+namespace extensions {
+struct DraggableRegion;
+}
+
+// ShellWindowContents class specific to panel windows created by v1
+// extenstions. This class maintains a WebContents instance and observes it for
+// the purpose of passing messages to the extensions system. It also creates
+// an extensions::WindowController instance for interfacing with the v1
+// extensions API.
+class AshPanelContents : public ShellWindowContents,
+ public content::WebContentsObserver,
+ public ExtensionFunctionDispatcher::Delegate {
+ public:
+ explicit AshPanelContents(ShellWindow* host);
+ virtual ~AshPanelContents();
+
+ // ShellWindowContents
+ virtual void Initialize(Profile* profile, const GURL& url) OVERRIDE;
+ virtual void LoadContents(int32 creator_process_id) OVERRIDE;
+ virtual void NativeWindowChanged(NativeAppWindow* native_app_window) OVERRIDE;
+ virtual void NativeWindowClosed() OVERRIDE;
+ virtual content::WebContents* GetWebContents() const OVERRIDE;
+
+ // ExtensionFunctionDispatcher::Delegate
+ virtual extensions::WindowController* GetExtensionWindowController() const
+ OVERRIDE;
+ virtual content::WebContents* GetAssociatedWebContents() const OVERRIDE;
+
+ private:
+ // content::WebContentsObserver
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+
+ void OnRequest(const ExtensionHostMsg_Request_Params& params);
+
+ ShellWindow* host_;
+ GURL url_;
+ scoped_ptr<content::WebContents> web_contents_;
+ scoped_ptr<ExtensionFunctionDispatcher> extension_function_dispatcher_;
+ scoped_ptr<AshPanelWindowController> window_controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(AshPanelContents);
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_TABS_ASH_PANEL_CONTENTS_H_
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc
index b227e6d..c5879f7 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -88,6 +88,12 @@
#include "win8/util/win8_util.h"
#endif // OS_WIN
+#if defined(USE_ASH)
+#include "ash/ash_switches.h"
+#include "chrome/browser/extensions/api/tabs/ash_panel_contents.h"
+#include "chrome/browser/extensions/shell_window_registry.h"
+#endif
+
namespace Get = extensions::api::windows::Get;
namespace GetAll = extensions::api::windows::GetAll;
namespace GetCurrent = extensions::api::windows::GetCurrent;
@@ -531,15 +537,8 @@ bool WindowsCreateFunction::RunImpl() {
}
// Initialize default window bounds according to window type.
- // In ChromiumOS the default popup bounds is 0x0 which indicates default
- // window sizes in PanelBrowserView. In other OSs use the same default
- // bounds as windows.
-#if !defined(OS_CHROMEOS)
if (Browser::TYPE_TABBED == window_type ||
Browser::TYPE_POPUP == window_type) {
-#else
- if (Browser::TYPE_TABBED == window_type) {
-#endif
// Try to position the new browser relative to its originating
// browser window. The call offsets the bounds by kWindowTilePixels
// (defined in WindowSizer to be 10).
@@ -594,8 +593,28 @@ bool WindowsCreateFunction::RunImpl() {
}
}
-#if !defined(OS_CHROMEOS)
if (window_type == Browser::TYPE_PANEL) {
+#if defined(OS_CHROMEOS)
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePanels) &&
+ PanelManager::ShouldUsePanels(extension_id)) {
+ ShellWindow::CreateParams create_params;
+ create_params.window_type = ShellWindow::WINDOW_TYPE_PANEL;
+ create_params.bounds = window_bounds;
+ create_params.minimum_size = window_bounds.size();
+ create_params.maximum_size = window_bounds.size();
+ ShellWindow* shell_window =
+ new ShellWindow(window_profile, GetExtension());
+ AshPanelContents* ash_panel_contents = new AshPanelContents(shell_window);
+ shell_window->Init(urls[0], ash_panel_contents, create_params);
+ SetResult(ash_panel_contents->GetExtensionWindowController()->
+ CreateWindowValueWithTabs(GetExtension()));
+ // Add the panel to the shell window registry so that it shows up in
+ // the launcher and as an active render process.
+ extensions::ShellWindowRegistry::Get(window_profile)->AddShellWindow(
+ shell_window);
+ return true;
+ }
+#else
std::string title =
web_app::GenerateApplicationNameFromExtensionId(extension_id);
// Note: Panels ignore all but the first url provided.
@@ -612,8 +631,8 @@ bool WindowsCreateFunction::RunImpl() {
panel->extension_window_controller()->CreateWindowValueWithTabs(
GetExtension()));
return true;
- }
#endif
+ }
// Create a new BrowserWindow.
chrome::HostDesktopType host_desktop_type = chrome::GetActiveDesktop();