OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |