Move extension_messages.h to extensions/common.
[chromium-blink-merge.git] / chrome / browser / extensions / api / tabs / ash_panel_contents.cc
blobf0c3cdd69455d538b052767a3d7b947ee2662fb7
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/api/tabs/ash_panel_contents.h"
7 #include "apps/ui/native_app_window.h"
8 #include "base/values.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
11 #include "chrome/browser/extensions/api/tabs/tabs_windows_api.h"
12 #include "chrome/browser/extensions/api/tabs/windows_event_router.h"
13 #include "chrome/browser/extensions/extension_tab_util.h"
14 #include "chrome/browser/extensions/window_controller_list.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/sessions/session_tab_helper.h"
17 #include "content/public/browser/browser_context.h"
18 #include "content/public/browser/site_instance.h"
19 #include "content/public/browser/web_contents.h"
20 #include "extensions/common/extension.h"
21 #include "extensions/common/extension_messages.h"
22 #include "ui/gfx/image/image.h"
24 using apps::AppWindow;
25 using apps::NativeAppWindow;
27 // AshPanelWindowController ----------------------------------------------------
29 // This class enables an AppWindow instance to be accessed (to a limited
30 // extent) via the chrome.windows and chrome.tabs API. This is a temporary
31 // bridge to support instantiating AppWindows from v1 apps, specifically
32 // for creating Panels in Ash. See crbug.com/160645.
33 class AshPanelWindowController : public extensions::WindowController {
34 public:
35 AshPanelWindowController(AppWindow* window, Profile* profile);
36 virtual ~AshPanelWindowController();
38 void NativeWindowChanged();
40 // Overridden from extensions::WindowController.
41 virtual int GetWindowId() const OVERRIDE;
42 virtual std::string GetWindowTypeText() const OVERRIDE;
43 virtual base::DictionaryValue* CreateWindowValueWithTabs(
44 const extensions::Extension* extension) const OVERRIDE;
45 virtual base::DictionaryValue* CreateTabValue(
46 const extensions::Extension* extension, int tab_index) const OVERRIDE;
47 virtual bool CanClose(Reason* reason) const OVERRIDE;
48 virtual void SetFullscreenMode(bool is_fullscreen,
49 const GURL& extension_url) const OVERRIDE;
50 virtual bool IsVisibleToExtension(
51 const extensions::Extension* extension) const OVERRIDE;
53 private:
54 AppWindow* app_window_; // Weak pointer; this is owned by app_window_
55 bool is_active_;
57 DISALLOW_COPY_AND_ASSIGN(AshPanelWindowController);
60 AshPanelWindowController::AshPanelWindowController(AppWindow* app_window,
61 Profile* profile)
62 : extensions::WindowController(app_window->GetBaseWindow(), profile),
63 app_window_(app_window),
64 is_active_(app_window->GetBaseWindow()->IsActive()) {
65 extensions::WindowControllerList::GetInstance()->AddExtensionWindow(this);
68 AshPanelWindowController::~AshPanelWindowController() {
69 extensions::WindowControllerList::GetInstance()->RemoveExtensionWindow(this);
72 int AshPanelWindowController::GetWindowId() const {
73 return static_cast<int>(app_window_->session_id().id());
76 std::string AshPanelWindowController::GetWindowTypeText() const {
77 return extensions::tabs_constants::kWindowTypeValuePanel;
80 base::DictionaryValue* AshPanelWindowController::CreateWindowValueWithTabs(
81 const extensions::Extension* extension) const {
82 DCHECK(IsVisibleToExtension(extension));
83 base::DictionaryValue* result = CreateWindowValue();
84 base::DictionaryValue* tab_value = CreateTabValue(extension, 0);
85 if (tab_value) {
86 base::ListValue* tab_list = new base::ListValue();
87 tab_list->Append(tab_value);
88 result->Set(extensions::tabs_constants::kTabsKey, tab_list);
90 return result;
93 base::DictionaryValue* AshPanelWindowController::CreateTabValue(
94 const extensions::Extension* extension, int tab_index) const {
95 if ((extension && !IsVisibleToExtension(extension)) ||
96 (tab_index > 0)) {
97 return NULL;
99 content::WebContents* web_contents = app_window_->web_contents();
100 if (!web_contents)
101 return NULL;
103 base::DictionaryValue* tab_value = new base::DictionaryValue();
104 tab_value->SetInteger(extensions::tabs_constants::kIdKey,
105 SessionID::IdForTab(web_contents));
106 tab_value->SetInteger(extensions::tabs_constants::kIndexKey, 0);
107 const int window_id = GetWindowId();
108 tab_value->SetInteger(extensions::tabs_constants::kWindowIdKey, window_id);
109 tab_value->SetString(
110 extensions::tabs_constants::kUrlKey, web_contents->GetURL().spec());
111 tab_value->SetString(
112 extensions::tabs_constants::kStatusKey,
113 extensions::ExtensionTabUtil::GetTabStatusText(
114 web_contents->IsLoading()));
115 tab_value->SetBoolean(extensions::tabs_constants::kActiveKey,
116 app_window_->GetBaseWindow()->IsActive());
117 // AppWindow only ever contains one tab, so that tab is always effectively
118 // selcted and highlighted (for purposes of the chrome.tabs API).
119 tab_value->SetInteger(extensions::tabs_constants::kWindowIdKey, window_id);
120 tab_value->SetInteger(extensions::tabs_constants::kIdKey, window_id);
121 tab_value->SetBoolean(extensions::tabs_constants::kSelectedKey, true);
122 tab_value->SetBoolean(extensions::tabs_constants::kHighlightedKey, true);
123 tab_value->SetBoolean(extensions::tabs_constants::kPinnedKey, false);
124 tab_value->SetString(
125 extensions::tabs_constants::kTitleKey, web_contents->GetTitle());
126 tab_value->SetBoolean(
127 extensions::tabs_constants::kIncognitoKey,
128 web_contents->GetBrowserContext()->IsOffTheRecord());
129 return tab_value;
132 bool AshPanelWindowController::CanClose(Reason* reason) const {
133 return true;
136 void AshPanelWindowController::SetFullscreenMode(
137 bool is_fullscreen, const GURL& extension_url) const {
138 // Do nothing. Panels cannot be fullscreen.
141 bool AshPanelWindowController::IsVisibleToExtension(
142 const extensions::Extension* extension) const {
143 return app_window_->extension() &&
144 extension->id() == app_window_->extension()->id();
147 void AshPanelWindowController::NativeWindowChanged() {
148 bool active = app_window_->GetBaseWindow()->IsActive();
149 if (active == is_active_)
150 return;
151 is_active_ = active;
152 // Let the extension API know that the active window changed.
153 extensions::TabsWindowsAPI* tabs_windows_api =
154 extensions::TabsWindowsAPI::Get(profile());
155 if (!tabs_windows_api)
156 return;
157 tabs_windows_api->windows_event_router()->OnActiveWindowChanged(
158 active ? this : NULL);
161 // AshPanelContents -----------------------------------------------------
163 AshPanelContents::AshPanelContents(AppWindow* host) : host_(host) {}
165 AshPanelContents::~AshPanelContents() {
168 void AshPanelContents::Initialize(content::BrowserContext* context,
169 const GURL& url) {
170 url_ = url;
172 extension_function_dispatcher_.reset(
173 new ExtensionFunctionDispatcher(context, this));
175 web_contents_.reset(
176 content::WebContents::Create(content::WebContents::CreateParams(
177 context, content::SiteInstance::CreateForURL(context, url_))));
179 // Needed to give the web contents a Window ID. Extension APIs expect web
180 // contents to have a Window ID. Also required for FaviconTabHelper to
181 // correctly set the window icon and title.
182 SessionTabHelper::CreateForWebContents(web_contents_.get());
183 SessionTabHelper::FromWebContents(web_contents_.get())->SetWindowID(
184 host_->session_id());
186 // Responsible for loading favicons for the Launcher, which uses different
187 // logic than the FaviconTabHelper associated with web_contents_
188 // (instantiated in AppWindow::Init())
189 launcher_favicon_loader_.reset(
190 new LauncherFaviconLoader(this, web_contents_.get()));
192 content::WebContentsObserver::Observe(web_contents_.get());
195 void AshPanelContents::LoadContents(int32 creator_process_id) {
196 // This must be created after the native window has been created.
197 window_controller_.reset(new AshPanelWindowController(
198 host_, Profile::FromBrowserContext(host_->browser_context())));
200 web_contents_->GetController().LoadURL(
201 url_, content::Referrer(), content::PAGE_TRANSITION_LINK,
202 std::string());
205 void AshPanelContents::NativeWindowChanged(NativeAppWindow* native_app_window) {
206 if (window_controller_)
207 window_controller_->NativeWindowChanged();
210 void AshPanelContents::NativeWindowClosed() {
213 content::WebContents* AshPanelContents::GetWebContents() const {
214 return web_contents_.get();
217 void AshPanelContents::FaviconUpdated() {
218 gfx::Image new_image = gfx::Image::CreateFrom1xBitmap(
219 launcher_favicon_loader_->GetFavicon());
220 host_->UpdateAppIcon(new_image);
223 bool AshPanelContents::OnMessageReceived(const IPC::Message& message) {
224 bool handled = true;
225 IPC_BEGIN_MESSAGE_MAP(AshPanelContents, message)
226 IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest)
227 IPC_MESSAGE_UNHANDLED(handled = false)
228 IPC_END_MESSAGE_MAP()
229 return handled;
232 extensions::WindowController*
233 AshPanelContents::GetExtensionWindowController() const {
234 return window_controller_.get();
237 content::WebContents* AshPanelContents::GetAssociatedWebContents() const {
238 return web_contents_.get();
241 void AshPanelContents::OnRequest(
242 const ExtensionHostMsg_Request_Params& params) {
243 extension_function_dispatcher_->Dispatch(
244 params, web_contents_->GetRenderViewHost());