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

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

Issue 186343002: Create windows for new app window bounds API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Self nit: comment Created 6 years, 9 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/apps_client.h" 10 #include "apps/apps_client.h"
11 #include "apps/ui/native_app_window.h" 11 #include "apps/ui/native_app_window.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h"
14 #include "base/time/time.h" 15 #include "base/time/time.h"
15 #include "base/values.h" 16 #include "base/values.h"
16 #include "chrome/browser/app_mode/app_mode_utils.h" 17 #include "chrome/browser/app_mode/app_mode_utils.h"
17 #include "chrome/browser/devtools/devtools_window.h" 18 #include "chrome/browser/devtools/devtools_window.h"
18 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" 19 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
19 #include "chrome/browser/extensions/window_controller.h" 20 #include "chrome/browser/extensions/window_controller.h"
20 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/common/extensions/api/app_window.h" 22 #include "chrome/common/extensions/api/app_window.h"
22 #include "chrome/common/extensions/features/feature_channel.h" 23 #include "chrome/common/extensions/features/feature_channel.h"
23 #include "content/public/browser/notification_registrar.h" 24 #include "content/public/browser/notification_registrar.h"
(...skipping 25 matching lines...) Expand all
49 namespace app_window_constants { 50 namespace app_window_constants {
50 const char kInvalidWindowId[] = 51 const char kInvalidWindowId[] =
51 "The window id can not be more than 256 characters long."; 52 "The window id can not be more than 256 characters long.";
52 const char kInvalidColorSpecification[] = 53 const char kInvalidColorSpecification[] =
53 "The color specification could not be parsed."; 54 "The color specification could not be parsed.";
54 const char kInvalidChannelForFrameOptions[] = 55 const char kInvalidChannelForFrameOptions[] =
55 "frameOptions is only available in dev channel."; 56 "frameOptions is only available in dev channel.";
56 const char kFrameOptionsAndFrame[] = 57 const char kFrameOptionsAndFrame[] =
57 "Only one of frame and frameOptions can be supplied."; 58 "Only one of frame and frameOptions can be supplied.";
58 const char kColorWithFrameNone[] = "Windows with no frame cannot have a color."; 59 const char kColorWithFrameNone[] = "Windows with no frame cannot have a color.";
60 const char kInvalidChannelForBounds[] =
61 "innerBounds and outerBounds are only available in dev channel.";
59 } // namespace app_window_constants 62 } // namespace app_window_constants
60 63
61 const char kNoneFrameOption[] = "none"; 64 const char kNoneFrameOption[] = "none";
62 // TODO(benwells): Remove HTML titlebar injection. 65 // TODO(benwells): Remove HTML titlebar injection.
63 const char kHtmlFrameOption[] = "experimental-html"; 66 const char kHtmlFrameOption[] = "experimental-html";
64 67
65 namespace { 68 namespace {
66 69
67 // Opens an inspector window and delays the response to the 70 // Opens an inspector window and delays the response to the
68 // AppWindowCreateFunction until the DevToolsWindow has finished loading, and is 71 // AppWindowCreateFunction until the DevToolsWindow has finished loading, and is
(...skipping 17 matching lines...) Expand all
86 ~DevToolsRestorer() {} 89 ~DevToolsRestorer() {}
87 90
88 void LoadCompleted() { 91 void LoadCompleted() {
89 delayed_create_function_->SendDelayedResponse(); 92 delayed_create_function_->SendDelayedResponse();
90 Release(); 93 Release();
91 } 94 }
92 95
93 scoped_refptr<AppWindowCreateFunction> delayed_create_function_; 96 scoped_refptr<AppWindowCreateFunction> delayed_create_function_;
94 }; 97 };
95 98
99 // If the same property is specified for the inner and outer bounds, raise an
100 // error.
101 bool CheckBoundsConflict(const scoped_ptr<int>& inner_property,
102 const scoped_ptr<int>& outer_property,
103 const std::string& property_name,
104 std::string* error) {
105 if (inner_property.get() && outer_property.get()) {
106 std::vector<std::string> subst;
107 subst.push_back(property_name);
108 *error = ReplaceStringPlaceholders(
109 "The $1 property cannot be specified for both inner and outer bounds.",
benwells 2014/03/05 02:33:30 Nit: put this in kConflictingBlahBlah up with the
110 subst,
111 NULL);
112 return false;
113 }
114
115 return true;
116 }
117
118 // Copy over the bounds specification properties from the API to the
119 // AppWindow::CreateParams.
120 void CopyBoundsSpec(
121 const extensions::api::app_window::BoundsSpecification* input_spec,
122 apps::AppWindow::BoundsSpecification* create_spec) {
123 if (input_spec && input_spec->left.get())
tapted 2014/03/05 03:14:03 nit: if (!input_spec) return;
124 create_spec->bounds.set_x(*input_spec->left);
125 if (input_spec && input_spec->top.get())
126 create_spec->bounds.set_y(*input_spec->top);
127 if (input_spec && input_spec->width.get())
128 create_spec->bounds.set_width(*input_spec->width);
129 if (input_spec && input_spec->height.get())
130 create_spec->bounds.set_height(*input_spec->height);
131 if (input_spec && input_spec->min_width.get())
132 create_spec->minimum_size.set_width(*input_spec->min_width);
133 if (input_spec && input_spec->min_height.get())
134 create_spec->minimum_size.set_height(*input_spec->min_height);
135 if (input_spec && input_spec->max_width.get())
136 create_spec->maximum_size.set_width(*input_spec->max_width);
137 if (input_spec && input_spec->max_height.get())
138 create_spec->maximum_size.set_height(*input_spec->max_height);
139 }
140
96 } // namespace 141 } // namespace
97 142
98 AppWindowCreateFunction::AppWindowCreateFunction() 143 AppWindowCreateFunction::AppWindowCreateFunction()
99 : inject_html_titlebar_(false) {} 144 : inject_html_titlebar_(false) {}
100 145
101 void AppWindowCreateFunction::SendDelayedResponse() { 146 void AppWindowCreateFunction::SendDelayedResponse() {
102 SendResponse(true); 147 SendResponse(true);
103 } 148 }
104 149
105 bool AppWindowCreateFunction::RunImpl() { 150 bool AppWindowCreateFunction::RunImpl() {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 result->SetBoolean("existingWindow", true); 211 result->SetBoolean("existingWindow", true);
167 // TODO(benwells): Remove HTML titlebar injection. 212 // TODO(benwells): Remove HTML titlebar injection.
168 result->SetBoolean("injectTitlebar", false); 213 result->SetBoolean("injectTitlebar", false);
169 SetResult(result); 214 SetResult(result);
170 SendResponse(true); 215 SendResponse(true);
171 return true; 216 return true;
172 } 217 }
173 } 218 }
174 } 219 }
175 220
176 // TODO(jeremya): remove these, since they do the same thing as 221 if (!ParseBoundsSpec(*options, &create_params, &error_))
benwells 2014/03/05 02:33:30 Yay for making this monster function shorter. Mayb
177 // left/top/width/height. 222 return false;
178 if (options->default_width.get())
179 create_params.bounds.set_width(*options->default_width.get());
180 if (options->default_height.get())
181 create_params.bounds.set_height(*options->default_height.get());
182 if (options->default_left.get())
183 create_params.bounds.set_x(*options->default_left.get());
184 if (options->default_top.get())
185 create_params.bounds.set_y(*options->default_top.get());
186
187 if (options->width.get())
188 create_params.bounds.set_width(*options->width.get());
189 if (options->height.get())
190 create_params.bounds.set_height(*options->height.get());
191 if (options->left.get())
192 create_params.bounds.set_x(*options->left.get());
193 if (options->top.get())
194 create_params.bounds.set_y(*options->top.get());
195
196 if (options->bounds.get()) {
197 app_window::ContentBounds* bounds = options->bounds.get();
198 if (bounds->width.get())
199 create_params.bounds.set_width(*bounds->width.get());
200 if (bounds->height.get())
201 create_params.bounds.set_height(*bounds->height.get());
202 if (bounds->left.get())
203 create_params.bounds.set_x(*bounds->left.get());
204 if (bounds->top.get())
205 create_params.bounds.set_y(*bounds->top.get());
206 }
207 223
208 if (GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV || 224 if (GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV ||
209 GetExtension()->location() == extensions::Manifest::COMPONENT) { 225 GetExtension()->location() == extensions::Manifest::COMPONENT) {
210 if (options->type == extensions::api::app_window::WINDOW_TYPE_PANEL) { 226 if (options->type == extensions::api::app_window::WINDOW_TYPE_PANEL) {
211 create_params.window_type = AppWindow::WINDOW_TYPE_PANEL; 227 create_params.window_type = AppWindow::WINDOW_TYPE_PANEL;
212 } 228 }
213 } 229 }
214 230
215 if (!GetFrameOptions(*options, &create_params)) 231 if (!GetFrameOptions(*options, &create_params))
216 return false; 232 return false;
217 233
218 if (options->transparent_background.get() && 234 if (options->transparent_background.get() &&
219 (GetExtension()->HasAPIPermission(APIPermission::kExperimental) || 235 (GetExtension()->HasAPIPermission(APIPermission::kExperimental) ||
220 CommandLine::ForCurrentProcess()->HasSwitch( 236 CommandLine::ForCurrentProcess()->HasSwitch(
221 switches::kEnableExperimentalExtensionApis))) { 237 switches::kEnableExperimentalExtensionApis))) {
222 create_params.transparent_background = *options->transparent_background; 238 create_params.transparent_background = *options->transparent_background;
223 } 239 }
224 240
225 gfx::Size& minimum_size = create_params.minimum_size;
226 if (options->min_width.get())
227 minimum_size.set_width(*options->min_width);
228 if (options->min_height.get())
229 minimum_size.set_height(*options->min_height);
230 gfx::Size& maximum_size = create_params.maximum_size;
231 if (options->max_width.get())
232 maximum_size.set_width(*options->max_width);
233 if (options->max_height.get())
234 maximum_size.set_height(*options->max_height);
235
236 if (options->hidden.get()) 241 if (options->hidden.get())
237 create_params.hidden = *options->hidden.get(); 242 create_params.hidden = *options->hidden.get();
238 243
239 if (options->resizable.get()) 244 if (options->resizable.get())
240 create_params.resizable = *options->resizable.get(); 245 create_params.resizable = *options->resizable.get();
241 246
242 if (options->always_on_top.get() && 247 if (options->always_on_top.get() &&
243 GetExtension()->HasAPIPermission(APIPermission::kAlwaysOnTopWindows)) 248 GetExtension()->HasAPIPermission(APIPermission::kAlwaysOnTopWindows))
244 create_params.always_on_top = *options->always_on_top.get(); 249 create_params.always_on_top = *options->always_on_top.get();
245 250
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 if (apps::AppWindowRegistry::Get(GetProfile()) 299 if (apps::AppWindowRegistry::Get(GetProfile())
295 ->HadDevToolsAttached(created_view)) { 300 ->HadDevToolsAttached(created_view)) {
296 new DevToolsRestorer(this, created_view); 301 new DevToolsRestorer(this, created_view);
297 return true; 302 return true;
298 } 303 }
299 304
300 SendResponse(true); 305 SendResponse(true);
301 return true; 306 return true;
302 } 307 }
303 308
309 bool AppWindowCreateFunction::ParseBoundsSpec(
310 const extensions::api::app_window::CreateWindowOptions& options,
311 apps::AppWindow::CreateParams* params,
312 std::string* error) {
313 DCHECK(params);
314 DCHECK(error);
315
316 if (options.inner_bounds.get() || options.outer_bounds.get()) {
317 // Parse the inner and outer bounds specifications. If developers use the
318 // new API, the deprecated fields will be ignored - do not allow them to
319 // be mixed.
tapted 2014/03/05 03:14:03 nit: I read this thinking it would be an error if
320
321 if (GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV) {
322 *error = app_window_constants::kInvalidChannelForBounds;
323 return false;
324 }
325
326 const extensions::api::app_window::BoundsSpecification* inner_bounds =
327 options.inner_bounds.get();
328 const extensions::api::app_window::BoundsSpecification* outer_bounds =
329 options.outer_bounds.get();
330 if (inner_bounds && outer_bounds &&
benwells 2014/03/05 02:33:30 You can put all of these conflict checks into one
331 !CheckBoundsConflict(
332 inner_bounds->left, outer_bounds->left, "left", error)) {
333 return false;
334 }
335 if (inner_bounds && outer_bounds &&
336 !CheckBoundsConflict(
337 inner_bounds->top, outer_bounds->top, "top", error)) {
338 return false;
339 }
340 if (inner_bounds && outer_bounds &&
341 !CheckBoundsConflict(
342 inner_bounds->width, outer_bounds->width, "width", error)) {
343 return false;
344 }
345 if (inner_bounds && outer_bounds &&
346 !CheckBoundsConflict(
347 inner_bounds->height, outer_bounds->height, "height", error)) {
348 return false;
349 }
350 if (inner_bounds && outer_bounds &&
351 !CheckBoundsConflict(inner_bounds->min_width,
352 outer_bounds->min_width,
353 "minWidth",
354 error)) {
355 return false;
356 }
357 if (inner_bounds && outer_bounds &&
358 !CheckBoundsConflict(inner_bounds->min_height,
359 outer_bounds->min_height,
360 "minHeight",
361 error)) {
362 return false;
363 }
364 if (inner_bounds && outer_bounds &&
365 !CheckBoundsConflict(inner_bounds->max_width,
366 outer_bounds->max_width,
367 "maxWidth",
368 error)) {
369 return false;
370 }
371 if (inner_bounds && outer_bounds &&
372 !CheckBoundsConflict(inner_bounds->max_height,
373 outer_bounds->max_height,
374 "maxHeight",
375 error)) {
376 return false;
377 }
378
379 CopyBoundsSpec(inner_bounds, &(params->content_spec));
380 CopyBoundsSpec(outer_bounds, &(params->window_spec));
381 } else {
382 // Parse deprecated fields.
383
384 // TODO(jeremya): remove these, since they do the same thing as
benwells 2014/03/05 02:33:30 I don't think we have a plan or bug to remove thes
385 // left/top/width/height.
386 if (options.default_width.get())
387 params->content_spec.bounds.set_width(*options.default_width.get());
388 if (options.default_height.get())
389 params->content_spec.bounds.set_height(*options.default_height.get());
390 if (options.default_left.get())
391 params->content_spec.bounds.set_x(*options.default_left.get());
benwells 2014/03/05 02:33:30 My understanding is that previously left / top in
tmdiep 2014/03/05 03:06:47 Ugh. bounds.left and bounds.top were actually inte
tmdiep 2014/03/06 01:06:49 I will make top/left be interpreted as top/left of
benwells 2014/03/06 22:40:16 Awesome, love it. You should add a comment briefly
392 if (options.default_top.get())
393 params->content_spec.bounds.set_y(*options.default_top.get());
394
395 if (options.width.get())
396 params->content_spec.bounds.set_width(*options.width.get());
397 if (options.height.get())
398 params->content_spec.bounds.set_height(*options.height.get());
399 if (options.left.get())
400 params->content_spec.bounds.set_x(*options.left.get());
401 if (options.top.get())
402 params->content_spec.bounds.set_y(*options.top.get());
403
404 if (options.bounds.get()) {
405 app_window::ContentBounds* bounds = options.bounds.get();
406 if (bounds->width.get())
407 params->content_spec.bounds.set_width(*bounds->width.get());
408 if (bounds->height.get())
409 params->content_spec.bounds.set_height(*bounds->height.get());
410 if (bounds->left.get())
411 params->content_spec.bounds.set_x(*bounds->left.get());
412 if (bounds->top.get())
413 params->content_spec.bounds.set_y(*bounds->top.get());
414 }
415
416 gfx::Size& minimum_size = params->content_spec.minimum_size;
417 if (options.min_width.get())
418 minimum_size.set_width(*options.min_width);
419 if (options.min_height.get())
420 minimum_size.set_height(*options.min_height);
421 gfx::Size& maximum_size = params->content_spec.maximum_size;
422 if (options.max_width.get())
423 maximum_size.set_width(*options.max_width);
424 if (options.max_height.get())
425 maximum_size.set_height(*options.max_height);
426 }
427
428 return true;
429 }
430
304 AppWindow::Frame AppWindowCreateFunction::GetFrameFromString( 431 AppWindow::Frame AppWindowCreateFunction::GetFrameFromString(
305 const std::string& frame_string) { 432 const std::string& frame_string) {
306 if (frame_string == kHtmlFrameOption && 433 if (frame_string == kHtmlFrameOption &&
307 (GetExtension()->HasAPIPermission(APIPermission::kExperimental) || 434 (GetExtension()->HasAPIPermission(APIPermission::kExperimental) ||
308 CommandLine::ForCurrentProcess()->HasSwitch( 435 CommandLine::ForCurrentProcess()->HasSwitch(
309 switches::kEnableExperimentalExtensionApis))) { 436 switches::kEnableExperimentalExtensionApis))) {
310 inject_html_titlebar_ = true; 437 inject_html_titlebar_ = true;
311 return AppWindow::FRAME_NONE; 438 return AppWindow::FRAME_NONE;
312 } 439 }
313 440
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV) { 492 GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV) {
366 // If not on trunk or dev channel, always use the standard white frame. 493 // 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 494 // TODO(benwells): Remove this code once we get agreement to use the new
368 // native style frame. 495 // native style frame.
369 create_params->has_frame_color = true; 496 create_params->has_frame_color = true;
370 create_params->frame_color = SK_ColorWHITE; 497 create_params->frame_color = SK_ColorWHITE;
371 } 498 }
372 } 499 }
373 500
374 } // namespace extensions 501 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698