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

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

Issue 2860503002: mash: Replace int ShelfIDs with AppLaunchID strings. (Closed)
Patch Set: Restore AppLaunchId class via using ShelfID = AppLaunchId; cleanup. 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_model.h" 5 #include "ash/shelf/shelf_model.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ash/public/cpp/app_launch_id.h"
10 #include "ash/public/cpp/shelf_item_delegate.h" 9 #include "ash/public/cpp/shelf_item_delegate.h"
11 #include "ash/shelf/shelf_model_observer.h" 10 #include "ash/shelf/shelf_model_observer.h"
12 11
13 namespace ash { 12 namespace ash {
14 13
15 namespace { 14 namespace {
16 15
17 int ShelfItemTypeToWeight(ShelfItemType type) { 16 int ShelfItemTypeToWeight(ShelfItemType type) {
18 switch (type) { 17 switch (type) {
19 case TYPE_APP_LIST: 18 case TYPE_APP_LIST:
(...skipping 25 matching lines...) Expand all
45 // Returns shelf app id. Play Store app is mapped to ARC platform host app. 44 // Returns shelf app id. Play Store app is mapped to ARC platform host app.
46 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859 45 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
47 std::string GetShelfAppIdFromArcAppId(const std::string& arc_app_id) { 46 std::string GetShelfAppIdFromArcAppId(const std::string& arc_app_id) {
48 static const char kPlayStoreAppId[] = "gpkmicpkkebkmabiaedjognfppcchdfa"; 47 static const char kPlayStoreAppId[] = "gpkmicpkkebkmabiaedjognfppcchdfa";
49 static const char kArcHostAppId[] = "cnbgggchhmkkdmeppjobngjoejnihlei"; 48 static const char kArcHostAppId[] = "cnbgggchhmkkdmeppjobngjoejnihlei";
50 return arc_app_id == kPlayStoreAppId ? kArcHostAppId : arc_app_id; 49 return arc_app_id == kPlayStoreAppId ? kArcHostAppId : arc_app_id;
51 } 50 }
52 51
53 } // namespace 52 } // namespace
54 53
55 ShelfModel::ShelfModel() : next_id_(1) {} 54 ShelfModel::ShelfModel() {}
James Cook 2017/05/04 16:38:49 optional: = default
msw 2017/05/04 19:05:57 Done.
56 55
57 ShelfModel::~ShelfModel() {} 56 ShelfModel::~ShelfModel() {}
58 57
59 ShelfID ShelfModel::GetShelfIDForAppID(const std::string& app_id) { 58 ShelfID ShelfModel::GetShelfIDForAppID(const std::string& app_id) {
60 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859 59 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
61 const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id); 60 const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id);
62 61
63 if (shelf_app_id.empty()) 62 if (shelf_app_id.empty())
64 return ash::kInvalidShelfID; 63 return ShelfID();
65 64
66 for (const ShelfItem& item : items_) { 65 for (const ShelfItem& item : items_) {
67 // ShelfWindowWatcher handles app panel windows separately. 66 // ShelfWindowWatcher handles app panel windows separately.
68 if (item.type != TYPE_APP_PANEL && 67 if (item.type != TYPE_APP_PANEL && item.id.app_id() == shelf_app_id)
69 item.app_launch_id.app_id() == shelf_app_id) {
70 return item.id; 68 return item.id;
71 }
72 } 69 }
73 return kInvalidShelfID; 70 return ShelfID();
74 } 71 }
75 72
76 ShelfID ShelfModel::GetShelfIDForAppIDAndLaunchID( 73 ShelfID ShelfModel::GetShelfIDForAppIDAndLaunchID(
77 const std::string& app_id, 74 const std::string& app_id,
78 const std::string& launch_id) { 75 const std::string& launch_id) {
79 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859 76 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
80 const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id); 77 const ShelfID id = ShelfID(GetShelfAppIdFromArcAppId(app_id), launch_id);
81 78
82 if (shelf_app_id.empty()) 79 if (id.IsEmpty())
83 return ash::kInvalidShelfID; 80 return ShelfID();
84 81
85 for (const ShelfItem& item : items_) { 82 for (const ShelfItem& item : items_) {
86 // ShelfWindowWatcher handles app panel windows separately. 83 // ShelfWindowWatcher handles app panel windows separately.
87 if (item.type != TYPE_APP_PANEL && 84 if (item.type != TYPE_APP_PANEL && item.id == id)
88 item.app_launch_id.app_id() == shelf_app_id &&
89 item.app_launch_id.launch_id() == launch_id) {
90 return item.id; 85 return item.id;
91 }
92 } 86 }
93 return kInvalidShelfID; 87 return ShelfID();
94 } 88 }
95 89
96 const std::string& ShelfModel::GetAppIDForShelfID(ShelfID id) { 90 const std::string& ShelfModel::GetAppIDForShelfID(const ShelfID& id) {
97 ShelfItems::const_iterator item = ItemByID(id); 91 ShelfItems::const_iterator item = ItemByID(id);
98 return item != items().end() ? item->app_launch_id.app_id() 92 return item != items().end() ? item->id.app_id() : base::EmptyString();
99 : base::EmptyString();
100 } 93 }
101 94
102 void ShelfModel::PinAppWithID(const std::string& app_id) { 95 void ShelfModel::PinAppWithID(const std::string& app_id) {
103 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859 96 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
104 const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id); 97 const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id);
105 98
106 // If the app is already pinned, do nothing and return. 99 // If the app is already pinned, do nothing and return.
107 if (IsAppPinned(shelf_app_id)) 100 if (IsAppPinned(shelf_app_id))
108 return; 101 return;
109 102
110 // Convert an existing item to be pinned, or create a new pinned item. 103 // Convert an existing item to be pinned, or create a new pinned item.
111 const int index = ItemIndexByID(GetShelfIDForAppID(shelf_app_id)); 104 const int index = ItemIndexByID(GetShelfIDForAppID(shelf_app_id));
112 if (index >= 0) { 105 if (index >= 0) {
113 ShelfItem item = items_[index]; 106 ShelfItem item = items_[index];
114 DCHECK_EQ(item.type, TYPE_APP); 107 DCHECK_EQ(item.type, TYPE_APP);
115 DCHECK(!item.pinned_by_policy); 108 DCHECK(!item.pinned_by_policy);
116 item.type = TYPE_PINNED_APP; 109 item.type = TYPE_PINNED_APP;
117 Set(index, item); 110 Set(index, item);
118 } else if (!shelf_app_id.empty()) { 111 } else if (!shelf_app_id.empty()) {
119 ash::ShelfItem item; 112 ShelfItem item;
120 item.type = ash::TYPE_PINNED_APP; 113 item.type = TYPE_PINNED_APP;
121 item.app_launch_id = AppLaunchId(shelf_app_id); 114 item.id = ShelfID(shelf_app_id);
122 Add(item); 115 Add(item);
123 } 116 }
124 } 117 }
125 118
126 bool ShelfModel::IsAppPinned(const std::string& app_id) { 119 bool ShelfModel::IsAppPinned(const std::string& app_id) {
127 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859 120 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
128 const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id); 121 const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id);
129 122
130 const int index = ItemIndexByID(GetShelfIDForAppID(shelf_app_id)); 123 const int index = ItemIndexByID(GetShelfIDForAppID(shelf_app_id));
131 return index >= 0 && (items_[index].type == TYPE_PINNED_APP || 124 return index >= 0 && (items_[index].type == TYPE_PINNED_APP ||
132 items_[index].type == TYPE_BROWSER_SHORTCUT); 125 items_[index].type == TYPE_BROWSER_SHORTCUT);
133 } 126 }
134 127
135 void ShelfModel::UnpinAppWithID(const std::string& app_id) { 128 void ShelfModel::UnpinAppWithID(const std::string& app_id) {
136 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859 129 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
137 const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id); 130 const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id);
138 131
139 // If the app is already not pinned, do nothing and return. 132 // If the app is already not pinned, do nothing and return.
140 if (!IsAppPinned(shelf_app_id)) 133 if (!IsAppPinned(shelf_app_id))
141 return; 134 return;
142 135
143 // Remove the item if it is closed, or mark it as unpinned. 136 // Remove the item if it is closed, or mark it as unpinned.
144 const int index = ItemIndexByID(GetShelfIDForAppID(shelf_app_id)); 137 const int index = ItemIndexByID(GetShelfIDForAppID(shelf_app_id));
145 ShelfItem item = items_[index]; 138 ShelfItem item = items_[index];
146 DCHECK_EQ(item.type, TYPE_PINNED_APP); 139 DCHECK_EQ(item.type, TYPE_PINNED_APP);
147 DCHECK(!item.pinned_by_policy); 140 DCHECK(!item.pinned_by_policy);
148 if (item.status == ash::STATUS_CLOSED) { 141 if (item.status == STATUS_CLOSED) {
James Cook 2017/05/04 16:38:49 I think it's really nice that you clean up these s
msw 2017/05/04 19:05:57 Acknowledged.
149 RemoveItemAt(index); 142 RemoveItemAt(index);
150 } else { 143 } else {
151 item.type = TYPE_APP; 144 item.type = TYPE_APP;
152 Set(index, item); 145 Set(index, item);
153 } 146 }
154 } 147 }
155 148
156 void ShelfModel::DestroyItemDelegates() { 149 void ShelfModel::DestroyItemDelegates() {
157 // Some ShelfItemDelegates access this model in their destructors and hence 150 // Some ShelfItemDelegates access this model in their destructors and hence
158 // need early cleanup. 151 // need early cleanup.
159 id_to_item_delegate_map_.clear(); 152 id_to_item_delegate_map_.clear();
160 } 153 }
161 154
162 int ShelfModel::Add(const ShelfItem& item) { 155 int ShelfModel::Add(const ShelfItem& item) {
163 return AddAt(items_.size(), item); 156 return AddAt(items_.size(), item);
164 } 157 }
165 158
166 int ShelfModel::AddAt(int index, const ShelfItem& item) { 159 int ShelfModel::AddAt(int index, const ShelfItem& item) {
160 // Items should have unique non-empty ids to avoid undefined model behavior.
161 DCHECK(!item.id.IsEmpty());
162 DCHECK_EQ(ItemIndexByID(item.id), -1);
167 index = ValidateInsertionIndex(item.type, index); 163 index = ValidateInsertionIndex(item.type, index);
168 items_.insert(items_.begin() + index, item); 164 items_.insert(items_.begin() + index, item);
169 items_[index].id = next_id_++;
170 for (auto& observer : observers_) 165 for (auto& observer : observers_)
171 observer.ShelfItemAdded(index); 166 observer.ShelfItemAdded(index);
172 return index; 167 return index;
173 } 168 }
174 169
175 void ShelfModel::RemoveItemAt(int index) { 170 void ShelfModel::RemoveItemAt(int index) {
176 DCHECK(index >= 0 && index < item_count()); 171 DCHECK(index >= 0 && index < item_count());
177 ShelfItem old_item(items_[index]); 172 ShelfItem old_item(items_[index]);
178 items_.erase(items_.begin() + index); 173 items_.erase(items_.begin() + index);
179 id_to_item_delegate_map_.erase(old_item.id); 174 id_to_item_delegate_map_.erase(old_item.id);
(...skipping 17 matching lines...) Expand all
197 NOTREACHED(); 192 NOTREACHED();
198 return; 193 return;
199 } 194 }
200 195
201 int new_index = item.type == items_[index].type 196 int new_index = item.type == items_[index].type
202 ? index 197 ? index
203 : ValidateInsertionIndex(item.type, index); 198 : ValidateInsertionIndex(item.type, index);
204 199
205 ShelfItem old_item(items_[index]); 200 ShelfItem old_item(items_[index]);
206 items_[index] = item; 201 items_[index] = item;
207 items_[index].id = old_item.id; 202 DCHECK(old_item.id == item.id);
208 for (auto& observer : observers_) 203 for (auto& observer : observers_)
209 observer.ShelfItemChanged(index, old_item); 204 observer.ShelfItemChanged(index, old_item);
210 205
211 // If the type changes confirm that the item is still in the right order. 206 // If the type changes confirm that the item is still in the right order.
212 if (new_index != index) { 207 if (new_index != index) {
213 // The move function works by removing one item and then inserting it at the 208 // The move function works by removing one item and then inserting it at the
214 // new location. However - by removing the item first the order will change 209 // new location. However - by removing the item first the order will change
215 // so that our target index needs to be corrected. 210 // so that our target index needs to be corrected.
216 // TODO(skuhne): Moving this into the Move function breaks lots of unit 211 // TODO(skuhne): Moving this into the Move function breaks lots of unit
217 // tests. So several functions were already using this incorrectly. 212 // tests. So several functions were already using this incorrectly.
218 // That needs to be cleaned up. 213 // That needs to be cleaned up.
219 if (index < new_index) 214 if (index < new_index)
220 new_index--; 215 new_index--;
221 216
222 Move(index, new_index); 217 Move(index, new_index);
223 } 218 }
224 } 219 }
225 220
226 int ShelfModel::ItemIndexByID(ShelfID id) const { 221 int ShelfModel::ItemIndexByID(const ShelfID& id) const {
227 ShelfItems::const_iterator i = ItemByID(id); 222 ShelfItems::const_iterator i = ItemByID(id);
228 return i == items_.end() ? -1 : static_cast<int>(i - items_.begin()); 223 return i == items_.end() ? -1 : static_cast<int>(i - items_.begin());
229 } 224 }
230 225
231 int ShelfModel::GetItemIndexForType(ShelfItemType type) { 226 int ShelfModel::GetItemIndexForType(ShelfItemType type) {
232 for (size_t i = 0; i < items_.size(); ++i) { 227 for (size_t i = 0; i < items_.size(); ++i) {
233 if (items_[i].type == type) 228 if (items_[i].type == type)
234 return i; 229 return i;
235 } 230 }
236 return -1; 231 return -1;
237 } 232 }
238 233
239 ShelfItems::const_iterator ShelfModel::ItemByID(ShelfID id) const { 234 ShelfItems::const_iterator ShelfModel::ItemByID(const ShelfID& id) const {
240 for (ShelfItems::const_iterator i = items_.begin(); i != items_.end(); ++i) { 235 for (ShelfItems::const_iterator i = items_.begin(); i != items_.end(); ++i) {
241 if (i->id == id) 236 if (i->id == id)
242 return i; 237 return i;
243 } 238 }
244 return items_.end(); 239 return items_.end();
245 } 240 }
246 241
247 int ShelfModel::FirstRunningAppIndex() const { 242 int ShelfModel::FirstRunningAppIndex() const {
248 ShelfItem weight_dummy; 243 ShelfItem weight_dummy;
249 weight_dummy.type = TYPE_APP; 244 weight_dummy.type = TYPE_APP;
250 return std::lower_bound(items_.begin(), items_.end(), weight_dummy, 245 return std::lower_bound(items_.begin(), items_.end(), weight_dummy,
251 CompareByWeight) - 246 CompareByWeight) -
252 items_.begin(); 247 items_.begin();
253 } 248 }
254 249
255 int ShelfModel::FirstPanelIndex() const { 250 int ShelfModel::FirstPanelIndex() const {
256 ShelfItem weight_dummy; 251 ShelfItem weight_dummy;
257 weight_dummy.type = TYPE_APP_PANEL; 252 weight_dummy.type = TYPE_APP_PANEL;
258 return std::lower_bound(items_.begin(), items_.end(), weight_dummy, 253 return std::lower_bound(items_.begin(), items_.end(), weight_dummy,
259 CompareByWeight) - 254 CompareByWeight) -
260 items_.begin(); 255 items_.begin();
261 } 256 }
262 257
263 void ShelfModel::SetShelfItemDelegate( 258 void ShelfModel::SetShelfItemDelegate(
264 ShelfID id, 259 const ShelfID& id,
265 std::unique_ptr<ShelfItemDelegate> item_delegate) { 260 std::unique_ptr<ShelfItemDelegate> item_delegate) {
266 if (item_delegate) 261 if (item_delegate)
267 item_delegate->set_shelf_id(id); 262 item_delegate->set_shelf_id(id);
268 // This assignment replaces any ShelfItemDelegate already registered for |id|. 263 // This assignment replaces any ShelfItemDelegate already registered for |id|.
269 id_to_item_delegate_map_[id] = std::move(item_delegate); 264 id_to_item_delegate_map_[id] = std::move(item_delegate);
270 } 265 }
271 266
272 ShelfItemDelegate* ShelfModel::GetShelfItemDelegate(ShelfID id) { 267 ShelfItemDelegate* ShelfModel::GetShelfItemDelegate(const ShelfID& id) {
273 if (id_to_item_delegate_map_.find(id) != id_to_item_delegate_map_.end()) 268 if (id_to_item_delegate_map_.find(id) != id_to_item_delegate_map_.end())
274 return id_to_item_delegate_map_[id].get(); 269 return id_to_item_delegate_map_[id].get();
275 return nullptr; 270 return nullptr;
276 } 271 }
277 272
278 void ShelfModel::AddObserver(ShelfModelObserver* observer) { 273 void ShelfModel::AddObserver(ShelfModelObserver* observer) {
279 observers_.AddObserver(observer); 274 observers_.AddObserver(observer);
280 } 275 }
281 276
282 void ShelfModel::RemoveObserver(ShelfModelObserver* observer) { 277 void ShelfModel::RemoveObserver(ShelfModelObserver* observer) {
(...skipping 12 matching lines...) Expand all
295 static_cast<ShelfItems::difference_type>(index)); 290 static_cast<ShelfItems::difference_type>(index));
296 index = std::min(std::upper_bound(items_.begin(), items_.end(), weight_dummy, 291 index = std::min(std::upper_bound(items_.begin(), items_.end(), weight_dummy,
297 CompareByWeight) - 292 CompareByWeight) -
298 items_.begin(), 293 items_.begin(),
299 static_cast<ShelfItems::difference_type>(index)); 294 static_cast<ShelfItems::difference_type>(index));
300 295
301 return index; 296 return index;
302 } 297 }
303 298
304 } // namespace ash 299 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698