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

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: Addressed nit 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.";
62 const char kConflictingBoundsOptions[] =
63 "The $1 property cannot be specified for both inner and outer bounds.";
59 } // namespace app_window_constants 64 } // namespace app_window_constants
60 65
61 const char kNoneFrameOption[] = "none"; 66 const char kNoneFrameOption[] = "none";
62 // TODO(benwells): Remove HTML titlebar injection. 67 // TODO(benwells): Remove HTML titlebar injection.
63 const char kHtmlFrameOption[] = "experimental-html"; 68 const char kHtmlFrameOption[] = "experimental-html";
64 69
65 namespace { 70 namespace {
66 71
67 // Opens an inspector window and delays the response to the 72 // Opens an inspector window and delays the response to the
68 // AppWindowCreateFunction until the DevToolsWindow has finished loading, and is 73 // AppWindowCreateFunction until the DevToolsWindow has finished loading, and is
(...skipping 17 matching lines...) Expand all
86 ~DevToolsRestorer() {} 91 ~DevToolsRestorer() {}
87 92
88 void LoadCompleted() { 93 void LoadCompleted() {
89 delayed_create_function_->SendDelayedResponse(); 94 delayed_create_function_->SendDelayedResponse();
90 Release(); 95 Release();
91 } 96 }
92 97
93 scoped_refptr<AppWindowCreateFunction> delayed_create_function_; 98 scoped_refptr<AppWindowCreateFunction> delayed_create_function_;
94 }; 99 };
95 100
101 // If the same property is specified for the inner and outer bounds, raise an
102 // error.
103 bool CheckBoundsConflict(const scoped_ptr<int>& inner_property,
104 const scoped_ptr<int>& outer_property,
105 const std::string& property_name,
106 std::string* error) {
107 if (inner_property.get() && outer_property.get()) {
108 std::vector<std::string> subst;
109 subst.push_back(property_name);
110 *error = ReplaceStringPlaceholders(
111 app_window_constants::kConflictingBoundsOptions, subst, 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)
124 return;
125
126 if (input_spec->left.get())
127 create_spec->bounds.set_x(*input_spec->left);
128 if (input_spec->top.get())
129 create_spec->bounds.set_y(*input_spec->top);
130 if (input_spec->width.get())
131 create_spec->bounds.set_width(*input_spec->width);
132 if (input_spec->height.get())
133 create_spec->bounds.set_height(*input_spec->height);
134 if (input_spec->min_width.get())
135 create_spec->minimum_size.set_width(*input_spec->min_width);
136 if (input_spec->min_height.get())
137 create_spec->minimum_size.set_height(*input_spec->min_height);
138 if (input_spec->max_width.get())
139 create_spec->maximum_size.set_width(*input_spec->max_width);
140 if (input_spec->max_height.get())
141 create_spec->maximum_size.set_height(*input_spec->max_height);
142 }
143
96 } // namespace 144 } // namespace
97 145
98 AppWindowCreateFunction::AppWindowCreateFunction() 146 AppWindowCreateFunction::AppWindowCreateFunction()
99 : inject_html_titlebar_(false) {} 147 : inject_html_titlebar_(false) {}
100 148
101 void AppWindowCreateFunction::SendDelayedResponse() { 149 void AppWindowCreateFunction::SendDelayedResponse() {
102 SendResponse(true); 150 SendResponse(true);
103 } 151 }
104 152
105 bool AppWindowCreateFunction::RunImpl() { 153 bool AppWindowCreateFunction::RunImpl() {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 result->SetBoolean("existingWindow", true); 214 result->SetBoolean("existingWindow", true);
167 // TODO(benwells): Remove HTML titlebar injection. 215 // TODO(benwells): Remove HTML titlebar injection.
168 result->SetBoolean("injectTitlebar", false); 216 result->SetBoolean("injectTitlebar", false);
169 SetResult(result); 217 SetResult(result);
170 SendResponse(true); 218 SendResponse(true);
171 return true; 219 return true;
172 } 220 }
173 } 221 }
174 } 222 }
175 223
176 // TODO(jeremya): remove these, since they do the same thing as 224 if (!GetBoundsSpec(*options, &create_params, &error_))
177 // left/top/width/height. 225 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 226
208 if (GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV || 227 if (GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV ||
209 GetExtension()->location() == extensions::Manifest::COMPONENT) { 228 GetExtension()->location() == extensions::Manifest::COMPONENT) {
210 if (options->type == extensions::api::app_window::WINDOW_TYPE_PANEL) { 229 if (options->type == extensions::api::app_window::WINDOW_TYPE_PANEL) {
211 create_params.window_type = AppWindow::WINDOW_TYPE_PANEL; 230 create_params.window_type = AppWindow::WINDOW_TYPE_PANEL;
212 } 231 }
213 } 232 }
214 233
215 if (!GetFrameOptions(*options, &create_params)) 234 if (!GetFrameOptions(*options, &create_params))
216 return false; 235 return false;
217 236
218 if (options->transparent_background.get() && 237 if (options->transparent_background.get() &&
219 (GetExtension()->HasAPIPermission(APIPermission::kExperimental) || 238 (GetExtension()->HasAPIPermission(APIPermission::kExperimental) ||
220 CommandLine::ForCurrentProcess()->HasSwitch( 239 CommandLine::ForCurrentProcess()->HasSwitch(
221 switches::kEnableExperimentalExtensionApis))) { 240 switches::kEnableExperimentalExtensionApis))) {
222 create_params.transparent_background = *options->transparent_background; 241 create_params.transparent_background = *options->transparent_background;
223 } 242 }
224 243
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()) 244 if (options->hidden.get())
237 create_params.hidden = *options->hidden.get(); 245 create_params.hidden = *options->hidden.get();
238 246
239 if (options->resizable.get()) 247 if (options->resizable.get())
240 create_params.resizable = *options->resizable.get(); 248 create_params.resizable = *options->resizable.get();
241 249
242 if (options->always_on_top.get() && 250 if (options->always_on_top.get() &&
243 GetExtension()->HasAPIPermission(APIPermission::kAlwaysOnTopWindows)) 251 GetExtension()->HasAPIPermission(APIPermission::kAlwaysOnTopWindows))
244 create_params.always_on_top = *options->always_on_top.get(); 252 create_params.always_on_top = *options->always_on_top.get();
245 253
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 if (apps::AppWindowRegistry::Get(GetProfile()) 302 if (apps::AppWindowRegistry::Get(GetProfile())
295 ->HadDevToolsAttached(created_view)) { 303 ->HadDevToolsAttached(created_view)) {
296 new DevToolsRestorer(this, created_view); 304 new DevToolsRestorer(this, created_view);
297 return true; 305 return true;
298 } 306 }
299 307
300 SendResponse(true); 308 SendResponse(true);
301 return true; 309 return true;
302 } 310 }
303 311
312 bool AppWindowCreateFunction::GetBoundsSpec(
313 const extensions::api::app_window::CreateWindowOptions& options,
314 apps::AppWindow::CreateParams* params,
315 std::string* error) {
316 DCHECK(params);
317 DCHECK(error);
318
319 if (options.inner_bounds.get() || options.outer_bounds.get()) {
320 // Parse the inner and outer bounds specifications. If developers use the
321 // new API, the deprecated fields will be ignored - do not attempt to merge
322 // them.
323
324 if (GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV) {
325 *error = app_window_constants::kInvalidChannelForBounds;
326 return false;
327 }
328
329 const extensions::api::app_window::BoundsSpecification* inner_bounds =
330 options.inner_bounds.get();
331 const extensions::api::app_window::BoundsSpecification* outer_bounds =
332 options.outer_bounds.get();
333 if (inner_bounds && outer_bounds) {
334 if (!CheckBoundsConflict(
335 inner_bounds->left, outer_bounds->left, "left", error)) {
336 return false;
337 }
338 if (!CheckBoundsConflict(
339 inner_bounds->top, outer_bounds->top, "top", error)) {
340 return false;
341 }
342 if (!CheckBoundsConflict(
343 inner_bounds->width, outer_bounds->width, "width", error)) {
344 return false;
345 }
346 if (!CheckBoundsConflict(
347 inner_bounds->height, outer_bounds->height, "height", error)) {
348 return false;
349 }
350 if (!CheckBoundsConflict(inner_bounds->min_width,
351 outer_bounds->min_width,
352 "minWidth",
353 error)) {
354 return false;
355 }
356 if (!CheckBoundsConflict(inner_bounds->min_height,
357 outer_bounds->min_height,
358 "minHeight",
359 error)) {
360 return false;
361 }
362 if (!CheckBoundsConflict(inner_bounds->max_width,
363 outer_bounds->max_width,
364 "maxWidth",
365 error)) {
366 return false;
367 }
368 if (!CheckBoundsConflict(inner_bounds->max_height,
369 outer_bounds->max_height,
370 "maxHeight",
371 error)) {
372 return false;
373 }
374 }
375
376 CopyBoundsSpec(inner_bounds, &(params->content_spec));
377 CopyBoundsSpec(outer_bounds, &(params->window_spec));
378 } else {
379 // Parse deprecated fields.
380 // Due to a bug in NativeAppWindow::GetFrameInsets() on Windows and ChromeOS
381 // the bounds set the position of the window and the size of the content.
382 // This will be preserved as apps may be relying on this behavior.
383
384 if (options.default_width.get())
385 params->content_spec.bounds.set_width(*options.default_width.get());
386 if (options.default_height.get())
387 params->content_spec.bounds.set_height(*options.default_height.get());
388 if (options.default_left.get())
389 params->window_spec.bounds.set_x(*options.default_left.get());
390 if (options.default_top.get())
391 params->window_spec.bounds.set_y(*options.default_top.get());
392
393 if (options.width.get())
394 params->content_spec.bounds.set_width(*options.width.get());
395 if (options.height.get())
396 params->content_spec.bounds.set_height(*options.height.get());
397 if (options.left.get())
398 params->window_spec.bounds.set_x(*options.left.get());
399 if (options.top.get())
400 params->window_spec.bounds.set_y(*options.top.get());
401
402 if (options.bounds.get()) {
403 app_window::ContentBounds* bounds = options.bounds.get();
404 if (bounds->width.get())
405 params->content_spec.bounds.set_width(*bounds->width.get());
406 if (bounds->height.get())
407 params->content_spec.bounds.set_height(*bounds->height.get());
408 if (bounds->left.get())
409 params->window_spec.bounds.set_x(*bounds->left.get());
410 if (bounds->top.get())
411 params->window_spec.bounds.set_y(*bounds->top.get());
412 }
413
414 gfx::Size& minimum_size = params->content_spec.minimum_size;
415 if (options.min_width.get())
416 minimum_size.set_width(*options.min_width);
417 if (options.min_height.get())
418 minimum_size.set_height(*options.min_height);
419 gfx::Size& maximum_size = params->content_spec.maximum_size;
420 if (options.max_width.get())
421 maximum_size.set_width(*options.max_width);
422 if (options.max_height.get())
423 maximum_size.set_height(*options.max_height);
424 }
425
426 return true;
427 }
428
304 AppWindow::Frame AppWindowCreateFunction::GetFrameFromString( 429 AppWindow::Frame AppWindowCreateFunction::GetFrameFromString(
305 const std::string& frame_string) { 430 const std::string& frame_string) {
306 if (frame_string == kHtmlFrameOption && 431 if (frame_string == kHtmlFrameOption &&
307 (GetExtension()->HasAPIPermission(APIPermission::kExperimental) || 432 (GetExtension()->HasAPIPermission(APIPermission::kExperimental) ||
308 CommandLine::ForCurrentProcess()->HasSwitch( 433 CommandLine::ForCurrentProcess()->HasSwitch(
309 switches::kEnableExperimentalExtensionApis))) { 434 switches::kEnableExperimentalExtensionApis))) {
310 inject_html_titlebar_ = true; 435 inject_html_titlebar_ = true;
311 return AppWindow::FRAME_NONE; 436 return AppWindow::FRAME_NONE;
312 } 437 }
313 438
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV) { 490 GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV) {
366 // If not on trunk or dev channel, always use the standard white frame. 491 // 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 492 // TODO(benwells): Remove this code once we get agreement to use the new
368 // native style frame. 493 // native style frame.
369 create_params->has_frame_color = true; 494 create_params->has_frame_color = true;
370 create_params->frame_color = SK_ColorWHITE; 495 create_params->frame_color = SK_ColorWHITE;
371 } 496 }
372 } 497 }
373 498
374 } // namespace extensions 499 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/app_window/app_window_api.h ('k') | chrome/browser/extensions/api/tabs/tabs_api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698