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

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

Issue 2055553004: arc: Support pinned apps across Arc-enabled and Arc-disabled platforms. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: chrome_mash_shelf_controller.cc update due namespace renaming Created 4 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_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 10 matching lines...) Expand all
21 #include "ash/wm/window_util.h" 21 #include "ash/wm/window_util.h"
22 #include "base/command_line.h" 22 #include "base/command_line.h"
23 #include "base/macros.h" 23 #include "base/macros.h"
24 #include "base/strings/pattern.h" 24 #include "base/strings/pattern.h"
25 #include "base/strings/string_util.h" 25 #include "base/strings/string_util.h"
26 #include "base/strings/utf_string_conversions.h" 26 #include "base/strings/utf_string_conversions.h"
27 #include "base/values.h" 27 #include "base/values.h"
28 #include "build/build_config.h" 28 #include "build/build_config.h"
29 #include "chrome/browser/browser_process.h" 29 #include "chrome/browser/browser_process.h"
30 #include "chrome/browser/chrome_notification_types.h" 30 #include "chrome/browser/chrome_notification_types.h"
31 #include "chrome/browser/chromeos/arc/arc_support_host.h"
32 #include "chrome/browser/chromeos/extensions/gfx_utils.h" 31 #include "chrome/browser/chromeos/extensions/gfx_utils.h"
33 #include "chrome/browser/defaults.h" 32 #include "chrome/browser/defaults.h"
34 #include "chrome/browser/extensions/extension_app_icon_loader.h" 33 #include "chrome/browser/extensions/extension_app_icon_loader.h"
35 #include "chrome/browser/extensions/extension_util.h" 34 #include "chrome/browser/extensions/extension_util.h"
36 #include "chrome/browser/extensions/launch_util.h" 35 #include "chrome/browser/extensions/launch_util.h"
37 #include "chrome/browser/prefs/incognito_mode_prefs.h" 36 #include "chrome/browser/prefs/incognito_mode_prefs.h"
38 #include "chrome/browser/profiles/profile.h" 37 #include "chrome/browser/profiles/profile.h"
39 #include "chrome/browser/profiles/profile_manager.h" 38 #include "chrome/browser/profiles/profile_manager.h"
39 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
40 #include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h" 40 #include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h"
41 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" 41 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
42 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" 42 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
43 #include "chrome/browser/ui/ash/app_sync_ui_state.h" 43 #include "chrome/browser/ui/ash/app_sync_ui_state.h"
44 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" 44 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h"
45 #include "chrome/browser/ui/ash/chrome_shell_delegate.h" 45 #include "chrome/browser/ui/ash/chrome_shell_delegate.h"
46 #include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h " 46 #include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h "
47 #include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h" 47 #include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h"
48 #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h" 48 #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h"
49 #include "chrome/browser/ui/ash/launcher/arc_app_deferred_launcher_controller.h" 49 #include "chrome/browser/ui/ash/launcher/arc_app_deferred_launcher_controller.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 110
111 int64_t GetDisplayIDForShelf(ash::Shelf* shelf) { 111 int64_t GetDisplayIDForShelf(ash::Shelf* shelf) {
112 aura::Window* root_window = 112 aura::Window* root_window =
113 shelf->shelf_widget()->GetNativeWindow()->GetRootWindow(); 113 shelf->shelf_widget()->GetNativeWindow()->GetRootWindow();
114 display::Display display = 114 display::Display display =
115 display::Screen::GetScreen()->GetDisplayNearestWindow(root_window); 115 display::Screen::GetScreen()->GetDisplayNearestWindow(root_window);
116 DCHECK(display.is_valid()); 116 DCHECK(display.is_valid());
117 return display.id(); 117 return display.id();
118 } 118 }
119 119
120 /*
121 * Return whether an app is pinned only by user.
122 * This function doesn't expect an app_id neither pinned by user nor by
123 * policy, the app_id in the arguments list MUST be pinned by either of
124 * those. Invalid input may lead to unexpected result.
125 * If this app is pinned by policy, but not by user, false is returned.
126 * If this app is pinned by both policy and user, false is returned.
127 * If this app is pinned not by policy, but by user, true is returned.
128 */
129 bool IsAppForUserPinned(const std::string& app_id,
130 const base::ListValue* pinned_apps_pref,
131 const base::ListValue* policy_pinned_apps_pref) {
132 for (size_t index = 0; index < pinned_apps_pref->GetSize(); ++index) {
133 const base::DictionaryValue* app;
134 if (pinned_apps_pref->GetDictionary(index, &app)) {
135 std::string current_app_id;
136 bool pinned_by_policy = false;
137 if (app->GetString(ash::kPinnedAppsPrefAppIDPath, &current_app_id)) {
138 if (app_id == current_app_id) {
139 if (app->GetBoolean(ash::kPinnedAppsPrefPinnedByPolicy,
140 &pinned_by_policy) &&
141 pinned_by_policy) {
142 // Pinned by policy in the past or present.
143 // Need to check policy_pinned_apps to determine
144 break;
145 } else {
146 // User Preference Already Pinned
147 return true;
148 }
149 }
150 }
151 }
152 }
153 for (size_t index = 0; index < policy_pinned_apps_pref->GetSize(); ++index) {
154 const base::DictionaryValue* app;
155 if (policy_pinned_apps_pref->GetDictionary(index, &app)) {
156 std::string app_id_;
157 if (app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id_)) {
158 // Only pinned by policy, which is not part of user-pinned
159 if (app_id == app_id_)
160 return false;
161 }
162 }
163 }
164 // Default, user added new pins
165 return true;
166 }
167
168 const char* const kPinProhibitedExtensionIds[] = {
169 ArcSupportHost::kHostAppId, arc::kPlayStoreAppId,
170 };
171
172 const size_t kPinProhibitedExtensionIdsLength =
173 arraysize(kPinProhibitedExtensionIds);
174
175 } // namespace 120 } // namespace
176 121
177 // A class to get events from ChromeOS when a user gets changed or added. 122 // A class to get events from ChromeOS when a user gets changed or added.
178 class ChromeLauncherControllerUserSwitchObserver 123 class ChromeLauncherControllerUserSwitchObserver
179 : public user_manager::UserManager::UserSessionStateObserver { 124 : public user_manager::UserManager::UserSessionStateObserver {
180 public: 125 public:
181 ChromeLauncherControllerUserSwitchObserver( 126 ChromeLauncherControllerUserSwitchObserver(
182 ChromeLauncherControllerImpl* controller) 127 ChromeLauncherControllerImpl* controller)
183 : controller_(controller) { 128 : controller_(controller) {
184 DCHECK(user_manager::UserManager::IsInitialized()); 129 DCHECK(user_manager::UserManager::IsInitialized());
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) { 184 void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) {
240 if (chrome::MultiUserWindowManager::GetMultiProfileMode() == 185 if (chrome::MultiUserWindowManager::GetMultiProfileMode() ==
241 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) 186 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED)
242 chrome::MultiUserWindowManager::GetInstance()->AddUser(profile); 187 chrome::MultiUserWindowManager::GetInstance()->AddUser(profile);
243 controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile()); 188 controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile());
244 } 189 }
245 190
246 ChromeLauncherControllerImpl::ChromeLauncherControllerImpl( 191 ChromeLauncherControllerImpl::ChromeLauncherControllerImpl(
247 Profile* profile, 192 Profile* profile,
248 ash::ShelfModel* model) 193 ash::ShelfModel* model)
249 : model_(model), 194 : model_(model), profile_(profile) {
250 item_delegate_manager_(NULL),
251 profile_(profile),
252 app_sync_ui_state_(NULL),
253 ignore_persist_pinned_state_change_(false) {
254 if (!profile_) { 195 if (!profile_) {
255 // If no profile was passed, we take the currently active profile and use it 196 // If no profile was passed, we take the currently active profile and use it
256 // as the owner of the current desktop. 197 // as the owner of the current desktop.
257 // Use the original profile as on chromeos we may get a temporary off the 198 // Use the original profile as on chromeos we may get a temporary off the
258 // record profile, unless in guest session (where off the record profile is 199 // record profile, unless in guest session (where off the record profile is
259 // the right one). 200 // the right one).
260 profile_ = ProfileManager::GetActiveUserProfile(); 201 profile_ = ProfileManager::GetActiveUserProfile();
261 if (!profile_->IsGuestSession() && !profile_->IsSystemProfile()) 202 if (!profile_->IsGuestSession() && !profile_->IsSystemProfile())
262 profile_ = profile_->GetOriginalProfile(); 203 profile_ = profile_->GetOriginalProfile();
263 204
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 310
370 void ChromeLauncherControllerImpl::Init() { 311 void ChromeLauncherControllerImpl::Init() {
371 CreateBrowserShortcutLauncherItem(); 312 CreateBrowserShortcutLauncherItem();
372 UpdateAppLaunchersFromPref(); 313 UpdateAppLaunchersFromPref();
373 314
374 // TODO(sky): update unit test so that this test isn't necessary. 315 // TODO(sky): update unit test so that this test isn't necessary.
375 if (ash::Shell::HasInstance()) 316 if (ash::Shell::HasInstance())
376 SetVirtualKeyboardBehaviorFromPrefs(); 317 SetVirtualKeyboardBehaviorFromPrefs();
377 318
378 prefs_observer_ = 319 prefs_observer_ =
379 ash::ChromeLauncherPrefsObserver::CreateIfNecessary(profile_); 320 ash::launcher::ChromeLauncherPrefsObserver::CreateIfNecessary(profile_);
380 } 321 }
381 322
382 ash::ShelfID ChromeLauncherControllerImpl::CreateAppLauncherItem( 323 ash::ShelfID ChromeLauncherControllerImpl::CreateAppLauncherItem(
383 LauncherItemController* controller, 324 LauncherItemController* controller,
384 const std::string& app_id, 325 const std::string& app_id,
385 ash::ShelfItemStatus status) { 326 ash::ShelfItemStatus status) {
386 CHECK(controller); 327 CHECK(controller);
387 int index = 0; 328 int index = 0;
388 // Panels are inserted on the left so as not to push all existing panels over. 329 // Panels are inserted on the left so as not to push all existing panels over.
389 if (controller->GetShelfItemType() != ash::TYPE_APP_PANEL) 330 if (controller->GetShelfItemType() != ash::TYPE_APP_PANEL)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 ash::ShelfItem item = model_->items()[index]; 384 ash::ShelfItem item = model_->items()[index];
444 385
445 if (item.type == ash::TYPE_PLATFORM_APP || 386 if (item.type == ash::TYPE_PLATFORM_APP ||
446 item.type == ash::TYPE_WINDOWED_APP) { 387 item.type == ash::TYPE_WINDOWED_APP) {
447 item.type = ash::TYPE_APP_SHORTCUT; 388 item.type = ash::TYPE_APP_SHORTCUT;
448 model_->Set(index, item); 389 model_->Set(index, item);
449 } else if (item.type != ash::TYPE_APP_SHORTCUT) { 390 } else if (item.type != ash::TYPE_APP_SHORTCUT) {
450 return; 391 return;
451 } 392 }
452 393
453 if (GetLauncherItemController(id)->CanPin()) 394 SyncPinPosition(id);
454 PersistPinnedState();
455 } 395 }
456 396
457 void ChromeLauncherControllerImpl::Unpin(ash::ShelfID id) { 397 void ChromeLauncherControllerImpl::Unpin(ash::ShelfID id) {
458 LauncherItemController* controller = GetLauncherItemController(id); 398 LauncherItemController* controller = GetLauncherItemController(id);
459 CHECK(controller); 399 CHECK(controller);
460 const bool can_pin = controller->CanPin(); 400
401 ash::launcher::RemovePinPosition(profile_, GetAppIDForShelfID(id));
461 402
462 if (controller->type() == LauncherItemController::TYPE_APP || 403 if (controller->type() == LauncherItemController::TYPE_APP ||
463 controller->locked()) { 404 controller->locked()) {
464 UnpinRunningAppInternal(model_->ItemIndexByID(id)); 405 UnpinRunningAppInternal(model_->ItemIndexByID(id));
465 } else { 406 } else {
466 LauncherItemClosed(id); 407 LauncherItemClosed(id);
467 } 408 }
468 if (can_pin)
469 PersistPinnedState();
470 } 409 }
471 410
472 bool ChromeLauncherControllerImpl::IsPinned(ash::ShelfID id) { 411 bool ChromeLauncherControllerImpl::IsPinned(ash::ShelfID id) {
473 int index = model_->ItemIndexByID(id); 412 int index = model_->ItemIndexByID(id);
474 if (index < 0) 413 if (index < 0)
475 return false; 414 return false;
476 ash::ShelfItemType type = model_->items()[index].type; 415 ash::ShelfItemType type = model_->items()[index].type;
477 return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT); 416 return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT);
478 } 417 }
479 418
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 void ChromeLauncherControllerImpl::SetLaunchType( 555 void ChromeLauncherControllerImpl::SetLaunchType(
617 ash::ShelfID id, 556 ash::ShelfID id,
618 extensions::LaunchType launch_type) { 557 extensions::LaunchType launch_type) {
619 LauncherItemController* controller = GetLauncherItemController(id); 558 LauncherItemController* controller = GetLauncherItemController(id);
620 if (!controller) 559 if (!controller)
621 return; 560 return;
622 561
623 extensions::SetLaunchType(profile_, controller->app_id(), launch_type); 562 extensions::SetLaunchType(profile_, controller->app_id(), launch_type);
624 } 563 }
625 564
626 void ChromeLauncherControllerImpl::PersistPinnedState() {
627 if (ignore_persist_pinned_state_change_)
628 return;
629 // It is a coding error to call PersistPinnedState() if the pinned apps are
630 // not user-editable. The code should check earlier and not perform any
631 // modification actions that trigger persisting the state.
632 // Mutating kPinnedLauncherApps is going to notify us and trigger us to
633 // process the change. We don't want that to happen so remove ourselves as a
634 // listener.
635 pref_change_registrar_.Remove(prefs::kPinnedLauncherApps);
636 {
637 std::unique_ptr<const base::ListValue> pinned_apps_pref =
638 profile_->GetPrefs()
639 ->GetList(prefs::kPinnedLauncherApps)
640 ->CreateDeepCopy();
641
642 const base::ListValue* policy_pinned_apps_pref =
643 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps);
644
645 ListPrefUpdate updater(profile_->GetPrefs(), prefs::kPinnedLauncherApps);
646 updater->Clear();
647 for (size_t i = 0; i < model_->items().size(); ++i) {
648 if (model_->items()[i].type == ash::TYPE_APP_SHORTCUT) {
649 ash::ShelfID id = model_->items()[i].id;
650 LauncherItemController* controller = GetLauncherItemController(id);
651 // Don't persist pinning state for apps that are handled internally and
652 // have pinnable state AppListControllerDelegate::NO_PIN.
653 if (controller && IsPinned(id) &&
654 GetPinnable(controller->app_id()) !=
655 AppListControllerDelegate::NO_PIN) {
656 base::DictionaryValue* app_value =
657 ash::CreateAppDict(controller->app_id());
658 if (app_value) {
659 if (!IsAppForUserPinned(controller->app_id(),
660 pinned_apps_pref.get(),
661 policy_pinned_apps_pref))
662 app_value->SetBoolean(ash::kPinnedAppsPrefPinnedByPolicy, true);
663 updater->Append(app_value);
664 }
665 }
666 } else if (model_->items()[i].type == ash::TYPE_BROWSER_SHORTCUT) {
667 PersistChromeItemIndex(i);
668 } else if (model_->items()[i].type == ash::TYPE_APP_LIST) {
669 base::DictionaryValue* app_value =
670 ash::CreateAppDict(ash::kPinnedAppsPlaceholder);
671 if (app_value)
672 updater->Append(app_value);
673 }
674 }
675 }
676 pref_change_registrar_.Add(
677 prefs::kPinnedLauncherApps,
678 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref,
679 base::Unretained(this)));
680 }
681
682 Profile* ChromeLauncherControllerImpl::GetProfile() { 565 Profile* ChromeLauncherControllerImpl::GetProfile() {
683 return profile_; 566 return profile_;
684 } 567 }
685 568
686 void ChromeLauncherControllerImpl::UpdateAppState( 569 void ChromeLauncherControllerImpl::UpdateAppState(
687 content::WebContents* contents, 570 content::WebContents* contents,
688 AppState app_state) { 571 AppState app_state) {
689 std::string app_id = launcher_controller_helper_->GetAppID(contents); 572 std::string app_id = launcher_controller_helper_->GetAppID(contents);
690 573
691 // Check if the gMail app is loaded and it matches the given content. 574 // Check if the gMail app is loaded and it matches the given content.
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 AccountId::FromUserEmail(user_id)); 868 AccountId::FromUserEmail(user_id));
986 if (other_profile == profile_) 869 if (other_profile == profile_)
987 return false; 870 return false;
988 871
989 // Note: The Auto hide state from preferences is not the same as the actual 872 // Note: The Auto hide state from preferences is not the same as the actual
990 // visibility of the shelf. Depending on all the various states (full screen, 873 // visibility of the shelf. Depending on all the various states (full screen,
991 // no window on desktop, multi user, ..) the shelf could be shown - or not. 874 // no window on desktop, multi user, ..) the shelf could be shown - or not.
992 PrefService* prefs = profile_->GetPrefs(); 875 PrefService* prefs = profile_->GetPrefs();
993 PrefService* other_prefs = other_profile->GetPrefs(); 876 PrefService* other_prefs = other_profile->GetPrefs();
994 const int64_t display = GetDisplayIDForShelf(shelf); 877 const int64_t display = GetDisplayIDForShelf(shelf);
995 bool currently_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER == 878 const bool currently_shown =
996 ash::GetShelfAutoHideBehaviorPref(prefs, display); 879 ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
997 bool other_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER == 880 ash::launcher::GetShelfAutoHideBehaviorPref(prefs, display);
998 ash::GetShelfAutoHideBehaviorPref(other_prefs, display); 881 const bool other_shown =
882 ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
883 ash::launcher::GetShelfAutoHideBehaviorPref(other_prefs, display);
999 884
1000 return currently_shown != other_shown || 885 return currently_shown != other_shown ||
1001 ash::GetShelfAlignmentPref(prefs, display) != 886 ash::launcher::GetShelfAlignmentPref(prefs, display) !=
1002 ash::GetShelfAlignmentPref(other_prefs, display); 887 ash::launcher::GetShelfAlignmentPref(other_prefs, display);
1003 } 888 }
1004 889
1005 void ChromeLauncherControllerImpl::OnUserProfileReadyToSwitch( 890 void ChromeLauncherControllerImpl::OnUserProfileReadyToSwitch(
1006 Profile* profile) { 891 Profile* profile) {
1007 if (user_switch_observer_.get()) 892 if (user_switch_observer_.get())
1008 user_switch_observer_->OnUserProfileReadyToSwitch(profile); 893 user_switch_observer_->OnUserProfileReadyToSwitch(profile);
1009 } 894 }
1010 895
1011 AppListControllerDelegate::Pinnable ChromeLauncherControllerImpl::GetPinnable( 896 AppListControllerDelegate::Pinnable ChromeLauncherControllerImpl::GetPinnable(
1012 const std::string& app_id) { 897 const std::string& app_id) {
1013 for (size_t i = 0; i < kPinProhibitedExtensionIdsLength; ++i) {
1014 if (kPinProhibitedExtensionIds[i] == app_id)
1015 return AppListControllerDelegate::NO_PIN;
1016 }
1017
1018 const base::ListValue* pref = 898 const base::ListValue* pref =
1019 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps); 899 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps);
1020 if (!pref) 900 if (!pref)
1021 return AppListControllerDelegate::PIN_EDITABLE; 901 return AppListControllerDelegate::PIN_EDITABLE;
1022 902
1023 // Pinned ARC apps policy defines the package name of the apps, that must 903 // Pinned ARC apps policy defines the package name of the apps, that must
1024 // be pinned. All the launch activities of any package in policy are pinned. 904 // be pinned. All the launch activities of any package in policy are pinned.
1025 // In turn the input parameter to this function is app_id, which 905 // In turn the input parameter to this function is app_id, which
1026 // is 32 chars hash. In case of ARC app this is a hash of 906 // is 32 chars hash. In case of ARC app this is a hash of
1027 // (package name + activity). This means that we must identify the package 907 // (package name + activity). This means that we must identify the package
1028 // from the hash, and check if this package is pinned by policy. 908 // from the hash, and check if this package is pinned by policy.
1029 const ArcAppListPrefs* const arc_prefs = ArcAppListPrefs::Get(GetProfile()); 909 const ArcAppListPrefs* const arc_prefs = ArcAppListPrefs::Get(GetProfile());
1030 std::string arc_app_packege_name; 910 std::string arc_app_packege_name;
1031 if (arc_prefs) { 911 if (arc_prefs) {
1032 std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = 912 std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
1033 arc_prefs->GetApp(app_id); 913 arc_prefs->GetApp(app_id);
1034 if (app_info) 914 if (app_info)
1035 arc_app_packege_name = app_info->package_name; 915 arc_app_packege_name = app_info->package_name;
1036 } 916 }
1037 917
1038 for (size_t index = 0; index < pref->GetSize(); ++index) { 918 for (size_t index = 0; index < pref->GetSize(); ++index) {
1039 const base::DictionaryValue* app = nullptr; 919 const base::DictionaryValue* app = nullptr;
1040 std::string app_id_or_package; 920 std::string app_id_or_package;
1041 if (pref->GetDictionary(index, &app) && 921 if (pref->GetDictionary(index, &app) &&
1042 app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id_or_package) && 922 app->GetString(ash::launcher::kPinnedAppsPrefAppIDPath,
923 &app_id_or_package) &&
1043 (app_id == app_id_or_package || 924 (app_id == app_id_or_package ||
1044 arc_app_packege_name == app_id_or_package)) { 925 arc_app_packege_name == app_id_or_package)) {
1045 return AppListControllerDelegate::PIN_FIXED; 926 return AppListControllerDelegate::PIN_FIXED;
1046 } 927 }
1047 } 928 }
1048 return AppListControllerDelegate::PIN_EDITABLE; 929 return AppListControllerDelegate::PIN_EDITABLE;
1049 } 930 }
1050 931
1051 ArcAppDeferredLauncherController* 932 ArcAppDeferredLauncherController*
1052 ChromeLauncherControllerImpl::GetArcDeferredLauncher() { 933 ChromeLauncherControllerImpl::GetArcDeferredLauncher() {
1053 return arc_deferred_launcher_.get(); 934 return arc_deferred_launcher_.get();
1054 } 935 }
1055 936
1056 /////////////////////////////////////////////////////////////////////////////// 937 ///////////////////////////////////////////////////////////////////////////////
1057 // ash::ShelfDelegate: 938 // ash::ShelfDelegate:
1058 939
1059 void ChromeLauncherControllerImpl::OnShelfCreated(ash::Shelf* shelf) { 940 void ChromeLauncherControllerImpl::OnShelfCreated(ash::Shelf* shelf) {
1060 PrefService* prefs = profile_->GetPrefs(); 941 PrefService* prefs = profile_->GetPrefs();
1061 const int64_t display = GetDisplayIDForShelf(shelf); 942 const int64_t display = GetDisplayIDForShelf(shelf);
1062 943
1063 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref(prefs, display)); 944 shelf->SetAutoHideBehavior(
945 ash::launcher::GetShelfAutoHideBehaviorPref(prefs, display));
1064 946
1065 if (ash::ShelfWidget::ShelfAlignmentAllowed()) 947 if (ash::ShelfWidget::ShelfAlignmentAllowed())
1066 shelf->SetAlignment(ash::GetShelfAlignmentPref(prefs, display)); 948 shelf->SetAlignment(ash::launcher::GetShelfAlignmentPref(prefs, display));
1067 } 949 }
1068 950
1069 void ChromeLauncherControllerImpl::OnShelfDestroyed(ash::Shelf* shelf) {} 951 void ChromeLauncherControllerImpl::OnShelfDestroyed(ash::Shelf* shelf) {}
1070 952
1071 void ChromeLauncherControllerImpl::OnShelfAlignmentChanged(ash::Shelf* shelf) { 953 void ChromeLauncherControllerImpl::OnShelfAlignmentChanged(ash::Shelf* shelf) {
1072 ash::SetShelfAlignmentPref(profile_->GetPrefs(), GetDisplayIDForShelf(shelf), 954 ash::launcher::SetShelfAlignmentPref(
1073 shelf->alignment()); 955 profile_->GetPrefs(), GetDisplayIDForShelf(shelf), shelf->alignment());
1074 } 956 }
1075 957
1076 void ChromeLauncherControllerImpl::OnShelfAutoHideBehaviorChanged( 958 void ChromeLauncherControllerImpl::OnShelfAutoHideBehaviorChanged(
1077 ash::Shelf* shelf) { 959 ash::Shelf* shelf) {
1078 ash::SetShelfAutoHideBehaviorPref(profile_->GetPrefs(), 960 ash::launcher::SetShelfAutoHideBehaviorPref(profile_->GetPrefs(),
1079 GetDisplayIDForShelf(shelf), 961 GetDisplayIDForShelf(shelf),
1080 shelf->auto_hide_behavior()); 962 shelf->auto_hide_behavior());
1081 } 963 }
1082 964
1083 void ChromeLauncherControllerImpl::OnShelfAutoHideStateChanged( 965 void ChromeLauncherControllerImpl::OnShelfAutoHideStateChanged(
1084 ash::Shelf* shelf) {} 966 ash::Shelf* shelf) {}
1085 967
1086 void ChromeLauncherControllerImpl::OnShelfVisibilityStateChanged( 968 void ChromeLauncherControllerImpl::OnShelfVisibilityStateChanged(
1087 ash::Shelf* shelf) {} 969 ash::Shelf* shelf) {}
1088 970
1089 ash::ShelfID ChromeLauncherControllerImpl::GetShelfIDForAppID( 971 ash::ShelfID ChromeLauncherControllerImpl::GetShelfIDForAppID(
1090 const std::string& app_id) { 972 const std::string& app_id) {
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 if (IsAppPinned(app_id)) 1177 if (IsAppPinned(app_id))
1296 return; 1178 return;
1297 1179
1298 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); 1180 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id);
1299 if (shelf_id) { 1181 if (shelf_id) {
1300 // App item exists, pin it 1182 // App item exists, pin it
1301 Pin(shelf_id); 1183 Pin(shelf_id);
1302 } else { 1184 } else {
1303 // Otherwise, create a shortcut item for it. 1185 // Otherwise, create a shortcut item for it.
1304 shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count()); 1186 shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count());
1305 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE) 1187 SyncPinPosition(shelf_id);
1306 PersistPinnedState();
1307 } 1188 }
1308 } 1189 }
1309 1190
1310 void ChromeLauncherControllerImpl::DoUnpinAppWithID(const std::string& app_id) { 1191 void ChromeLauncherControllerImpl::DoUnpinAppWithID(const std::string& app_id) {
1311 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); 1192 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id);
1312 if (shelf_id && IsPinned(shelf_id)) 1193 if (shelf_id && IsPinned(shelf_id))
1313 Unpin(shelf_id); 1194 Unpin(shelf_id);
1314 } 1195 }
1315 1196
1316 int ChromeLauncherControllerImpl::PinRunningAppInternal(int index, 1197 int ChromeLauncherControllerImpl::PinRunningAppInternal(int index,
(...skipping 20 matching lines...) Expand all
1337 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT); 1218 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT);
1338 item.type = ash::TYPE_WINDOWED_APP; 1219 item.type = ash::TYPE_WINDOWED_APP;
1339 // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such 1220 // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such
1340 // we have to check here what this was before it got a shortcut. 1221 // we have to check here what this was before it got a shortcut.
1341 LauncherItemController* controller = GetLauncherItemController(item.id); 1222 LauncherItemController* controller = GetLauncherItemController(item.id);
1342 if (controller && controller->type() == LauncherItemController::TYPE_APP) 1223 if (controller && controller->type() == LauncherItemController::TYPE_APP)
1343 item.type = ash::TYPE_PLATFORM_APP; 1224 item.type = ash::TYPE_PLATFORM_APP;
1344 model_->Set(index, item); 1225 model_->Set(index, item);
1345 } 1226 }
1346 1227
1228 void ChromeLauncherControllerImpl::SyncPinPosition(ash::ShelfID shelf_id) {
1229 DCHECK(shelf_id);
1230 if (ignore_persist_pinned_state_change_)
1231 return;
1232
1233 const int max_index = model_->item_count();
1234 const int index = model_->ItemIndexByID(shelf_id);
1235 DCHECK_GT(index, 0);
1236
1237 const std::string& app_id = GetAppIDForShelfID(shelf_id);
1238 DCHECK(!app_id.empty());
1239
1240 std::string app_id_before;
1241 std::string app_id_after;
1242
1243 for (int i = index - 1; i > 0; --i) {
1244 const ash::ShelfID shelf_id_before = model_->items()[i].id;
1245 if (IsPinned(shelf_id_before)) {
1246 app_id_before = GetAppIDForShelfID(shelf_id_before);
1247 DCHECK(!app_id_before.empty());
1248 break;
1249 }
1250 }
1251
1252 for (int i = index + 1; i < max_index; ++i) {
1253 const ash::ShelfID shelf_id_after = model_->items()[i].id;
1254 if (IsPinned(shelf_id_after)) {
1255 app_id_after = GetAppIDForShelfID(shelf_id_after);
1256 DCHECK(!app_id_after.empty());
1257 break;
1258 }
1259 }
1260
1261 ash::launcher::SetPinPosition(profile_, app_id, app_id_before, app_id_after);
1262 }
1263
1264 void ChromeLauncherControllerImpl::OnSyncModelUpdated() {
1265 UpdateAppLaunchersFromPref();
1266 }
1267
1347 void ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref() { 1268 void ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref() {
1348 // There are various functions which will trigger a |PersistPinnedState| call 1269 // There are various functions which will trigger a |SyncPinPosition| call
1349 // like a direct call to |DoPinAppWithID|, or an indirect call to the menu 1270 // like a direct call to |DoPinAppWithID|, or an indirect call to the menu
1350 // model which will use weights to re-arrange the icons to new positions. 1271 // model which will use weights to re-arrange the icons to new positions.
1351 // Since this function is meant to synchronize the "is state" with the 1272 // Since this function is meant to synchronize the "is state" with the
1352 // "sync state", it makes no sense to store any changes by this function back 1273 // "sync state", it makes no sense to store any changes by this function back
1353 // into the pref state. Therefore we tell |persistPinnedState| to ignore any 1274 // into the pref state. Therefore we tell |persistPinnedState| to ignore any
1354 // invocations while we are running. 1275 // invocations while we are running.
1355 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true); 1276 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true);
1356 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs( 1277 std::vector<std::string> pinned_apps = ash::launcher::GetPinnedAppsFromPrefs(
1357 profile_->GetPrefs(), launcher_controller_helper_.get()); 1278 profile_->GetPrefs(), launcher_controller_helper_.get());
1358 1279
1359 int index = 0; 1280 int index = 0;
1360 int max_index = model_->item_count(); 1281 int max_index = model_->item_count();
1282 int seen_chrome_index = -1;
1361 1283
1362 // When one of the two special items cannot be moved (and we do not know where 1284 // At least chrome browser shortcut should exist.
1363 // yet), we remember the current location in one of these variables. 1285 DCHECK_GT(max_index, 0);
1364 int chrome_index = -1; 1286
1365 int app_list_index = -1; 1287 // Skip app list items if it exists.
1288 if (model_->items()[0].type == ash::TYPE_APP_LIST)
1289 ++index;
1366 1290
1367 // Walk the model and |pinned_apps| from the pref lockstep, adding and 1291 // Walk the model and |pinned_apps| from the pref lockstep, adding and
1368 // removing items as necessary. NB: This code uses plain old indexing instead 1292 // removing items as necessary. NB: This code uses plain old indexing instead
1369 // of iterators because of model mutations as part of the loop. 1293 // of iterators because of model mutations as part of the loop.
1370 std::vector<std::string>::const_iterator pref_app_id(pinned_apps.begin()); 1294 std::vector<std::string>::const_iterator pref_app_id(pinned_apps.begin());
1371 for (; index < max_index && pref_app_id != pinned_apps.end(); ++index) { 1295 for (; index < max_index && pref_app_id != pinned_apps.end(); ++index) {
1372 // Update apps icon if applicable. 1296 // Update apps icon if applicable.
1373 OnAppUpdated(profile_, *pref_app_id); 1297 OnAppUpdated(profile_, *pref_app_id);
1374 // Check if we have an item which we need to handle. 1298 // Check if we have an item which we need to handle.
1375 if (*pref_app_id == extension_misc::kChromeAppId || 1299 if (IsAppPinned(*pref_app_id)) {
1376 *pref_app_id == ash::kPinnedAppsPlaceholder || 1300 if (seen_chrome_index >= 0 &&
1377 IsAppPinned(*pref_app_id)) { 1301 *pref_app_id == extension_misc::kChromeAppId) {
1302 // Current item is Chrome browser and we saw it before.
1303 model_->Move(seen_chrome_index, index);
1304 ++pref_app_id;
1305 --index;
1306 continue;
1307 }
1378 for (; index < max_index; ++index) { 1308 for (; index < max_index; ++index) {
1379 const ash::ShelfItem& item(model_->items()[index]); 1309 const ash::ShelfItem& item(model_->items()[index]);
1380 bool is_app_list = item.type == ash::TYPE_APP_LIST; 1310 if (item.type != ash::TYPE_APP_SHORTCUT &&
1381 bool is_chrome = item.type == ash::TYPE_BROWSER_SHORTCUT; 1311 item.type != ash::TYPE_BROWSER_SHORTCUT) {
1382 if (item.type != ash::TYPE_APP_SHORTCUT && !is_app_list && !is_chrome)
1383 continue; 1312 continue;
1313 }
1384 LauncherItemController* controller = GetLauncherItemController(item.id); 1314 LauncherItemController* controller = GetLauncherItemController(item.id);
1385 if ((ash::kPinnedAppsPlaceholder == *pref_app_id && is_app_list) || 1315 if (controller && controller->app_id() == *pref_app_id) {
1386 (extension_misc::kChromeAppId == *pref_app_id && is_chrome) ||
1387 (controller && controller->app_id() == *pref_app_id)) {
1388 // Check if an item needs to be moved here.
1389 MoveChromeOrApplistToFinalPosition(is_chrome, is_app_list, index,
1390 &chrome_index, &app_list_index);
1391 ++pref_app_id; 1316 ++pref_app_id;
1392 break; 1317 break;
1318 } else if (item.type == ash::TYPE_BROWSER_SHORTCUT) {
1319 // We cannot close browser shortcut. Remember its position.
1320 seen_chrome_index = index;
1393 } else { 1321 } else {
1394 if (is_chrome || is_app_list) { 1322 // Check if this is a platform or a windowed app.
1395 // We cannot delete any of these shortcuts. As such we remember 1323 if (item.type == ash::TYPE_APP_SHORTCUT && controller &&
1396 // their positions and move them later where they belong. 1324 (controller->locked() ||
1397 if (is_chrome) 1325 controller->type() == LauncherItemController::TYPE_APP)) {
1398 chrome_index = index; 1326 // Note: This will not change the amount of items (|max_index|).
1399 else 1327 // Even changes to the actual |index| due to item weighting
1400 app_list_index = index; 1328 // changes should be fine.
1401 // And skip the item - or exit the loop if end is reached (note that 1329 UnpinRunningAppInternal(index);
1402 // in that case we will reduce the index again by one and this only
1403 // compensates for it).
1404 if (index >= max_index - 1)
1405 break;
1406 ++index;
1407 } else { 1330 } else {
1408 // Check if this is a platform or a windowed app. 1331 if (controller)
1409 if (item.type == ash::TYPE_APP_SHORTCUT && controller && 1332 LauncherItemClosed(item.id);
1410 (controller->locked() || 1333 --max_index;
1411 controller->type() == LauncherItemController::TYPE_APP)) {
1412 // Note: This will not change the amount of items (|max_index|).
1413 // Even changes to the actual |index| due to item weighting
1414 // changes should be fine.
1415 UnpinRunningAppInternal(index);
1416 } else {
1417 if (controller)
1418 LauncherItemClosed(item.id);
1419 --max_index;
1420 }
1421 } 1334 }
1422 --index; 1335 --index;
1423 } 1336 }
1424 } 1337 }
1425 // If the item wasn't found, that means id_to_item_controller_map_ 1338 // If the item wasn't found, that means id_to_item_controller_map_
1426 // is out of sync. 1339 // is out of sync.
1427 DCHECK(index <= max_index); 1340 DCHECK(index <= max_index);
1428 } else { 1341 } else {
1429 // Check if the item was already running but not yet pinned. 1342 // Check if the item was already running but not yet pinned.
1430 ash::ShelfID shelf_id = GetShelfIDForAppID(*pref_app_id); 1343 ash::ShelfID shelf_id = GetShelfIDForAppID(*pref_app_id);
(...skipping 17 matching lines...) Expand all
1448 LauncherItemController* controller = GetLauncherItemController(item.id); 1361 LauncherItemController* controller = GetLauncherItemController(item.id);
1449 if (controller) { 1362 if (controller) {
1450 if (controller->locked() || 1363 if (controller->locked() ||
1451 controller->type() == LauncherItemController::TYPE_APP) { 1364 controller->type() == LauncherItemController::TYPE_APP) {
1452 UnpinRunningAppInternal(index); 1365 UnpinRunningAppInternal(index);
1453 } else { 1366 } else {
1454 LauncherItemClosed(item.id); 1367 LauncherItemClosed(item.id);
1455 } 1368 }
1456 } 1369 }
1457 } else { 1370 } else {
1458 if (item.type == ash::TYPE_BROWSER_SHORTCUT)
1459 chrome_index = index;
1460 else if (item.type == ash::TYPE_APP_LIST)
1461 app_list_index = index;
1462 ++index; 1371 ++index;
1463 } 1372 }
1464 } 1373 }
1465 1374
1466 // Append unprocessed items from the pref to the end of the model. 1375 // Append unprocessed items from the pref to the end of the model.
1467 for (; pref_app_id != pinned_apps.end(); ++pref_app_id) { 1376 for (; pref_app_id != pinned_apps.end(); ++pref_app_id) {
1468 // Update apps icon if applicable. 1377 // Update apps icon if applicable.
1469 OnAppUpdated(profile_, *pref_app_id); 1378 OnAppUpdated(profile_, *pref_app_id);
1470 // All items but the chrome and / or app list shortcut needs to be added. 1379 if (*pref_app_id == extension_misc::kChromeAppId) {
1471 bool is_chrome = *pref_app_id == extension_misc::kChromeAppId; 1380 int target_index = FindInsertionPoint();
1472 bool is_app_list = *pref_app_id == ash::kPinnedAppsPlaceholder; 1381 DCHECK(seen_chrome_index >= 0 && seen_chrome_index < target_index);
1473 // Coming here we know the next item which can be finalized, either the 1382 model_->Move(seen_chrome_index, target_index);
1474 // chrome item or the app launcher. The final position is the end of the 1383 } else {
1475 // list. The menu model will make sure that the item is grouped according
1476 // to its weight (which we do not know here).
1477 if (!is_chrome && !is_app_list) {
1478 DoPinAppWithID(*pref_app_id); 1384 DoPinAppWithID(*pref_app_id);
1479 int target_index = FindInsertionPoint(false); 1385 int target_index = FindInsertionPoint();
1480 ash::ShelfID id = GetShelfIDForAppID(*pref_app_id); 1386 ash::ShelfID id = GetShelfIDForAppID(*pref_app_id);
1481 int source_index = model_->ItemIndexByID(id); 1387 int source_index = model_->ItemIndexByID(id);
1482 if (source_index != target_index) 1388 if (source_index != target_index)
1483 model_->Move(source_index, target_index); 1389 model_->Move(source_index, target_index);
1484
1485 // Needed for the old layout - the weight might force it to be lower in
1486 // rank.
1487 if (app_list_index != -1 && target_index <= app_list_index)
1488 ++app_list_index;
1489 } else {
1490 int target_index = FindInsertionPoint(is_app_list);
1491 MoveChromeOrApplistToFinalPosition(is_chrome, is_app_list, target_index,
1492 &chrome_index, &app_list_index);
1493 } 1390 }
1494 } 1391 }
1495 } 1392 }
1496 1393
1497 void ChromeLauncherControllerImpl::SetShelfAutoHideBehaviorFromPrefs() { 1394 void ChromeLauncherControllerImpl::SetShelfAutoHideBehaviorFromPrefs() {
1498 for (auto* window : ash::Shell::GetAllRootWindows()) { 1395 for (auto* window : ash::Shell::GetAllRootWindows()) {
1499 ash::Shelf* shelf = ash::Shelf::ForWindow(window); 1396 ash::Shelf* shelf = ash::Shelf::ForWindow(window);
1500 if (shelf) { 1397 if (shelf) {
1501 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref( 1398 shelf->SetAutoHideBehavior(ash::launcher::GetShelfAutoHideBehaviorPref(
1502 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); 1399 profile_->GetPrefs(), GetDisplayIDForShelf(shelf)));
1503 } 1400 }
1504 } 1401 }
1505 } 1402 }
1506 1403
1507 void ChromeLauncherControllerImpl::SetShelfAlignmentFromPrefs() { 1404 void ChromeLauncherControllerImpl::SetShelfAlignmentFromPrefs() {
1508 if (!ash::ShelfWidget::ShelfAlignmentAllowed()) 1405 if (!ash::ShelfWidget::ShelfAlignmentAllowed())
1509 return; 1406 return;
1510 1407
1511 for (auto* window : ash::Shell::GetAllRootWindows()) { 1408 for (auto* window : ash::Shell::GetAllRootWindows()) {
1512 ash::Shelf* shelf = ash::Shelf::ForWindow(window); 1409 ash::Shelf* shelf = ash::Shelf::ForWindow(window);
1513 if (shelf) { 1410 if (shelf) {
1514 shelf->SetAlignment(ash::GetShelfAlignmentPref( 1411 shelf->SetAlignment(ash::launcher::GetShelfAlignmentPref(
1515 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); 1412 profile_->GetPrefs(), GetDisplayIDForShelf(shelf)));
1516 } 1413 }
1517 } 1414 }
1518 } 1415 }
1519 1416
1520 void ChromeLauncherControllerImpl::SetShelfBehaviorsFromPrefs() { 1417 void ChromeLauncherControllerImpl::SetShelfBehaviorsFromPrefs() {
1521 SetShelfAutoHideBehaviorFromPrefs(); 1418 SetShelfAutoHideBehaviorFromPrefs();
1522 SetShelfAlignmentFromPrefs(); 1419 SetShelfAlignmentFromPrefs();
1523 } 1420 }
1524 1421
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 static_cast<AppShortcutLauncherItemController*>(controller); 1505 static_cast<AppShortcutLauncherItemController*>(controller);
1609 return app_controller->GetRunningApplications(); 1506 return app_controller->GetRunningApplications();
1610 } 1507 }
1611 1508
1612 ash::ShelfID ChromeLauncherControllerImpl::CreateBrowserShortcutLauncherItem() { 1509 ash::ShelfID ChromeLauncherControllerImpl::CreateBrowserShortcutLauncherItem() {
1613 ash::ShelfItem browser_shortcut; 1510 ash::ShelfItem browser_shortcut;
1614 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT; 1511 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT;
1615 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 1512 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
1616 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32); 1513 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32);
1617 ash::ShelfID id = model_->next_id(); 1514 ash::ShelfID id = model_->next_id();
1618 size_t index = GetChromeIconIndexForCreation(); 1515 model_->AddAt(0, browser_shortcut);
1619 model_->AddAt(index, browser_shortcut);
1620 id_to_item_controller_map_[id] = 1516 id_to_item_controller_map_[id] =
1621 new BrowserShortcutLauncherItemController(this, model_); 1517 new BrowserShortcutLauncherItemController(this, model_);
1622 id_to_item_controller_map_[id]->set_shelf_id(id); 1518 id_to_item_controller_map_[id]->set_shelf_id(id);
1623 // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController. 1519 // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController.
1624 SetShelfItemDelegate(id, id_to_item_controller_map_[id]); 1520 SetShelfItemDelegate(id, id_to_item_controller_map_[id]);
1625 return id; 1521 return id;
1626 } 1522 }
1627 1523
1628 bool ChromeLauncherControllerImpl::IsIncognito( 1524 bool ChromeLauncherControllerImpl::IsIncognito(
1629 const content::WebContents* web_contents) const { 1525 const content::WebContents* web_contents) const {
1630 const Profile* profile = 1526 const Profile* profile =
1631 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 1527 Profile::FromBrowserContext(web_contents->GetBrowserContext());
1632 return profile->IsOffTheRecord() && !profile->IsGuestSession() && 1528 return profile->IsOffTheRecord() && !profile->IsGuestSession() &&
1633 !profile->IsSystemProfile(); 1529 !profile->IsSystemProfile();
1634 } 1530 }
1635 1531
1636 void ChromeLauncherControllerImpl::PersistChromeItemIndex(int index) { 1532 int ChromeLauncherControllerImpl::FindInsertionPoint() {
1637 profile_->GetPrefs()->SetInteger(prefs::kShelfChromeIconIndex, index); 1533 DCHECK_GT(model_->item_count(), 0);
1638 }
1639
1640 void ChromeLauncherControllerImpl::MoveChromeOrApplistToFinalPosition(
1641 bool is_chrome,
1642 bool is_app_list,
1643 int target_index,
1644 int* chrome_index,
1645 int* app_list_index) {
1646 if (is_chrome && *chrome_index != -1) {
1647 model_->Move(*chrome_index, target_index);
1648 if (*app_list_index != -1 && *chrome_index < *app_list_index &&
1649 target_index > *app_list_index)
1650 --(*app_list_index);
1651 *chrome_index = -1;
1652 } else if (is_app_list && *app_list_index != -1) {
1653 model_->Move(*app_list_index, target_index);
1654 if (*chrome_index != -1 && *app_list_index < *chrome_index &&
1655 target_index > *chrome_index)
1656 --(*chrome_index);
1657 *app_list_index = -1;
1658 }
1659 }
1660
1661 int ChromeLauncherControllerImpl::FindInsertionPoint(bool is_app_list) {
1662 // Keeping this change small to backport to M33&32 (see crbug.com/329597).
1663 // TODO(skuhne): With the removal of the legacy shelf layout we should remove
1664 // the ability to move the app list item since this was never used. We should
1665 // instead ask the ShelfModel::ValidateInsertionIndex or similir for an index.
1666 if (is_app_list)
1667 return 0;
1668
1669 for (int i = model_->item_count() - 1; i > 0; --i) { 1534 for (int i = model_->item_count() - 1; i > 0; --i) {
1670 ash::ShelfItemType type = model_->items()[i].type; 1535 ash::ShelfItemType type = model_->items()[i].type;
1536 DCHECK_NE(ash::TYPE_APP_LIST, type);
1671 if (type == ash::TYPE_APP_SHORTCUT || 1537 if (type == ash::TYPE_APP_SHORTCUT ||
1672 (is_app_list && type == ash::TYPE_APP_LIST) ||
1673 type == ash::TYPE_BROWSER_SHORTCUT) { 1538 type == ash::TYPE_BROWSER_SHORTCUT) {
1674 return i; 1539 return i;
1675 } 1540 }
1676 } 1541 }
1677 return 0; 1542 return 0;
1678 } 1543 }
1679 1544
1680 int ChromeLauncherControllerImpl::GetChromeIconIndexForCreation() {
1681 // We get the list of pinned apps as they currently would get pinned.
1682 // Within this list the chrome icon will be the correct location.
1683 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs(
1684 profile_->GetPrefs(), launcher_controller_helper_.get());
1685
1686 std::vector<std::string>::iterator it =
1687 std::find(pinned_apps.begin(), pinned_apps.end(),
1688 std::string(extension_misc::kChromeAppId));
1689 DCHECK(it != pinned_apps.end());
1690 int index = it - pinned_apps.begin();
1691
1692 // We should do here a comparison between the is state and the "want to be"
1693 // state since some apps might be able to pin but are not yet. Instead - for
1694 // the time being we clamp against the amount of known items and wait for the
1695 // next |UpdateAppLaunchersFromPref()| call to correct it - it will come since
1696 // the pinning will be done then.
1697 return std::min(model_->item_count(), index);
1698 }
1699
1700 void ChromeLauncherControllerImpl::CloseWindowedAppsFromRemovedExtension( 1545 void ChromeLauncherControllerImpl::CloseWindowedAppsFromRemovedExtension(
1701 const std::string& app_id, 1546 const std::string& app_id,
1702 const Profile* profile) { 1547 const Profile* profile) {
1703 // This function cannot rely on the controller's enumeration functionality 1548 // This function cannot rely on the controller's enumeration functionality
1704 // since the extension has already be unloaded. 1549 // since the extension has already be unloaded.
1705 const BrowserList* browser_list = BrowserList::GetInstance(); 1550 const BrowserList* browser_list = BrowserList::GetInstance();
1706 std::vector<Browser*> browser_to_close; 1551 std::vector<Browser*> browser_to_close;
1707 for (BrowserList::const_reverse_iterator it = 1552 for (BrowserList::const_reverse_iterator it =
1708 browser_list->begin_last_active(); 1553 browser_list->begin_last_active();
1709 it != browser_list->end_last_active(); ++it) { 1554 it != browser_list->end_last_active(); ++it) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1752 app_icon_loaders_.push_back(std::move(extension_app_icon_loader)); 1597 app_icon_loaders_.push_back(std::move(extension_app_icon_loader));
1753 1598
1754 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { 1599 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) {
1755 std::unique_ptr<AppIconLoader> arc_app_icon_loader(new ArcAppIconLoader( 1600 std::unique_ptr<AppIconLoader> arc_app_icon_loader(new ArcAppIconLoader(
1756 profile_, extension_misc::EXTENSION_ICON_SMALL, this)); 1601 profile_, extension_misc::EXTENSION_ICON_SMALL, this));
1757 app_icon_loaders_.push_back(std::move(arc_app_icon_loader)); 1602 app_icon_loaders_.push_back(std::move(arc_app_icon_loader));
1758 } 1603 }
1759 1604
1760 pref_change_registrar_.Init(profile_->GetPrefs()); 1605 pref_change_registrar_.Init(profile_->GetPrefs());
1761 pref_change_registrar_.Add( 1606 pref_change_registrar_.Add(
1762 prefs::kPinnedLauncherApps,
1763 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref,
1764 base::Unretained(this)));
1765 pref_change_registrar_.Add(
1766 prefs::kPolicyPinnedLauncherApps, 1607 prefs::kPolicyPinnedLauncherApps,
1767 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref, 1608 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref,
1768 base::Unretained(this))); 1609 base::Unretained(this)));
1769 pref_change_registrar_.Add( 1610 pref_change_registrar_.Add(
1770 prefs::kShelfAlignmentLocal, 1611 prefs::kShelfAlignmentLocal,
1771 base::Bind(&ChromeLauncherControllerImpl::SetShelfAlignmentFromPrefs, 1612 base::Bind(&ChromeLauncherControllerImpl::SetShelfAlignmentFromPrefs,
1772 base::Unretained(this))); 1613 base::Unretained(this)));
1773 pref_change_registrar_.Add( 1614 pref_change_registrar_.Add(
1774 prefs::kShelfAutoHideBehaviorLocal, 1615 prefs::kShelfAutoHideBehaviorLocal,
1775 base::Bind( 1616 base::Bind(
(...skipping 11 matching lines...) Expand all
1787 1628
1788 std::unique_ptr<LauncherAppUpdater> extension_app_updater( 1629 std::unique_ptr<LauncherAppUpdater> extension_app_updater(
1789 new LauncherExtensionAppUpdater(this, profile_)); 1630 new LauncherExtensionAppUpdater(this, profile_));
1790 app_updaters_.push_back(std::move(extension_app_updater)); 1631 app_updaters_.push_back(std::move(extension_app_updater));
1791 1632
1792 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { 1633 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) {
1793 std::unique_ptr<LauncherAppUpdater> arc_app_updater( 1634 std::unique_ptr<LauncherAppUpdater> arc_app_updater(
1794 new LauncherArcAppUpdater(this, profile_)); 1635 new LauncherArcAppUpdater(this, profile_));
1795 app_updaters_.push_back(std::move(arc_app_updater)); 1636 app_updaters_.push_back(std::move(arc_app_updater));
1796 } 1637 }
1638
1639 app_list::AppListSyncableService* app_service =
1640 app_list::AppListSyncableServiceFactory::GetForProfile(profile_);
1641 if (app_service)
1642 app_service->AddObserverAndStart(this);
1797 } 1643 }
1798 1644
1799 void ChromeLauncherControllerImpl::ReleaseProfile() { 1645 void ChromeLauncherControllerImpl::ReleaseProfile() {
1800 if (app_sync_ui_state_) 1646 if (app_sync_ui_state_)
1801 app_sync_ui_state_->RemoveObserver(this); 1647 app_sync_ui_state_->RemoveObserver(this);
1802 1648
1803 app_updaters_.clear(); 1649 app_updaters_.clear();
1804 1650
1805 prefs_observer_.reset(); 1651 prefs_observer_.reset();
1806 1652
1807 pref_change_registrar_.RemoveAll(); 1653 pref_change_registrar_.RemoveAll();
1654
1655 app_list::AppListSyncableService* app_service =
1656 app_list::AppListSyncableServiceFactory::GetForProfile(profile_);
1657 if (app_service)
1658 app_service->RemoveObserver(this);
1808 } 1659 }
1809 1660
1810 AppIconLoader* ChromeLauncherControllerImpl::GetAppIconLoaderForApp( 1661 AppIconLoader* ChromeLauncherControllerImpl::GetAppIconLoaderForApp(
1811 const std::string& app_id) { 1662 const std::string& app_id) {
1812 for (const auto& app_icon_loader : app_icon_loaders_) { 1663 for (const auto& app_icon_loader : app_icon_loaders_) {
1813 if (app_icon_loader->CanLoadImageForApp(app_id)) 1664 if (app_icon_loader->CanLoadImageForApp(app_id))
1814 return app_icon_loader.get(); 1665 return app_icon_loader.get();
1815 } 1666 }
1816 1667
1817 return nullptr; 1668 return nullptr;
(...skipping 11 matching lines...) Expand all
1829 if (iter == id_to_item_controller_map_.end() || item_delegate == iter->second) 1680 if (iter == id_to_item_controller_map_.end() || item_delegate == iter->second)
1830 return; 1681 return;
1831 LOG(ERROR) << "Unexpected change of shelf item id: " << id; 1682 LOG(ERROR) << "Unexpected change of shelf item id: " << id;
1832 id_to_item_controller_map_.erase(iter); 1683 id_to_item_controller_map_.erase(iter);
1833 } 1684 }
1834 1685
1835 /////////////////////////////////////////////////////////////////////////////// 1686 ///////////////////////////////////////////////////////////////////////////////
1836 // ash::ShelfModelObserver: 1687 // ash::ShelfModelObserver:
1837 1688
1838 void ChromeLauncherControllerImpl::ShelfItemAdded(int index) { 1689 void ChromeLauncherControllerImpl::ShelfItemAdded(int index) {
1839 // The app list launcher can get added to the shelf after we applied the
1840 // preferences. In that case the item might be at the wrong spot. As such we
1841 // call the function again.
1842 if (model_->items()[index].type == ash::TYPE_APP_LIST)
1843 UpdateAppLaunchersFromPref();
1844 } 1690 }
1845 1691
1846 void ChromeLauncherControllerImpl::ShelfItemRemoved(int index, 1692 void ChromeLauncherControllerImpl::ShelfItemRemoved(int index,
1847 ash::ShelfID id) { 1693 ash::ShelfID id) {
1848 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we 1694 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we
1849 // get into this state in the first place. 1695 // get into this state in the first place.
1850 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 1696 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
1851 if (iter == id_to_item_controller_map_.end()) 1697 if (iter == id_to_item_controller_map_.end())
1852 return; 1698 return;
1853 1699
1854 LOG(ERROR) << "Unexpected change of shelf item id: " << id; 1700 LOG(ERROR) << "Unexpected change of shelf item id: " << id;
1855 1701
1856 id_to_item_controller_map_.erase(iter); 1702 id_to_item_controller_map_.erase(iter);
1857 } 1703 }
1858 1704
1859 void ChromeLauncherControllerImpl::ShelfItemMoved(int start_index, 1705 void ChromeLauncherControllerImpl::ShelfItemMoved(int start_index,
1860 int target_index) { 1706 int target_index) {
1861 const ash::ShelfItem& item = model_->items()[target_index]; 1707 const ash::ShelfItem& item = model_->items()[target_index];
1862 // We remember the moved item position if it is either pinnable or 1708 // We remember the moved item position if it is either pinnable or
1863 // it is the app list with the alternate shelf layout. 1709 // it is the app list with the alternate shelf layout.
1864 if ((HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id)) || 1710 DCHECK_NE(ash::TYPE_APP_LIST, item.type);
1865 item.type == ash::TYPE_APP_LIST) 1711 if (HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id))
1866 PersistPinnedState(); 1712 SyncPinPosition(item.id);
1867 } 1713 }
1868 1714
1869 void ChromeLauncherControllerImpl::ShelfItemChanged( 1715 void ChromeLauncherControllerImpl::ShelfItemChanged(
1870 int index, 1716 int index,
1871 const ash::ShelfItem& old_item) {} 1717 const ash::ShelfItem& old_item) {}
1872 1718
1873 /////////////////////////////////////////////////////////////////////////////// 1719 ///////////////////////////////////////////////////////////////////////////////
1874 // ash::WindowTreeHostManager::Observer: 1720 // ash::WindowTreeHostManager::Observer:
1875 1721
1876 void ChromeLauncherControllerImpl::OnDisplayConfigurationChanged() { 1722 void ChromeLauncherControllerImpl::OnDisplayConfigurationChanged() {
(...skipping 29 matching lines...) Expand all
1906 if (index == -1) 1752 if (index == -1)
1907 continue; 1753 continue;
1908 ash::ShelfItem item = model_->items()[index]; 1754 ash::ShelfItem item = model_->items()[index];
1909 item.image = image; 1755 item.image = image;
1910 if (arc_deferred_launcher_) 1756 if (arc_deferred_launcher_)
1911 arc_deferred_launcher_->MaybeApplySpinningEffect(id, &item.image); 1757 arc_deferred_launcher_->MaybeApplySpinningEffect(id, &item.image);
1912 model_->Set(index, item); 1758 model_->Set(index, item);
1913 // It's possible we're waiting on more than one item, so don't break. 1759 // It's possible we're waiting on more than one item, so don't break.
1914 } 1760 }
1915 } 1761 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698