Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: chrome/browser/extensions/api/app_window/app_window_api.cc

Issue 166443004: Add frame color option to packaged app windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/api/app_window/app_window_api.h" 5 #include "chrome/browser/extensions/api/app_window/app_window_api.h"
6 6
7 #include "apps/app_window.h" 7 #include "apps/app_window.h"
8 #include "apps/app_window_contents.h" 8 #include "apps/app_window_contents.h"
9 #include "apps/app_window_registry.h" 9 #include "apps/app_window_registry.h"
10 #include "apps/ui/native_app_window.h" 10 #include "apps/ui/native_app_window.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/strings/string_number_conversions.h"
12 #include "base/time/time.h" 13 #include "base/time/time.h"
13 #include "base/values.h" 14 #include "base/values.h"
14 #include "chrome/browser/app_mode/app_mode_utils.h" 15 #include "chrome/browser/app_mode/app_mode_utils.h"
15 #include "chrome/browser/devtools/devtools_window.h" 16 #include "chrome/browser/devtools/devtools_window.h"
17 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
16 #include "chrome/browser/extensions/window_controller.h" 18 #include "chrome/browser/extensions/window_controller.h"
17 #include "chrome/browser/profiles/profile.h" 19 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/apps/chrome_app_window_delegate.h" 20 #include "chrome/browser/ui/apps/chrome_app_window_delegate.h"
19 #include "chrome/common/extensions/api/app_window.h" 21 #include "chrome/common/extensions/api/app_window.h"
20 #include "chrome/common/extensions/features/feature_channel.h" 22 #include "chrome/common/extensions/features/feature_channel.h"
21 #include "content/public/browser/notification_registrar.h" 23 #include "content/public/browser/notification_registrar.h"
22 #include "content/public/browser/notification_types.h" 24 #include "content/public/browser/notification_types.h"
23 #include "content/public/browser/render_process_host.h" 25 #include "content/public/browser/render_process_host.h"
24 #include "content/public/browser/render_view_host.h" 26 #include "content/public/browser/render_view_host.h"
25 #include "content/public/browser/web_contents.h" 27 #include "content/public/browser/web_contents.h"
26 #include "content/public/common/url_constants.h" 28 #include "content/public/common/url_constants.h"
27 #include "extensions/browser/extensions_browser_client.h" 29 #include "extensions/browser/extensions_browser_client.h"
28 #include "extensions/common/switches.h" 30 #include "extensions/common/switches.h"
31 #include "third_party/skia/include/core/SkColor.h"
29 #include "ui/base/ui_base_types.h" 32 #include "ui/base/ui_base_types.h"
30 #include "ui/gfx/rect.h" 33 #include "ui/gfx/rect.h"
31 #include "url/gurl.h" 34 #include "url/gurl.h"
32 35
33 #if defined(USE_ASH) 36 #if defined(USE_ASH)
34 #include "ash/shell.h" 37 #include "ash/shell.h"
35 #include "ui/aura/root_window.h" 38 #include "ui/aura/root_window.h"
36 #include "ui/aura/window.h" 39 #include "ui/aura/window.h"
37 #endif 40 #endif
38 41
39 using apps::AppWindow; 42 using apps::AppWindow;
40 43
41 namespace app_window = extensions::api::app_window; 44 namespace app_window = extensions::api::app_window;
42 namespace Create = app_window::Create; 45 namespace Create = app_window::Create;
43 46
44 namespace extensions { 47 namespace extensions {
45 48
46 namespace app_window_constants { 49 namespace app_window_constants {
47 const char kInvalidWindowId[] = 50 const char kInvalidWindowId[] =
48 "The window id can not be more than 256 characters long."; 51 "The window id can not be more than 256 characters long.";
49 } 52 const char kInvalidColorSpecification[] =
53 "The color specification could not be parsed.";
54 const char kInvalidChannelForFrameOptions[] =
55 "frameOptions is only available in dev channel.";
56 const char kFrameOptionsAndFrame[] =
57 "Only one of frame and frameOptions can be supplied.";
58 const char kColorWithFrameNone[] = "Windows with no frame cannot have a color.";
59 } // namespace app_window_constants
50 60
51 const char kNoneFrameOption[] = "none"; 61 const char kNoneFrameOption[] = "none";
62 // TODO(benwells): Remove HTML titlebar injection.
52 const char kHtmlFrameOption[] = "experimental-html"; 63 const char kHtmlFrameOption[] = "experimental-html";
53 64
54 namespace { 65 namespace {
55 66
56 // Opens an inspector window and delays the response to the 67 // Opens an inspector window and delays the response to the
57 // AppWindowCreateFunction until the DevToolsWindow has finished loading, and is 68 // AppWindowCreateFunction until the DevToolsWindow has finished loading, and is
58 // ready to stop on breakpoints in the callback. 69 // ready to stop on breakpoints in the callback.
59 class DevToolsRestorer : public base::RefCounted<DevToolsRestorer> { 70 class DevToolsRestorer : public base::RefCounted<DevToolsRestorer> {
60 public: 71 public:
61 DevToolsRestorer(AppWindowCreateFunction* delayed_create_function, 72 DevToolsRestorer(AppWindowCreateFunction* delayed_create_function,
(...skipping 15 matching lines...) Expand all
77 void LoadCompleted() { 88 void LoadCompleted() {
78 delayed_create_function_->SendDelayedResponse(); 89 delayed_create_function_->SendDelayedResponse();
79 Release(); 90 Release();
80 } 91 }
81 92
82 scoped_refptr<AppWindowCreateFunction> delayed_create_function_; 93 scoped_refptr<AppWindowCreateFunction> delayed_create_function_;
83 }; 94 };
84 95
85 } // namespace 96 } // namespace
86 97
98 AppWindowCreateFunction::AppWindowCreateFunction()
99 : inject_html_titlebar_(false) {}
100
87 void AppWindowCreateFunction::SendDelayedResponse() { 101 void AppWindowCreateFunction::SendDelayedResponse() {
88 SendResponse(true); 102 SendResponse(true);
89 } 103 }
90 104
91 bool AppWindowCreateFunction::RunImpl() { 105 bool AppWindowCreateFunction::RunImpl() {
92 // Don't create app window if the system is shutting down. 106 // Don't create app window if the system is shutting down.
93 if (extensions::ExtensionsBrowserClient::Get()->IsShuttingDown()) 107 if (extensions::ExtensionsBrowserClient::Get()->IsShuttingDown())
94 return false; 108 return false;
95 109
96 scoped_ptr<Create::Params> params(Create::Params::Create(*args_)); 110 scoped_ptr<Create::Params> params(Create::Params::Create(*args_));
97 EXTENSION_FUNCTION_VALIDATE(params.get()); 111 EXTENSION_FUNCTION_VALIDATE(params.get());
98 112
99 GURL url = GetExtension()->GetResourceURL(params->url); 113 GURL url = GetExtension()->GetResourceURL(params->url);
100 // Allow absolute URLs for component apps, otherwise prepend the extension 114 // Allow absolute URLs for component apps, otherwise prepend the extension
101 // path. 115 // path.
102 if (GetExtension()->location() == extensions::Manifest::COMPONENT) { 116 if (GetExtension()->location() == extensions::Manifest::COMPONENT) {
103 GURL absolute = GURL(params->url); 117 GURL absolute = GURL(params->url);
104 if (absolute.has_scheme()) 118 if (absolute.has_scheme())
105 url = absolute; 119 url = absolute;
106 } 120 }
107 121
108 bool inject_html_titlebar = false;
109
110 // TODO(jeremya): figure out a way to pass the opening WebContents through to 122 // TODO(jeremya): figure out a way to pass the opening WebContents through to
111 // AppWindow::Create so we can set the opener at create time rather than 123 // AppWindow::Create so we can set the opener at create time rather than
112 // with a hack in AppWindowCustomBindings::GetView(). 124 // with a hack in AppWindowCustomBindings::GetView().
113 AppWindow::CreateParams create_params; 125 AppWindow::CreateParams create_params;
114 app_window::CreateWindowOptions* options = params->options.get(); 126 app_window::CreateWindowOptions* options = params->options.get();
115 if (options) { 127 if (options) {
116 if (options->id.get()) { 128 if (options->id.get()) {
117 // TODO(mek): use URL if no id specified? 129 // TODO(mek): use URL if no id specified?
118 // Limit length of id to 256 characters. 130 // Limit length of id to 256 characters.
119 if (options->id->length() > 256) { 131 if (options->id->length() > 256) {
(...skipping 25 matching lines...) Expand all
145 157
146 if (options->focused.get() && !*options->focused.get()) 158 if (options->focused.get() && !*options->focused.get())
147 window->Show(AppWindow::SHOW_INACTIVE); 159 window->Show(AppWindow::SHOW_INACTIVE);
148 else 160 else
149 window->Show(AppWindow::SHOW_ACTIVE); 161 window->Show(AppWindow::SHOW_ACTIVE);
150 162
151 base::DictionaryValue* result = new base::DictionaryValue; 163 base::DictionaryValue* result = new base::DictionaryValue;
152 result->Set("viewId", new base::FundamentalValue(view_id)); 164 result->Set("viewId", new base::FundamentalValue(view_id));
153 window->GetSerializedState(result); 165 window->GetSerializedState(result);
154 result->SetBoolean("existingWindow", true); 166 result->SetBoolean("existingWindow", true);
167 // TODO(benwells): Remove HTML titlebar injection.
155 result->SetBoolean("injectTitlebar", false); 168 result->SetBoolean("injectTitlebar", false);
156 SetResult(result); 169 SetResult(result);
157 SendResponse(true); 170 SendResponse(true);
158 return true; 171 return true;
159 } 172 }
160 } 173 }
161 } 174 }
162 175
163 // TODO(jeremya): remove these, since they do the same thing as 176 // TODO(jeremya): remove these, since they do the same thing as
164 // left/top/width/height. 177 // left/top/width/height.
(...skipping 27 matching lines...) Expand all
192 create_params.bounds.set_y(*bounds->top.get()); 205 create_params.bounds.set_y(*bounds->top.get());
193 } 206 }
194 207
195 if (GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV || 208 if (GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV ||
196 GetExtension()->location() == extensions::Manifest::COMPONENT) { 209 GetExtension()->location() == extensions::Manifest::COMPONENT) {
197 if (options->type == extensions::api::app_window::WINDOW_TYPE_PANEL) { 210 if (options->type == extensions::api::app_window::WINDOW_TYPE_PANEL) {
198 create_params.window_type = AppWindow::WINDOW_TYPE_PANEL; 211 create_params.window_type = AppWindow::WINDOW_TYPE_PANEL;
199 } 212 }
200 } 213 }
201 214
202 if (options->frame.get()) { 215 if (!GetFrameOptions(*options, &create_params))
203 if (*options->frame == kHtmlFrameOption && 216 return false;
204 (GetExtension()->HasAPIPermission(APIPermission::kExperimental) ||
205 CommandLine::ForCurrentProcess()->HasSwitch(
206 switches::kEnableExperimentalExtensionApis))) {
207 create_params.frame = AppWindow::FRAME_NONE;
208 inject_html_titlebar = true;
209 } else if (*options->frame == kNoneFrameOption) {
210 create_params.frame = AppWindow::FRAME_NONE;
211 } else {
212 create_params.frame = AppWindow::FRAME_CHROME;
213 }
214 }
215 217
216 if (options->transparent_background.get() && 218 if (options->transparent_background.get() &&
217 (GetExtension()->HasAPIPermission(APIPermission::kExperimental) || 219 (GetExtension()->HasAPIPermission(APIPermission::kExperimental) ||
218 CommandLine::ForCurrentProcess()->HasSwitch( 220 CommandLine::ForCurrentProcess()->HasSwitch(
219 switches::kEnableExperimentalExtensionApis))) { 221 switches::kEnableExperimentalExtensionApis))) {
220 create_params.transparent_background = *options->transparent_background; 222 create_params.transparent_background = *options->transparent_background;
221 } 223 }
222 224
223 gfx::Size& minimum_size = create_params.minimum_size; 225 gfx::Size& minimum_size = create_params.minimum_size;
224 if (options->min_width.get()) 226 if (options->min_width.get())
(...skipping 30 matching lines...) Expand all
255 case extensions::api::app_window::STATE_MAXIMIZED: 257 case extensions::api::app_window::STATE_MAXIMIZED:
256 create_params.state = ui::SHOW_STATE_MAXIMIZED; 258 create_params.state = ui::SHOW_STATE_MAXIMIZED;
257 break; 259 break;
258 case extensions::api::app_window::STATE_MINIMIZED: 260 case extensions::api::app_window::STATE_MINIMIZED:
259 create_params.state = ui::SHOW_STATE_MINIMIZED; 261 create_params.state = ui::SHOW_STATE_MINIMIZED;
260 break; 262 break;
261 } 263 }
262 } 264 }
263 } 265 }
264 266
267 UpdateFrameOptionsForChannel(&create_params);
268
265 create_params.creator_process_id = 269 create_params.creator_process_id =
266 render_view_host_->GetProcess()->GetID(); 270 render_view_host_->GetProcess()->GetID();
267 271
268 AppWindow* app_window = new AppWindow( 272 AppWindow* app_window = new AppWindow(
269 GetProfile(), new ChromeAppWindowDelegate(), GetExtension()); 273 GetProfile(), new ChromeAppWindowDelegate(), GetExtension());
270 app_window->Init( 274 app_window->Init(
271 url, new apps::AppWindowContentsImpl(app_window), create_params); 275 url, new apps::AppWindowContentsImpl(app_window), create_params);
272 276
273 if (chrome::IsRunningInForcedAppMode()) 277 if (chrome::IsRunningInForcedAppMode())
274 app_window->ForcedFullscreen(); 278 app_window->ForcedFullscreen();
275 279
276 content::RenderViewHost* created_view = 280 content::RenderViewHost* created_view =
277 app_window->web_contents()->GetRenderViewHost(); 281 app_window->web_contents()->GetRenderViewHost();
278 int view_id = MSG_ROUTING_NONE; 282 int view_id = MSG_ROUTING_NONE;
279 if (create_params.creator_process_id == created_view->GetProcess()->GetID()) 283 if (create_params.creator_process_id == created_view->GetProcess()->GetID())
280 view_id = created_view->GetRoutingID(); 284 view_id = created_view->GetRoutingID();
281 285
282 base::DictionaryValue* result = new base::DictionaryValue; 286 base::DictionaryValue* result = new base::DictionaryValue;
283 result->Set("viewId", new base::FundamentalValue(view_id)); 287 result->Set("viewId", new base::FundamentalValue(view_id));
284 result->Set("injectTitlebar", 288 result->Set("injectTitlebar",
285 new base::FundamentalValue(inject_html_titlebar)); 289 new base::FundamentalValue(inject_html_titlebar_));
286 result->Set("id", new base::StringValue(app_window->window_key())); 290 result->Set("id", new base::StringValue(app_window->window_key()));
287 app_window->GetSerializedState(result); 291 app_window->GetSerializedState(result);
288 SetResult(result); 292 SetResult(result);
289 293
290 if (apps::AppWindowRegistry::Get(GetProfile()) 294 if (apps::AppWindowRegistry::Get(GetProfile())
291 ->HadDevToolsAttached(created_view)) { 295 ->HadDevToolsAttached(created_view)) {
292 new DevToolsRestorer(this, created_view); 296 new DevToolsRestorer(this, created_view);
293 return true; 297 return true;
294 } 298 }
295 299
296 SendResponse(true); 300 SendResponse(true);
297 return true; 301 return true;
298 } 302 }
299 303
304 AppWindow::Frame AppWindowCreateFunction::GetFrameFromString(
305 const std::string& frame_string) {
306 if (frame_string == kHtmlFrameOption &&
307 (GetExtension()->HasAPIPermission(APIPermission::kExperimental) ||
308 CommandLine::ForCurrentProcess()->HasSwitch(
309 switches::kEnableExperimentalExtensionApis))) {
310 inject_html_titlebar_ = true;
311 return AppWindow::FRAME_NONE;
312 }
313
314 if (frame_string == kNoneFrameOption)
315 return AppWindow::FRAME_NONE;
316
317 return AppWindow::FRAME_CHROME;
318 }
319
320 bool AppWindowCreateFunction::GetFrameOptions(
321 const app_window::CreateWindowOptions& options,
322 AppWindow::CreateParams* create_params) {
323 if (options.frame.get() && options.frame_options.get()) {
324 error_ = app_window_constants::kFrameOptionsAndFrame;
325 return false;
326 }
327
328 if (options.frame.get())
329 create_params->frame = GetFrameFromString(*options.frame);
330
331 if (options.frame_options.get()) {
332 if (GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV) {
333 app_window::FrameOptions* frame_options = options.frame_options.get();
334
335 if (frame_options->type.get())
336 create_params->frame = GetFrameFromString(*frame_options->type);
337
338 if (frame_options->color.get()) {
339 if (create_params->frame != AppWindow::FRAME_CHROME) {
340 error_ = app_window_constants::kColorWithFrameNone;
341 return false;
342 }
343
344 if (ExtensionActionFunction::ParseCSSColorString(
345 *frame_options->color,
346 &create_params->frame_color)) {
347 create_params->has_frame_color = true;
348 } else {
349 error_ = app_window_constants::kInvalidColorSpecification;
350 return false;
351 }
352 }
353 } else {
354 error_ = app_window_constants::kInvalidChannelForFrameOptions;
355 return false;
356 }
357 }
358
359 return true;
360 }
361
362 void AppWindowCreateFunction::UpdateFrameOptionsForChannel(
363 apps::AppWindow::CreateParams* create_params) {
364 if (create_params->frame == AppWindow::FRAME_CHROME &&
365 GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV) {
366 // If not on trunk or dev channel, always use the standard white frame.
367 // TODO(benwells): Remove this code once we get agreement to use the new
368 // native style frame.
369 create_params->has_frame_color = true;
370 create_params->frame_color = SK_ColorWHITE;
371 }
372 }
373
300 } // namespace extensions 374 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698