diff options
Diffstat (limited to 'chrome/browser/extensions/api/tabs')
-rw-r--r-- | chrome/browser/extensions/api/tabs/ash_panel_contents.cc | 221 | ||||
-rw-r--r-- | chrome/browser/extensions/api/tabs/ash_panel_contents.h | 66 | ||||
-rw-r--r-- | chrome/browser/extensions/api/tabs/tabs_api.cc | 37 |
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(); |