OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_tab_util.h" | 5 #include "chrome/browser/extensions/extension_tab_util.h" |
6 | 6 |
7 #include "apps/app_window.h" | 7 #include "apps/app_window.h" |
8 #include "apps/app_window_registry.h" | 8 #include "apps/app_window_registry.h" |
9 #include "base/strings/string_number_conversions.h" | |
9 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" | 10 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" |
11 #include "chrome/browser/extensions/chrome_extension_function.h" | |
10 #include "chrome/browser/extensions/tab_helper.h" | 12 #include "chrome/browser/extensions/tab_helper.h" |
11 #include "chrome/browser/extensions/window_controller.h" | 13 #include "chrome/browser/extensions/window_controller.h" |
12 #include "chrome/browser/extensions/window_controller_list.h" | 14 #include "chrome/browser/extensions/window_controller_list.h" |
13 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
14 #include "chrome/browser/sessions/session_id.h" | 16 #include "chrome/browser/sessions/session_id.h" |
15 #include "chrome/browser/ui/browser.h" | 17 #include "chrome/browser/ui/browser.h" |
16 #include "chrome/browser/ui/browser_finder.h" | 18 #include "chrome/browser/ui/browser_finder.h" |
17 #include "chrome/browser/ui/browser_iterator.h" | 19 #include "chrome/browser/ui/browser_iterator.h" |
18 #include "chrome/browser/ui/browser_window.h" | 20 #include "chrome/browser/ui/browser_window.h" |
19 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" | 21 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" |
20 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" | 22 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" |
21 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 23 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
22 #include "chrome/common/extensions/manifest_url_handler.h" | 24 #include "chrome/common/extensions/manifest_url_handler.h" |
23 #include "chrome/common/net/url_fixer_upper.h" | 25 #include "chrome/common/net/url_fixer_upper.h" |
24 #include "chrome/common/url_constants.h" | 26 #include "chrome/common/url_constants.h" |
25 #include "content/public/browser/favicon_status.h" | 27 #include "content/public/browser/favicon_status.h" |
26 #include "content/public/browser/navigation_entry.h" | 28 #include "content/public/browser/navigation_entry.h" |
27 #include "content/public/browser/web_contents.h" | 29 #include "content/public/browser/web_contents.h" |
28 #include "content/public/browser/web_contents_view.h" | 30 #include "content/public/browser/web_contents_view.h" |
31 #include "extensions/common/constants.h" | |
32 #include "extensions/common/error_utils.h" | |
29 #include "extensions/common/extension.h" | 33 #include "extensions/common/extension.h" |
30 #include "extensions/common/manifest_constants.h" | 34 #include "extensions/common/manifest_constants.h" |
35 #include "extensions/common/manifest_handlers/incognito_info.h" | |
31 #include "extensions/common/permissions/api_permission.h" | 36 #include "extensions/common/permissions/api_permission.h" |
32 #include "extensions/common/permissions/permissions_data.h" | 37 #include "extensions/common/permissions/permissions_data.h" |
33 #include "url/gurl.h" | 38 #include "url/gurl.h" |
34 | 39 |
35 using apps::AppWindow; | 40 using apps::AppWindow; |
36 using content::NavigationEntry; | 41 using content::NavigationEntry; |
37 using content::WebContents; | 42 using content::WebContents; |
38 | 43 |
39 namespace extensions { | 44 namespace extensions { |
40 | 45 |
41 namespace { | 46 namespace { |
42 | 47 |
43 namespace keys = tabs_constants; | 48 namespace keys = tabs_constants; |
44 | 49 |
45 WindowController* GetAppWindowController(const WebContents* contents) { | 50 WindowController* GetAppWindowController(const WebContents* contents) { |
46 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); | 51 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); |
47 apps::AppWindowRegistry* registry = apps::AppWindowRegistry::Get(profile); | 52 apps::AppWindowRegistry* registry = apps::AppWindowRegistry::Get(profile); |
48 if (!registry) | 53 if (!registry) |
49 return NULL; | 54 return NULL; |
50 AppWindow* app_window = | 55 AppWindow* app_window = |
51 registry->GetAppWindowForRenderViewHost(contents->GetRenderViewHost()); | 56 registry->GetAppWindowForRenderViewHost(contents->GetRenderViewHost()); |
52 if (!app_window) | 57 if (!app_window) |
53 return NULL; | 58 return NULL; |
54 return WindowControllerList::GetInstance()->FindWindowById( | 59 return WindowControllerList::GetInstance()->FindWindowById( |
55 app_window->session_id().id()); | 60 app_window->session_id().id()); |
56 } | 61 } |
57 | 62 |
63 // |error_message| can optionally be passed in a will be set with an appropriate | |
miket_OOO
2014/04/28 18:24:35
a => and?
rpaquay
2014/04/28 19:44:12
Done.
| |
64 // message if the window cannot be found by id. | |
65 Browser* GetBrowserInProfileWithId(Profile* profile, | |
66 const int window_id, | |
67 bool include_incognito, | |
68 std::string* error_message) { | |
69 Profile* incognito_profile = | |
70 include_incognito && profile->HasOffTheRecordProfile() | |
71 ? profile->GetOffTheRecordProfile() | |
72 : NULL; | |
73 for (chrome::BrowserIterator it; !it.done(); it.Next()) { | |
74 Browser* browser = *it; | |
75 if ((browser->profile() == profile || | |
76 browser->profile() == incognito_profile) && | |
77 ExtensionTabUtil::GetWindowId(browser) == window_id && | |
78 browser->window()) { | |
79 return browser; | |
80 } | |
81 } | |
82 | |
83 if (error_message) | |
84 *error_message = ErrorUtils::FormatErrorMessage( | |
85 keys::kWindowNotFoundError, base::IntToString(window_id)); | |
86 | |
87 return NULL; | |
88 } | |
89 | |
90 Browser* CreateBrowser(ChromeAsyncExtensionFunction* function, | |
91 int window_id, | |
92 std::string* error) { | |
93 content::WebContents* web_contents = function->GetAssociatedWebContents(); | |
94 DCHECK(web_contents); | |
miket_OOO
2014/04/28 18:24:35
I don't know whether these should be DCHECKs or CH
rpaquay
2014/04/28 19:44:12
AFAIK, looking the the implementations, the first
| |
95 DCHECK(web_contents->GetView()); | |
96 DCHECK(web_contents->GetView()->GetNativeView()); | |
97 DCHECK(!chrome::FindBrowserWithWebContents(web_contents)); | |
98 | |
99 chrome::HostDesktopType desktop_type = | |
100 chrome::GetHostDesktopTypeForNativeView( | |
101 web_contents->GetView()->GetNativeView()); | |
102 Browser::CreateParams params( | |
103 Browser::TYPE_TABBED, function->GetProfile(), desktop_type); | |
104 Browser* browser = new Browser(params); | |
105 browser->window()->Show(); | |
106 return browser; | |
107 } | |
108 | |
58 } // namespace | 109 } // namespace |
59 | 110 |
111 ExtensionTabUtil::OpenTabParams::OpenTabParams() | |
112 : create_browser_if_needed(false) { | |
113 } | |
114 | |
115 ExtensionTabUtil::OpenTabParams::~OpenTabParams() { | |
116 } | |
117 | |
118 // Opens a new tab for a given extension. Returns NULL and sets |error| if an | |
119 // error occurs. | |
120 base::DictionaryValue* ExtensionTabUtil::OpenTab( | |
121 ChromeAsyncExtensionFunction* function, | |
122 const OpenTabParams& params, | |
123 std::string* error) { | |
124 // windowId defaults to "current" window. | |
125 int window_id = extension_misc::kCurrentWindowId; | |
126 if (params.window_id.get()) | |
127 window_id = *params.window_id; | |
128 | |
129 Browser* browser = GetBrowserFromWindowID(function, window_id, error); | |
130 if (!browser) { | |
131 if (!params.create_browser_if_needed) { | |
132 return NULL; | |
133 } | |
134 browser = CreateBrowser(function, window_id, error); | |
135 if (!browser) | |
136 return NULL; | |
137 } | |
138 | |
139 // Ensure the selected browser is tabbed. | |
140 if (!browser->is_type_tabbed() && browser->IsAttemptingToCloseBrowser()) | |
141 browser = chrome::FindTabbedBrowser(function->GetProfile(), | |
142 function->include_incognito(), | |
143 browser->host_desktop_type()); | |
144 | |
145 if (!browser || !browser->window()) { | |
146 // TODO(rpaquay): Error message? | |
147 return NULL; | |
148 } | |
149 | |
150 // TODO(jstritar): Add a constant, chrome.tabs.TAB_ID_ACTIVE, that | |
151 // represents the active tab. | |
152 WebContents* opener = NULL; | |
153 if (params.opener_tab_id.get()) { | |
154 int opener_id = *params.opener_tab_id; | |
155 | |
156 if (!ExtensionTabUtil::GetTabById(opener_id, | |
157 function->GetProfile(), | |
158 function->include_incognito(), | |
159 NULL, | |
160 NULL, | |
161 &opener, | |
162 NULL)) { | |
163 // TODO(rpaquay): Error message? | |
164 return NULL; | |
165 } | |
166 } | |
167 | |
168 // TODO(rafaelw): handle setting remaining tab properties: | |
169 // -title | |
170 // -favIconUrl | |
171 | |
172 std::string url_string; | |
173 GURL url; | |
174 if (params.url.get()) { | |
175 url_string = *params.url; | |
176 url = ExtensionTabUtil::ResolvePossiblyRelativeURL( | |
177 url_string, function->GetExtension()); | |
178 if (!url.is_valid()) { | |
179 *error = | |
180 ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, url_string); | |
181 return NULL; | |
182 } | |
183 } | |
184 | |
185 // Don't let extensions crash the browser or renderers. | |
186 if (ExtensionTabUtil::IsCrashURL(url)) { | |
187 *error = keys::kNoCrashBrowserError; | |
188 return NULL; | |
189 } | |
190 | |
191 // Default to foreground for the new tab. The presence of 'active' property | |
192 // will override this default. | |
193 bool active = true; | |
194 if (params.active.get()) | |
195 active = *params.active; | |
196 | |
197 // Default to not pinning the tab. Setting the 'pinned' property to true | |
198 // will override this default. | |
199 bool pinned = false; | |
200 if (params.pinned.get()) | |
201 pinned = *params.pinned; | |
202 | |
203 // We can't load extension URLs into incognito windows unless the extension | |
204 // uses split mode. Special case to fall back to a tabbed window. | |
205 if (url.SchemeIs(kExtensionScheme) && | |
206 !IncognitoInfo::IsSplitMode(function->GetExtension()) && | |
207 browser->profile()->IsOffTheRecord()) { | |
208 Profile* profile = browser->profile()->GetOriginalProfile(); | |
209 chrome::HostDesktopType desktop_type = browser->host_desktop_type(); | |
210 | |
211 browser = chrome::FindTabbedBrowser(profile, false, desktop_type); | |
212 if (!browser) { | |
213 browser = new Browser( | |
214 Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type)); | |
215 browser->window()->Show(); | |
216 } | |
217 } | |
218 | |
219 // If index is specified, honor the value, but keep it bound to | |
220 // -1 <= index <= tab_strip->count() where -1 invokes the default behavior. | |
221 int index = -1; | |
222 if (params.index.get()) | |
223 index = *params.index; | |
224 | |
225 TabStripModel* tab_strip = browser->tab_strip_model(); | |
226 | |
227 index = std::min(std::max(index, -1), tab_strip->count()); | |
228 | |
229 int add_types = active ? TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE; | |
230 add_types |= TabStripModel::ADD_FORCE_INDEX; | |
231 if (pinned) | |
232 add_types |= TabStripModel::ADD_PINNED; | |
233 chrome::NavigateParams navigate_params( | |
234 browser, url, content::PAGE_TRANSITION_LINK); | |
235 navigate_params.disposition = | |
236 active ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; | |
237 navigate_params.tabstrip_index = index; | |
238 navigate_params.tabstrip_add_types = add_types; | |
239 chrome::Navigate(&navigate_params); | |
240 | |
241 // The tab may have been created in a different window, so make sure we look | |
242 // at the right tab strip. | |
243 tab_strip = navigate_params.browser->tab_strip_model(); | |
244 int new_index = | |
245 tab_strip->GetIndexOfWebContents(navigate_params.target_contents); | |
246 if (opener) | |
247 tab_strip->SetOpenerOfWebContentsAt(new_index, opener); | |
248 | |
249 if (active) | |
250 navigate_params.target_contents->GetView()->SetInitialFocus(); | |
251 | |
252 // Return data about the newly created tab. | |
253 return ExtensionTabUtil::CreateTabValue(navigate_params.target_contents, | |
254 tab_strip, | |
255 new_index, | |
256 function->GetExtension()); | |
257 } | |
258 | |
259 Browser* ExtensionTabUtil::GetBrowserFromWindowID( | |
260 ChromeAsyncExtensionFunction* function, | |
261 int window_id, | |
262 std::string* error) { | |
263 if (window_id == extension_misc::kCurrentWindowId) { | |
264 Browser* result = function->GetCurrentBrowser(); | |
265 if (!result || !result->window()) { | |
266 if (error) | |
267 *error = keys::kNoCurrentWindowError; | |
268 return NULL; | |
269 } | |
270 return result; | |
271 } else { | |
272 return GetBrowserInProfileWithId(function->GetProfile(), | |
273 window_id, | |
274 function->include_incognito(), | |
275 error); | |
276 } | |
277 } | |
278 | |
60 int ExtensionTabUtil::GetWindowId(const Browser* browser) { | 279 int ExtensionTabUtil::GetWindowId(const Browser* browser) { |
61 return browser->session_id().id(); | 280 return browser->session_id().id(); |
62 } | 281 } |
63 | 282 |
64 int ExtensionTabUtil::GetWindowIdOfTabStripModel( | 283 int ExtensionTabUtil::GetWindowIdOfTabStripModel( |
65 const TabStripModel* tab_strip_model) { | 284 const TabStripModel* tab_strip_model) { |
66 for (chrome::BrowserIterator it; !it.done(); it.Next()) { | 285 for (chrome::BrowserIterator it; !it.done(); it.Next()) { |
67 if (it->tab_strip_model() == tab_strip_model) | 286 if (it->tab_strip_model() == tab_strip_model) |
68 return GetWindowId(*it); | 287 return GetWindowId(*it); |
69 } | 288 } |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
354 content::PAGE_TRANSITION_LINK, | 573 content::PAGE_TRANSITION_LINK, |
355 false); | 574 false); |
356 browser->OpenURL(params); | 575 browser->OpenURL(params); |
357 browser->window()->Show(); | 576 browser->window()->Show(); |
358 WebContents* web_contents = | 577 WebContents* web_contents = |
359 browser->tab_strip_model()->GetActiveWebContents(); | 578 browser->tab_strip_model()->GetActiveWebContents(); |
360 web_contents->GetDelegate()->ActivateContents(web_contents); | 579 web_contents->GetDelegate()->ActivateContents(web_contents); |
361 } | 580 } |
362 | 581 |
363 } // namespace extensions | 582 } // namespace extensions |
OLD | NEW |