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

Side by Side Diff: chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc

Issue 2833173002: mash: Support ShelfModel access in Chrome. (Closed)
Patch Set: Refine init pattern; add AppList item in ShelfModel ctor. Created 3 years, 6 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 "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" 5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
6 6
7 #include "ash/multi_profile_uma.h" 7 #include "ash/multi_profile_uma.h"
8 #include "ash/public/cpp/remote_shelf_item_delegate.h"
8 #include "ash/public/cpp/shelf_item.h" 9 #include "ash/public/cpp/shelf_item.h"
9 #include "ash/public/interfaces/constants.mojom.h" 10 #include "ash/public/interfaces/constants.mojom.h"
10 #include "ash/resources/grit/ash_resources.h" 11 #include "ash/resources/grit/ash_resources.h"
11 #include "ash/shelf/shelf.h" 12 #include "ash/shelf/shelf.h"
12 #include "ash/shelf/shelf_model.h" 13 #include "ash/shelf/shelf_model.h"
13 #include "ash/shell.h" 14 #include "ash/shell.h"
14 #include "ash/shell_port.h" 15 #include "ash/shell_port.h"
15 #include "ash/strings/grit/ash_strings.h" 16 #include "ash/strings/grit/ash_strings.h"
16 #include "ash/system/tray/system_tray_delegate.h" 17 #include "ash/system/tray/system_tray_delegate.h"
17 #include "base/memory/ptr_util.h" 18 #include "base/memory/ptr_util.h"
18 #include "base/strings/pattern.h" 19 #include "base/strings/pattern.h"
19 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
20 #include "base/strings/utf_string_conversions.h" 21 #include "base/strings/utf_string_conversions.h"
21 #include "base/threading/thread_task_runner_handle.h" 22 #include "base/threading/thread_task_runner_handle.h"
22 #include "chrome/browser/chromeos/arc/arc_util.h" 23 #include "chrome/browser/chromeos/arc/arc_util.h"
24 #include "chrome/browser/chromeos/ash_config.h"
23 #include "chrome/browser/extensions/chrome_app_icon_loader.h" 25 #include "chrome/browser/extensions/chrome_app_icon_loader.h"
24 #include "chrome/browser/extensions/extension_util.h" 26 #include "chrome/browser/extensions/extension_util.h"
25 #include "chrome/browser/prefs/pref_service_syncable_util.h" 27 #include "chrome/browser/prefs/pref_service_syncable_util.h"
26 #include "chrome/browser/profiles/profile.h" 28 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/browser/profiles/profile_manager.h" 29 #include "chrome/browser/profiles/profile_manager.h"
28 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" 30 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
29 #include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h" 31 #include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h"
30 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" 32 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
31 #include "chrome/browser/ui/ash/app_sync_ui_state.h" 33 #include "chrome/browser/ui/ash/app_sync_ui_state.h"
32 #include "chrome/browser/ui/ash/ash_util.h" 34 #include "chrome/browser/ui/ash/ash_util.h"
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 if (instance_ == this) 274 if (instance_ == this)
273 instance_ = nullptr; 275 instance_ = nullptr;
274 } 276 }
275 277
276 void ChromeLauncherController::Init() { 278 void ChromeLauncherController::Init() {
277 // Start observing the shelf controller. 279 // Start observing the shelf controller.
278 if (ConnectToShelfController()) { 280 if (ConnectToShelfController()) {
279 ash::mojom::ShelfObserverAssociatedPtrInfo ptr_info; 281 ash::mojom::ShelfObserverAssociatedPtrInfo ptr_info;
280 observer_binding_.Bind(mojo::MakeRequest(&ptr_info)); 282 observer_binding_.Bind(mojo::MakeRequest(&ptr_info));
281 shelf_controller_->AddObserver(std::move(ptr_info)); 283 shelf_controller_->AddObserver(std::move(ptr_info));
284 // ShelfModel's constructor should have initialized the app list item.
285 DCHECK_EQ(1, model_->item_count());
286 DCHECK_EQ(ash::kAppListId, model_->items()[0].id.app_id);
282 } 287 }
283 288
284 CreateBrowserShortcutLauncherItem(); 289 CreateBrowserShortcutLauncherItem();
285 UpdateAppLaunchersFromPref(); 290 UpdateAppLaunchersFromPref();
286 291
287 // TODO(sky): update unit test so that this test isn't necessary. 292 // TODO(sky): update unit test so that this test isn't necessary.
288 if (ash::Shell::HasInstance()) 293 if (ash::Shell::HasInstance())
289 SetVirtualKeyboardBehaviorFromPrefs(); 294 SetVirtualKeyboardBehaviorFromPrefs();
290 295
291 prefs_observer_ = ChromeLauncherPrefsObserver::CreateIfNecessary(profile()); 296 prefs_observer_ = ChromeLauncherPrefsObserver::CreateIfNecessary(profile());
(...skipping 969 matching lines...) Expand 10 before | Expand all | Expand 10 after
1261 1266
1262 void ChromeLauncherController::OnAutoHideBehaviorChanged( 1267 void ChromeLauncherController::OnAutoHideBehaviorChanged(
1263 ash::ShelfAutoHideBehavior auto_hide, 1268 ash::ShelfAutoHideBehavior auto_hide,
1264 int64_t display_id) { 1269 int64_t display_id) {
1265 DCHECK(!updating_shelf_pref_from_observer_); 1270 DCHECK(!updating_shelf_pref_from_observer_);
1266 base::AutoReset<bool> updating(&updating_shelf_pref_from_observer_, true); 1271 base::AutoReset<bool> updating(&updating_shelf_pref_from_observer_, true);
1267 // This will uselessly store a preference value for invalid display ids. 1272 // This will uselessly store a preference value for invalid display ids.
1268 SetShelfAutoHideBehaviorPref(profile_->GetPrefs(), display_id, auto_hide); 1273 SetShelfAutoHideBehaviorPref(profile_->GetPrefs(), display_id, auto_hide);
1269 } 1274 }
1270 1275
1276 void ChromeLauncherController::OnShelfItemAdded(int32_t index,
1277 const ash::ShelfItem& item) {
1278 // Ignore notifications of adding the AppList item; it should already exist.
1279 if (item.id.app_id == ash::kAppListId) {
1280 DCHECK_EQ(0, model_->ItemIndexByID(item.id));
1281 return;
1282 }
1283
1284 DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
1285 DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change";
1286 DCHECK_GE(model_->item_count(), index) << "Models out of sync";
1287 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
1288 model_->AddAt(index, item);
1289 }
1290
1291 void ChromeLauncherController::OnShelfItemRemoved(int32_t index,
1292 const ash::ShelfItem& item) {
1293 DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
1294 DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change";
1295 DCHECK_GT(model_->item_count(), index) << "Models out of sync";
1296 DCHECK_EQ(model_->items()[index].id, item.id) << "Models out of sync";
1297 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
1298 model_->RemoveItemAt(index);
1299 }
1300
1301 void ChromeLauncherController::OnShelfItemMoved(int32_t start_index,
1302 int32_t target_index) {
1303 DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
1304 DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change";
1305 DCHECK_GT(model_->item_count(), start_index) << "Models out of sync";
1306 DCHECK_GT(model_->item_count(), target_index) << "Models out of sync";
1307 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
1308 model_->Move(start_index, target_index);
1309 }
1310
1311 void ChromeLauncherController::OnShelfItemChanged(int32_t index,
1312 const ash::ShelfItem& item) {
1313 DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
1314 DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change";
1315 DCHECK_GT(model_->item_count(), index) << "Models out of sync";
1316 DCHECK_EQ(model_->items()[index].id, item.id) << "Models out of sync";
1317 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
1318 model_->Set(index, item);
1319 }
1320
1321 void ChromeLauncherController::OnShelfItemDelegateChanged(
1322 const ash::ShelfID& id,
1323 ash::mojom::ShelfItemDelegatePtr delegate) {
1324 DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
1325 DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change";
1326 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
1327 if (delegate.is_bound())
James Cook 2017/05/30 22:47:48 nit: curlies
msw 2017/05/31 16:55:22 Done.
1328 model_->SetShelfItemDelegate(id,
1329 base::MakeUnique<ash::RemoteShelfItemDelegate>(
1330 id, std::move(delegate)));
1331 else
1332 model_->SetShelfItemDelegate(id, nullptr);
1333 }
1334
1271 /////////////////////////////////////////////////////////////////////////////// 1335 ///////////////////////////////////////////////////////////////////////////////
1272 // ash::ShelfModelObserver: 1336 // ash::ShelfModelObserver:
1273 1337
1274 void ChromeLauncherController::ShelfItemAdded(int index) { 1338 void ChromeLauncherController::ShelfItemAdded(int index) {
1339 ash::ShelfItem item = model_->items()[index];
1340 if (shelf_controller_ && !applying_remote_shelf_model_changes_ &&
1341 chromeos::GetAshConfig() == ash::Config::MASH) {
James Cook 2017/05/30 22:47:48 This (and the blocks below) is a little odd. So CL
msw 2017/05/31 16:55:22 Yes, code in chrome directly accesses CLC's ShelfM
1342 shelf_controller_->AddShelfItem(index, item);
1343 }
1344
1275 // Update the pin position preference as needed. 1345 // Update the pin position preference as needed.
1276 ash::ShelfItem item = model_->items()[index];
1277 if (ItemTypeIsPinned(item) && should_sync_pin_changes_) 1346 if (ItemTypeIsPinned(item) && should_sync_pin_changes_)
1278 SyncPinPosition(item.id); 1347 SyncPinPosition(item.id);
1279 1348
1280 // Fetch and update the icon for the app's item. 1349 // Fetch and update the icon for the app's item.
1281 const std::string& app_id = item.id.app_id; 1350 const std::string& app_id = item.id.app_id;
1282 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id); 1351 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
1283 if (app_icon_loader) { 1352 if (app_icon_loader) {
1284 app_icon_loader->FetchImage(app_id); 1353 app_icon_loader->FetchImage(app_id);
1285 app_icon_loader->UpdateImage(app_id); 1354 app_icon_loader->UpdateImage(app_id);
1286 } 1355 }
1287 1356
1288 // Update the item with any missing Chrome-specific info. 1357 // Update the item with any missing Chrome-specific info.
1289 if (item.type == ash::TYPE_APP || item.type == ash::TYPE_PINNED_APP) { 1358 if (item.type == ash::TYPE_APP || item.type == ash::TYPE_PINNED_APP) {
1290 bool needs_update = false; 1359 bool needs_update = false;
1291 if (item.image.isNull()) { 1360 if (item.image.isNull()) {
1292 needs_update = true; 1361 needs_update = true;
1293 item.image = extensions::util::GetDefaultAppIcon(); 1362 item.image = extensions::util::GetDefaultAppIcon();
1294 } 1363 }
1295 if (item.title.empty()) { 1364 if (item.title.empty()) {
1296 needs_update = true; 1365 needs_update = true;
1297 item.title = LauncherControllerHelper::GetAppTitle(profile(), app_id); 1366 item.title = LauncherControllerHelper::GetAppTitle(profile(), app_id);
1298 } 1367 }
1299 ash::ShelfItemStatus status = GetAppState(app_id); 1368 ash::ShelfItemStatus status = GetAppState(app_id);
1300 if (status != item.status && status != ash::STATUS_CLOSED) { 1369 if (status != item.status && status != ash::STATUS_CLOSED) {
1301 needs_update = true; 1370 needs_update = true;
1302 item.status = status; 1371 item.status = status;
1303 } 1372 }
1304 if (needs_update) 1373 if (needs_update) {
1374 // Ensure these changes are reported back to Ash.
1375 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, false);
1305 model_->Set(index, item); 1376 model_->Set(index, item);
1377 }
1306 } 1378 }
1307 1379
1308 // Construct a ShelfItemDelegate for the item if one does not yet exist. 1380 // Construct a ShelfItemDelegate for the item if one does not yet exist.
1309 if (!model_->GetShelfItemDelegate(item.id)) { 1381 if (!model_->GetShelfItemDelegate(item.id)) {
1382 // Ensure these changes are reported back to Ash.
1383 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, false);
James Cook 2017/05/30 22:47:48 Aside: It's kind of a bummer that adding an item c
msw 2017/05/31 16:55:22 Perhaps worth following up.
1310 model_->SetShelfItemDelegate( 1384 model_->SetShelfItemDelegate(
1311 item.id, AppShortcutLauncherItemController::Create(item.id)); 1385 item.id, AppShortcutLauncherItemController::Create(item.id));
1312 } 1386 }
1313 } 1387 }
1314 1388
1315 void ChromeLauncherController::ShelfItemRemoved( 1389 void ChromeLauncherController::ShelfItemRemoved(
1316 int index, 1390 int index,
1317 const ash::ShelfItem& old_item) { 1391 const ash::ShelfItem& old_item) {
1392 if (shelf_controller_ && !applying_remote_shelf_model_changes_ &&
1393 chromeos::GetAshConfig() == ash::Config::MASH) {
1394 shelf_controller_->RemoveShelfItem(old_item.id);
1395 }
1396
1318 // Remove the pin position from preferences as needed. 1397 // Remove the pin position from preferences as needed.
1319 if (ItemTypeIsPinned(old_item) && should_sync_pin_changes_) 1398 if (ItemTypeIsPinned(old_item) && should_sync_pin_changes_)
1320 RemovePinPosition(profile(), old_item.id); 1399 RemovePinPosition(profile(), old_item.id);
1321 1400
1322 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(old_item.id.app_id); 1401 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(old_item.id.app_id);
1323 if (app_icon_loader) 1402 if (app_icon_loader)
1324 app_icon_loader->ClearImage(old_item.id.app_id); 1403 app_icon_loader->ClearImage(old_item.id.app_id);
1325 } 1404 }
1326 1405
1327 void ChromeLauncherController::ShelfItemMoved(int start_index, 1406 void ChromeLauncherController::ShelfItemMoved(int start_index,
1328 int target_index) { 1407 int target_index) {
1408 const ash::ShelfItem& item = model_->items()[target_index];
1409 if (shelf_controller_ && !applying_remote_shelf_model_changes_ &&
1410 chromeos::GetAshConfig() == ash::Config::MASH) {
1411 shelf_controller_->MoveShelfItem(item.id, target_index);
1412 }
1413
1329 // Update the pin position preference as needed. 1414 // Update the pin position preference as needed.
1330 const ash::ShelfItem& item = model_->items()[target_index];
1331 DCHECK_NE(ash::TYPE_APP_LIST, item.type); 1415 DCHECK_NE(ash::TYPE_APP_LIST, item.type);
1332 if (ItemTypeIsPinned(item) && should_sync_pin_changes_) 1416 if (ItemTypeIsPinned(item) && should_sync_pin_changes_)
1333 SyncPinPosition(item.id); 1417 SyncPinPosition(item.id);
1334 } 1418 }
1335 1419
1336 void ChromeLauncherController::ShelfItemChanged( 1420 void ChromeLauncherController::ShelfItemChanged(
1337 int index, 1421 int index,
1338 const ash::ShelfItem& old_item) { 1422 const ash::ShelfItem& old_item) {
1423 const ash::ShelfItem& item = model_->items()[index];
1424 if (shelf_controller_ && !applying_remote_shelf_model_changes_ &&
1425 chromeos::GetAshConfig() == ash::Config::MASH) {
1426 shelf_controller_->UpdateShelfItem(item);
1427 }
1428
1339 if (!should_sync_pin_changes_) 1429 if (!should_sync_pin_changes_)
1340 return; 1430 return;
1341 1431
1342 const ash::ShelfItem& item = model_->items()[index];
1343 // Add or remove the pin position from preferences as needed. 1432 // Add or remove the pin position from preferences as needed.
1344 if (!ItemTypeIsPinned(old_item) && ItemTypeIsPinned(item)) 1433 if (!ItemTypeIsPinned(old_item) && ItemTypeIsPinned(item))
1345 SyncPinPosition(item.id); 1434 SyncPinPosition(item.id);
1346 else if (ItemTypeIsPinned(old_item) && !ItemTypeIsPinned(item)) 1435 else if (ItemTypeIsPinned(old_item) && !ItemTypeIsPinned(item))
1347 RemovePinPosition(profile(), old_item.id); 1436 RemovePinPosition(profile(), old_item.id);
1348 } 1437 }
1349 1438
1439 void ChromeLauncherController::ShelfItemDelegateChanged(
1440 const ash::ShelfID& id,
1441 ash::ShelfItemDelegate* delegate) {
1442 if (shelf_controller_ && !applying_remote_shelf_model_changes_ &&
1443 chromeos::GetAshConfig() == ash::Config::MASH) {
1444 shelf_controller_->SetShelfItemDelegate(
1445 id, delegate ? delegate->CreateInterfacePtrAndBind()
1446 : ash::mojom::ShelfItemDelegatePtr());
1447 }
1448 }
1449
1350 /////////////////////////////////////////////////////////////////////////////// 1450 ///////////////////////////////////////////////////////////////////////////////
1351 // ash::WindowTreeHostManager::Observer: 1451 // ash::WindowTreeHostManager::Observer:
1352 1452
1353 void ChromeLauncherController::OnDisplayConfigurationChanged() { 1453 void ChromeLauncherController::OnDisplayConfigurationChanged() {
1354 // In BOTTOM_LOCKED state, ignore the call of SetShelfBehaviorsFromPrefs. 1454 // In BOTTOM_LOCKED state, ignore the call of SetShelfBehaviorsFromPrefs.
1355 // Because it might be called by some operations, like crbug.com/627040 1455 // Because it might be called by some operations, like crbug.com/627040
1356 // rotating screen. 1456 // rotating screen.
1357 ash::Shelf* shelf = ash::Shelf::ForWindow(ash::Shell::GetPrimaryRootWindow()); 1457 ash::Shelf* shelf = ash::Shelf::ForWindow(ash::Shell::GetPrimaryRootWindow());
1358 if (shelf->alignment() != ash::SHELF_ALIGNMENT_BOTTOM_LOCKED) 1458 if (shelf->alignment() != ash::SHELF_ALIGNMENT_BOTTOM_LOCKED)
1359 SetShelfBehaviorsFromPrefs(); 1459 SetShelfBehaviorsFromPrefs();
(...skipping 10 matching lines...) Expand all
1370 : IDS_ASH_SHELF_APP_LIST_LAUNCHER_TITLE); 1470 : IDS_ASH_SHELF_APP_LIST_LAUNCHER_TITLE);
1371 1471
1372 const int app_list_index = model_->GetItemIndexForType(ash::TYPE_APP_LIST); 1472 const int app_list_index = model_->GetItemIndexForType(ash::TYPE_APP_LIST);
1373 DCHECK_GE(app_list_index, 0); 1473 DCHECK_GE(app_list_index, 0);
1374 ash::ShelfItem item = model_->items()[app_list_index]; 1474 ash::ShelfItem item = model_->items()[app_list_index];
1375 if (item.title != title) { 1475 if (item.title != title) {
1376 item.title = title; 1476 item.title = title;
1377 model_->Set(app_list_index, item); 1477 model_->Set(app_list_index, item);
1378 } 1478 }
1379 } 1479 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698