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

Side by Side Diff: ash/shelf/shelf_window_watcher.cc

Issue 2878133002: mash: Serialize ShelfIDs for property conversion and transport. (Closed)
Patch Set: Remove |user_windows_with_items_| entries in workaround; disable a test in mash. Created 3 years, 7 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/shelf/shelf_window_watcher.h" 5 #include "ash/shelf/shelf_window_watcher.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "ash/public/cpp/config.h" 10 #include "ash/public/cpp/config.h"
11 #include "ash/public/cpp/shell_window_ids.h" 11 #include "ash/public/cpp/shell_window_ids.h"
12 #include "ash/public/cpp/window_properties.h" 12 #include "ash/public/cpp/window_properties.h"
13 #include "ash/shelf/shelf_constants.h" 13 #include "ash/shelf/shelf_constants.h"
14 #include "ash/shelf/shelf_model.h" 14 #include "ash/shelf/shelf_model.h"
15 #include "ash/shelf/shelf_window_watcher_item_delegate.h" 15 #include "ash/shelf/shelf_window_watcher_item_delegate.h"
16 #include "ash/shell.h" 16 #include "ash/shell.h"
17 #include "ash/shell_port.h" 17 #include "ash/shell_port.h"
18 #include "ash/wm/window_state.h" 18 #include "ash/wm/window_state.h"
19 #include "ash/wm/window_state_aura.h" 19 #include "ash/wm/window_state_aura.h"
20 #include "ash/wm/window_util.h" 20 #include "ash/wm/window_util.h"
21 #include "ash/wm_window.h" 21 #include "ash/wm_window.h"
22 #include "base/strings/string_number_conversions.h"
22 #include "ui/aura/client/aura_constants.h" 23 #include "ui/aura/client/aura_constants.h"
23 #include "ui/aura/window.h" 24 #include "ui/aura/window.h"
24 #include "ui/base/resource/resource_bundle.h" 25 #include "ui/base/resource/resource_bundle.h"
25 #include "ui/display/display.h" 26 #include "ui/display/display.h"
26 #include "ui/display/screen.h" 27 #include "ui/display/screen.h"
27 #include "ui/resources/grit/ui_resources.h" 28 #include "ui/resources/grit/ui_resources.h"
28 #include "ui/wm/public/activation_client.h" 29 #include "ui/wm/public/activation_client.h"
29 30
30 namespace ash { 31 namespace ash {
31 namespace { 32 namespace {
32 33
33 // Returns the shelf item type, with special temporary behavior for Mash: 34 // Returns the shelf item type, with special temporary behavior for Mash:
34 // Mash provides a default shelf item type (TYPE_APP) for non-ignored windows. 35 // Mash provides a default shelf item type (TYPE_APP) for non-ignored windows.
35 ShelfItemType GetShelfItemType(aura::Window* window) { 36 ShelfItemType GetShelfItemType(aura::Window* window) {
36 if (Shell::GetAshConfig() != Config::MASH || 37 // TODO(msw): Remove this temporary Mash default ShelfItemType assignment.
37 window->GetProperty(kShelfItemTypeKey) != TYPE_UNDEFINED) { 38 if (Shell::GetAshConfig() == Config::MASH &&
38 return static_cast<ShelfItemType>(window->GetProperty(kShelfItemTypeKey)); 39 window->GetProperty(kShelfItemTypeKey) == TYPE_UNDEFINED &&
40 !wm::GetWindowState(window)->ignored_by_shelf()) {
41 return TYPE_APP;
39 } 42 }
40 return wm::GetWindowState(window)->ignored_by_shelf() ? TYPE_UNDEFINED 43 return static_cast<ShelfItemType>(window->GetProperty(kShelfItemTypeKey));
41 : TYPE_APP; 44 }
45
46 // Returns the shelf id, with special temporary behavior for Mash:
47 // Mash provides a default shelf ids for non-ignored windows.
48 ShelfID GetShelfID(aura::Window* window) {
49 // TODO(msw): Remove this temporary Mash default ShelfID assignment.
50 if (Shell::GetAshConfig() == Config::MASH &&
51 !window->GetProperty(kShelfIDKey) &&
52 !wm::GetWindowState(window)->ignored_by_shelf()) {
53 static int id = 0;
54 const ash::ShelfID shelf_id(base::IntToString(id++));
55 window->SetProperty(kShelfIDKey, new std::string(shelf_id.Serialize()));
56 return shelf_id;
57 }
58 return ShelfID::Deserialize(window->GetProperty(kShelfIDKey));
42 } 59 }
43 60
44 // Update the ShelfItem from relevant window properties. 61 // Update the ShelfItem from relevant window properties.
45 void UpdateShelfItemForWindow(ShelfItem* item, aura::Window* window) { 62 void UpdateShelfItemForWindow(ShelfItem* item, aura::Window* window) {
63 item->id = GetShelfID(window);
46 item->type = GetShelfItemType(window); 64 item->type = GetShelfItemType(window);
47 65
48 item->status = STATUS_RUNNING; 66 item->status = STATUS_RUNNING;
49 if (wm::IsActiveWindow(window)) 67 if (wm::IsActiveWindow(window))
50 item->status = STATUS_ACTIVE; 68 item->status = STATUS_ACTIVE;
51 else if (window->GetProperty(aura::client::kDrawAttentionKey)) 69 else if (window->GetProperty(aura::client::kDrawAttentionKey))
52 item->status = STATUS_ATTENTION; 70 item->status = STATUS_ATTENTION;
53 71
54 const ShelfID* shelf_id = window->GetProperty(kShelfIDKey);
55 item->id = shelf_id ? *shelf_id : ShelfID();
56
57 // Prefer app icons over window icons, they're typically larger. 72 // Prefer app icons over window icons, they're typically larger.
58 gfx::ImageSkia* image = window->GetProperty(aura::client::kAppIconKey); 73 gfx::ImageSkia* image = window->GetProperty(aura::client::kAppIconKey);
59 if (!image || image->isNull()) 74 if (!image || image->isNull())
60 image = window->GetProperty(aura::client::kWindowIconKey); 75 image = window->GetProperty(aura::client::kWindowIconKey);
61 if (!image || image->isNull()) { 76 if (!image || image->isNull()) {
62 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 77 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
63 item->image = rb.GetImageNamed(IDR_DEFAULT_FAVICON_32).AsImageSkia(); 78 item->image = rb.GetImageNamed(IDR_DEFAULT_FAVICON_32).AsImageSkia();
64 } else { 79 } else {
65 item->image = *image; 80 item->image = *image;
66 } 81 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 ShelfWindowWatcher::UserWindowObserver::UserWindowObserver( 115 ShelfWindowWatcher::UserWindowObserver::UserWindowObserver(
101 ShelfWindowWatcher* window_watcher) 116 ShelfWindowWatcher* window_watcher)
102 : window_watcher_(window_watcher) {} 117 : window_watcher_(window_watcher) {}
103 118
104 ShelfWindowWatcher::UserWindowObserver::~UserWindowObserver() {} 119 ShelfWindowWatcher::UserWindowObserver::~UserWindowObserver() {}
105 120
106 void ShelfWindowWatcher::UserWindowObserver::OnWindowPropertyChanged( 121 void ShelfWindowWatcher::UserWindowObserver::OnWindowPropertyChanged(
107 aura::Window* window, 122 aura::Window* window,
108 const void* key, 123 const void* key,
109 intptr_t old) { 124 intptr_t old) {
125 // ShelfIDs should never change except when replacing Mash temporary defaults.
126 // TODO(msw): Remove this temporary Mash default ShelfID handling code.
James Cook 2017/05/15 16:37:23 Given that this comment is in 3 places, please fil
msw 2017/05/15 19:21:31 Done.
127 if (Shell::GetAshConfig() == Config::MASH && key == kShelfIDKey) {
128 ShelfID old_id = ShelfID::Deserialize(reinterpret_cast<std::string*>(old));
129 ShelfID new_id = ShelfID::Deserialize(window->GetProperty(kShelfIDKey));
130 if (old_id != new_id && !old_id.IsNull() && !new_id.IsNull()) {
131 // Id changing is not supported; remove the item and it will be re-added.
132 window_watcher_->user_windows_with_items_.erase(window);
133 const int index = window_watcher_->model_->ItemIndexByID(old_id);
134 window_watcher_->model_->RemoveItemAt(index);
135 }
136 }
137
110 if (key == aura::client::kAppIconKey || key == aura::client::kWindowIconKey || 138 if (key == aura::client::kAppIconKey || key == aura::client::kWindowIconKey ||
111 key == aura::client::kDrawAttentionKey || key == kPanelAttachedKey || 139 key == aura::client::kDrawAttentionKey || key == kPanelAttachedKey ||
112 key == kShelfItemTypeKey || key == kShelfIDKey) { 140 key == kShelfItemTypeKey || key == kShelfIDKey) {
113 window_watcher_->OnUserWindowPropertyChanged(window); 141 window_watcher_->OnUserWindowPropertyChanged(window);
114 } 142 }
115 } 143 }
116 144
117 void ShelfWindowWatcher::UserWindowObserver::OnWindowDestroying( 145 void ShelfWindowWatcher::UserWindowObserver::OnWindowDestroying(
118 aura::Window* window) { 146 aura::Window* window) {
119 window_watcher_->OnUserWindowDestroying(window); 147 window_watcher_->OnUserWindowDestroying(window);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 180
153 ShelfWindowWatcher::~ShelfWindowWatcher() { 181 ShelfWindowWatcher::~ShelfWindowWatcher() {
154 display::Screen::GetScreen()->RemoveObserver(this); 182 display::Screen::GetScreen()->RemoveObserver(this);
155 Shell::Get()->activation_client()->RemoveObserver(this); 183 Shell::Get()->activation_client()->RemoveObserver(this);
156 } 184 }
157 185
158 void ShelfWindowWatcher::AddShelfItem(aura::Window* window) { 186 void ShelfWindowWatcher::AddShelfItem(aura::Window* window) {
159 user_windows_with_items_.insert(window); 187 user_windows_with_items_.insert(window);
160 ShelfItem item; 188 ShelfItem item;
161 UpdateShelfItemForWindow(&item, window); 189 UpdateShelfItemForWindow(&item, window);
190
191 // ShelfWindowWatcher[ItemDelegate] doesn't support multiple windows per item,
192 // but this can happen in Mash (eg. when multiple browser windows are open).
193 // Assign a unique launch id in this case to avoid crashing on DCHECKs.
194 // TODO(msw): Remove this temporary Mash duplicate ShelfID handling.
195 if (Shell::GetAshConfig() == Config::MASH &&
196 model_->ItemIndexByID(item.id) > 0) {
197 static int id = 0;
198 item.id.launch_id = base::IntToString(id++);
199 }
200
162 model_->SetShelfItemDelegate(item.id, 201 model_->SetShelfItemDelegate(item.id,
163 base::MakeUnique<ShelfWindowWatcherItemDelegate>( 202 base::MakeUnique<ShelfWindowWatcherItemDelegate>(
164 item.id, WmWindow::Get(window))); 203 item.id, WmWindow::Get(window)));
165 // Panels are inserted on the left so as not to push all existing panels over. 204 // Panels are inserted on the left so as not to push all existing panels over.
166 model_->AddAt(item.type == TYPE_APP_PANEL ? 0 : model_->item_count(), item); 205 model_->AddAt(item.type == TYPE_APP_PANEL ? 0 : model_->item_count(), item);
167 } 206 }
168 207
169 void ShelfWindowWatcher::RemoveShelfItem(aura::Window* window) { 208 void ShelfWindowWatcher::RemoveShelfItem(aura::Window* window) {
170 user_windows_with_items_.erase(window); 209 user_windows_with_items_.erase(window);
171 ShelfID* shelf_id = window->GetProperty(kShelfIDKey); 210 const ShelfID shelf_id = GetShelfID(window);
172 DCHECK(shelf_id); 211 DCHECK(!shelf_id.IsNull());
173 DCHECK(!shelf_id->IsNull()); 212 const int index = model_->ItemIndexByID(shelf_id);
174 int index = model_->ItemIndexByID(*shelf_id);
175 DCHECK_GE(index, 0); 213 DCHECK_GE(index, 0);
176 model_->RemoveItemAt(index); 214 model_->RemoveItemAt(index);
177 } 215 }
178 216
179 void ShelfWindowWatcher::OnContainerWindowDestroying(aura::Window* container) { 217 void ShelfWindowWatcher::OnContainerWindowDestroying(aura::Window* container) {
180 observed_container_windows_.Remove(container); 218 observed_container_windows_.Remove(container);
181 } 219 }
182 220
183 int ShelfWindowWatcher::GetShelfItemIndexForWindow(aura::Window* window) const { 221 int ShelfWindowWatcher::GetShelfItemIndexForWindow(aura::Window* window) const {
184 ShelfID* shelf_id = window->GetProperty(kShelfIDKey); 222 const ShelfID shelf_id = GetShelfID(window);
185 return shelf_id ? model_->ItemIndexByID(*shelf_id) : -1; 223 return shelf_id.IsNull() ? -1 : model_->ItemIndexByID(shelf_id);
186 } 224 }
187 225
188 void ShelfWindowWatcher::OnUserWindowAdded(aura::Window* window) { 226 void ShelfWindowWatcher::OnUserWindowAdded(aura::Window* window) {
189 // The window may already be tracked from a prior display or parent container. 227 // The window may already be tracked from a prior display or parent container.
190 if (observed_user_windows_.IsObserving(window)) 228 if (observed_user_windows_.IsObserving(window))
191 return; 229 return;
192 230
193 observed_user_windows_.Add(window); 231 observed_user_windows_.Add(window);
194 232
195 // Add, update, or remove a ShelfItem for |window|, as needed. 233 // Add, update, or remove a ShelfItem for |window|, as needed.
196 OnUserWindowPropertyChanged(window); 234 OnUserWindowPropertyChanged(window);
197 } 235 }
198 236
199 void ShelfWindowWatcher::OnUserWindowDestroying(aura::Window* window) { 237 void ShelfWindowWatcher::OnUserWindowDestroying(aura::Window* window) {
200 if (observed_user_windows_.IsObserving(window)) 238 if (observed_user_windows_.IsObserving(window))
201 observed_user_windows_.Remove(window); 239 observed_user_windows_.Remove(window);
202 240
203 if (user_windows_with_items_.count(window) > 0) 241 if (user_windows_with_items_.count(window) > 0)
204 RemoveShelfItem(window); 242 RemoveShelfItem(window);
205 DCHECK_EQ(0u, user_windows_with_items_.count(window)); 243 DCHECK_EQ(0u, user_windows_with_items_.count(window));
206 } 244 }
207 245
208 void ShelfWindowWatcher::OnUserWindowPropertyChanged(aura::Window* window) { 246 void ShelfWindowWatcher::OnUserWindowPropertyChanged(aura::Window* window) {
209 if (GetShelfItemType(window) == TYPE_UNDEFINED || 247 if (GetShelfItemType(window) == TYPE_UNDEFINED ||
210 !window->GetProperty(kShelfIDKey)) { 248 GetShelfID(window).IsNull()) {
211 // Remove |window|'s ShelfItem if it was added by this ShelfWindowWatcher. 249 // Remove |window|'s ShelfItem if it was added by this ShelfWindowWatcher.
212 if (user_windows_with_items_.count(window) > 0) 250 if (user_windows_with_items_.count(window) > 0)
213 RemoveShelfItem(window); 251 RemoveShelfItem(window);
214 return; 252 return;
215 } 253 }
216 254
217 // Update an existing ShelfItem for |window| when a property has changed. 255 // Update an existing ShelfItem for |window| when a property has changed.
218 int index = GetShelfItemIndexForWindow(window); 256 int index = GetShelfItemIndexForWindow(window);
219 if (index > 0) { 257 if (index > 0) {
220 ShelfItem item = model_->items()[index]; 258 ShelfItem item = model_->items()[index];
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 } 297 }
260 } 298 }
261 299
262 void ShelfWindowWatcher::OnDisplayRemoved(const display::Display& old_display) { 300 void ShelfWindowWatcher::OnDisplayRemoved(const display::Display& old_display) {
263 } 301 }
264 302
265 void ShelfWindowWatcher::OnDisplayMetricsChanged(const display::Display&, 303 void ShelfWindowWatcher::OnDisplayMetricsChanged(const display::Display&,
266 uint32_t) {} 304 uint32_t) {}
267 305
268 } // namespace ash 306 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698