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