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 "ash/desktop_background/desktop_background_controller.h" | 5 #include "ash/desktop_background/desktop_background_controller.h" |
6 | 6 |
7 #include "ash/desktop_background/desktop_background_view.h" | 7 #include "ash/desktop_background/desktop_background_view.h" |
| 8 #include "ash/desktop_background/desktop_background_widget_controller.h" |
8 #include "ash/shell.h" | 9 #include "ash/shell.h" |
9 #include "ash/shell_factory.h" | 10 #include "ash/shell_factory.h" |
10 #include "ash/shell_window_ids.h" | 11 #include "ash/shell_window_ids.h" |
11 #include "ash/wm/root_window_layout_manager.h" | 12 #include "ash/wm/root_window_layout_manager.h" |
12 #include "base/bind.h" | 13 #include "base/bind.h" |
13 #include "base/logging.h" | 14 #include "base/logging.h" |
14 #include "base/synchronization/cancellation_flag.h" | 15 #include "base/synchronization/cancellation_flag.h" |
15 #include "base/threading/worker_pool.h" | 16 #include "base/threading/worker_pool.h" |
16 #include "grit/ui_resources.h" | 17 #include "grit/ui_resources.h" |
17 #include "ui/aura/root_window.h" | 18 #include "ui/aura/root_window.h" |
18 #include "ui/aura/window.h" | 19 #include "ui/aura/window.h" |
19 #include "ui/base/resource/resource_bundle.h" | 20 #include "ui/base/resource/resource_bundle.h" |
20 #include "ui/compositor/layer.h" | 21 #include "ui/compositor/layer.h" |
| 22 #include "ui/gfx/rect.h" |
21 #include "ui/gfx/image/image.h" | 23 #include "ui/gfx/image/image.h" |
22 #include "ui/views/widget/widget.h" | 24 #include "ui/views/widget/widget.h" |
23 | 25 |
24 namespace ash { | 26 namespace ash { |
25 namespace { | 27 namespace { |
26 | 28 |
27 const int kSmallWallpaperMaximalWidth = 1366; | 29 const int kSmallWallpaperMaximalWidth = 1366; |
28 const int kSmallWallpaperMaximalHeight = 800; | 30 const int kSmallWallpaperMaximalHeight = 800; |
29 | 31 |
30 internal::RootWindowLayoutManager* GetRootWindowLayoutManager( | 32 internal::RootWindowLayoutManager* GetRootWindowLayoutManager( |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 scoped_ptr<WallpaperData> wallpaper_data_; | 94 scoped_ptr<WallpaperData> wallpaper_data_; |
93 | 95 |
94 const int index_; | 96 const int index_; |
95 | 97 |
96 const WallpaperResolution resolution_; | 98 const WallpaperResolution resolution_; |
97 | 99 |
98 DISALLOW_COPY_AND_ASSIGN(WallpaperOperation); | 100 DISALLOW_COPY_AND_ASSIGN(WallpaperOperation); |
99 }; | 101 }; |
100 | 102 |
101 DesktopBackgroundController::DesktopBackgroundController() | 103 DesktopBackgroundController::DesktopBackgroundController() |
102 : desktop_background_mode_(BACKGROUND_IMAGE), | 104 : locked_(false), |
| 105 desktop_background_mode_(BACKGROUND_SOLID_COLOR), |
103 background_color_(SK_ColorGRAY), | 106 background_color_(SK_ColorGRAY), |
104 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 107 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| 108 InstallComponentForAllWindows(); |
105 } | 109 } |
106 | 110 |
107 DesktopBackgroundController::~DesktopBackgroundController() { | 111 DesktopBackgroundController::~DesktopBackgroundController() { |
108 CancelPendingWallpaperOperation(); | 112 CancelPendingWallpaperOperation(); |
109 } | 113 } |
110 | 114 |
111 gfx::ImageSkia DesktopBackgroundController::GetWallpaper() const { | 115 gfx::ImageSkia DesktopBackgroundController::GetWallpaper() const { |
112 if (current_wallpaper_.get()) | 116 if (current_wallpaper_.get()) |
113 return current_wallpaper_->wallpaper_image; | 117 return current_wallpaper_->wallpaper_image; |
114 return gfx::ImageSkia(); | 118 return gfx::ImageSkia(); |
115 } | 119 } |
116 | 120 |
117 WallpaperLayout DesktopBackgroundController::GetWallpaperLayout() const { | 121 WallpaperLayout DesktopBackgroundController::GetWallpaperLayout() const { |
118 if (current_wallpaper_.get()) | 122 if (current_wallpaper_.get()) |
119 return current_wallpaper_->wallpaper_layout; | 123 return current_wallpaper_->wallpaper_layout; |
120 return CENTER_CROPPED; | 124 return CENTER_CROPPED; |
121 } | 125 } |
122 | 126 |
123 SkBitmap DesktopBackgroundController::GetCurrentWallpaperImage() { | 127 SkBitmap DesktopBackgroundController::GetCurrentWallpaperImage() { |
124 if (desktop_background_mode_ != BACKGROUND_IMAGE) | 128 if (desktop_background_mode_ != BACKGROUND_IMAGE) |
125 return SkBitmap(); | 129 return SkBitmap(); |
126 return GetWallpaper(); | 130 return GetWallpaper(); |
127 } | 131 } |
128 | 132 |
129 void DesktopBackgroundController::OnRootWindowAdded( | 133 void DesktopBackgroundController::OnRootWindowAdded( |
130 aura::RootWindow* root_window) { | 134 aura::RootWindow* root_window) { |
131 switch (desktop_background_mode_) { | 135 // Handle resolution change for "built-in" images." |
132 case BACKGROUND_IMAGE: | 136 if (BACKGROUND_IMAGE == desktop_background_mode_) { |
133 if (current_wallpaper_.get()) { | 137 if (current_wallpaper_.get()) { |
134 gfx::Size root_window_size = root_window->GetHostSize(); | 138 gfx::Size root_window_size = root_window->GetHostSize(); |
135 int wallpaper_width = current_wallpaper_->wallpaper_image.width(); | 139 int wallpaper_width = current_wallpaper_->wallpaper_image.width(); |
136 int wallpaper_height = current_wallpaper_->wallpaper_image.height(); | 140 int wallpaper_height = current_wallpaper_->wallpaper_image.height(); |
137 // Loads a higher resolution wallpaper if needed. | 141 // Loads a higher resolution wallpaper if needed. |
138 if ((wallpaper_width < root_window_size.width() || | 142 if ((wallpaper_width < root_window_size.width() || |
139 wallpaper_height < root_window_size.height()) && | 143 wallpaper_height < root_window_size.height()) && |
140 current_wallpaper_->wallpaper_index != -1 && | 144 current_wallpaper_->wallpaper_index != -1 && |
141 current_wallpaper_->wallpaper_layout != TILE) | 145 current_wallpaper_->wallpaper_layout != TILE) |
142 SetDefaultWallpaper(current_wallpaper_->wallpaper_index, true); | 146 SetDefaultWallpaper(current_wallpaper_->wallpaper_index, true); |
143 else | 147 } |
144 SetDesktopBackgroundImage(root_window); | |
145 } else { | |
146 internal::CreateDesktopBackground(root_window); | |
147 } | |
148 break; | |
149 case BACKGROUND_SOLID_COLOR: | |
150 SetDesktopBackgroundSolidColorMode(background_color_); | |
151 break; | |
152 } | 148 } |
| 149 |
| 150 InstallComponent(root_window); |
153 } | 151 } |
154 | 152 |
155 void DesktopBackgroundController::SetDefaultWallpaper(int index, | 153 void DesktopBackgroundController::SetDefaultWallpaper(int index, |
156 bool force_reload) { | 154 bool force_reload) { |
157 // We should not change background when index is invalid. For instance, at | 155 // We should not change background when index is invalid. For instance, at |
158 // login screen or stub_user login. | 156 // login screen or stub_user login. |
159 if (index == ash::GetInvalidWallpaperIndex()) { | 157 if (index == GetInvalidWallpaperIndex()) { |
160 CreateEmptyWallpaper(); | 158 CreateEmptyWallpaper(); |
161 return; | 159 return; |
162 } else if (index == ash::GetSolidColorIndex()) { | 160 } else if (index == GetSolidColorIndex()) { |
163 SetDesktopBackgroundSolidColorMode(kLoginWallpaperColor); | 161 SetDesktopBackgroundSolidColorMode(kLoginWallpaperColor); |
164 return; | 162 return; |
165 } | 163 } |
166 | 164 |
167 if (!force_reload && current_wallpaper_.get() && | 165 if (!force_reload && current_wallpaper_.get() && |
168 current_wallpaper_->wallpaper_index == index) | 166 current_wallpaper_->wallpaper_index == index) |
169 return; | 167 return; |
170 | 168 |
171 CancelPendingWallpaperOperation(); | 169 CancelPendingWallpaperOperation(); |
172 | 170 |
(...skipping 15 matching lines...) Expand all Loading... |
188 weak_ptr_factory_.GetWeakPtr(), | 186 weak_ptr_factory_.GetWeakPtr(), |
189 wallpaper_op_), | 187 wallpaper_op_), |
190 true /* task_is_slow */); | 188 true /* task_is_slow */); |
191 } | 189 } |
192 | 190 |
193 void DesktopBackgroundController::SetCustomWallpaper( | 191 void DesktopBackgroundController::SetCustomWallpaper( |
194 const gfx::ImageSkia& wallpaper, | 192 const gfx::ImageSkia& wallpaper, |
195 WallpaperLayout layout) { | 193 WallpaperLayout layout) { |
196 CancelPendingWallpaperOperation(); | 194 CancelPendingWallpaperOperation(); |
197 current_wallpaper_.reset(new WallpaperData(layout, wallpaper)); | 195 current_wallpaper_.reset(new WallpaperData(layout, wallpaper)); |
198 desktop_background_mode_ = BACKGROUND_IMAGE; | 196 SetDesktopBackgroundImageMode(); |
199 UpdateDesktopBackgroundImageMode(); | |
200 } | 197 } |
201 | 198 |
202 void DesktopBackgroundController::CancelPendingWallpaperOperation() { | 199 void DesktopBackgroundController::CancelPendingWallpaperOperation() { |
203 // Set canceled flag of previous request to skip unneeded loading. | 200 // Set canceled flag of previous request to skip unneeded loading. |
204 if (wallpaper_op_.get()) | 201 if (wallpaper_op_.get()) |
205 wallpaper_op_->Cancel(); | 202 wallpaper_op_->Cancel(); |
206 | 203 |
207 // Cancel reply callback for previous request. | 204 // Cancel reply callback for previous request. |
208 weak_ptr_factory_.InvalidateWeakPtrs(); | 205 weak_ptr_factory_.InvalidateWeakPtrs(); |
209 } | 206 } |
210 | 207 |
211 void DesktopBackgroundController::SetDesktopBackgroundSolidColorMode( | 208 void DesktopBackgroundController::SetDesktopBackgroundSolidColorMode( |
212 SkColor color) { | 209 SkColor color) { |
213 // Set a solid black background. | |
214 // TODO(derat): Remove this in favor of having the compositor only clear the | |
215 // viewport when there are regions not covered by a layer: | |
216 // http://crbug.com/113445 | |
217 current_wallpaper_.reset(NULL); | |
218 background_color_ = color; | 210 background_color_ = color; |
219 desktop_background_mode_ = BACKGROUND_SOLID_COLOR; | 211 if (desktop_background_mode_ != BACKGROUND_SOLID_COLOR) { |
| 212 desktop_background_mode_ = BACKGROUND_SOLID_COLOR; |
| 213 InstallComponentForAllWindows(); |
| 214 return; |
| 215 } |
| 216 |
220 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); | 217 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); |
221 for (Shell::RootWindowList::iterator iter = root_windows.begin(); | 218 for (Shell::RootWindowList::iterator iter = root_windows.begin(); |
222 iter != root_windows.end(); ++iter) { | 219 iter != root_windows.end(); ++iter) { |
223 ui::Layer* background_layer = new ui::Layer(ui::LAYER_SOLID_COLOR); | |
224 background_layer->SetColor(color); | |
225 aura::RootWindow* root_window = *iter; | 220 aura::RootWindow* root_window = *iter; |
226 Shell::GetContainer( | 221 internal::DesktopBackgroundWidgetController* component = root_window-> |
227 root_window, | 222 GetProperty(internal::kWindowDesktopComponent); |
228 internal::kShellWindowId_DesktopBackgroundContainer)-> | 223 DCHECK(component); |
229 layer()->Add(background_layer); | 224 DCHECK(component->layer()); |
230 GetRootWindowLayoutManager(root_window)->SetBackgroundLayer( | 225 component->layer()->SetColor(background_color_ ); |
231 background_layer); | |
232 GetRootWindowLayoutManager(root_window)->SetBackgroundWidget(NULL); | |
233 } | 226 } |
234 } | 227 } |
235 | 228 |
236 void DesktopBackgroundController::SetDesktopBackgroundImage( | 229 void DesktopBackgroundController::CreateEmptyWallpaper() { |
237 aura::RootWindow* root_window) { | 230 current_wallpaper_.reset(NULL); |
238 GetRootWindowLayoutManager(root_window)->SetBackgroundLayer(NULL); | 231 SetDesktopBackgroundImageMode(); |
239 if (current_wallpaper_.get() && | |
240 !current_wallpaper_->wallpaper_image.empty()) | |
241 internal::CreateDesktopBackground(root_window); | |
242 } | 232 } |
243 | 233 |
244 void DesktopBackgroundController::UpdateDesktopBackgroundImageMode() { | 234 void DesktopBackgroundController::MoveDesktopToLockedContainer() { |
| 235 if (locked_) |
| 236 return; |
| 237 locked_ = true; |
| 238 ReparentBackgroundWidgets(GetBackgroundContainerId(false), |
| 239 GetBackgroundContainerId(true)); |
| 240 } |
| 241 |
| 242 void DesktopBackgroundController::MoveDesktopToUnlockedContainer() { |
| 243 if (!locked_) |
| 244 return; |
| 245 locked_ = false; |
| 246 ReparentBackgroundWidgets(GetBackgroundContainerId(true), |
| 247 GetBackgroundContainerId(false)); |
| 248 } |
| 249 |
| 250 void DesktopBackgroundController::OnWindowDestroying(aura::Window* window) { |
| 251 window->SetProperty(internal::kWindowDesktopComponent, |
| 252 static_cast<internal::DesktopBackgroundWidgetController*>(NULL)); |
| 253 } |
| 254 |
| 255 void DesktopBackgroundController::SetDesktopBackgroundImageMode() { |
| 256 if (desktop_background_mode_ != BACKGROUND_IMAGE) { |
| 257 desktop_background_mode_ = BACKGROUND_IMAGE; |
| 258 InstallComponentForAllWindows(); |
| 259 return; |
| 260 } |
| 261 |
245 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); | 262 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); |
246 | |
247 for (Shell::RootWindowList::iterator iter = root_windows.begin(); | 263 for (Shell::RootWindowList::iterator iter = root_windows.begin(); |
248 iter != root_windows.end(); ++iter) { | 264 iter != root_windows.end(); ++iter) { |
249 SetDesktopBackgroundImage(*iter); | 265 aura::RootWindow* root_window = *iter; |
| 266 internal::DesktopBackgroundWidgetController* component = root_window-> |
| 267 GetProperty(internal::kWindowDesktopComponent); |
| 268 DCHECK(component); |
| 269 DCHECK(component->widget()); |
| 270 aura::Window* window = component->widget()->GetNativeView(); |
| 271 gfx::Rect bounds = window->bounds(); |
| 272 window->SchedulePaintInRect(gfx::Rect(0, 0, |
| 273 bounds.width(), bounds.height())); |
250 } | 274 } |
251 desktop_background_mode_ = BACKGROUND_IMAGE; | |
252 } | 275 } |
253 | 276 |
254 void DesktopBackgroundController::OnWallpaperLoadCompleted( | 277 void DesktopBackgroundController::OnWallpaperLoadCompleted( |
255 scoped_refptr<WallpaperOperation> wo) { | 278 scoped_refptr<WallpaperOperation> wo) { |
256 current_wallpaper_.reset(wo->ReleaseWallpaperData()); | 279 current_wallpaper_.reset(wo->ReleaseWallpaperData()); |
257 | 280 |
258 UpdateDesktopBackgroundImageMode(); | 281 SetDesktopBackgroundImageMode(); |
259 | 282 |
260 DCHECK(wo.get() == wallpaper_op_.get()); | 283 DCHECK(wo.get() == wallpaper_op_.get()); |
261 wallpaper_op_ = NULL; | 284 wallpaper_op_ = NULL; |
262 } | 285 } |
263 | 286 |
264 void DesktopBackgroundController::CreateEmptyWallpaper() { | 287 ui::Layer* DesktopBackgroundController::SetColorLayerForContainer( |
265 current_wallpaper_.reset(NULL); | 288 SkColor color, |
266 desktop_background_mode_ = BACKGROUND_IMAGE; | 289 aura::RootWindow* root_window, |
| 290 int container_id) { |
| 291 ui::Layer* background_layer = new ui::Layer(ui::LAYER_SOLID_COLOR); |
| 292 background_layer->SetColor(color); |
| 293 |
| 294 Shell::GetContainer(root_window,container_id)-> |
| 295 layer()->Add(background_layer); |
| 296 return background_layer; |
| 297 } |
| 298 |
| 299 void DesktopBackgroundController::InstallComponent( |
| 300 aura::RootWindow* root_window) { |
| 301 internal::DesktopBackgroundWidgetController* component = NULL; |
| 302 int container_id = GetBackgroundContainerId(locked_); |
| 303 |
| 304 switch (desktop_background_mode_) { |
| 305 case BACKGROUND_IMAGE: { |
| 306 views::Widget* widget = internal::CreateDesktopBackground(root_window, |
| 307 container_id); |
| 308 component = new internal::DesktopBackgroundWidgetController(widget); |
| 309 break; |
| 310 } |
| 311 case BACKGROUND_SOLID_COLOR: { |
| 312 ui::Layer* layer = SetColorLayerForContainer(background_color_, |
| 313 root_window, |
| 314 container_id); |
| 315 component = new internal::DesktopBackgroundWidgetController(layer); |
| 316 break; |
| 317 } |
| 318 default: { |
| 319 NOTREACHED(); |
| 320 } |
| 321 } |
| 322 if (NULL == root_window->GetProperty(internal::kWindowDesktopComponent)) { |
| 323 // First time for this root window |
| 324 root_window->AddObserver(this); |
| 325 } |
| 326 root_window->SetProperty(internal::kWindowDesktopComponent, component); |
| 327 } |
| 328 |
| 329 void DesktopBackgroundController::InstallComponentForAllWindows() { |
267 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); | 330 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); |
268 for (Shell::RootWindowList::iterator iter = root_windows.begin(); | 331 for (Shell::RootWindowList::iterator iter = root_windows.begin(); |
269 iter != root_windows.end(); ++iter) { | 332 iter != root_windows.end(); ++iter) { |
270 internal::CreateDesktopBackground(*iter); | 333 InstallComponent(*iter); |
271 } | 334 } |
272 } | 335 } |
273 | 336 |
| 337 void DesktopBackgroundController::ReparentBackgroundWidgets(int src_container, |
| 338 int dst_container) { |
| 339 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); |
| 340 for (Shell::RootWindowList::iterator iter = root_windows.begin(); |
| 341 iter != root_windows.end(); ++iter) { |
| 342 aura::RootWindow* root_window = *iter; |
| 343 internal::DesktopBackgroundWidgetController* component = root_window-> |
| 344 GetProperty(internal::kWindowDesktopComponent); |
| 345 DCHECK(component); |
| 346 component->Reparent(root_window, |
| 347 src_container, |
| 348 dst_container); |
| 349 } |
| 350 } |
| 351 |
| 352 int DesktopBackgroundController::GetBackgroundContainerId(bool locked) { |
| 353 return locked ? internal::kShellWindowId_LockScreenBackgroundContainer : |
| 354 internal::kShellWindowId_DesktopBackgroundContainer; |
| 355 } |
| 356 |
274 } // namespace ash | 357 } // namespace ash |
OLD | NEW |