Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / tabs / ash_panel_contents.cc
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.
4
5 #include "chrome/browser/extensions/api/tabs/ash_panel_contents.h"
6
7 #include "base/values.h"
8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
10 #include "chrome/browser/extensions/api/tabs/tabs_windows_api.h"
11 #include "chrome/browser/extensions/api/tabs/windows_event_router.h"
12 #include "chrome/browser/extensions/extension_tab_util.h"
13 #include "chrome/browser/extensions/window_controller_list.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/sessions/session_tab_helper.h"
16 #include "content/public/browser/browser_context.h"
17 #include "content/public/browser/site_instance.h"
18 #include "content/public/browser/web_contents.h"
19 #include "extensions/browser/app_window/native_app_window.h"
20 #include "extensions/common/extension.h"
21 #include "extensions/common/extension_messages.h"
22 #include "ui/gfx/image/image.h"
23
24 using extensions::AppWindow;
25 using extensions::NativeAppWindow;
26
27 // AshPanelWindowController ----------------------------------------------------
28
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   ~AshPanelWindowController() override;
37
38   void NativeWindowChanged();
39
40   // Overridden from extensions::WindowController.
41   int GetWindowId() const override;
42   std::string GetWindowTypeText() const override;
43   base::DictionaryValue* CreateWindowValueWithTabs(
44       const extensions::Extension* extension) const override;
45   base::DictionaryValue* CreateTabValue(const extensions::Extension* extension,
46                                         int tab_index) const override;
47   bool CanClose(Reason* reason) const override;
48   void SetFullscreenMode(bool is_fullscreen,
49                          const GURL& extension_url) const override;
50   bool IsVisibleToExtension(
51       const extensions::Extension* extension) const override;
52
53  private:
54   AppWindow* app_window_;  // Weak pointer; this is owned by app_window_
55   bool is_active_;
56
57   DISALLOW_COPY_AND_ASSIGN(AshPanelWindowController);
58 };
59
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);
66 }
67
68 AshPanelWindowController::~AshPanelWindowController() {
69   extensions::WindowControllerList::GetInstance()->RemoveExtensionWindow(this);
70 }
71
72 int AshPanelWindowController::GetWindowId() const {
73   return static_cast<int>(app_window_->session_id().id());
74 }
75
76 std::string AshPanelWindowController::GetWindowTypeText() const {
77   return extensions::tabs_constants::kWindowTypeValuePanel;
78 }
79
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);
89   }
90   return result;
91 }
92
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;
98   }
99   content::WebContents* web_contents = app_window_->web_contents();
100   if (!web_contents)
101     return NULL;
102
103   base::DictionaryValue* tab_value = new base::DictionaryValue();
104   tab_value->SetInteger(extensions::tabs_constants::kIdKey,
105                         SessionTabHelper::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;
130 }
131
132 bool AshPanelWindowController::CanClose(Reason* reason) const {
133   return true;
134 }
135
136 void AshPanelWindowController::SetFullscreenMode(
137     bool is_fullscreen, const GURL& extension_url) const {
138   // Do nothing. Panels cannot be fullscreen.
139 }
140
141 bool AshPanelWindowController::IsVisibleToExtension(
142     const extensions::Extension* extension) const {
143   return extension->id() == app_window_->extension_id();
144 }
145
146 void AshPanelWindowController::NativeWindowChanged() {
147   bool active = app_window_->GetBaseWindow()->IsActive();
148   if (active == is_active_)
149     return;
150   is_active_ = active;
151   // Let the extension API know that the active window changed.
152   extensions::TabsWindowsAPI* tabs_windows_api =
153       extensions::TabsWindowsAPI::Get(profile());
154   if (!tabs_windows_api)
155     return;
156   tabs_windows_api->windows_event_router()->OnActiveWindowChanged(
157       active ? this : NULL);
158 }
159
160 // AshPanelContents -----------------------------------------------------
161
162 AshPanelContents::AshPanelContents(AppWindow* host) : host_(host) {}
163
164 AshPanelContents::~AshPanelContents() {
165 }
166
167 void AshPanelContents::Initialize(content::BrowserContext* context,
168                                   const GURL& url) {
169   url_ = url;
170
171   extension_function_dispatcher_.reset(
172       new extensions::ExtensionFunctionDispatcher(context, this));
173
174   web_contents_.reset(
175       content::WebContents::Create(content::WebContents::CreateParams(
176           context, content::SiteInstance::CreateForURL(context, url_))));
177
178   // Needed to give the web contents a Window ID. Extension APIs expect web
179   // contents to have a Window ID. Also required for FaviconTabHelper to
180   // correctly set the window icon and title.
181   SessionTabHelper::CreateForWebContents(web_contents_.get());
182   SessionTabHelper::FromWebContents(web_contents_.get())->SetWindowID(
183       host_->session_id());
184
185   // Responsible for loading favicons for the Launcher, which uses different
186   // logic than the FaviconTabHelper associated with web_contents_
187   // (instantiated in AppWindow::Init())
188   launcher_favicon_loader_.reset(
189       new LauncherFaviconLoader(this, web_contents_.get()));
190
191   content::WebContentsObserver::Observe(web_contents_.get());
192 }
193
194 void AshPanelContents::LoadContents(int32 creator_process_id) {
195   // This must be created after the native window has been created.
196   window_controller_.reset(new AshPanelWindowController(
197       host_, Profile::FromBrowserContext(host_->browser_context())));
198
199   web_contents_->GetController().LoadURL(
200       url_, content::Referrer(), ui::PAGE_TRANSITION_LINK,
201       std::string());
202 }
203
204 void AshPanelContents::NativeWindowChanged(NativeAppWindow* native_app_window) {
205   if (window_controller_)
206     window_controller_->NativeWindowChanged();
207 }
208
209 void AshPanelContents::NativeWindowClosed() {
210 }
211
212 void AshPanelContents::DispatchWindowShownForTests() const {
213 }
214
215 content::WebContents* AshPanelContents::GetWebContents() const {
216   return web_contents_.get();
217 }
218
219 void AshPanelContents::FaviconUpdated() {
220   gfx::Image new_image = gfx::Image::CreateFrom1xBitmap(
221       launcher_favicon_loader_->GetFavicon());
222   host_->UpdateAppIcon(new_image);
223 }
224
225 bool AshPanelContents::OnMessageReceived(const IPC::Message& message) {
226   bool handled = true;
227   IPC_BEGIN_MESSAGE_MAP(AshPanelContents, message)
228     IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest)
229     IPC_MESSAGE_UNHANDLED(handled = false)
230   IPC_END_MESSAGE_MAP()
231   return handled;
232 }
233
234 extensions::WindowController*
235 AshPanelContents::GetExtensionWindowController() const {
236   return window_controller_.get();
237 }
238
239 content::WebContents* AshPanelContents::GetAssociatedWebContents() const {
240   return web_contents_.get();
241 }
242
243 void AshPanelContents::OnRequest(
244     const ExtensionHostMsg_Request_Params& params) {
245   extension_function_dispatcher_->Dispatch(
246       params, web_contents_->GetRenderViewHost());
247 }