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

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

Issue 2833173002: mash: Support ShelfModel access in Chrome. (Closed)
Patch Set: Address comments; fix test failures. 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 DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
1279 DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change";
1280
1281 // Ignore notifications of adding the AppList item; it should already exist.
1282 if (item.id.app_id == ash::kAppListId) {
1283 DCHECK_EQ(0, model_->ItemIndexByID(item.id));
1284 return;
1285 }
1286
1287 DCHECK_LE(index, model_->item_count()) << "Index out of bounds";
1288 DCHECK_GT(index, 0) << "Items can not preceed the AppList";
1289 index = std::min(std::max(index, 1), model_->item_count());
1290 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
1291 model_->AddAt(index, item);
1292 }
1293
1294 void ChromeLauncherController::OnShelfItemRemoved(const ash::ShelfID& id) {
1295 DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
1296 DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change";
1297 const int index = model_->ItemIndexByID(id);
1298 DCHECK_GE(index, 0) << "Item not found";
1299 DCHECK_NE(index, 0) << "The AppList shelf item cannot be removed";
1300 if (index <= 0)
1301 return;
1302 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
1303 model_->RemoveItemAt(index);
1304 }
1305
1306 void ChromeLauncherController::OnShelfItemMoved(const ash::ShelfID& id,
1307 int32_t index) {
1308 DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
1309 DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change";
1310 const int current_index = model_->ItemIndexByID(id);
1311 DCHECK_GE(current_index, 0) << "No item found with the given id";
1312 DCHECK_NE(current_index, 0) << "The AppList shelf item cannot be moved";
1313 if (current_index <= 0)
1314 return;
1315 DCHECK_GT(index, 0) << "Items can not preceed the AppList";
1316 DCHECK_LT(index, model_->item_count()) << "Index out of bounds";
1317 index = std::min(std::max(index, 1), model_->item_count() - 1);
1318 DCHECK_NE(current_index, index) << "The item is already at the given index";
1319 if (current_index == index)
1320 return;
1321 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
1322 model_->Move(current_index, index);
1323 }
1324
1325 void ChromeLauncherController::OnShelfItemUpdated(const ash::ShelfItem& item) {
1326 DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
1327 DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change";
1328 const int index = model_->ItemIndexByID(item.id);
1329 DCHECK_GE(index, 0) << "No item found with the given id";
1330 if (index < 0)
1331 return;
1332 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
1333 model_->Set(index, item);
1334 }
1335
1336 void ChromeLauncherController::OnShelfItemDelegateChanged(
1337 const ash::ShelfID& id,
1338 ash::mojom::ShelfItemDelegatePtr delegate) {
1339 DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
1340 DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change";
1341 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
1342 if (delegate.is_bound()) {
1343 model_->SetShelfItemDelegate(id,
1344 base::MakeUnique<ash::RemoteShelfItemDelegate>(
1345 id, std::move(delegate)));
1346 } else {
1347 model_->SetShelfItemDelegate(id, nullptr);
1348 }
1349 }
1350
1271 /////////////////////////////////////////////////////////////////////////////// 1351 ///////////////////////////////////////////////////////////////////////////////
1272 // ash::ShelfModelObserver: 1352 // ash::ShelfModelObserver:
1273 1353
1274 void ChromeLauncherController::ShelfItemAdded(int index) { 1354 void ChromeLauncherController::ShelfItemAdded(int index) {
1355 ash::ShelfItem item = model_->items()[index];
1356 if (shelf_controller_ && !applying_remote_shelf_model_changes_ &&
1357 chromeos::GetAshConfig() == ash::Config::MASH) {
1358 shelf_controller_->AddShelfItem(index, item);
1359 }
1360
1275 // Update the pin position preference as needed. 1361 // Update the pin position preference as needed.
1276 ash::ShelfItem item = model_->items()[index];
1277 if (ItemTypeIsPinned(item) && should_sync_pin_changes_) 1362 if (ItemTypeIsPinned(item) && should_sync_pin_changes_)
1278 SyncPinPosition(item.id); 1363 SyncPinPosition(item.id);
1279 1364
1280 // Fetch and update the icon for the app's item. 1365 // Fetch and update the icon for the app's item.
1281 const std::string& app_id = item.id.app_id; 1366 const std::string& app_id = item.id.app_id;
1282 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id); 1367 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
1283 if (app_icon_loader) { 1368 if (app_icon_loader) {
1284 app_icon_loader->FetchImage(app_id); 1369 app_icon_loader->FetchImage(app_id);
1285 app_icon_loader->UpdateImage(app_id); 1370 app_icon_loader->UpdateImage(app_id);
1286 } 1371 }
1287 1372
1288 // Update the item with any missing Chrome-specific info. 1373 // Update the item with any missing Chrome-specific info.
1289 if (item.type == ash::TYPE_APP || item.type == ash::TYPE_PINNED_APP) { 1374 if (item.type == ash::TYPE_APP || item.type == ash::TYPE_PINNED_APP) {
1290 bool needs_update = false; 1375 bool needs_update = false;
1291 if (item.image.isNull()) { 1376 if (item.image.isNull()) {
1292 needs_update = true; 1377 needs_update = true;
1293 item.image = extensions::util::GetDefaultAppIcon(); 1378 item.image = extensions::util::GetDefaultAppIcon();
1294 } 1379 }
1295 if (item.title.empty()) { 1380 if (item.title.empty()) {
1296 needs_update = true; 1381 needs_update = true;
1297 item.title = LauncherControllerHelper::GetAppTitle(profile(), app_id); 1382 item.title = LauncherControllerHelper::GetAppTitle(profile(), app_id);
1298 } 1383 }
1299 ash::ShelfItemStatus status = GetAppState(app_id); 1384 ash::ShelfItemStatus status = GetAppState(app_id);
1300 if (status != item.status && status != ash::STATUS_CLOSED) { 1385 if (status != item.status && status != ash::STATUS_CLOSED) {
1301 needs_update = true; 1386 needs_update = true;
1302 item.status = status; 1387 item.status = status;
1303 } 1388 }
1304 if (needs_update) 1389 if (needs_update) {
1390 // Ensure these changes are reported back to Ash.
1391 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, false);
1305 model_->Set(index, item); 1392 model_->Set(index, item);
1393 }
1306 } 1394 }
1307 1395
1308 // Construct a ShelfItemDelegate for the item if one does not yet exist. 1396 // Construct a ShelfItemDelegate for the item if one does not yet exist.
1309 if (!model_->GetShelfItemDelegate(item.id)) { 1397 if (!model_->GetShelfItemDelegate(item.id)) {
1398 // Ensure these changes are reported back to Ash.
1399 base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, false);
1310 model_->SetShelfItemDelegate( 1400 model_->SetShelfItemDelegate(
1311 item.id, AppShortcutLauncherItemController::Create(item.id)); 1401 item.id, AppShortcutLauncherItemController::Create(item.id));
1312 } 1402 }
1313 } 1403 }
1314 1404
1315 void ChromeLauncherController::ShelfItemRemoved( 1405 void ChromeLauncherController::ShelfItemRemoved(
1316 int index, 1406 int index,
1317 const ash::ShelfItem& old_item) { 1407 const ash::ShelfItem& old_item) {
1408 if (shelf_controller_ && !applying_remote_shelf_model_changes_ &&
1409 chromeos::GetAshConfig() == ash::Config::MASH) {
1410 shelf_controller_->RemoveShelfItem(old_item.id);
1411 }
1412
1318 // Remove the pin position from preferences as needed. 1413 // Remove the pin position from preferences as needed.
1319 if (ItemTypeIsPinned(old_item) && should_sync_pin_changes_) 1414 if (ItemTypeIsPinned(old_item) && should_sync_pin_changes_)
1320 RemovePinPosition(profile(), old_item.id); 1415 RemovePinPosition(profile(), old_item.id);
1321 1416
1322 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(old_item.id.app_id); 1417 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(old_item.id.app_id);
1323 if (app_icon_loader) 1418 if (app_icon_loader)
1324 app_icon_loader->ClearImage(old_item.id.app_id); 1419 app_icon_loader->ClearImage(old_item.id.app_id);
1325 } 1420 }
1326 1421
1327 void ChromeLauncherController::ShelfItemMoved(int start_index, 1422 void ChromeLauncherController::ShelfItemMoved(int start_index,
1328 int target_index) { 1423 int target_index) {
1424 const ash::ShelfItem& item = model_->items()[target_index];
1425 if (shelf_controller_ && !applying_remote_shelf_model_changes_ &&
1426 chromeos::GetAshConfig() == ash::Config::MASH) {
1427 shelf_controller_->MoveShelfItem(item.id, target_index);
1428 }
1429
1329 // Update the pin position preference as needed. 1430 // 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); 1431 DCHECK_NE(ash::TYPE_APP_LIST, item.type);
1332 if (ItemTypeIsPinned(item) && should_sync_pin_changes_) 1432 if (ItemTypeIsPinned(item) && should_sync_pin_changes_)
1333 SyncPinPosition(item.id); 1433 SyncPinPosition(item.id);
1334 } 1434 }
1335 1435
1336 void ChromeLauncherController::ShelfItemChanged( 1436 void ChromeLauncherController::ShelfItemChanged(
1337 int index, 1437 int index,
1338 const ash::ShelfItem& old_item) { 1438 const ash::ShelfItem& old_item) {
1439 const ash::ShelfItem& item = model_->items()[index];
1440 if (shelf_controller_ && !applying_remote_shelf_model_changes_ &&
1441 chromeos::GetAshConfig() == ash::Config::MASH) {
1442 shelf_controller_->UpdateShelfItem(item);
1443 }
1444
1339 if (!should_sync_pin_changes_) 1445 if (!should_sync_pin_changes_)
1340 return; 1446 return;
1341 1447
1342 const ash::ShelfItem& item = model_->items()[index];
1343 // Add or remove the pin position from preferences as needed. 1448 // Add or remove the pin position from preferences as needed.
1344 if (!ItemTypeIsPinned(old_item) && ItemTypeIsPinned(item)) 1449 if (!ItemTypeIsPinned(old_item) && ItemTypeIsPinned(item))
1345 SyncPinPosition(item.id); 1450 SyncPinPosition(item.id);
1346 else if (ItemTypeIsPinned(old_item) && !ItemTypeIsPinned(item)) 1451 else if (ItemTypeIsPinned(old_item) && !ItemTypeIsPinned(item))
1347 RemovePinPosition(profile(), old_item.id); 1452 RemovePinPosition(profile(), old_item.id);
1348 } 1453 }
1349 1454
1455 void ChromeLauncherController::ShelfItemDelegateChanged(
1456 const ash::ShelfID& id,
1457 ash::ShelfItemDelegate* delegate) {
1458 if (shelf_controller_ && !applying_remote_shelf_model_changes_ &&
1459 chromeos::GetAshConfig() == ash::Config::MASH) {
1460 shelf_controller_->SetShelfItemDelegate(
1461 id, delegate ? delegate->CreateInterfacePtrAndBind()
1462 : ash::mojom::ShelfItemDelegatePtr());
1463 }
1464 }
1465
1350 /////////////////////////////////////////////////////////////////////////////// 1466 ///////////////////////////////////////////////////////////////////////////////
1351 // ash::WindowTreeHostManager::Observer: 1467 // ash::WindowTreeHostManager::Observer:
1352 1468
1353 void ChromeLauncherController::OnDisplayConfigurationChanged() { 1469 void ChromeLauncherController::OnDisplayConfigurationChanged() {
1354 // In BOTTOM_LOCKED state, ignore the call of SetShelfBehaviorsFromPrefs. 1470 // In BOTTOM_LOCKED state, ignore the call of SetShelfBehaviorsFromPrefs.
1355 // Because it might be called by some operations, like crbug.com/627040 1471 // Because it might be called by some operations, like crbug.com/627040
1356 // rotating screen. 1472 // rotating screen.
1357 ash::Shelf* shelf = ash::Shelf::ForWindow(ash::Shell::GetPrimaryRootWindow()); 1473 ash::Shelf* shelf = ash::Shelf::ForWindow(ash::Shell::GetPrimaryRootWindow());
1358 if (shelf->alignment() != ash::SHELF_ALIGNMENT_BOTTOM_LOCKED) 1474 if (shelf->alignment() != ash::SHELF_ALIGNMENT_BOTTOM_LOCKED)
1359 SetShelfBehaviorsFromPrefs(); 1475 SetShelfBehaviorsFromPrefs();
(...skipping 10 matching lines...) Expand all
1370 : IDS_ASH_SHELF_APP_LIST_LAUNCHER_TITLE); 1486 : IDS_ASH_SHELF_APP_LIST_LAUNCHER_TITLE);
1371 1487
1372 const int app_list_index = model_->GetItemIndexForType(ash::TYPE_APP_LIST); 1488 const int app_list_index = model_->GetItemIndexForType(ash::TYPE_APP_LIST);
1373 DCHECK_GE(app_list_index, 0); 1489 DCHECK_GE(app_list_index, 0);
1374 ash::ShelfItem item = model_->items()[app_list_index]; 1490 ash::ShelfItem item = model_->items()[app_list_index];
1375 if (item.title != title) { 1491 if (item.title != title) {
1376 item.title = title; 1492 item.title = title;
1377 model_->Set(app_list_index, item); 1493 model_->Set(app_list_index, item);
1378 } 1494 }
1379 } 1495 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698