OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/chrome_launcher_prefs.h" | 5 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <set> | 9 #include <set> |
10 | 10 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 } | 230 } |
231 | 231 |
232 void AddApp(const AppLauncherId& app_launcher_id) { | 232 void AddApp(const AppLauncherId& app_launcher_id) { |
233 if (HasApp(app_launcher_id)) | 233 if (HasApp(app_launcher_id)) |
234 return; | 234 return; |
235 app_list_.push_back(app_launcher_id); | 235 app_list_.push_back(app_launcher_id); |
236 app_set_.insert(app_launcher_id); | 236 app_set_.insert(app_launcher_id); |
237 } | 237 } |
238 | 238 |
239 void MaybeAddApp(const AppLauncherId& app_launcher_id, | 239 void MaybeAddApp(const AppLauncherId& app_launcher_id, |
240 const LauncherControllerHelper* helper) { | 240 const LauncherControllerHelper* helper, |
| 241 bool check_for_valid_app) { |
241 DCHECK_NE(kPinnedAppsPlaceholder, app_launcher_id.ToString()); | 242 DCHECK_NE(kPinnedAppsPlaceholder, app_launcher_id.ToString()); |
242 if (!helper->IsValidIDForCurrentUser(app_launcher_id.ToString())) | 243 if (check_for_valid_app && |
| 244 !helper->IsValidIDForCurrentUser(app_launcher_id.ToString())) { |
243 return; | 245 return; |
| 246 } |
244 AddApp(app_launcher_id); | 247 AddApp(app_launcher_id); |
245 } | 248 } |
246 | 249 |
247 void MaybeAddAppFromPref(const base::DictionaryValue* app_pref, | 250 void MaybeAddAppFromPref(const base::DictionaryValue* app_pref, |
248 const LauncherControllerHelper* helper) { | 251 const LauncherControllerHelper* helper, |
| 252 bool check_for_valid_app) { |
249 std::string app_id; | 253 std::string app_id; |
250 if (!app_pref->GetString(kPinnedAppsPrefAppIDPath, &app_id)) { | 254 if (!app_pref->GetString(kPinnedAppsPrefAppIDPath, &app_id)) { |
251 LOG(ERROR) << "Cannot get app id from app pref entry."; | 255 LOG(ERROR) << "Cannot get app id from app pref entry."; |
252 return; | 256 return; |
253 } | 257 } |
254 | 258 |
255 if (app_id == kPinnedAppsPlaceholder) | 259 if (app_id == kPinnedAppsPlaceholder) |
256 return; | 260 return; |
257 | 261 |
258 bool pinned_by_policy = false; | 262 bool pinned_by_policy = false; |
259 if (app_pref->GetBoolean(kPinnedAppsPrefPinnedByPolicy, | 263 if (app_pref->GetBoolean(kPinnedAppsPrefPinnedByPolicy, |
260 &pinned_by_policy) && | 264 &pinned_by_policy) && |
261 pinned_by_policy) { | 265 pinned_by_policy) { |
262 return; | 266 return; |
263 } | 267 } |
264 | 268 |
265 MaybeAddApp(AppLauncherId(app_id), helper); | 269 MaybeAddApp(AppLauncherId(app_id), helper, check_for_valid_app); |
266 } | 270 } |
267 | 271 |
268 const std::vector<AppLauncherId>& app_list() const { return app_list_; } | 272 const std::vector<AppLauncherId>& app_list() const { return app_list_; } |
269 | 273 |
270 private: | 274 private: |
271 std::vector<AppLauncherId> app_list_; | 275 std::vector<AppLauncherId> app_list_; |
272 std::set<AppLauncherId> app_set_; | 276 std::set<AppLauncherId> app_set_; |
273 }; | 277 }; |
274 | 278 |
275 } // namespace | 279 } // namespace |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 if (display_id == display::Screen::GetScreen()->GetPrimaryDisplay().id()) { | 396 if (display_id == display::Screen::GetScreen()->GetPrimaryDisplay().id()) { |
393 // See comment in |kShelfAlignment| as to why we consider two prefs. | 397 // See comment in |kShelfAlignment| as to why we consider two prefs. |
394 prefs->SetString(prefs::kShelfAlignmentLocal, value); | 398 prefs->SetString(prefs::kShelfAlignmentLocal, value); |
395 prefs->SetString(prefs::kShelfAlignment, value); | 399 prefs->SetString(prefs::kShelfAlignment, value); |
396 } | 400 } |
397 } | 401 } |
398 | 402 |
399 // Helper that extracts app list from policy preferences. | 403 // Helper that extracts app list from policy preferences. |
400 void GetAppsPinnedByPolicy(const PrefService* prefs, | 404 void GetAppsPinnedByPolicy(const PrefService* prefs, |
401 const LauncherControllerHelper* helper, | 405 const LauncherControllerHelper* helper, |
| 406 bool check_for_valid_app, |
402 AppTracker* apps) { | 407 AppTracker* apps) { |
403 DCHECK(apps); | 408 DCHECK(apps); |
404 DCHECK(apps->app_list().empty()); | 409 DCHECK(apps->app_list().empty()); |
405 | 410 |
406 const auto* policy_apps = prefs->GetList(prefs::kPolicyPinnedLauncherApps); | 411 const auto* policy_apps = prefs->GetList(prefs::kPolicyPinnedLauncherApps); |
407 if (!policy_apps) | 412 if (!policy_apps) |
408 return; | 413 return; |
409 | 414 |
410 // Obtain here all ids of ARC apps because it takes linear time, and getting | 415 // Obtain here all ids of ARC apps because it takes linear time, and getting |
411 // them in the loop bellow would lead to quadratic complexity. | 416 // them in the loop bellow would lead to quadratic complexity. |
(...skipping 14 matching lines...) Expand all Loading... |
426 if (!arc_app_list_pref) | 431 if (!arc_app_list_pref) |
427 continue; | 432 continue; |
428 | 433 |
429 // We are dealing with package name, not with 32 characters ID. | 434 // We are dealing with package name, not with 32 characters ID. |
430 const std::string& arc_package = app_id; | 435 const std::string& arc_package = app_id; |
431 const std::vector<std::string> activities = GetActivitiesForPackage( | 436 const std::vector<std::string> activities = GetActivitiesForPackage( |
432 arc_package, all_arc_app_ids, *arc_app_list_pref); | 437 arc_package, all_arc_app_ids, *arc_app_list_pref); |
433 for (const auto& activity : activities) { | 438 for (const auto& activity : activities) { |
434 const std::string arc_app_id = | 439 const std::string arc_app_id = |
435 ArcAppListPrefs::GetAppId(arc_package, activity); | 440 ArcAppListPrefs::GetAppId(arc_package, activity); |
436 apps->MaybeAddApp(AppLauncherId(arc_app_id), helper); | 441 apps->MaybeAddApp(AppLauncherId(arc_app_id), helper, |
| 442 check_for_valid_app); |
437 } | 443 } |
438 } else { | 444 } else { |
439 apps->MaybeAddApp(AppLauncherId(app_id), helper); | 445 apps->MaybeAddApp(AppLauncherId(app_id), helper, check_for_valid_app); |
440 } | 446 } |
441 } | 447 } |
442 } | 448 } |
443 | 449 |
444 std::vector<AppLauncherId> GetPinnedAppsFromPrefsLegacy( | 450 std::vector<AppLauncherId> GetPinnedAppsFromPrefsLegacy( |
445 const PrefService* prefs, | 451 const PrefService* prefs, |
446 const LauncherControllerHelper* helper) { | 452 const LauncherControllerHelper* helper, |
| 453 bool check_for_valid_app) { |
447 // Adding the app list item to the list of items requires that the ID is not | 454 // Adding the app list item to the list of items requires that the ID is not |
448 // a valid and known ID for the extension system. The ID was constructed that | 455 // a valid and known ID for the extension system. The ID was constructed that |
449 // way - but just to make sure... | 456 // way - but just to make sure... |
450 DCHECK(!helper->IsValidIDForCurrentUser(kPinnedAppsPlaceholder)); | 457 DCHECK(!helper->IsValidIDForCurrentUser(kPinnedAppsPlaceholder)); |
451 | 458 |
452 const auto* pinned_apps = prefs->GetList(prefs::kPinnedLauncherApps); | 459 const auto* pinned_apps = prefs->GetList(prefs::kPinnedLauncherApps); |
453 | 460 |
454 // Get the sanitized preference value for the index of the Chrome app icon. | 461 // Get the sanitized preference value for the index of the Chrome app icon. |
455 const size_t chrome_icon_index = std::max<size_t>( | 462 const size_t chrome_icon_index = std::max<size_t>( |
456 0, std::min<size_t>(pinned_apps->GetSize(), | 463 0, std::min<size_t>(pinned_apps->GetSize(), |
457 prefs->GetInteger(prefs::kShelfChromeIconIndex))); | 464 prefs->GetInteger(prefs::kShelfChromeIconIndex))); |
458 | 465 |
459 // Check if Chrome is in either of the the preferences lists. | 466 // Check if Chrome is in either of the the preferences lists. |
460 std::unique_ptr<base::Value> chrome_app( | 467 std::unique_ptr<base::Value> chrome_app( |
461 CreateAppDict(AppLauncherId(extension_misc::kChromeAppId))); | 468 CreateAppDict(AppLauncherId(extension_misc::kChromeAppId))); |
462 | 469 |
463 AppTracker apps; | 470 AppTracker apps; |
464 GetAppsPinnedByPolicy(prefs, helper, &apps); | 471 GetAppsPinnedByPolicy(prefs, helper, check_for_valid_app, &apps); |
465 | 472 |
466 std::string app_id; | 473 std::string app_id; |
467 for (size_t i = 0; i < pinned_apps->GetSize(); ++i) { | 474 for (size_t i = 0; i < pinned_apps->GetSize(); ++i) { |
468 // We need to position the chrome icon relative to its place in the pinned | 475 // We need to position the chrome icon relative to its place in the pinned |
469 // preference list - even if an item of that list isn't shown yet. | 476 // preference list - even if an item of that list isn't shown yet. |
470 if (i == chrome_icon_index) | 477 if (i == chrome_icon_index) |
471 apps.AddApp(AppLauncherId(extension_misc::kChromeAppId)); | 478 apps.AddApp(AppLauncherId(extension_misc::kChromeAppId)); |
472 const base::DictionaryValue* app_pref = nullptr; | 479 const base::DictionaryValue* app_pref = nullptr; |
473 if (!pinned_apps->GetDictionary(i, &app_pref)) { | 480 if (!pinned_apps->GetDictionary(i, &app_pref)) { |
474 LOG(ERROR) << "There is no dictionary for app entry."; | 481 LOG(ERROR) << "There is no dictionary for app entry."; |
475 continue; | 482 continue; |
476 } | 483 } |
477 apps.MaybeAddAppFromPref(app_pref, helper); | 484 apps.MaybeAddAppFromPref(app_pref, helper, check_for_valid_app); |
478 } | 485 } |
479 | 486 |
480 // If not added yet, the chrome item will be the last item in the list. | 487 // If not added yet, the chrome item will be the last item in the list. |
481 apps.AddApp(AppLauncherId(extension_misc::kChromeAppId)); | 488 apps.AddApp(AppLauncherId(extension_misc::kChromeAppId)); |
482 return apps.app_list(); | 489 return apps.app_list(); |
483 } | 490 } |
484 | 491 |
485 // static | 492 // static |
486 std::unique_ptr<ChromeLauncherPrefsObserver> | 493 std::unique_ptr<ChromeLauncherPrefsObserver> |
487 ChromeLauncherPrefsObserver::CreateIfNecessary(Profile* profile) { | 494 ChromeLauncherPrefsObserver::CreateIfNecessary(Profile* profile) { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 position = sync_peer.second->item_pin_ordinal; | 559 position = sync_peer.second->item_pin_ordinal; |
553 } | 560 } |
554 } | 561 } |
555 | 562 |
556 return position.IsValid() ? position.CreateAfter() | 563 return position.IsValid() ? position.CreateAfter() |
557 : syncer::StringOrdinal::CreateInitialOrdinal(); | 564 : syncer::StringOrdinal::CreateInitialOrdinal(); |
558 } | 565 } |
559 | 566 |
560 std::vector<AppLauncherId> ImportLegacyPinnedApps( | 567 std::vector<AppLauncherId> ImportLegacyPinnedApps( |
561 const PrefService* prefs, | 568 const PrefService* prefs, |
562 LauncherControllerHelper* helper, | 569 LauncherControllerHelper* helper) { |
563 const AppTracker& policy_apps) { | 570 std::vector<AppLauncherId> legacy_pins_all = |
564 std::vector<AppLauncherId> legacy_pins = | 571 GetPinnedAppsFromPrefsLegacy(prefs, helper, false); |
565 GetPinnedAppsFromPrefsLegacy(prefs, helper); | 572 DCHECK(!legacy_pins_all.empty()); |
566 DCHECK(!legacy_pins.empty()); | |
567 | 573 |
568 app_list::AppListSyncableService* app_service = | 574 app_list::AppListSyncableService* app_service = |
569 app_list::AppListSyncableServiceFactory::GetForProfile(helper->profile()); | 575 app_list::AppListSyncableServiceFactory::GetForProfile(helper->profile()); |
570 | 576 |
| 577 std::vector<AppLauncherId> legacy_pins_valid; |
571 syncer::StringOrdinal last_position = | 578 syncer::StringOrdinal last_position = |
572 syncer::StringOrdinal::CreateInitialOrdinal(); | 579 syncer::StringOrdinal::CreateInitialOrdinal(); |
573 // Convert to sync item record. | 580 // Convert to sync item record. |
574 for (const auto& app_launcher_id : legacy_pins) { | 581 for (const auto& app_launcher_id : legacy_pins_all) { |
575 DCHECK_NE(kPinnedAppsPlaceholder, app_launcher_id.ToString()); | 582 DCHECK_NE(kPinnedAppsPlaceholder, app_launcher_id.ToString()); |
576 app_service->SetPinPosition(app_launcher_id.ToString(), last_position); | 583 app_service->SetPinPosition(app_launcher_id.ToString(), last_position); |
577 last_position = last_position.CreateAfter(); | 584 last_position = last_position.CreateAfter(); |
| 585 if (helper->IsValidIDForCurrentUser(app_launcher_id.ToString())) |
| 586 legacy_pins_valid.push_back(app_launcher_id); |
578 } | 587 } |
579 | 588 |
580 // Now process default apps. | 589 // Now process default apps. |
581 for (size_t i = 0; i < arraysize(kDefaultPinnedApps); ++i) { | 590 for (size_t i = 0; i < arraysize(kDefaultPinnedApps); ++i) { |
582 const std::string& app_id = kDefaultPinnedApps[i]; | 591 const std::string& app_id = kDefaultPinnedApps[i]; |
583 // Check if it is already imported. | 592 // Check if it is already imported. |
584 if (app_service->GetPinPosition(app_id).IsValid()) | 593 if (app_service->GetPinPosition(app_id).IsValid()) |
585 continue; | 594 continue; |
586 // Check if it is present but not in legacy pin. | 595 // Check if it is present but not in legacy pin. |
587 if (helper->IsValidIDForCurrentUser(app_id)) | 596 if (helper->IsValidIDForCurrentUser(app_id)) |
588 continue; | 597 continue; |
589 app_service->SetPinPosition(app_id, last_position); | 598 app_service->SetPinPosition(app_id, last_position); |
590 last_position = last_position.CreateAfter(); | 599 last_position = last_position.CreateAfter(); |
591 } | 600 } |
592 | 601 |
593 return legacy_pins; | 602 return legacy_pins_valid; |
594 } | 603 } |
595 | 604 |
596 std::vector<AppLauncherId> GetPinnedAppsFromPrefs( | 605 std::vector<AppLauncherId> GetPinnedAppsFromPrefs( |
597 const PrefService* prefs, | 606 const PrefService* prefs, |
598 LauncherControllerHelper* helper) { | 607 LauncherControllerHelper* helper) { |
599 app_list::AppListSyncableService* app_service = | 608 app_list::AppListSyncableService* app_service = |
600 app_list::AppListSyncableServiceFactory::GetForProfile(helper->profile()); | 609 app_list::AppListSyncableServiceFactory::GetForProfile(helper->profile()); |
601 // Some unit tests may not have it or service may not be initialized. | 610 // Some unit tests may not have it or service may not be initialized. |
602 if (!app_service || !app_service->IsInitialized()) | 611 if (!app_service || !app_service->IsInitialized()) |
603 return std::vector<AppLauncherId>(); | 612 return std::vector<AppLauncherId>(); |
604 | 613 |
605 std::vector<PinInfo> pin_infos; | 614 std::vector<PinInfo> pin_infos; |
606 | 615 |
607 AppTracker policy_apps; | |
608 GetAppsPinnedByPolicy(prefs, helper, &policy_apps); | |
609 | |
610 // Empty pins indicates that sync based pin model is used for the first | 616 // Empty pins indicates that sync based pin model is used for the first |
611 // time. In normal workflow we have at least Chrome browser pin info. | 617 // time. In normal workflow we have at least Chrome browser pin info. |
612 bool first_run = true; | 618 bool first_run = true; |
613 | 619 |
614 for (const auto& sync_peer : app_service->sync_items()) { | 620 for (const auto& sync_peer : app_service->sync_items()) { |
615 if (!sync_peer.second->item_pin_ordinal.IsValid()) | 621 if (!sync_peer.second->item_pin_ordinal.IsValid()) |
616 continue; | 622 continue; |
617 | 623 |
618 first_run = false; | 624 first_run = false; |
619 // Don't include apps that currently do not exist on device. | 625 // Don't include apps that currently do not exist on device. |
620 if (sync_peer.first != extension_misc::kChromeAppId && | 626 if (sync_peer.first != extension_misc::kChromeAppId && |
621 !helper->IsValidIDForCurrentUser(sync_peer.first)) { | 627 !helper->IsValidIDForCurrentUser(sync_peer.first)) { |
622 continue; | 628 continue; |
623 } | 629 } |
624 | 630 |
625 pin_infos.push_back(PinInfo(AppLauncherId(sync_peer.first), | 631 pin_infos.push_back(PinInfo(AppLauncherId(sync_peer.first), |
626 sync_peer.second->item_pin_ordinal)); | 632 sync_peer.second->item_pin_ordinal)); |
627 } | 633 } |
628 | 634 |
629 if (first_run) { | 635 if (first_run) { |
| 636 // Return default apps in case profile is not synced yet. |
| 637 sync_preferences::PrefServiceSyncable* const pref_service_syncable = |
| 638 PrefServiceSyncableFromProfile(helper->profile()); |
| 639 if (!pref_service_syncable->IsSyncing()) |
| 640 return GetPinnedAppsFromPrefsLegacy(prefs, helper, true); |
| 641 |
630 // We need to import legacy pins model and convert it to sync based | 642 // We need to import legacy pins model and convert it to sync based |
631 // model. | 643 // model. |
632 return ImportLegacyPinnedApps(prefs, helper, policy_apps); | 644 return ImportLegacyPinnedApps(prefs, helper); |
633 } | 645 } |
634 | 646 |
635 // Sort pins according their ordinals. | 647 // Sort pins according their ordinals. |
636 std::sort(pin_infos.begin(), pin_infos.end(), ComparePinInfo()); | 648 std::sort(pin_infos.begin(), pin_infos.end(), ComparePinInfo()); |
637 | 649 |
| 650 AppTracker policy_apps; |
| 651 GetAppsPinnedByPolicy(prefs, helper, true, &policy_apps); |
| 652 |
638 // Pinned by policy apps appear first, if they were not shown before. | 653 // Pinned by policy apps appear first, if they were not shown before. |
639 syncer::StringOrdinal front_position = GetFirstPinPosition(helper->profile()); | 654 syncer::StringOrdinal front_position = GetFirstPinPosition(helper->profile()); |
640 std::vector<AppLauncherId>::const_reverse_iterator it; | 655 std::vector<AppLauncherId>::const_reverse_iterator it; |
641 for (it = policy_apps.app_list().rbegin(); | 656 for (it = policy_apps.app_list().rbegin(); |
642 it != policy_apps.app_list().rend(); ++it) { | 657 it != policy_apps.app_list().rend(); ++it) { |
643 const std::string& app_launcher_id_str = (*it).ToString(); | 658 const std::string& app_launcher_id_str = (*it).ToString(); |
644 if (app_launcher_id_str == kPinnedAppsPlaceholder) | 659 if (app_launcher_id_str == kPinnedAppsPlaceholder) |
645 continue; | 660 continue; |
646 | 661 |
647 // Check if we already processed current app. | 662 // Check if we already processed current app. |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 pin_position = position_before.CreateAfter(); | 754 pin_position = position_before.CreateAfter(); |
740 else if (position_after.IsValid()) | 755 else if (position_after.IsValid()) |
741 pin_position = position_after.CreateBefore(); | 756 pin_position = position_after.CreateBefore(); |
742 else | 757 else |
743 pin_position = syncer::StringOrdinal::CreateInitialOrdinal(); | 758 pin_position = syncer::StringOrdinal::CreateInitialOrdinal(); |
744 app_service->SetPinPosition(app_launcher_id_str, pin_position); | 759 app_service->SetPinPosition(app_launcher_id_str, pin_position); |
745 } | 760 } |
746 | 761 |
747 } // namespace launcher | 762 } // namespace launcher |
748 } // namespace ash | 763 } // namespace ash |
OLD | NEW |