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
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/api/app_current_window_internal/app_current_window_internal_api.h"
7 #include "apps/shell_window.h"
8 #include "apps/shell_window_registry.h"
9 #include "apps/ui/native_app_window.h"
10 #include "base/command_line.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/common/extensions/api/app_current_window_internal.h"
13 #include "chrome/common/extensions/api/app_window.h"
14 #include "chrome/common/extensions/features/feature_channel.h"
15 #include "chrome/common/extensions/features/simple_feature.h"
16 #include "extensions/common/switches.h"
17 #include "third_party/skia/include/core/SkRegion.h"
19 namespace app_current_window_internal =
20 extensions::api::app_current_window_internal;
22 namespace SetBounds = app_current_window_internal::SetBounds;
23 namespace SetMinWidth = app_current_window_internal::SetMinWidth;
24 namespace SetMinHeight = app_current_window_internal::SetMinHeight;
25 namespace SetMaxWidth = app_current_window_internal::SetMaxWidth;
26 namespace SetMaxHeight = app_current_window_internal::SetMaxHeight;
27 namespace SetIcon = app_current_window_internal::SetIcon;
28 namespace SetInputRegion = app_current_window_internal::SetInputRegion;
29 namespace SetAlwaysOnTop = app_current_window_internal::SetAlwaysOnTop;
31 using apps::ShellWindow;
32 using app_current_window_internal::Bounds;
33 using app_current_window_internal::Region;
34 using app_current_window_internal::RegionRect;
36 namespace extensions {
40 const char kNoAssociatedShellWindow[] =
41 "The context from which the function was called did not have an "
42 "associated shell window.";
44 const char kDevChannelOnly[] =
45 "This function is currently only available in the Dev channel.";
47 const int kUnboundedSize = apps::ShellWindow::SizeConstraints::kUnboundedSize;
51 bool AppCurrentWindowInternalExtensionFunction::RunImpl() {
52 apps::ShellWindowRegistry* registry =
53 apps::ShellWindowRegistry::Get(GetProfile());
55 content::RenderViewHost* rvh = render_view_host();
57 // No need to set an error, since we won't return to the caller anyway if
60 ShellWindow* window = registry->GetShellWindowForRenderViewHost(rvh);
62 error_ = kNoAssociatedShellWindow;
65 return RunWithWindow(window);
68 bool AppCurrentWindowInternalFocusFunction::RunWithWindow(ShellWindow* window) {
69 window->GetBaseWindow()->Activate();
73 bool AppCurrentWindowInternalFullscreenFunction::RunWithWindow(
74 ShellWindow* window) {
79 bool AppCurrentWindowInternalMaximizeFunction::RunWithWindow(
80 ShellWindow* window) {
85 bool AppCurrentWindowInternalMinimizeFunction::RunWithWindow(
86 ShellWindow* window) {
91 bool AppCurrentWindowInternalRestoreFunction::RunWithWindow(
92 ShellWindow* window) {
97 bool AppCurrentWindowInternalDrawAttentionFunction::RunWithWindow(
98 ShellWindow* window) {
99 window->GetBaseWindow()->FlashFrame(true);
103 bool AppCurrentWindowInternalClearAttentionFunction::RunWithWindow(
104 ShellWindow* window) {
105 window->GetBaseWindow()->FlashFrame(false);
109 bool AppCurrentWindowInternalShowFunction::RunWithWindow(
110 ShellWindow* window) {
111 window->GetBaseWindow()->Show();
115 bool AppCurrentWindowInternalHideFunction::RunWithWindow(
116 ShellWindow* window) {
117 window->GetBaseWindow()->Hide();
121 bool AppCurrentWindowInternalSetBoundsFunction::RunWithWindow(
122 ShellWindow* window) {
123 // Start with the current bounds, and change any values that are specified in
124 // the incoming parameters.
125 gfx::Rect bounds = window->GetClientBounds();
126 scoped_ptr<SetBounds::Params> params(SetBounds::Params::Create(*args_));
128 if (params->bounds.left)
129 bounds.set_x(*(params->bounds.left));
130 if (params->bounds.top)
131 bounds.set_y(*(params->bounds.top));
132 if (params->bounds.width)
133 bounds.set_width(*(params->bounds.width));
134 if (params->bounds.height)
135 bounds.set_height(*(params->bounds.height));
137 bounds.Inset(-window->GetBaseWindow()->GetFrameInsets());
138 window->GetBaseWindow()->SetBounds(bounds);
142 bool AppCurrentWindowInternalSetMinWidthFunction::RunWithWindow(
143 ShellWindow* window) {
144 scoped_ptr<SetMinWidth::Params> params(SetMinWidth::Params::Create(*args_));
146 gfx::Size min_size = window->size_constraints().GetMinimumSize();
147 min_size.set_width(params->min_width.get() ?
148 *(params->min_width) : kUnboundedSize);
149 window->SetMinimumSize(min_size);
153 bool AppCurrentWindowInternalSetMinHeightFunction::RunWithWindow(
154 ShellWindow* window) {
155 scoped_ptr<SetMinHeight::Params> params(SetMinHeight::Params::Create(*args_));
157 gfx::Size min_size = window->size_constraints().GetMinimumSize();
158 min_size.set_height(params->min_height.get() ?
159 *(params->min_height) : kUnboundedSize);
160 window->SetMinimumSize(min_size);
164 bool AppCurrentWindowInternalSetMaxWidthFunction::RunWithWindow(
165 ShellWindow* window) {
166 scoped_ptr<SetMaxWidth::Params> params(SetMaxWidth::Params::Create(*args_));
168 gfx::Size max_size = window->size_constraints().GetMaximumSize();
169 max_size.set_width(params->max_width.get() ?
170 *(params->max_width) : kUnboundedSize);
171 window->SetMaximumSize(max_size);
175 bool AppCurrentWindowInternalSetMaxHeightFunction::RunWithWindow(
176 ShellWindow* window) {
177 scoped_ptr<SetMaxHeight::Params> params(SetMaxHeight::Params::Create(*args_));
179 gfx::Size max_size = window->size_constraints().GetMaximumSize();
180 max_size.set_height(params->max_height.get() ?
181 *(params->max_height) : kUnboundedSize);
182 window->SetMaximumSize(max_size);
186 bool AppCurrentWindowInternalSetIconFunction::RunWithWindow(
187 ShellWindow* window) {
188 if (GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV &&
189 GetExtension()->location() != extensions::Manifest::COMPONENT) {
190 error_ = kDevChannelOnly;
194 scoped_ptr<SetIcon::Params> params(SetIcon::Params::Create(*args_));
196 // The |icon_url| parameter may be a blob url (e.g. an image fetched with an
197 // XMLHttpRequest) or a resource url.
198 GURL url(params->icon_url);
200 url = GetExtension()->GetResourceURL(params->icon_url);
202 window->SetAppIconUrl(url);
206 bool AppCurrentWindowInternalSetInputRegionFunction::RunWithWindow(
207 ShellWindow* window) {
209 const char* whitelist[] = {
210 "EBA908206905323CECE6DC4B276A58A0F4AC573F",
211 "2775E568AC98F9578791F1EAB65A1BF5F8CEF414",
212 "4AA3C5D69A4AECBD236CAD7884502209F0F5C169",
213 "E410CDAB2C6E6DD408D731016CECF2444000A912",
214 "9E930B2B5EABA6243AE6C710F126E54688E8FAF6"
216 if (GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV &&
217 !SimpleFeature::IsIdInWhitelist(
218 GetExtension()->id(),
219 std::set<std::string>(whitelist,
220 whitelist + arraysize(whitelist)))) {
221 error_ = kDevChannelOnly;
225 scoped_ptr<SetInputRegion::Params> params(
226 SetInputRegion::Params::Create(*args_));
227 const Region& inputRegion = params->region;
229 // Build a region from the supplied list of rects.
230 // If |rects| is missing, then the input region is removed. This clears the
231 // input region so that the entire window accepts input events.
232 // To specify an empty input region (so the window ignores all input),
233 // |rects| should be an empty list.
234 scoped_ptr<SkRegion> region(new SkRegion);
235 if (inputRegion.rects) {
236 for (std::vector<linked_ptr<RegionRect> >::const_iterator i =
237 inputRegion.rects->begin();
238 i != inputRegion.rects->end();
240 const RegionRect& inputRect = **i;
241 int32_t x = inputRect.left;
242 int32_t y = inputRect.top;
243 int32_t width = inputRect.width;
244 int32_t height = inputRect.height;
246 SkIRect rect = SkIRect::MakeXYWH(x, y, width, height);
247 region->op(rect, SkRegion::kUnion_Op);
253 window->UpdateInputRegion(region.Pass());
258 bool AppCurrentWindowInternalSetAlwaysOnTopFunction::RunWithWindow(
259 ShellWindow* window) {
260 scoped_ptr<SetAlwaysOnTop::Params> params(
261 SetAlwaysOnTop::Params::Create(*args_));
263 window->GetBaseWindow()->SetAlwaysOnTop(params->always_on_top);
267 } // namespace extensions