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

Side by Side Diff: chrome/browser/ui/ash/launcher/chrome_launcher_controller.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: rebased, comments addressed, removed item_pinned_by_policy 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.h" 5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <vector> 9 #include <vector>
10 10
11 #include "ash/ash_switches.h" 11 #include "ash/ash_switches.h"
12 #include "ash/common/shelf/shelf_item_delegate_manager.h" 12 #include "ash/common/shelf/shelf_item_delegate_manager.h"
13 #include "ash/common/shelf/shelf_model.h" 13 #include "ash/common/shelf/shelf_model.h"
14 #include "ash/common/system/tray/system_tray_delegate.h" 14 #include "ash/common/system/tray/system_tray_delegate.h"
15 #include "ash/desktop_background/desktop_background_controller.h" 15 #include "ash/desktop_background/desktop_background_controller.h"
16 #include "ash/multi_profile_uma.h" 16 #include "ash/multi_profile_uma.h"
17 #include "ash/root_window_controller.h" 17 #include "ash/root_window_controller.h"
18 #include "ash/shelf/shelf.h" 18 #include "ash/shelf/shelf.h"
19 #include "ash/shell.h" 19 #include "ash/shell.h"
20 #include "ash/wm/window_util.h" 20 #include "ash/wm/window_util.h"
21 #include "base/command_line.h" 21 #include "base/command_line.h"
22 #include "base/macros.h" 22 #include "base/macros.h"
23 #include "base/strings/pattern.h" 23 #include "base/strings/pattern.h"
24 #include "base/strings/string_util.h" 24 #include "base/strings/string_util.h"
25 #include "base/strings/utf_string_conversions.h" 25 #include "base/strings/utf_string_conversions.h"
26 #include "base/values.h" 26 #include "base/values.h"
27 #include "build/build_config.h" 27 #include "build/build_config.h"
28 #include "chrome/browser/browser_process.h" 28 #include "chrome/browser/browser_process.h"
29 #include "chrome/browser/chrome_notification_types.h" 29 #include "chrome/browser/chrome_notification_types.h"
30 #include "chrome/browser/chromeos/arc/arc_support_host.h"
31 #include "chrome/browser/defaults.h" 30 #include "chrome/browser/defaults.h"
32 #include "chrome/browser/extensions/extension_app_icon_loader.h" 31 #include "chrome/browser/extensions/extension_app_icon_loader.h"
33 #include "chrome/browser/extensions/extension_util.h" 32 #include "chrome/browser/extensions/extension_util.h"
34 #include "chrome/browser/extensions/launch_util.h" 33 #include "chrome/browser/extensions/launch_util.h"
35 #include "chrome/browser/prefs/incognito_mode_prefs.h" 34 #include "chrome/browser/prefs/incognito_mode_prefs.h"
36 #include "chrome/browser/profiles/profile.h" 35 #include "chrome/browser/profiles/profile.h"
37 #include "chrome/browser/profiles/profile_manager.h" 36 #include "chrome/browser/profiles/profile_manager.h"
37 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
38 #include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h" 38 #include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h"
39 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" 39 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
40 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" 40 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
41 #include "chrome/browser/ui/ash/app_sync_ui_state.h" 41 #include "chrome/browser/ui/ash/app_sync_ui_state.h"
42 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" 42 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h"
43 #include "chrome/browser/ui/ash/chrome_shell_delegate.h" 43 #include "chrome/browser/ui/ash/chrome_shell_delegate.h"
44 #include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h " 44 #include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h "
45 #include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h" 45 #include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h"
46 #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h" 46 #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h"
47 #include "chrome/browser/ui/ash/launcher/arc_app_deferred_launcher_controller.h" 47 #include "chrome/browser/ui/ash/launcher/arc_app_deferred_launcher_controller.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 111
112 int64_t GetDisplayIDForShelf(ash::Shelf* shelf) { 112 int64_t GetDisplayIDForShelf(ash::Shelf* shelf) {
113 aura::Window* root_window = 113 aura::Window* root_window =
114 shelf->shelf_widget()->GetNativeWindow()->GetRootWindow(); 114 shelf->shelf_widget()->GetNativeWindow()->GetRootWindow();
115 display::Display display = 115 display::Display display =
116 display::Screen::GetScreen()->GetDisplayNearestWindow(root_window); 116 display::Screen::GetScreen()->GetDisplayNearestWindow(root_window);
117 DCHECK(display.is_valid()); 117 DCHECK(display.is_valid());
118 return display.id(); 118 return display.id();
119 } 119 }
120 120
121 /*
122 * Return whether an app is pinned only by user.
123 * This function doesn't expect an app_id neither pinned by user nor by
124 * policy, the app_id in the arguments list MUST be pinned by either of
125 * those. Invalid input may lead to unexpected result.
126 * If this app is pinned by policy, but not by user, false is returned.
127 * If this app is pinned by both policy and user, false is returned.
128 * If this app is pinned not by policy, but by user, true is returned.
129 */
130 bool IsAppForUserPinned(const std::string& app_id,
131 const base::ListValue* pinned_apps_pref,
132 const base::ListValue* policy_pinned_apps_pref) {
133 for (size_t index = 0; index < pinned_apps_pref->GetSize(); ++index) {
134 const base::DictionaryValue* app;
135 if (pinned_apps_pref->GetDictionary(index, &app)) {
136 std::string current_app_id;
137 bool pinned_by_policy = false;
138 if (app->GetString(ash::kPinnedAppsPrefAppIDPath, &current_app_id)) {
139 if (app_id == current_app_id) {
140 if (app->GetBoolean(ash::kPinnedAppsPrefPinnedByPolicy,
141 &pinned_by_policy) &&
142 pinned_by_policy) {
143 // Pinned by policy in the past or present.
144 // Need to check policy_pinned_apps to determine
145 break;
146 } else {
147 // User Preference Already Pinned
148 return true;
149 }
150 }
151 }
152 }
153 }
154 for (size_t index = 0; index < policy_pinned_apps_pref->GetSize(); ++index) {
155 const base::DictionaryValue* app;
156 if (policy_pinned_apps_pref->GetDictionary(index, &app)) {
157 std::string app_id_;
158 if (app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id_)) {
159 // Only pinned by policy, which is not part of user-pinned
160 if (app_id == app_id_)
161 return false;
162 }
163 }
164 }
165 // Default, user added new pins
166 return true;
167 }
168
169 const char* const kPinProhibitedExtensionIds[] = {
170 ArcSupportHost::kHostAppId, arc::kPlayStoreAppId,
171 };
172
173 const size_t kPinProhibitedExtensionIdsLength =
174 arraysize(kPinProhibitedExtensionIds);
175
176 } // namespace 121 } // namespace
177 122
178 // A class to get events from ChromeOS when a user gets changed or added. 123 // A class to get events from ChromeOS when a user gets changed or added.
179 class ChromeLauncherControllerUserSwitchObserver 124 class ChromeLauncherControllerUserSwitchObserver
180 : public user_manager::UserManager::UserSessionStateObserver { 125 : public user_manager::UserManager::UserSessionStateObserver {
181 public: 126 public:
182 ChromeLauncherControllerUserSwitchObserver( 127 ChromeLauncherControllerUserSwitchObserver(
183 ChromeLauncherController* controller) 128 ChromeLauncherController* controller)
184 : controller_(controller) { 129 : controller_(controller) {
185 DCHECK(user_manager::UserManager::IsInitialized()); 130 DCHECK(user_manager::UserManager::IsInitialized());
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 185
241 void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) { 186 void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) {
242 if (chrome::MultiUserWindowManager::GetMultiProfileMode() == 187 if (chrome::MultiUserWindowManager::GetMultiProfileMode() ==
243 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) 188 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED)
244 chrome::MultiUserWindowManager::GetInstance()->AddUser(profile); 189 chrome::MultiUserWindowManager::GetInstance()->AddUser(profile);
245 controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile()); 190 controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile());
246 } 191 }
247 192
248 ChromeLauncherController::ChromeLauncherController(Profile* profile, 193 ChromeLauncherController::ChromeLauncherController(Profile* profile,
249 ash::ShelfModel* model) 194 ash::ShelfModel* model)
250 : model_(model), 195 : model_(model), profile_(profile) {
251 item_delegate_manager_(NULL),
252 profile_(profile),
253 app_sync_ui_state_(NULL),
254 ignore_persist_pinned_state_change_(false) {
255 if (!profile_) { 196 if (!profile_) {
256 // If no profile was passed, we take the currently active profile and use it 197 // If no profile was passed, we take the currently active profile and use it
257 // as the owner of the current desktop. 198 // as the owner of the current desktop.
258 // Use the original profile as on chromeos we may get a temporary off the 199 // Use the original profile as on chromeos we may get a temporary off the
259 // record profile, unless in guest session (where off the record profile is 200 // record profile, unless in guest session (where off the record profile is
260 // the right one). 201 // the right one).
261 profile_ = ProfileManager::GetActiveUserProfile(); 202 profile_ = ProfileManager::GetActiveUserProfile();
262 if (!profile_->IsGuestSession() && !profile_->IsSystemProfile()) 203 if (!profile_->IsGuestSession() && !profile_->IsSystemProfile())
263 profile_ = profile_->GetOriginalProfile(); 204 profile_ = profile_->GetOriginalProfile();
264 205
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 310
370 void ChromeLauncherController::Init() { 311 void ChromeLauncherController::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 ChromeLauncherController::CreateAppLauncherItem( 323 ash::ShelfID ChromeLauncherController::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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 iter->second->set_shelf_id(id); 373 iter->second->set_shelf_id(id);
433 // Existing controller is destroyed and replaced by registering again. 374 // Existing controller is destroyed and replaced by registering again.
434 SetShelfItemDelegate(id, iter->second); 375 SetShelfItemDelegate(id, iter->second);
435 } else { 376 } else {
436 LauncherItemClosed(id); 377 LauncherItemClosed(id);
437 } 378 }
438 } 379 }
439 380
440 AppListControllerDelegate::Pinnable ChromeLauncherController::GetPinnable( 381 AppListControllerDelegate::Pinnable ChromeLauncherController::GetPinnable(
441 const std::string& app_id) { 382 const std::string& app_id) {
442 for (size_t i = 0; i < kPinProhibitedExtensionIdsLength; ++i) {
443 if (kPinProhibitedExtensionIds[i] == app_id)
444 return AppListControllerDelegate::NO_PIN;
445 }
446
447 const base::ListValue* pref = 383 const base::ListValue* pref =
448 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps); 384 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps);
449 if (!pref) 385 if (!pref)
450 return AppListControllerDelegate::PIN_EDITABLE; 386 return AppListControllerDelegate::PIN_EDITABLE;
451 387
452 // Pinned ARC apps policy defines the package name of the apps, that must 388 // Pinned ARC apps policy defines the package name of the apps, that must
453 // be pinned. All the launch activities of any package in policy are pinned. 389 // be pinned. All the launch activities of any package in policy are pinned.
454 // In turn the input parameter to this function is app_id, which 390 // In turn the input parameter to this function is app_id, which
455 // is 32 chars hash. In case of ARC app this is a hash of 391 // is 32 chars hash. In case of ARC app this is a hash of
456 // (package name + activity). This means that we must identify the package 392 // (package name + activity). This means that we must identify the package
457 // from the hash, and check if this package is pinned by policy. 393 // from the hash, and check if this package is pinned by policy.
458 const ArcAppListPrefs* const arc_prefs = ArcAppListPrefs::Get(profile()); 394 const ArcAppListPrefs* const arc_prefs = ArcAppListPrefs::Get(profile());
459 std::string arc_app_packege_name; 395 std::string arc_app_packege_name;
460 if (arc_prefs) { 396 if (arc_prefs) {
461 std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = 397 std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
462 arc_prefs->GetApp(app_id); 398 arc_prefs->GetApp(app_id);
463 if (app_info) 399 if (app_info)
464 arc_app_packege_name = app_info->package_name; 400 arc_app_packege_name = app_info->package_name;
465 } 401 }
466 402
467 for (size_t index = 0; index < pref->GetSize(); ++index) { 403 for (size_t index = 0; index < pref->GetSize(); ++index) {
468 const base::DictionaryValue* app = nullptr; 404 const base::DictionaryValue* app = nullptr;
469 std::string app_id_or_package; 405 std::string app_id_or_package;
470 if (pref->GetDictionary(index, &app) && 406 if (pref->GetDictionary(index, &app) &&
471 app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id_or_package) && 407 app->GetString(ash::launcher::kPinnedAppsPrefAppIDPath,
408 &app_id_or_package) &&
472 (app_id == app_id_or_package || 409 (app_id == app_id_or_package ||
473 arc_app_packege_name == app_id_or_package)) { 410 arc_app_packege_name == app_id_or_package)) {
474 return AppListControllerDelegate::PIN_FIXED; 411 return AppListControllerDelegate::PIN_FIXED;
475 } 412 }
476 } 413 }
477 return AppListControllerDelegate::PIN_EDITABLE; 414 return AppListControllerDelegate::PIN_EDITABLE;
478 } 415 }
479 416
480 void ChromeLauncherController::Pin(ash::ShelfID id) { 417 void ChromeLauncherController::Pin(ash::ShelfID id) {
481 DCHECK(HasShelfIDToAppIDMapping(id)); 418 DCHECK(HasShelfIDToAppIDMapping(id));
482 419
483 int index = model_->ItemIndexByID(id); 420 int index = model_->ItemIndexByID(id);
484 DCHECK_GE(index, 0); 421 DCHECK_GE(index, 0);
485 422
486 ash::ShelfItem item = model_->items()[index]; 423 ash::ShelfItem item = model_->items()[index];
487 424
488 if (item.type == ash::TYPE_PLATFORM_APP || 425 if (item.type == ash::TYPE_PLATFORM_APP ||
489 item.type == ash::TYPE_WINDOWED_APP) { 426 item.type == ash::TYPE_WINDOWED_APP) {
490 item.type = ash::TYPE_APP_SHORTCUT; 427 item.type = ash::TYPE_APP_SHORTCUT;
491 model_->Set(index, item); 428 model_->Set(index, item);
492 } else if (item.type != ash::TYPE_APP_SHORTCUT) { 429 } else if (item.type != ash::TYPE_APP_SHORTCUT) {
493 return; 430 return;
494 } 431 }
495 432
496 if (GetLauncherItemController(id)->CanPin()) 433 SyncPinPosition(id);
497 PersistPinnedState();
498 } 434 }
499 435
500 void ChromeLauncherController::Unpin(ash::ShelfID id) { 436 void ChromeLauncherController::Unpin(ash::ShelfID id) {
501 LauncherItemController* controller = GetLauncherItemController(id); 437 LauncherItemController* controller = GetLauncherItemController(id);
502 CHECK(controller); 438 CHECK(controller);
503 const bool can_pin = controller->CanPin(); 439
440 ash::launcher::RemovePinPosition(profile_, GetAppIDForShelfID(id));
504 441
505 if (controller->type() == LauncherItemController::TYPE_APP || 442 if (controller->type() == LauncherItemController::TYPE_APP ||
506 controller->locked()) { 443 controller->locked()) {
507 UnpinRunningAppInternal(model_->ItemIndexByID(id)); 444 UnpinRunningAppInternal(model_->ItemIndexByID(id));
508 } else { 445 } else {
509 LauncherItemClosed(id); 446 LauncherItemClosed(id);
510 } 447 }
511 if (can_pin)
512 PersistPinnedState();
513 } 448 }
514 449
515 bool ChromeLauncherController::IsPinned(ash::ShelfID id) { 450 bool ChromeLauncherController::IsPinned(ash::ShelfID id) {
516 int index = model_->ItemIndexByID(id); 451 int index = model_->ItemIndexByID(id);
517 if (index < 0) 452 if (index < 0)
518 return false; 453 return false;
519 ash::ShelfItemType type = model_->items()[index].type; 454 ash::ShelfItemType type = model_->items()[index].type;
520 return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT); 455 return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT);
521 } 456 }
522 457
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 ash::ShelfItemDelegate* item_delegate) { 675 ash::ShelfItemDelegate* item_delegate) {
741 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we 676 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we
742 // get into this state in the first place. 677 // get into this state in the first place.
743 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 678 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
744 if (iter == id_to_item_controller_map_.end() || item_delegate == iter->second) 679 if (iter == id_to_item_controller_map_.end() || item_delegate == iter->second)
745 return; 680 return;
746 LOG(ERROR) << "Unexpected change of shelf item id: " << id; 681 LOG(ERROR) << "Unexpected change of shelf item id: " << id;
747 id_to_item_controller_map_.erase(iter); 682 id_to_item_controller_map_.erase(iter);
748 } 683 }
749 684
750 void ChromeLauncherController::PersistPinnedState() {
751 if (ignore_persist_pinned_state_change_)
752 return;
753 // It is a coding error to call PersistPinnedState() if the pinned apps are
754 // not user-editable. The code should check earlier and not perform any
755 // modification actions that trigger persisting the state.
756 // Mutating kPinnedLauncherApps is going to notify us and trigger us to
757 // process the change. We don't want that to happen so remove ourselves as a
758 // listener.
759 pref_change_registrar_.Remove(prefs::kPinnedLauncherApps);
760 {
761 std::unique_ptr<const base::ListValue> pinned_apps_pref =
762 profile_->GetPrefs()
763 ->GetList(prefs::kPinnedLauncherApps)
764 ->CreateDeepCopy();
765
766 const base::ListValue* policy_pinned_apps_pref =
767 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps);
768
769 ListPrefUpdate updater(profile_->GetPrefs(), prefs::kPinnedLauncherApps);
770 updater->Clear();
771 for (size_t i = 0; i < model_->items().size(); ++i) {
772 if (model_->items()[i].type == ash::TYPE_APP_SHORTCUT) {
773 ash::ShelfID id = model_->items()[i].id;
774 LauncherItemController* controller = GetLauncherItemController(id);
775 // Don't persist pinning state for apps that are handled internally and
776 // have pinnable state AppListControllerDelegate::NO_PIN.
777 if (controller && IsPinned(id) &&
778 GetPinnable(controller->app_id()) !=
779 AppListControllerDelegate::NO_PIN) {
780 base::DictionaryValue* app_value = ash::CreateAppDict(
781 controller->app_id());
782 if (app_value) {
783 if (!IsAppForUserPinned(controller->app_id(),
784 pinned_apps_pref.get(),
785 policy_pinned_apps_pref))
786 app_value->SetBoolean(ash::kPinnedAppsPrefPinnedByPolicy, true);
787 updater->Append(app_value);
788 }
789 }
790 } else if (model_->items()[i].type == ash::TYPE_BROWSER_SHORTCUT) {
791 PersistChromeItemIndex(i);
792 } else if (model_->items()[i].type == ash::TYPE_APP_LIST) {
793 base::DictionaryValue* app_value =
794 ash::CreateAppDict(ash::kPinnedAppsPlaceholder);
795 if (app_value)
796 updater->Append(app_value);
797 }
798 }
799 }
800 pref_change_registrar_.Add(
801 prefs::kPinnedLauncherApps,
802 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref,
803 base::Unretained(this)));
804 }
805
806 Profile* ChromeLauncherController::profile() { 685 Profile* ChromeLauncherController::profile() {
807 return profile_; 686 return profile_;
808 } 687 }
809 688
810 void ChromeLauncherController::UpdateAppState(content::WebContents* contents, 689 void ChromeLauncherController::UpdateAppState(content::WebContents* contents,
811 AppState app_state) { 690 AppState app_state) {
812 std::string app_id = launcher_controller_helper_->GetAppID(contents); 691 std::string app_id = launcher_controller_helper_->GetAppID(contents);
813 692
814 // Check if the gMail app is loaded and it matches the given content. 693 // Check if the gMail app is loaded and it matches the given content.
815 // This special treatment is needed to address crbug.com/234268. 694 // This special treatment is needed to address crbug.com/234268.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 798
920 window->Show(); 799 window->Show();
921 window->Activate(); 800 window->Activate();
922 return ash::ShelfItemDelegate::kExistingWindowActivated; 801 return ash::ShelfItemDelegate::kExistingWindowActivated;
923 } 802 }
924 803
925 void ChromeLauncherController::OnShelfCreated(ash::Shelf* shelf) { 804 void ChromeLauncherController::OnShelfCreated(ash::Shelf* shelf) {
926 PrefService* prefs = profile_->GetPrefs(); 805 PrefService* prefs = profile_->GetPrefs();
927 const int64_t display = GetDisplayIDForShelf(shelf); 806 const int64_t display = GetDisplayIDForShelf(shelf);
928 807
929 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref(prefs, display)); 808 shelf->SetAutoHideBehavior(
809 ash::launcher::GetShelfAutoHideBehaviorPref(prefs, display));
930 810
931 if (ash::ShelfWidget::ShelfAlignmentAllowed()) 811 if (ash::ShelfWidget::ShelfAlignmentAllowed())
932 shelf->SetAlignment(ash::GetShelfAlignmentPref(prefs, display)); 812 shelf->SetAlignment(ash::launcher::GetShelfAlignmentPref(prefs, display));
933 } 813 }
934 814
935 void ChromeLauncherController::OnShelfDestroyed(ash::Shelf* shelf) {} 815 void ChromeLauncherController::OnShelfDestroyed(ash::Shelf* shelf) {}
936 816
937 void ChromeLauncherController::OnShelfAlignmentChanged(ash::Shelf* shelf) { 817 void ChromeLauncherController::OnShelfAlignmentChanged(ash::Shelf* shelf) {
938 ash::SetShelfAlignmentPref(profile_->GetPrefs(), GetDisplayIDForShelf(shelf), 818 ash::launcher::SetShelfAlignmentPref(
939 shelf->alignment()); 819 profile_->GetPrefs(), GetDisplayIDForShelf(shelf), shelf->alignment());
940 } 820 }
941 821
942 void ChromeLauncherController::OnShelfAutoHideBehaviorChanged( 822 void ChromeLauncherController::OnShelfAutoHideBehaviorChanged(
943 ash::Shelf* shelf) { 823 ash::Shelf* shelf) {
944 ash::SetShelfAutoHideBehaviorPref(profile_->GetPrefs(), 824 ash::launcher::SetShelfAutoHideBehaviorPref(profile_->GetPrefs(),
945 GetDisplayIDForShelf(shelf), 825 GetDisplayIDForShelf(shelf),
946 shelf->auto_hide_behavior()); 826 shelf->auto_hide_behavior());
947 } 827 }
948 828
949 void ChromeLauncherController::OnShelfAutoHideStateChanged(ash::Shelf* shelf) {} 829 void ChromeLauncherController::OnShelfAutoHideStateChanged(ash::Shelf* shelf) {}
950 830
951 void ChromeLauncherController::OnShelfVisibilityStateChanged( 831 void ChromeLauncherController::OnShelfVisibilityStateChanged(
952 ash::Shelf* shelf) {} 832 ash::Shelf* shelf) {}
953 833
954 void ChromeLauncherController::ShelfItemAdded(int index) { 834 void ChromeLauncherController::ShelfItemAdded(int index) {
955 // The app list launcher can get added to the shelf after we applied the
956 // preferences. In that case the item might be at the wrong spot. As such we
957 // call the function again.
958 if (model_->items()[index].type == ash::TYPE_APP_LIST)
959 UpdateAppLaunchersFromPref();
960 } 835 }
961 836
962 void ChromeLauncherController::ShelfItemRemoved(int index, ash::ShelfID id) { 837 void ChromeLauncherController::ShelfItemRemoved(int index, ash::ShelfID id) {
963 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we 838 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we
964 // get into this state in the first place. 839 // get into this state in the first place.
965 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 840 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
966 if (iter == id_to_item_controller_map_.end()) 841 if (iter == id_to_item_controller_map_.end())
967 return; 842 return;
968 843
969 LOG(ERROR) << "Unexpected change of shelf item id: " << id; 844 LOG(ERROR) << "Unexpected change of shelf item id: " << id;
970 845
971 id_to_item_controller_map_.erase(iter); 846 id_to_item_controller_map_.erase(iter);
972 } 847 }
973 848
974 void ChromeLauncherController::ShelfItemMoved(int start_index, 849 void ChromeLauncherController::ShelfItemMoved(int start_index,
975 int target_index) { 850 int target_index) {
976 const ash::ShelfItem& item = model_->items()[target_index]; 851 const ash::ShelfItem& item = model_->items()[target_index];
977 // We remember the moved item position if it is either pinnable or 852 // We remember the moved item position if it is either pinnable or
978 // it is the app list with the alternate shelf layout. 853 // it is the app list with the alternate shelf layout.
979 if ((HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id)) || 854 DCHECK_NE(ash::TYPE_APP_LIST, item.type);
980 item.type == ash::TYPE_APP_LIST) 855 if (HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id))
981 PersistPinnedState(); 856 SyncPinPosition(item.id);
982 } 857 }
983 858
984 void ChromeLauncherController::ShelfItemChanged( 859 void ChromeLauncherController::ShelfItemChanged(
985 int index, 860 int index,
986 const ash::ShelfItem& old_item) {} 861 const ash::ShelfItem& old_item) {}
987 862
988 void ChromeLauncherController::ActiveUserChanged( 863 void ChromeLauncherController::ActiveUserChanged(
989 const std::string& user_email) { 864 const std::string& user_email) {
990 // Store the order of running applications for the user which gets inactive. 865 // Store the order of running applications for the user which gets inactive.
991 RememberUnpinnedRunningApplicationOrder(); 866 RememberUnpinnedRunningApplicationOrder();
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
1288 AccountId::FromUserEmail(user_id)); 1163 AccountId::FromUserEmail(user_id));
1289 if (other_profile == profile_) 1164 if (other_profile == profile_)
1290 return false; 1165 return false;
1291 1166
1292 // Note: The Auto hide state from preferences is not the same as the actual 1167 // Note: The Auto hide state from preferences is not the same as the actual
1293 // visibility of the shelf. Depending on all the various states (full screen, 1168 // visibility of the shelf. Depending on all the various states (full screen,
1294 // no window on desktop, multi user, ..) the shelf could be shown - or not. 1169 // no window on desktop, multi user, ..) the shelf could be shown - or not.
1295 PrefService* prefs = profile_->GetPrefs(); 1170 PrefService* prefs = profile_->GetPrefs();
1296 PrefService* other_prefs = other_profile->GetPrefs(); 1171 PrefService* other_prefs = other_profile->GetPrefs();
1297 const int64_t display = GetDisplayIDForShelf(shelf); 1172 const int64_t display = GetDisplayIDForShelf(shelf);
1298 bool currently_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER == 1173 bool currently_shown =
1299 ash::GetShelfAutoHideBehaviorPref(prefs, display); 1174 ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
1300 bool other_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER == 1175 ash::launcher::GetShelfAutoHideBehaviorPref(prefs, display);
1301 ash::GetShelfAutoHideBehaviorPref(other_prefs, display); 1176 bool other_shown =
1177 ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
1178 ash::launcher::GetShelfAutoHideBehaviorPref(other_prefs, display);
1302 1179
1303 return currently_shown != other_shown || 1180 return currently_shown != other_shown ||
1304 ash::GetShelfAlignmentPref(prefs, display) != 1181 ash::launcher::GetShelfAlignmentPref(prefs, display) !=
1305 ash::GetShelfAlignmentPref(other_prefs, display); 1182 ash::launcher::GetShelfAlignmentPref(other_prefs, display);
1306 } 1183 }
1307 1184
1308 void ChromeLauncherController::OnUserProfileReadyToSwitch(Profile* profile) { 1185 void ChromeLauncherController::OnUserProfileReadyToSwitch(Profile* profile) {
1309 if (user_switch_observer_.get()) 1186 if (user_switch_observer_.get())
1310 user_switch_observer_->OnUserProfileReadyToSwitch(profile); 1187 user_switch_observer_->OnUserProfileReadyToSwitch(profile);
1311 } 1188 }
1312 1189
1313 void ChromeLauncherController::LauncherItemClosed(ash::ShelfID id) { 1190 void ChromeLauncherController::LauncherItemClosed(ash::ShelfID id) {
1314 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 1191 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
1315 CHECK(iter != id_to_item_controller_map_.end()); 1192 CHECK(iter != id_to_item_controller_map_.end());
(...skipping 15 matching lines...) Expand all
1331 if (IsAppPinned(app_id)) 1208 if (IsAppPinned(app_id))
1332 return; 1209 return;
1333 1210
1334 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); 1211 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id);
1335 if (shelf_id) { 1212 if (shelf_id) {
1336 // App item exists, pin it 1213 // App item exists, pin it
1337 Pin(shelf_id); 1214 Pin(shelf_id);
1338 } else { 1215 } else {
1339 // Otherwise, create a shortcut item for it. 1216 // Otherwise, create a shortcut item for it.
1340 shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count()); 1217 shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count());
1341 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE) 1218 SyncPinPosition(shelf_id);
1342 PersistPinnedState();
1343 } 1219 }
1344 } 1220 }
1345 1221
1346 void ChromeLauncherController::DoUnpinAppWithID(const std::string& app_id) { 1222 void ChromeLauncherController::DoUnpinAppWithID(const std::string& app_id) {
1347 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); 1223 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id);
1348 if (shelf_id && IsPinned(shelf_id)) 1224 if (shelf_id && IsPinned(shelf_id))
1349 Unpin(shelf_id); 1225 Unpin(shelf_id);
1350 } 1226 }
1351 1227
1352 int ChromeLauncherController::PinRunningAppInternal(int index, 1228 int ChromeLauncherController::PinRunningAppInternal(int index,
(...skipping 20 matching lines...) Expand all
1373 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT); 1249 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT);
1374 item.type = ash::TYPE_WINDOWED_APP; 1250 item.type = ash::TYPE_WINDOWED_APP;
1375 // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such 1251 // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such
1376 // we have to check here what this was before it got a shortcut. 1252 // we have to check here what this was before it got a shortcut.
1377 LauncherItemController* controller = GetLauncherItemController(item.id); 1253 LauncherItemController* controller = GetLauncherItemController(item.id);
1378 if (controller && controller->type() == LauncherItemController::TYPE_APP) 1254 if (controller && controller->type() == LauncherItemController::TYPE_APP)
1379 item.type = ash::TYPE_PLATFORM_APP; 1255 item.type = ash::TYPE_PLATFORM_APP;
1380 model_->Set(index, item); 1256 model_->Set(index, item);
1381 } 1257 }
1382 1258
1259 void ChromeLauncherController::SyncPinPosition(ash::ShelfID shelf_id) {
1260 DCHECK(shelf_id);
1261 if (ignore_persist_pinned_state_change_)
1262 return;
1263
1264 const int max_index = model_->item_count();
1265 const int index = model_->ItemIndexByID(shelf_id);
1266 DCHECK_GT(index, 0);
1267
1268 const std::string& app_id = GetAppIDForShelfID(shelf_id);
1269 DCHECK(!app_id.empty());
1270
1271 std::string app_id_before;
1272 std::string app_id_after;
1273
1274 for (int i = index - 1; i > 0; --i) {
1275 const ash::ShelfID shelf_id_before = model_->items()[i].id;
1276 if (IsPinned(shelf_id_before)) {
1277 app_id_before = GetAppIDForShelfID(shelf_id_before);
1278 DCHECK(!app_id_before.empty());
1279 break;
1280 }
1281 }
1282
1283 for (int i = index + 1; i < max_index; ++i) {
1284 const ash::ShelfID shelf_id_after = model_->items()[i].id;
1285 if (IsPinned(shelf_id_after)) {
1286 app_id_after = GetAppIDForShelfID(shelf_id_after);
1287 DCHECK(!app_id_after.empty());
1288 break;
1289 }
1290 }
1291
1292 ash::launcher::SetPinPosition(profile_, app_id, app_id_before, app_id_after);
1293 }
1294
1295 void ChromeLauncherController::OnSyncModelUpdated() {
1296 UpdateAppLaunchersFromPref();
1297 }
1298
1383 void ChromeLauncherController::UpdateAppLaunchersFromPref() { 1299 void ChromeLauncherController::UpdateAppLaunchersFromPref() {
1384 // There are various functions which will trigger a |PersistPinnedState| call 1300 // There are various functions which will trigger a |SyncPinPosition| call
1385 // like a direct call to |DoPinAppWithID|, or an indirect call to the menu 1301 // like a direct call to |DoPinAppWithID|, or an indirect call to the
1386 // model which will use weights to re-arrange the icons to new positions. 1302 // menu model which will use weights to re-arrange the icons to new positions.
1387 // Since this function is meant to synchronize the "is state" with the 1303 // Since this function is meant to synchronize the "is state" with the
1388 // "sync state", it makes no sense to store any changes by this function back 1304 // "sync state", it makes no sense to store any changes by this function back
1389 // into the pref state. Therefore we tell |persistPinnedState| to ignore any 1305 // into the pref state. Therefore we tell |persistPinnedState| to ignore any
1390 // invocations while we are running. 1306 // invocations while we are running.
1391 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true); 1307 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true);
1392 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs( 1308
1309 std::vector<std::string> pinned_apps = ash::launcher::GetPinnedAppsFromPrefs(
1393 profile_->GetPrefs(), launcher_controller_helper_.get()); 1310 profile_->GetPrefs(), launcher_controller_helper_.get());
1394 1311
1395 int index = 0; 1312 int index = 0;
1396 int max_index = model_->item_count(); 1313 int max_index = model_->item_count();
1314 int seen_chrome_index = -1;
1397 1315
1398 // When one of the two special items cannot be moved (and we do not know where 1316 // At least chrome browser shortcut should exist.
1399 // yet), we remember the current location in one of these variables. 1317 DCHECK_GT(max_index, 0);
1400 int chrome_index = -1; 1318
1401 int app_list_index = -1; 1319 // Skip app list items if it exists.
1320 if (model_->items()[0].type == ash::TYPE_APP_LIST)
1321 ++index;
1402 1322
1403 // Walk the model and |pinned_apps| from the pref lockstep, adding and 1323 // Walk the model and |pinned_apps| from the pref lockstep, adding and
1404 // removing items as necessary. NB: This code uses plain old indexing instead 1324 // removing items as necessary. NB: This code uses plain old indexing instead
1405 // of iterators because of model mutations as part of the loop. 1325 // of iterators because of model mutations as part of the loop.
1406 std::vector<std::string>::const_iterator pref_app_id(pinned_apps.begin()); 1326 std::vector<std::string>::const_iterator pref_app_id(pinned_apps.begin());
1407 for (; index < max_index && pref_app_id != pinned_apps.end(); ++index) { 1327 for (; index < max_index && pref_app_id != pinned_apps.end(); ++index) {
1408 // Check if we have an item which we need to handle. 1328 // Check if we have an item which we need to handle.
1409 if (*pref_app_id == extension_misc::kChromeAppId || 1329 if (IsAppPinned(*pref_app_id)) {
1410 *pref_app_id == ash::kPinnedAppsPlaceholder || 1330 if (seen_chrome_index >= 0 &&
1411 IsAppPinned(*pref_app_id)) { 1331 *pref_app_id == extension_misc::kChromeAppId) {
1332 // Current item is Chrome browser and we saw it before.
1333 model_->Move(seen_chrome_index, index);
1334 ++pref_app_id;
1335 --index;
1336 continue;
1337 }
1412 for (; index < max_index; ++index) { 1338 for (; index < max_index; ++index) {
1413 const ash::ShelfItem& item(model_->items()[index]); 1339 const ash::ShelfItem& item(model_->items()[index]);
1414 bool is_app_list = item.type == ash::TYPE_APP_LIST; 1340 if (item.type != ash::TYPE_APP_SHORTCUT &&
1415 bool is_chrome = item.type == ash::TYPE_BROWSER_SHORTCUT; 1341 item.type != ash::TYPE_BROWSER_SHORTCUT)
1416 if (item.type != ash::TYPE_APP_SHORTCUT && !is_app_list && !is_chrome)
1417 continue; 1342 continue;
1418 LauncherItemController* controller = GetLauncherItemController(item.id); 1343 LauncherItemController* controller = GetLauncherItemController(item.id);
1419 if ((ash::kPinnedAppsPlaceholder == *pref_app_id && is_app_list) || 1344 if (controller && controller->app_id() == *pref_app_id) {
1420 (extension_misc::kChromeAppId == *pref_app_id && is_chrome) ||
1421 (controller && controller->app_id() == *pref_app_id)) {
1422 // Check if an item needs to be moved here.
1423 MoveChromeOrApplistToFinalPosition(
1424 is_chrome, is_app_list, index, &chrome_index, &app_list_index);
1425 ++pref_app_id; 1345 ++pref_app_id;
1426 break; 1346 break;
1347 } else if (item.type == ash::TYPE_BROWSER_SHORTCUT) {
1348 // We cannot close browser shortcut. Remember its position.
1349 seen_chrome_index = index;
1427 } else { 1350 } else {
1428 if (is_chrome || is_app_list) { 1351 // Check if this is a platform or a windowed app.
1429 // We cannot delete any of these shortcuts. As such we remember 1352 if (item.type == ash::TYPE_APP_SHORTCUT && controller &&
1430 // their positions and move them later where they belong. 1353 (controller->locked() ||
1431 if (is_chrome) 1354 controller->type() == LauncherItemController::TYPE_APP)) {
1432 chrome_index = index; 1355 // Note: This will not change the amount of items (|max_index|).
1433 else 1356 // Even changes to the actual |index| due to item weighting
1434 app_list_index = index; 1357 // changes should be fine.
1435 // And skip the item - or exit the loop if end is reached (note that 1358 UnpinRunningAppInternal(index);
1436 // in that case we will reduce the index again by one and this only
1437 // compensates for it).
1438 if (index >= max_index - 1)
1439 break;
1440 ++index;
1441 } else { 1359 } else {
1442 // Check if this is a platform or a windowed app. 1360 if (controller)
1443 if (item.type == ash::TYPE_APP_SHORTCUT && 1361 LauncherItemClosed(item.id);
1444 controller && 1362 --max_index;
1445 (controller->locked() ||
1446 controller->type() == LauncherItemController::TYPE_APP)) {
1447 // Note: This will not change the amount of items (|max_index|).
1448 // Even changes to the actual |index| due to item weighting
1449 // changes should be fine.
1450 UnpinRunningAppInternal(index);
1451 } else {
1452 if (controller)
1453 LauncherItemClosed(item.id);
1454 --max_index;
1455 }
1456 } 1363 }
1457 --index; 1364 --index;
1458 } 1365 }
1459 } 1366 }
1460 // If the item wasn't found, that means id_to_item_controller_map_ 1367 // If the item wasn't found, that means id_to_item_controller_map_
1461 // is out of sync. 1368 // is out of sync.
1462 DCHECK(index <= max_index); 1369 DCHECK(index <= max_index);
1463 } else { 1370 } else {
1464 // Check if the item was already running but not yet pinned. 1371 // Check if the item was already running but not yet pinned.
1465 ash::ShelfID shelf_id = GetShelfIDForAppID(*pref_app_id); 1372 ash::ShelfID shelf_id = GetShelfIDForAppID(*pref_app_id);
(...skipping 17 matching lines...) Expand all
1483 LauncherItemController* controller = GetLauncherItemController(item.id); 1390 LauncherItemController* controller = GetLauncherItemController(item.id);
1484 if (controller) { 1391 if (controller) {
1485 if (controller->locked() || 1392 if (controller->locked() ||
1486 controller->type() == LauncherItemController::TYPE_APP) { 1393 controller->type() == LauncherItemController::TYPE_APP) {
1487 UnpinRunningAppInternal(index); 1394 UnpinRunningAppInternal(index);
1488 } else { 1395 } else {
1489 LauncherItemClosed(item.id); 1396 LauncherItemClosed(item.id);
1490 } 1397 }
1491 } 1398 }
1492 } else { 1399 } else {
1493 if (item.type == ash::TYPE_BROWSER_SHORTCUT)
1494 chrome_index = index;
1495 else if (item.type == ash::TYPE_APP_LIST)
1496 app_list_index = index;
1497 ++index; 1400 ++index;
1498 } 1401 }
1499 } 1402 }
1500 1403
1501 // Append unprocessed items from the pref to the end of the model. 1404 // Append unprocessed items from the pref to the end of the model.
1502 for (; pref_app_id != pinned_apps.end(); ++pref_app_id) { 1405 for (; pref_app_id != pinned_apps.end(); ++pref_app_id) {
1503 // All items but the chrome and / or app list shortcut needs to be added. 1406 if (*pref_app_id == extension_misc::kChromeAppId) {
1504 bool is_chrome = *pref_app_id == extension_misc::kChromeAppId; 1407 int target_index = FindInsertionPoint();
1505 bool is_app_list = *pref_app_id == ash::kPinnedAppsPlaceholder; 1408 DCHECK(seen_chrome_index >= 0 && seen_chrome_index < target_index);
1506 // Coming here we know the next item which can be finalized, either the 1409 model_->Move(seen_chrome_index, target_index);
1507 // chrome item or the app launcher. The final position is the end of the 1410 } else {
1508 // list. The menu model will make sure that the item is grouped according
1509 // to its weight (which we do not know here).
1510 if (!is_chrome && !is_app_list) {
1511 DoPinAppWithID(*pref_app_id); 1411 DoPinAppWithID(*pref_app_id);
1512 int target_index = FindInsertionPoint(false); 1412 int target_index = FindInsertionPoint();
1513 ash::ShelfID id = GetShelfIDForAppID(*pref_app_id); 1413 ash::ShelfID id = GetShelfIDForAppID(*pref_app_id);
1514 int source_index = model_->ItemIndexByID(id); 1414 int source_index = model_->ItemIndexByID(id);
1515 if (source_index != target_index) 1415 if (source_index != target_index)
1516 model_->Move(source_index, target_index); 1416 model_->Move(source_index, target_index);
1517
1518 // Needed for the old layout - the weight might force it to be lower in
1519 // rank.
1520 if (app_list_index != -1 && target_index <= app_list_index)
1521 ++app_list_index;
1522 } else {
1523 int target_index = FindInsertionPoint(is_app_list);
1524 MoveChromeOrApplistToFinalPosition(
1525 is_chrome, is_app_list, target_index, &chrome_index, &app_list_index);
1526 } 1417 }
1527 } 1418 }
1528 } 1419 }
1529 1420
1530 void ChromeLauncherController::SetShelfAutoHideBehaviorFromPrefs() { 1421 void ChromeLauncherController::SetShelfAutoHideBehaviorFromPrefs() {
1531 for (auto* window : ash::Shell::GetAllRootWindows()) { 1422 for (auto* window : ash::Shell::GetAllRootWindows()) {
1532 ash::Shelf* shelf = ash::Shelf::ForWindow(window); 1423 ash::Shelf* shelf = ash::Shelf::ForWindow(window);
1533 if (shelf) { 1424 if (shelf) {
1534 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref( 1425 shelf->SetAutoHideBehavior(ash::launcher::GetShelfAutoHideBehaviorPref(
1535 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); 1426 profile_->GetPrefs(), GetDisplayIDForShelf(shelf)));
1536 } 1427 }
1537 } 1428 }
1538 } 1429 }
1539 1430
1540 void ChromeLauncherController::SetShelfAlignmentFromPrefs() { 1431 void ChromeLauncherController::SetShelfAlignmentFromPrefs() {
1541 if (!ash::ShelfWidget::ShelfAlignmentAllowed()) 1432 if (!ash::ShelfWidget::ShelfAlignmentAllowed())
1542 return; 1433 return;
1543 1434
1544 for (auto* window : ash::Shell::GetAllRootWindows()) { 1435 for (auto* window : ash::Shell::GetAllRootWindows()) {
1545 ash::Shelf* shelf = ash::Shelf::ForWindow(window); 1436 ash::Shelf* shelf = ash::Shelf::ForWindow(window);
1546 if (shelf) { 1437 if (shelf) {
1547 shelf->SetAlignment(ash::GetShelfAlignmentPref( 1438 shelf->SetAlignment(ash::launcher::GetShelfAlignmentPref(
1548 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); 1439 profile_->GetPrefs(), GetDisplayIDForShelf(shelf)));
1549 } 1440 }
1550 } 1441 }
1551 } 1442 }
1552 1443
1553 void ChromeLauncherController::SetShelfBehaviorsFromPrefs() { 1444 void ChromeLauncherController::SetShelfBehaviorsFromPrefs() {
1554 SetShelfAutoHideBehaviorFromPrefs(); 1445 SetShelfAutoHideBehaviorFromPrefs();
1555 SetShelfAlignmentFromPrefs(); 1446 SetShelfAlignmentFromPrefs();
1556 } 1447 }
1557 1448
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 << "There should be always be a BrowserShortcutLauncherItemController."; 1546 << "There should be always be a BrowserShortcutLauncherItemController.";
1656 return nullptr; 1547 return nullptr;
1657 } 1548 }
1658 1549
1659 ash::ShelfID ChromeLauncherController::CreateBrowserShortcutLauncherItem() { 1550 ash::ShelfID ChromeLauncherController::CreateBrowserShortcutLauncherItem() {
1660 ash::ShelfItem browser_shortcut; 1551 ash::ShelfItem browser_shortcut;
1661 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT; 1552 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT;
1662 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 1553 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
1663 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32); 1554 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32);
1664 ash::ShelfID id = model_->next_id(); 1555 ash::ShelfID id = model_->next_id();
1665 size_t index = GetChromeIconIndexForCreation(); 1556 model_->AddAt(0, browser_shortcut);
1666 model_->AddAt(index, browser_shortcut);
1667 id_to_item_controller_map_[id] = 1557 id_to_item_controller_map_[id] =
1668 new BrowserShortcutLauncherItemController(this, model_); 1558 new BrowserShortcutLauncherItemController(this, model_);
1669 id_to_item_controller_map_[id]->set_shelf_id(id); 1559 id_to_item_controller_map_[id]->set_shelf_id(id);
1670 // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController. 1560 // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController.
1671 SetShelfItemDelegate(id, id_to_item_controller_map_[id]); 1561 SetShelfItemDelegate(id, id_to_item_controller_map_[id]);
1672 return id; 1562 return id;
1673 } 1563 }
1674 1564
1675 void ChromeLauncherController::PersistChromeItemIndex(int index) { 1565 int ChromeLauncherController::FindInsertionPoint() {
1676 profile_->GetPrefs()->SetInteger(prefs::kShelfChromeIconIndex, index); 1566 DCHECK_GT(model_->item_count(), 0);
1677 }
1678
1679 void ChromeLauncherController::MoveChromeOrApplistToFinalPosition(
1680 bool is_chrome,
1681 bool is_app_list,
1682 int target_index,
1683 int* chrome_index,
1684 int* app_list_index) {
1685 if (is_chrome && *chrome_index != -1) {
1686 model_->Move(*chrome_index, target_index);
1687 if (*app_list_index != -1 &&
1688 *chrome_index < *app_list_index &&
1689 target_index > *app_list_index)
1690 --(*app_list_index);
1691 *chrome_index = -1;
1692 } else if (is_app_list && *app_list_index != -1) {
1693 model_->Move(*app_list_index, target_index);
1694 if (*chrome_index != -1 &&
1695 *app_list_index < *chrome_index &&
1696 target_index > *chrome_index)
1697 --(*chrome_index);
1698 *app_list_index = -1;
1699 }
1700 }
1701
1702 int ChromeLauncherController::FindInsertionPoint(bool is_app_list) {
1703 // Keeping this change small to backport to M33&32 (see crbug.com/329597).
1704 // TODO(skuhne): With the removal of the legacy shelf layout we should remove
1705 // the ability to move the app list item since this was never used. We should
1706 // instead ask the ShelfModel::ValidateInsertionIndex or similir for an index.
1707 if (is_app_list)
1708 return 0;
1709 1567
1710 for (int i = model_->item_count() - 1; i > 0; --i) { 1568 for (int i = model_->item_count() - 1; i > 0; --i) {
1711 ash::ShelfItemType type = model_->items()[i].type; 1569 ash::ShelfItemType type = model_->items()[i].type;
1570 DCHECK_NE(ash::TYPE_APP_LIST, type);
1712 if (type == ash::TYPE_APP_SHORTCUT || 1571 if (type == ash::TYPE_APP_SHORTCUT ||
1713 (is_app_list && type == ash::TYPE_APP_LIST) ||
1714 type == ash::TYPE_BROWSER_SHORTCUT) { 1572 type == ash::TYPE_BROWSER_SHORTCUT) {
1715 return i; 1573 return i;
1716 } 1574 }
1717 } 1575 }
1718 return 0; 1576 return 0;
1719 } 1577 }
1720 1578
1721 int ChromeLauncherController::GetChromeIconIndexForCreation() {
1722 // We get the list of pinned apps as they currently would get pinned.
1723 // Within this list the chrome icon will be the correct location.
1724 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs(
1725 profile_->GetPrefs(), launcher_controller_helper_.get());
1726
1727 std::vector<std::string>::iterator it =
1728 std::find(pinned_apps.begin(),
1729 pinned_apps.end(),
1730 std::string(extension_misc::kChromeAppId));
1731 DCHECK(it != pinned_apps.end());
1732 int index = it - pinned_apps.begin();
1733
1734 // We should do here a comparison between the is state and the "want to be"
1735 // state since some apps might be able to pin but are not yet. Instead - for
1736 // the time being we clamp against the amount of known items and wait for the
1737 // next |UpdateAppLaunchersFromPref()| call to correct it - it will come since
1738 // the pinning will be done then.
1739 return std::min(model_->item_count(), index);
1740 }
1741
1742 bool ChromeLauncherController::IsIncognito( 1579 bool ChromeLauncherController::IsIncognito(
1743 const content::WebContents* web_contents) const { 1580 const content::WebContents* web_contents) const {
1744 const Profile* profile = 1581 const Profile* profile =
1745 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 1582 Profile::FromBrowserContext(web_contents->GetBrowserContext());
1746 return profile->IsOffTheRecord() && !profile->IsGuestSession() && 1583 return profile->IsOffTheRecord() && !profile->IsGuestSession() &&
1747 !profile->IsSystemProfile(); 1584 !profile->IsSystemProfile();
1748 } 1585 }
1749 1586
1750 void ChromeLauncherController::CloseWindowedAppsFromRemovedExtension( 1587 void ChromeLauncherController::CloseWindowedAppsFromRemovedExtension(
1751 const std::string& app_id, 1588 const std::string& app_id,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1804 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { 1641 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) {
1805 DCHECK(arc_deferred_launcher()); 1642 DCHECK(arc_deferred_launcher());
1806 std::unique_ptr<AppIconLoader> arc_app_icon_loader( 1643 std::unique_ptr<AppIconLoader> arc_app_icon_loader(
1807 new ArcAppIconLoader(profile_, extension_misc::EXTENSION_ICON_SMALL, 1644 new ArcAppIconLoader(profile_, extension_misc::EXTENSION_ICON_SMALL,
1808 arc_deferred_launcher(), this)); 1645 arc_deferred_launcher(), this));
1809 app_icon_loaders_.push_back(std::move(arc_app_icon_loader)); 1646 app_icon_loaders_.push_back(std::move(arc_app_icon_loader));
1810 } 1647 }
1811 1648
1812 pref_change_registrar_.Init(profile_->GetPrefs()); 1649 pref_change_registrar_.Init(profile_->GetPrefs());
1813 pref_change_registrar_.Add( 1650 pref_change_registrar_.Add(
1814 prefs::kPinnedLauncherApps,
1815 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref,
1816 base::Unretained(this)));
1817 pref_change_registrar_.Add(
1818 prefs::kPolicyPinnedLauncherApps, 1651 prefs::kPolicyPinnedLauncherApps,
1819 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, 1652 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref,
1820 base::Unretained(this))); 1653 base::Unretained(this)));
1821 pref_change_registrar_.Add( 1654 pref_change_registrar_.Add(
1822 prefs::kShelfAlignmentLocal, 1655 prefs::kShelfAlignmentLocal,
1823 base::Bind(&ChromeLauncherController::SetShelfAlignmentFromPrefs, 1656 base::Bind(&ChromeLauncherController::SetShelfAlignmentFromPrefs,
1824 base::Unretained(this))); 1657 base::Unretained(this)));
1825 pref_change_registrar_.Add( 1658 pref_change_registrar_.Add(
1826 prefs::kShelfAutoHideBehaviorLocal, 1659 prefs::kShelfAutoHideBehaviorLocal,
1827 base::Bind(&ChromeLauncherController:: 1660 base::Bind(&ChromeLauncherController::
(...skipping 10 matching lines...) Expand all
1838 1671
1839 std::unique_ptr<LauncherAppUpdater> extension_app_updater( 1672 std::unique_ptr<LauncherAppUpdater> extension_app_updater(
1840 new LauncherExtensionAppUpdater(this, profile_)); 1673 new LauncherExtensionAppUpdater(this, profile_));
1841 app_updaters_.push_back(std::move(extension_app_updater)); 1674 app_updaters_.push_back(std::move(extension_app_updater));
1842 1675
1843 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { 1676 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) {
1844 std::unique_ptr<LauncherAppUpdater> arc_app_updater( 1677 std::unique_ptr<LauncherAppUpdater> arc_app_updater(
1845 new LauncherArcAppUpdater(this, profile_)); 1678 new LauncherArcAppUpdater(this, profile_));
1846 app_updaters_.push_back(std::move(arc_app_updater)); 1679 app_updaters_.push_back(std::move(arc_app_updater));
1847 } 1680 }
1681
1682 app_list::AppListSyncableService* app_service =
1683 app_list::AppListSyncableServiceFactory::GetForProfile(profile_);
1684 if (app_service)
1685 app_service->AddObserverAndStart(this);
1848 } 1686 }
1849 1687
1850 void ChromeLauncherController::ReleaseProfile() { 1688 void ChromeLauncherController::ReleaseProfile() {
1851 if (app_sync_ui_state_) 1689 if (app_sync_ui_state_)
1852 app_sync_ui_state_->RemoveObserver(this); 1690 app_sync_ui_state_->RemoveObserver(this);
1853 1691
1854 app_updaters_.clear(); 1692 app_updaters_.clear();
1855 1693
1856 prefs_observer_.reset(); 1694 prefs_observer_.reset();
1857 1695
1858 pref_change_registrar_.RemoveAll(); 1696 pref_change_registrar_.RemoveAll();
1697
1698 app_list::AppListSyncableService* app_service =
1699 app_list::AppListSyncableServiceFactory::GetForProfile(profile_);
1700 if (app_service)
1701 app_service->RemoveObserver(this);
1859 } 1702 }
1860 1703
1861 AppIconLoader* ChromeLauncherController::GetAppIconLoaderForApp( 1704 AppIconLoader* ChromeLauncherController::GetAppIconLoaderForApp(
1862 const std::string& app_id) { 1705 const std::string& app_id) {
1863 for (const auto& app_icon_loader : app_icon_loaders_) { 1706 for (const auto& app_icon_loader : app_icon_loaders_) {
1864 if (app_icon_loader->CanLoadImageForApp(app_id)) 1707 if (app_icon_loader->CanLoadImageForApp(app_id))
1865 return app_icon_loader.get(); 1708 return app_icon_loader.get();
1866 } 1709 }
1867 1710
1868 return nullptr; 1711 return nullptr;
1869 } 1712 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698