Chromium Code Reviews| 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_impl.h" | 5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 343 controller = AppShortcutLauncherItemController::Create(app_launch_id, this); | 343 controller = AppShortcutLauncherItemController::Create(app_launch_id, this); |
| 344 controller->set_shelf_id(id); | 344 controller->set_shelf_id(id); |
| 345 // Existing controller is destroyed and replaced by registering again. | 345 // Existing controller is destroyed and replaced by registering again. |
| 346 iter->second = controller; | 346 iter->second = controller; |
| 347 SetShelfItemDelegate(id, controller); | 347 SetShelfItemDelegate(id, controller); |
| 348 } else { | 348 } else { |
| 349 LauncherItemClosed(id); | 349 LauncherItemClosed(id); |
| 350 } | 350 } |
| 351 } | 351 } |
| 352 | 352 |
| 353 void ChromeLauncherControllerImpl::Pin(ash::ShelfID id) { | 353 void ChromeLauncherControllerImpl::UnpinShelfItemInternal(ash::ShelfID id) { |
|
James Cook
2017/03/23 16:43:49
nit: move to match header order (it's short, I don
msw
2017/03/23 18:08:10
Left as-is. The ordering in this file is a mess...
| |
| 354 DCHECK(HasShelfIDToAppIDMapping(id)); | |
| 355 const ash::ShelfItem* item = GetItem(id); | 354 const ash::ShelfItem* item = GetItem(id); |
| 356 if (item && item->type == ash::TYPE_APP) | |
| 357 SetItemType(id, ash::TYPE_PINNED_APP); | |
| 358 else if (!item || item->type != ash::TYPE_PINNED_APP) | |
| 359 return; | |
| 360 | |
| 361 SyncPinPosition(id); | |
| 362 } | |
| 363 | |
| 364 void ChromeLauncherControllerImpl::Unpin(ash::ShelfID id) { | |
| 365 UnpinAndUpdatePrefs(id, true /* update_prefs */); | |
| 366 } | |
| 367 | |
| 368 void ChromeLauncherControllerImpl::UnpinAndUpdatePrefs(ash::ShelfID id, | |
| 369 bool update_prefs) { | |
| 370 LauncherItemController* controller = GetLauncherItemController(id); | 355 LauncherItemController* controller = GetLauncherItemController(id); |
| 371 CHECK(controller); | |
| 372 | |
| 373 if (update_prefs) { | |
| 374 ash::launcher::RemovePinPosition( | |
| 375 profile(), | |
| 376 ash::AppLaunchId(GetAppIDForShelfID(id), GetLaunchIDForShelfID(id))); | |
| 377 } | |
| 378 | |
| 379 const ash::ShelfItem* item = GetItem(id); | |
| 380 if (item && (item->status != ash::STATUS_CLOSED || controller->locked())) | 356 if (item && (item->status != ash::STATUS_CLOSED || controller->locked())) |
| 381 UnpinRunningAppInternal(model_->ItemIndexByID(id)); | 357 UnpinRunningAppInternal(model_->ItemIndexByID(id)); |
| 382 else | 358 else |
| 383 LauncherItemClosed(id); | 359 LauncherItemClosed(id); |
| 384 } | 360 } |
| 385 | 361 |
| 386 bool ChromeLauncherControllerImpl::IsPinned(ash::ShelfID id) { | 362 bool ChromeLauncherControllerImpl::IsPinned(ash::ShelfID id) { |
| 387 const ash::ShelfItem* item = GetItem(id); | 363 const ash::ShelfItem* item = GetItem(id); |
| 388 return item && (item->type == ash::TYPE_PINNED_APP || | 364 return item && (item->type == ash::TYPE_PINNED_APP || |
| 389 item->type == ash::TYPE_BROWSER_SHORTCUT); | 365 item->type == ash::TYPE_BROWSER_SHORTCUT); |
| 390 } | 366 } |
| 391 | 367 |
| 392 void ChromeLauncherControllerImpl::TogglePinned(ash::ShelfID id) { | |
| 393 if (!HasShelfIDToAppIDMapping(id)) | |
| 394 return; // May happen if item closed with menu open. | |
| 395 | |
| 396 if (IsPinned(id)) | |
| 397 Unpin(id); | |
| 398 else | |
| 399 Pin(id); | |
| 400 } | |
| 401 | |
| 402 void ChromeLauncherControllerImpl::LockV1AppWithID(const std::string& app_id) { | 368 void ChromeLauncherControllerImpl::LockV1AppWithID(const std::string& app_id) { |
| 403 ash::ShelfID id = GetShelfIDForAppID(app_id); | 369 ash::ShelfID id = GetShelfIDForAppID(app_id); |
| 404 if (id == ash::kInvalidShelfID) { | 370 if (id == ash::kInvalidShelfID) { |
| 405 CreateAppShortcutLauncherItemWithType(ash::AppLaunchId(app_id), | 371 CreateAppShortcutLauncherItemWithType(ash::AppLaunchId(app_id), |
| 406 model_->item_count(), ash::TYPE_APP); | 372 model_->item_count(), ash::TYPE_APP); |
| 407 id = GetShelfIDForAppID(app_id); | 373 id = GetShelfIDForAppID(app_id); |
| 408 } | 374 } |
| 409 CHECK(id); | 375 CHECK(id); |
| 410 GetLauncherItemController(id)->lock(); | 376 GetLauncherItemController(id)->lock(); |
| 411 } | 377 } |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 437 return; // May happen if menu closed. | 403 return; // May happen if menu closed. |
| 438 delegate->Close(); | 404 delegate->Close(); |
| 439 } | 405 } |
| 440 | 406 |
| 441 bool ChromeLauncherControllerImpl::IsOpen(ash::ShelfID id) { | 407 bool ChromeLauncherControllerImpl::IsOpen(ash::ShelfID id) { |
| 442 const ash::ShelfItem* item = GetItem(id); | 408 const ash::ShelfItem* item = GetItem(id); |
| 443 return item && item->status != ash::STATUS_CLOSED; | 409 return item && item->status != ash::STATUS_CLOSED; |
| 444 } | 410 } |
| 445 | 411 |
| 446 bool ChromeLauncherControllerImpl::IsPlatformApp(ash::ShelfID id) { | 412 bool ChromeLauncherControllerImpl::IsPlatformApp(ash::ShelfID id) { |
| 447 if (!HasShelfIDToAppIDMapping(id)) | |
| 448 return false; | |
| 449 | |
| 450 std::string app_id = GetAppIDForShelfID(id); | 413 std::string app_id = GetAppIDForShelfID(id); |
| 451 const Extension* extension = GetExtensionForAppID(app_id, profile()); | 414 const Extension* extension = GetExtensionForAppID(app_id, profile()); |
| 452 // An extension can be synced / updated at any time and therefore not be | 415 // An extension can be synced / updated at any time and therefore not be |
| 453 // available. | 416 // available. |
| 454 return extension ? extension->is_platform_app() : false; | 417 return extension ? extension->is_platform_app() : false; |
| 455 } | 418 } |
| 456 | 419 |
| 457 void ChromeLauncherControllerImpl::ActivateApp(const std::string& app_id, | 420 void ChromeLauncherControllerImpl::ActivateApp(const std::string& app_id, |
| 458 ash::ShelfLaunchSource source, | 421 ash::ShelfLaunchSource source, |
| 459 int event_flags) { | 422 int event_flags) { |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 724 if (item && item->type == ash::TYPE_BROWSER_SHORTCUT) | 687 if (item && item->type == ash::TYPE_BROWSER_SHORTCUT) |
| 725 return static_cast<BrowserShortcutLauncherItemController*>(pair.second); | 688 return static_cast<BrowserShortcutLauncherItemController*>(pair.second); |
| 726 } | 689 } |
| 727 NOTREACHED() | 690 NOTREACHED() |
| 728 << "There should be always be a BrowserShortcutLauncherItemController."; | 691 << "There should be always be a BrowserShortcutLauncherItemController."; |
| 729 return nullptr; | 692 return nullptr; |
| 730 } | 693 } |
| 731 | 694 |
| 732 LauncherItemController* ChromeLauncherControllerImpl::GetLauncherItemController( | 695 LauncherItemController* ChromeLauncherControllerImpl::GetLauncherItemController( |
| 733 const ash::ShelfID id) { | 696 const ash::ShelfID id) { |
| 734 if (!HasShelfIDToAppIDMapping(id)) | 697 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); |
| 735 return nullptr; | 698 return iter == id_to_item_controller_map_.end() ? nullptr : iter->second; |
| 736 return id_to_item_controller_map_[id]; | |
| 737 } | 699 } |
| 738 | 700 |
| 739 bool ChromeLauncherControllerImpl::ShelfBoundsChangesProbablyWithUser( | 701 bool ChromeLauncherControllerImpl::ShelfBoundsChangesProbablyWithUser( |
| 740 ash::WmShelf* shelf, | 702 ash::WmShelf* shelf, |
| 741 const AccountId& account_id) const { | 703 const AccountId& account_id) const { |
| 742 Profile* other_profile = multi_user_util::GetProfileFromAccountId(account_id); | 704 Profile* other_profile = multi_user_util::GetProfileFromAccountId(account_id); |
| 743 if (!other_profile || other_profile == profile()) | 705 if (!other_profile || other_profile == profile()) |
| 744 return false; | 706 return false; |
| 745 | 707 |
| 746 // Note: The Auto hide state from preferences is not the same as the actual | 708 // Note: The Auto hide state from preferences is not the same as the actual |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 829 app_service->AddObserverAndStart(this); | 791 app_service->AddObserverAndStart(this); |
| 830 | 792 |
| 831 PrefServiceSyncableFromProfile(profile())->AddObserver(this); | 793 PrefServiceSyncableFromProfile(profile())->AddObserver(this); |
| 832 } | 794 } |
| 833 | 795 |
| 834 /////////////////////////////////////////////////////////////////////////////// | 796 /////////////////////////////////////////////////////////////////////////////// |
| 835 // ash::ShelfDelegate: | 797 // ash::ShelfDelegate: |
| 836 | 798 |
| 837 ash::ShelfID ChromeLauncherControllerImpl::GetShelfIDForAppID( | 799 ash::ShelfID ChromeLauncherControllerImpl::GetShelfIDForAppID( |
| 838 const std::string& app_id) { | 800 const std::string& app_id) { |
| 839 // Get shelf id for app_id and empty launch_id. | 801 // Get shelf id for |app_id| and an empty |launch_id|. |
| 840 return GetShelfIDForAppIDAndLaunchID(app_id, std::string()); | 802 return GetShelfIDForAppIDAndLaunchID(app_id, std::string()); |
| 841 } | 803 } |
| 842 | 804 |
| 843 ash::ShelfID ChromeLauncherControllerImpl::GetShelfIDForAppIDAndLaunchID( | 805 ash::ShelfID ChromeLauncherControllerImpl::GetShelfIDForAppIDAndLaunchID( |
| 844 const std::string& app_id, | 806 const std::string& app_id, |
|
James Cook
2017/03/23 16:43:49
Not for this CL: WDYT of converting this to use Ap
msw
2017/03/23 18:08:10
I'm very much in favor of that; I thought about do
| |
| 845 const std::string& launch_id) { | 807 const std::string& launch_id) { |
| 808 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859 | |
| 846 const std::string shelf_app_id = | 809 const std::string shelf_app_id = |
| 847 ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(app_id); | 810 ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(app_id); |
|
James Cook
2017/03/23 16:43:49
Wow, this is terrible. It implies that app_id is a
msw
2017/03/23 18:08:10
Yeah, this is a bad pattern. Yury said he'll work
| |
| 848 for (const auto& id_to_item_controller_pair : id_to_item_controller_map_) { | 811 |
| 849 if (id_to_item_controller_pair.second->app_id() == shelf_app_id && | 812 for (const ash::ShelfItem& item : model_->items()) { |
| 850 id_to_item_controller_pair.second->launch_id() == launch_id) { | 813 // Ash's ShelfWindowWatcher handles app panel windows separately. |
| 851 return id_to_item_controller_pair.first; | 814 if (item.type != ash::TYPE_APP_PANEL && |
| 815 item.app_launch_id.app_id() == shelf_app_id && | |
| 816 item.app_launch_id.launch_id() == launch_id) { | |
| 817 return item.id; | |
| 852 } | 818 } |
| 853 } | 819 } |
| 854 return ash::kInvalidShelfID; | 820 return ash::kInvalidShelfID; |
| 855 } | 821 } |
| 856 | 822 |
| 857 bool ChromeLauncherControllerImpl::HasShelfIDToAppIDMapping( | |
| 858 ash::ShelfID id) const { | |
| 859 return id_to_item_controller_map_.find(id) != | |
| 860 id_to_item_controller_map_.end(); | |
| 861 } | |
| 862 | |
| 863 const std::string& ChromeLauncherControllerImpl::GetAppIDForShelfID( | 823 const std::string& ChromeLauncherControllerImpl::GetAppIDForShelfID( |
| 864 ash::ShelfID id) { | 824 ash::ShelfID id) { |
| 865 LauncherItemController* controller = GetLauncherItemController(id); | |
| 866 if (controller) | |
| 867 return controller->app_id(); | |
| 868 ash::ShelfItems::const_iterator item = model_->ItemByID(id); | 825 ash::ShelfItems::const_iterator item = model_->ItemByID(id); |
| 869 return item != model_->items().end() ? item->app_launch_id.app_id() | 826 return item != model_->items().end() ? item->app_launch_id.app_id() |
| 870 : base::EmptyString(); | 827 : base::EmptyString(); |
| 871 } | 828 } |
| 872 | 829 |
| 873 void ChromeLauncherControllerImpl::PinAppWithID(const std::string& app_id) { | 830 void ChromeLauncherControllerImpl::PinAppWithID(const std::string& app_id) { |
| 831 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859 | |
| 874 const std::string shelf_app_id = | 832 const std::string shelf_app_id = |
| 875 ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(app_id); | 833 ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(app_id); |
| 876 if (GetPinnableForAppID(shelf_app_id, profile()) == | 834 |
| 877 AppListControllerDelegate::PIN_EDITABLE) | 835 // Requests to pin should only be be made for apps with editable pin states. |
| 878 DoPinAppWithID(shelf_app_id); | 836 DCHECK_EQ(GetPinnableForAppID(shelf_app_id, profile()), |
| 879 else | 837 AppListControllerDelegate::PIN_EDITABLE); |
| 880 NOTREACHED(); | 838 |
| 839 // If the app is already pinned, do nothing and return. | |
| 840 if (IsAppPinned(shelf_app_id)) | |
| 841 return; | |
| 842 | |
| 843 // If there is an existing item, convert that to a pinned item. | |
| 844 ash::ShelfID shelf_id = GetShelfIDForAppID(shelf_app_id); | |
| 845 if (shelf_id != ash::kInvalidShelfID) { | |
| 846 DCHECK_EQ(GetItem(shelf_id)->type, ash::TYPE_APP); | |
| 847 DCHECK(!GetItem(shelf_id)->pinned_by_policy); | |
| 848 SetItemType(shelf_id, ash::TYPE_PINNED_APP); | |
|
James Cook
2017/03/23 16:43:50
Do you need to trigger sync after this?
msw
2017/03/23 18:08:10
Good catch! I missed that! Fixed (but maybe I ruin
| |
| 849 return; | |
| 850 } | |
| 851 | |
| 852 // Create a new pinned item for the app. | |
| 853 shelf_id = CreateAppShortcutLauncherItem(ash::AppLaunchId(shelf_app_id), | |
| 854 model_->item_count()); | |
| 855 | |
| 856 // TODO(msw): Trigger pref updates in ShelfModelObserver overrides. | |
| 857 SyncPinPosition(shelf_id); | |
| 881 } | 858 } |
|
James Cook
2017/03/23 16:43:49
beautiful function, btw. I like the blocks with si
msw
2017/03/23 18:08:10
Acknowledged.
| |
| 882 | 859 |
| 883 bool ChromeLauncherControllerImpl::IsAppPinned(const std::string& app_id) { | 860 bool ChromeLauncherControllerImpl::IsAppPinned(const std::string& app_id) { |
| 861 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859 | |
| 884 const std::string shelf_app_id = | 862 const std::string shelf_app_id = |
| 885 ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(app_id); | 863 ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(app_id); |
| 886 for (const auto& pair : id_to_item_controller_map_) { | 864 |
| 887 if (IsPinned(pair.first) && pair.second->app_id() == shelf_app_id) | 865 return IsPinned(GetShelfIDForAppID(shelf_app_id)); |
| 888 return true; | |
| 889 } | |
| 890 return false; | |
| 891 } | 866 } |
| 892 | 867 |
| 893 void ChromeLauncherControllerImpl::UnpinAppWithID(const std::string& app_id) { | 868 void ChromeLauncherControllerImpl::UnpinAppWithID(const std::string& app_id) { |
| 869 // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859 | |
| 894 const std::string shelf_app_id = | 870 const std::string shelf_app_id = |
| 895 ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(app_id); | 871 ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(app_id); |
| 896 if (GetPinnableForAppID(shelf_app_id, profile()) == | 872 |
| 897 AppListControllerDelegate::PIN_EDITABLE) | 873 // Requests to unpin should only be be made for apps with editable pin states. |
| 898 DoUnpinAppWithID(shelf_app_id, true /* update_prefs */); | 874 DCHECK_EQ(GetPinnableForAppID(shelf_app_id, profile()), |
| 899 else | 875 AppListControllerDelegate::PIN_EDITABLE); |
| 900 NOTREACHED(); | 876 |
| 877 // If the app is already not pinned, do nothing and return. | |
| 878 if (!IsAppPinned(shelf_app_id)) | |
| 879 return; | |
| 880 | |
| 881 // TODO(msw): Trigger pref updates in ShelfModelObserver overrides. | |
| 882 ash::launcher::RemovePinPosition(profile(), ash::AppLaunchId(shelf_app_id)); | |
| 883 | |
| 884 // Unpin the shelf item. | |
| 885 UnpinShelfItemInternal(GetShelfIDForAppID(shelf_app_id)); | |
| 901 } | 886 } |
| 902 | 887 |
| 903 /////////////////////////////////////////////////////////////////////////////// | 888 /////////////////////////////////////////////////////////////////////////////// |
| 904 // LauncherAppUpdater::Delegate: | 889 // LauncherAppUpdater::Delegate: |
| 905 | 890 |
| 906 void ChromeLauncherControllerImpl::OnAppInstalled( | 891 void ChromeLauncherControllerImpl::OnAppInstalled( |
| 907 content::BrowserContext* browser_context, | 892 content::BrowserContext* browser_context, |
| 908 const std::string& app_id) { | 893 const std::string& app_id) { |
| 909 if (IsAppPinned(app_id)) { | 894 if (IsAppPinned(app_id)) { |
| 910 // Clear and re-fetch to ensure icon is up-to-date. | 895 // Clear and re-fetch to ensure icon is up-to-date. |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 925 if (app_icon_loader) | 910 if (app_icon_loader) |
| 926 app_icon_loader->UpdateImage(app_id); | 911 app_icon_loader->UpdateImage(app_id); |
| 927 } | 912 } |
| 928 | 913 |
| 929 void ChromeLauncherControllerImpl::OnAppUninstalledPrepared( | 914 void ChromeLauncherControllerImpl::OnAppUninstalledPrepared( |
| 930 content::BrowserContext* browser_context, | 915 content::BrowserContext* browser_context, |
| 931 const std::string& app_id) { | 916 const std::string& app_id) { |
| 932 // Since we might have windowed apps of this type which might have | 917 // Since we might have windowed apps of this type which might have |
| 933 // outstanding locks which needs to be removed. | 918 // outstanding locks which needs to be removed. |
| 934 const Profile* profile = Profile::FromBrowserContext(browser_context); | 919 const Profile* profile = Profile::FromBrowserContext(browser_context); |
| 935 if (GetShelfIDForAppID(app_id)) | 920 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); |
| 921 if (shelf_id != ash::kInvalidShelfID) | |
| 936 CloseWindowedAppsFromRemovedExtension(app_id, profile); | 922 CloseWindowedAppsFromRemovedExtension(app_id, profile); |
| 937 | 923 |
| 938 if (IsAppPinned(app_id)) { | 924 if (IsAppPinned(app_id)) { |
| 939 if (profile == this->profile()) { | 925 if (profile == this->profile() && shelf_id != ash::kInvalidShelfID) { |
| 940 // Some apps may be removed locally. Don't remove pin position from sync | 926 // Some apps may be removed locally. Unpin the item without removing the |
| 941 // model. When needed, it is automatically deleted on app list model | 927 // pin position from profile preferences. When needed, it is automatically |
| 942 // update. | 928 // deleted on app list model update. |
| 943 DoUnpinAppWithID(app_id, false /* update_prefs */); | 929 UnpinShelfItemInternal(shelf_id); |
| 944 } | 930 } |
| 945 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id); | 931 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id); |
| 946 if (app_icon_loader) | 932 if (app_icon_loader) |
| 947 app_icon_loader->ClearImage(app_id); | 933 app_icon_loader->ClearImage(app_id); |
| 948 } | 934 } |
| 949 } | 935 } |
| 950 | 936 |
| 951 /////////////////////////////////////////////////////////////////////////////// | 937 /////////////////////////////////////////////////////////////////////////////// |
| 952 // ChromeLauncherControllerImpl protected: | 938 // ChromeLauncherControllerImpl protected: |
| 953 | 939 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1025 if (app_icon_loader) | 1011 if (app_icon_loader) |
| 1026 app_icon_loader->ClearImage(app_id); | 1012 app_icon_loader->ClearImage(app_id); |
| 1027 id_to_item_controller_map_.erase(iter); | 1013 id_to_item_controller_map_.erase(iter); |
| 1028 int index = model_->ItemIndexByID(id); | 1014 int index = model_->ItemIndexByID(id); |
| 1029 // A "browser proxy" is not known to the model and this removal does | 1015 // A "browser proxy" is not known to the model and this removal does |
| 1030 // therefore not need to be propagated to the model. | 1016 // therefore not need to be propagated to the model. |
| 1031 if (index != -1) | 1017 if (index != -1) |
| 1032 model_->RemoveItemAt(index); | 1018 model_->RemoveItemAt(index); |
| 1033 } | 1019 } |
| 1034 | 1020 |
| 1035 void ChromeLauncherControllerImpl::DoPinAppWithID(const std::string& app_id) { | |
| 1036 // If there is an item, do nothing and return. | |
| 1037 if (IsAppPinned(app_id)) | |
| 1038 return; | |
| 1039 | |
| 1040 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); | |
| 1041 if (shelf_id) { | |
| 1042 // App item exists, pin it | |
| 1043 Pin(shelf_id); | |
| 1044 } else { | |
| 1045 // Otherwise, create a shortcut item for it. | |
| 1046 shelf_id = CreateAppShortcutLauncherItem(ash::AppLaunchId(app_id), | |
| 1047 model_->item_count()); | |
| 1048 SyncPinPosition(shelf_id); | |
| 1049 } | |
| 1050 } | |
| 1051 | |
| 1052 void ChromeLauncherControllerImpl::DoUnpinAppWithID(const std::string& app_id, | |
| 1053 bool update_prefs) { | |
| 1054 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); | |
| 1055 if (shelf_id && IsPinned(shelf_id)) | |
| 1056 UnpinAndUpdatePrefs(shelf_id, update_prefs); | |
| 1057 } | |
| 1058 | |
| 1059 void ChromeLauncherControllerImpl::PinRunningAppInternal( | 1021 void ChromeLauncherControllerImpl::PinRunningAppInternal( |
| 1060 int index, | 1022 int index, |
| 1061 ash::ShelfID shelf_id) { | 1023 ash::ShelfID shelf_id) { |
| 1062 DCHECK_EQ(GetItem(shelf_id)->type, ash::TYPE_APP); | 1024 DCHECK_EQ(GetItem(shelf_id)->type, ash::TYPE_APP); |
| 1063 SetItemType(shelf_id, ash::TYPE_PINNED_APP); | 1025 SetItemType(shelf_id, ash::TYPE_PINNED_APP); |
| 1064 int running_index = model_->ItemIndexByID(shelf_id); | 1026 int running_index = model_->ItemIndexByID(shelf_id); |
| 1065 if (running_index < index) | 1027 if (running_index < index) |
| 1066 --index; | 1028 --index; |
| 1067 if (running_index != index) | 1029 if (running_index != index) |
| 1068 model_->Move(running_index, index); | 1030 model_->Move(running_index, index); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1131 | 1093 |
| 1132 void ChromeLauncherControllerImpl::ScheduleUpdateAppLaunchersFromPref() { | 1094 void ChromeLauncherControllerImpl::ScheduleUpdateAppLaunchersFromPref() { |
| 1133 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1095 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 1134 FROM_HERE, | 1096 FROM_HERE, |
| 1135 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref, | 1097 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref, |
| 1136 weak_ptr_factory_.GetWeakPtr())); | 1098 weak_ptr_factory_.GetWeakPtr())); |
| 1137 } | 1099 } |
| 1138 | 1100 |
| 1139 void ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref() { | 1101 void ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref() { |
| 1140 // There are various functions which will trigger a |SyncPinPosition| call | 1102 // There are various functions which will trigger a |SyncPinPosition| call |
| 1141 // like a direct call to |DoPinAppWithID|, or an indirect call to the menu | 1103 // like a direct call to |PinAppWithID|, or an indirect call to the menu |
| 1142 // model which will use weights to re-arrange the icons to new positions. | 1104 // model which will use weights to re-arrange the icons to new positions. |
| 1143 // Since this function is meant to synchronize the "is state" with the | 1105 // Since this function is meant to synchronize the "is state" with the |
| 1144 // "sync state", it makes no sense to store any changes by this function back | 1106 // "sync state", it makes no sense to store any changes by this function back |
| 1145 // into the pref state. Therefore we tell |persistPinnedState| to ignore any | 1107 // into the pref state. Therefore we tell |persistPinnedState| to ignore any |
| 1146 // invocations while we are running. | 1108 // invocations while we are running. |
| 1147 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true); | 1109 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true); |
| 1148 const std::vector<ash::AppLaunchId> pinned_apps = | 1110 const std::vector<ash::AppLaunchId> pinned_apps = |
| 1149 ash::launcher::GetPinnedAppsFromPrefs(profile()->GetPrefs(), | 1111 ash::launcher::GetPinnedAppsFromPrefs(profile()->GetPrefs(), |
| 1150 launcher_controller_helper()); | 1112 launcher_controller_helper()); |
| 1151 | 1113 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1196 // This is fresh pin. Create new one. | 1158 // This is fresh pin. Create new one. |
| 1197 DCHECK_NE(app_id, extension_misc::kChromeAppId); | 1159 DCHECK_NE(app_id, extension_misc::kChromeAppId); |
| 1198 CreateAppShortcutLauncherItem(pref_app_launch_id, index); | 1160 CreateAppShortcutLauncherItem(pref_app_launch_id, index); |
| 1199 } | 1161 } |
| 1200 ++index; | 1162 ++index; |
| 1201 } | 1163 } |
| 1202 | 1164 |
| 1203 // At second step remove any pin to the right from the current index. | 1165 // At second step remove any pin to the right from the current index. |
| 1204 while (index < model_->item_count()) { | 1166 while (index < model_->item_count()) { |
| 1205 const ash::ShelfItem item = model_->items()[index]; | 1167 const ash::ShelfItem item = model_->items()[index]; |
| 1206 if (item.type != ash::TYPE_PINNED_APP) { | 1168 if (item.type == ash::TYPE_PINNED_APP) |
| 1169 UnpinShelfItemInternal(item.id); | |
| 1170 else | |
| 1207 ++index; | 1171 ++index; |
| 1208 continue; | |
| 1209 } | |
| 1210 | |
| 1211 const LauncherItemController* controller = | |
| 1212 GetLauncherItemController(item.id); | |
| 1213 DCHECK(controller); | |
| 1214 DCHECK_NE(controller->app_id(), extension_misc::kChromeAppId); | |
| 1215 | |
| 1216 if (item.status != ash::STATUS_CLOSED || controller->locked()) { | |
| 1217 UnpinRunningAppInternal(index); | |
| 1218 // Note, item can be moved to the right due weighting in shelf model. | |
| 1219 DCHECK_GE(model_->ItemIndexByID(item.id), index); | |
| 1220 } else { | |
| 1221 LauncherItemClosed(item.id); | |
| 1222 } | |
| 1223 } | 1172 } |
| 1224 | 1173 |
| 1225 UpdatePolicyPinnedAppsFromPrefs(); | 1174 UpdatePolicyPinnedAppsFromPrefs(); |
| 1226 } | 1175 } |
| 1227 | 1176 |
| 1228 void ChromeLauncherControllerImpl::UpdatePolicyPinnedAppsFromPrefs() { | 1177 void ChromeLauncherControllerImpl::UpdatePolicyPinnedAppsFromPrefs() { |
| 1229 for (int index = 0; index < model_->item_count(); index++) { | 1178 for (int index = 0; index < model_->item_count(); index++) { |
| 1230 ash::ShelfItem item = model_->items()[index]; | 1179 ash::ShelfItem item = model_->items()[index]; |
| 1231 const bool pinned_by_policy = | 1180 const bool pinned_by_policy = |
| 1232 GetPinnableForAppID(item.app_launch_id.app_id(), profile()) == | 1181 GetPinnableForAppID(item.app_launch_id.app_id(), profile()) == |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1280 } | 1229 } |
| 1281 return status; | 1230 return status; |
| 1282 } | 1231 } |
| 1283 | 1232 |
| 1284 ash::ShelfID ChromeLauncherControllerImpl::InsertAppLauncherItem( | 1233 ash::ShelfID ChromeLauncherControllerImpl::InsertAppLauncherItem( |
| 1285 LauncherItemController* controller, | 1234 LauncherItemController* controller, |
| 1286 ash::ShelfItemStatus status, | 1235 ash::ShelfItemStatus status, |
| 1287 int index, | 1236 int index, |
| 1288 ash::ShelfItemType shelf_item_type) { | 1237 ash::ShelfItemType shelf_item_type) { |
| 1289 ash::ShelfID id = model_->next_id(); | 1238 ash::ShelfID id = model_->next_id(); |
| 1290 CHECK(!HasShelfIDToAppIDMapping(id)); | 1239 CHECK(!GetItem(id)); |
| 1291 CHECK(controller); | 1240 CHECK(controller); |
| 1292 // Ash's ShelfWindowWatcher handles app panel windows separately. | 1241 // Ash's ShelfWindowWatcher handles app panel windows separately. |
| 1293 DCHECK_NE(ash::TYPE_APP_PANEL, shelf_item_type); | 1242 DCHECK_NE(ash::TYPE_APP_PANEL, shelf_item_type); |
| 1294 id_to_item_controller_map_[id] = controller; | 1243 id_to_item_controller_map_[id] = controller; |
| 1295 controller->set_shelf_id(id); | 1244 controller->set_shelf_id(id); |
| 1296 | 1245 |
| 1297 ash::ShelfItem item; | 1246 ash::ShelfItem item; |
| 1298 item.type = shelf_item_type; | 1247 item.type = shelf_item_type; |
| 1299 item.app_launch_id = controller->app_launch_id(); | 1248 item.app_launch_id = controller->app_launch_id(); |
| 1300 item.image = extensions::util::GetDefaultAppIcon(); | 1249 item.image = extensions::util::GetDefaultAppIcon(); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1318 SetShelfItemDelegate(id, controller); | 1267 SetShelfItemDelegate(id, controller); |
| 1319 return id; | 1268 return id; |
| 1320 } | 1269 } |
| 1321 | 1270 |
| 1322 void ChromeLauncherControllerImpl::CreateBrowserShortcutLauncherItem() { | 1271 void ChromeLauncherControllerImpl::CreateBrowserShortcutLauncherItem() { |
| 1323 ash::ShelfItem browser_shortcut; | 1272 ash::ShelfItem browser_shortcut; |
| 1324 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT; | 1273 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT; |
| 1325 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 1274 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 1326 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32); | 1275 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32); |
| 1327 browser_shortcut.title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); | 1276 browser_shortcut.title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); |
| 1277 browser_shortcut.app_launch_id = | |
| 1278 ash::AppLaunchId(extension_misc::kChromeAppId); | |
| 1328 ash::ShelfID id = model_->next_id(); | 1279 ash::ShelfID id = model_->next_id(); |
| 1329 model_->AddAt(0, browser_shortcut); | 1280 model_->AddAt(0, browser_shortcut); |
| 1330 BrowserShortcutLauncherItemController* controller = | 1281 BrowserShortcutLauncherItemController* controller = |
| 1331 new BrowserShortcutLauncherItemController(this, model_); | 1282 new BrowserShortcutLauncherItemController(this, model_); |
| 1332 controller->set_shelf_id(id); | 1283 controller->set_shelf_id(id); |
| 1333 id_to_item_controller_map_[id] = controller; | 1284 id_to_item_controller_map_[id] = controller; |
| 1334 // ShelfModel owns BrowserShortcutLauncherItemController. | 1285 // ShelfModel owns BrowserShortcutLauncherItemController. |
| 1335 SetShelfItemDelegate(id, controller); | 1286 SetShelfItemDelegate(id, controller); |
| 1336 controller->UpdateBrowserItemState(); | 1287 controller->UpdateBrowserItemState(); |
| 1337 } | 1288 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1425 LOG(ERROR) << "Unexpected removal of shelf item, id: " << id; | 1376 LOG(ERROR) << "Unexpected removal of shelf item, id: " << id; |
| 1426 id_to_item_controller_map_.erase(iter); | 1377 id_to_item_controller_map_.erase(iter); |
| 1427 } | 1378 } |
| 1428 | 1379 |
| 1429 void ChromeLauncherControllerImpl::ShelfItemMoved(int start_index, | 1380 void ChromeLauncherControllerImpl::ShelfItemMoved(int start_index, |
| 1430 int target_index) { | 1381 int target_index) { |
| 1431 const ash::ShelfItem& item = model_->items()[target_index]; | 1382 const ash::ShelfItem& item = model_->items()[target_index]; |
| 1432 // We remember the moved item position if it is either pinnable or | 1383 // We remember the moved item position if it is either pinnable or |
| 1433 // it is the app list with the alternate shelf layout. | 1384 // it is the app list with the alternate shelf layout. |
| 1434 DCHECK_NE(ash::TYPE_APP_LIST, item.type); | 1385 DCHECK_NE(ash::TYPE_APP_LIST, item.type); |
| 1435 if (HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id)) | 1386 if (IsPinned(item.id)) |
| 1436 SyncPinPosition(item.id); | 1387 SyncPinPosition(item.id); |
| 1437 } | 1388 } |
| 1438 | 1389 |
| 1439 void ChromeLauncherControllerImpl::ShelfItemChanged( | 1390 void ChromeLauncherControllerImpl::ShelfItemChanged( |
| 1440 int index, | 1391 int index, |
| 1441 const ash::ShelfItem& old_item) {} | 1392 const ash::ShelfItem& old_item) {} |
| 1442 | 1393 |
| 1443 void ChromeLauncherControllerImpl::OnSetShelfItemDelegate( | 1394 void ChromeLauncherControllerImpl::OnSetShelfItemDelegate( |
| 1444 ash::ShelfID id, | 1395 ash::ShelfID id, |
| 1445 ash::mojom::ShelfItemDelegate* item_delegate) { | 1396 ash::mojom::ShelfItemDelegate* item_delegate) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1498 LauncherItemController* controller = GetLauncherItemController(item.id); | 1449 LauncherItemController* controller = GetLauncherItemController(item.id); |
| 1499 if (!controller || controller->image_set_by_controller()) | 1450 if (!controller || controller->image_set_by_controller()) |
| 1500 continue; | 1451 continue; |
| 1501 item.image = image; | 1452 item.image = image; |
| 1502 if (arc_deferred_launcher_) | 1453 if (arc_deferred_launcher_) |
| 1503 arc_deferred_launcher_->MaybeApplySpinningEffect(id, &item.image); | 1454 arc_deferred_launcher_->MaybeApplySpinningEffect(id, &item.image); |
| 1504 model_->Set(index, item); | 1455 model_->Set(index, item); |
| 1505 // It's possible we're waiting on more than one item, so don't break. | 1456 // It's possible we're waiting on more than one item, so don't break. |
| 1506 } | 1457 } |
| 1507 } | 1458 } |
| OLD | NEW |