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

Side by Side Diff: chrome/browser/ui/ash/chrome_launcher_prefs.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: cleanup and update 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 (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 <memory> 9 #include <memory>
10 10
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/values.h" 13 #include "base/values.h"
14 #include "chrome/browser/app_mode/app_mode_utils.h" 14 #include "chrome/browser/app_mode/app_mode_utils.h"
15 #include "chrome/browser/chromeos/arc/arc_auth_service.h" 15 #include "chrome/browser/chromeos/arc/arc_auth_service.h"
16 #include "chrome/browser/chromeos/arc/arc_support_host.h" 16 #include "chrome/browser/chromeos/arc/arc_support_host.h"
17 #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
17 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" 18 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
18 #include "chrome/browser/ui/ash/launcher/launcher_controller_helper.h" 19 #include "chrome/browser/ui/ash/launcher/launcher_controller_helper.h"
19 #include "chrome/common/extensions/extension_constants.h" 20 #include "chrome/common/extensions/extension_constants.h"
20 #include "chrome/common/pref_names.h" 21 #include "chrome/common/pref_names.h"
21 #include "components/pref_registry/pref_registry_syncable.h" 22 #include "components/pref_registry/pref_registry_syncable.h"
22 #include "components/prefs/pref_service.h" 23 #include "components/prefs/pref_service.h"
23 #include "components/prefs/scoped_user_pref_update.h" 24 #include "components/prefs/scoped_user_pref_update.h"
25 #include "sync/api/string_ordinal.h"
24 #include "ui/display/display.h" 26 #include "ui/display/display.h"
25 #include "ui/display/screen.h" 27 #include "ui/display/screen.h"
26 28
27 namespace ash { 29 namespace ash {
28 30
29 namespace { 31 namespace {
30 32
31 // App ID of default pinned apps. 33 // App ID of default pinned apps.
32 const char* kDefaultPinnedApps[] = { 34 const char* kDefaultPinnedApps[] = {
33 extension_misc::kGmailAppId, 35 extension_misc::kGmailAppId,
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 for (const std::string& app_id : all_arc_app_ids) { 186 for (const std::string& app_id : all_arc_app_ids) {
185 const std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = 187 const std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
186 app_list_pref.GetApp(app_id); 188 app_list_pref.GetApp(app_id);
187 if (app_info->package_name == package) { 189 if (app_info->package_name == package) {
188 activities.push_back(app_info->activity); 190 activities.push_back(app_info->activity);
189 } 191 }
190 } 192 }
191 return activities; 193 return activities;
192 } 194 }
193 195
196 struct PinInfo {
197 PinInfo(const std::string& app_id, const syncer::StringOrdinal& item_ordinal)
198 : app_id(app_id), item_ordinal(item_ordinal) {}
199
200 std::string app_id;
201 syncer::StringOrdinal item_ordinal;
202 };
203
204 struct ComparePinInfo {
205 bool operator()(const PinInfo& pin1, const PinInfo& pin2) {
206 return pin1.item_ordinal.LessThan(pin2.item_ordinal);
207 }
208 };
209
194 } // namespace 210 } // namespace
195 211
196 const char kPinnedAppsPrefAppIDPath[] = "id"; 212 const char kPinnedAppsPrefAppIDPath[] = "id";
197 const char kPinnedAppsPrefPinnedByPolicy[] = "pinned_by_policy"; 213 const char kPinnedAppsPrefPinnedByPolicy[] = "pinned_by_policy";
198 const char kPinnedAppsPlaceholder[] = "AppShelfIDPlaceholder--------"; 214 const char kPinnedAppsPlaceholder[] = "AppShelfIDPlaceholder--------";
199 215
200 const char kShelfAutoHideBehaviorAlways[] = "Always"; 216 const char kShelfAutoHideBehaviorAlways[] = "Always";
201 const char kShelfAutoHideBehaviorNever[] = "Never"; 217 const char kShelfAutoHideBehaviorNever[] = "Never";
202 218
203 const char kShelfAlignmentBottom[] = "Bottom"; 219 const char kShelfAlignmentBottom[] = "Bottom";
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 return; 301 return;
286 302
287 SetPerDisplayPref(prefs, display_id, prefs::kShelfAlignment, value); 303 SetPerDisplayPref(prefs, display_id, prefs::kShelfAlignment, value);
288 if (display_id == display::Screen::GetScreen()->GetPrimaryDisplay().id()) { 304 if (display_id == display::Screen::GetScreen()->GetPrimaryDisplay().id()) {
289 // See comment in |kShelfAlignment| as to why we consider two prefs. 305 // See comment in |kShelfAlignment| as to why we consider two prefs.
290 prefs->SetString(prefs::kShelfAlignmentLocal, value); 306 prefs->SetString(prefs::kShelfAlignmentLocal, value);
291 prefs->SetString(prefs::kShelfAlignment, value); 307 prefs->SetString(prefs::kShelfAlignment, value);
292 } 308 }
293 } 309 }
294 310
295 std::vector<std::string> GetPinnedAppsFromPrefs( 311 // Helper that extracts app list from policy preferences.
312 std::vector<std::string> GetAppsPinnedByPolicy(
296 const PrefService* prefs, 313 const PrefService* prefs,
297 const LauncherControllerHelper* helper) { 314 const LauncherControllerHelper* helper) {
298 // Adding the app list item to the list of items requires that the ID is not
299 // a valid and known ID for the extension system. The ID was constructed that
300 // way - but just to make sure...
301 DCHECK(!helper->IsValidIDForCurrentUser(kPinnedAppsPlaceholder));
302
303 std::vector<std::string> apps; 315 std::vector<std::string> apps;
304 const auto* pinned = prefs->GetList(prefs::kPinnedLauncherApps);
305 const auto* policy = prefs->GetList(prefs::kPolicyPinnedLauncherApps); 316 const auto* policy = prefs->GetList(prefs::kPolicyPinnedLauncherApps);
306 317 if (!policy)
307 // Get the sanitized preference value for the index of the Chrome app icon. 318 return apps;
308 const size_t chrome_icon_index = std::max<size_t>(
309 0, std::min<size_t>(pinned->GetSize(),
310 prefs->GetInteger(prefs::kShelfChromeIconIndex)));
311
312 // Check if Chrome is in either of the the preferences lists.
313 std::unique_ptr<base::Value> chrome_app(
314 ash::CreateAppDict(extension_misc::kChromeAppId));
315 bool chrome_listed =
316 (pinned->Find(*chrome_app.get()) != pinned->end() ||
317 (policy && policy->Find(*chrome_app.get()) != policy->end()));
318 319
319 // Obtain here all ids of ARC apps because it takes linear time, and getting 320 // Obtain here all ids of ARC apps because it takes linear time, and getting
320 // them in the loop bellow would lead to quadratic complexity. 321 // them in the loop bellow would lead to quadratic complexity.
321 const ArcAppListPrefs* const arc_app_list_pref = helper->GetArcAppListPrefs(); 322 const ArcAppListPrefs* const arc_app_list_pref = helper->GetArcAppListPrefs();
322 const std::vector<std::string> all_arc_app_ids( 323 const std::vector<std::string> all_arc_app_ids(
323 arc_app_list_pref ? arc_app_list_pref->GetAppIds() 324 arc_app_list_pref ? arc_app_list_pref->GetAppIds()
324 : std::vector<std::string>()); 325 : std::vector<std::string>());
325 326
326 std::string app_id; 327 std::string app_id;
327 for (size_t i = 0; policy && (i < policy->GetSize()); ++i) { 328 for (size_t i = 0; i < policy->GetSize(); ++i) {
328 const base::DictionaryValue* dictionary = nullptr; 329 const base::DictionaryValue* dictionary = nullptr;
329 if (policy->GetDictionary(i, &dictionary) && 330 if (policy->GetDictionary(i, &dictionary) &&
330 dictionary->GetString(kPinnedAppsPrefAppIDPath, &app_id) && 331 dictionary->GetString(kPinnedAppsPrefAppIDPath, &app_id) &&
331 std::find(apps.begin(), apps.end(), app_id) == apps.end()) { 332 std::find(apps.begin(), apps.end(), app_id) == apps.end()) {
332 if (IsAppIdArcPackage(app_id)) { 333 if (IsAppIdArcPackage(app_id)) {
333 if (!arc_app_list_pref) 334 if (!arc_app_list_pref)
334 continue; 335 continue;
335 336
336 // We are dealing with package name, not with 32 characters ID. 337 // We are dealing with package name, not with 32 characters ID.
337 const std::string& arc_package = app_id; 338 const std::string& arc_package = app_id;
338 const std::vector<std::string> activities = GetActivitiesForPackage( 339 const std::vector<std::string> activities = GetActivitiesForPackage(
339 arc_package, all_arc_app_ids, *arc_app_list_pref); 340 arc_package, all_arc_app_ids, *arc_app_list_pref);
340 for (const auto& activity : activities) { 341 for (const auto& activity : activities) {
341 const std::string arc_app_id = 342 const std::string arc_app_id =
342 ArcAppListPrefs::GetAppId(arc_package, activity); 343 ArcAppListPrefs::GetAppId(arc_package, activity);
343 if (helper->IsValidIDForCurrentUser(arc_app_id)) 344 if (helper->IsValidIDForCurrentUser(arc_app_id))
344 apps.push_back(arc_app_id); 345 apps.push_back(arc_app_id);
345 } 346 }
346 } else if (helper->IsValidIDForCurrentUser(app_id)) { 347 } else if (helper->IsValidIDForCurrentUser(app_id)) {
347 apps.push_back(app_id); 348 apps.push_back(app_id);
348 } 349 }
349 } 350 }
350 } 351 }
351 352
353 return apps;
354 }
355
356 std::vector<std::string> GetPinnedAppsFromPrefsDepricated(
stevenjb 2016/06/10 18:00:41 s/Depricated/Deprecated/, but also maybe use Legac
khmel 2016/06/10 22:08:10 Legacy sounds better, thanks
357 const PrefService* prefs,
358 const LauncherControllerHelper* helper) {
359 // Adding the app list item to the list of items requires that the ID is not
360 // a valid and known ID for the extension system. The ID was constructed that
361 // way - but just to make sure...
362 DCHECK(!helper->IsValidIDForCurrentUser(kPinnedAppsPlaceholder));
363
364 const auto* pinned = prefs->GetList(prefs::kPinnedLauncherApps);
365 const auto* policy = prefs->GetList(prefs::kPolicyPinnedLauncherApps);
366
367 // Get the sanitized preference value for the index of the Chrome app icon.
368 const size_t chrome_icon_index = std::max<size_t>(
369 0, std::min<size_t>(pinned->GetSize(),
370 prefs->GetInteger(prefs::kShelfChromeIconIndex)));
371
372 // Check if Chrome is in either of the the preferences lists.
373 std::unique_ptr<base::Value> chrome_app(
374 ash::CreateAppDict(extension_misc::kChromeAppId));
375 bool chrome_listed =
376 (pinned->Find(*chrome_app.get()) != pinned->end() ||
377 (policy && policy->Find(*chrome_app.get()) != policy->end()));
378
379 std::vector<std::string> apps = GetAppsPinnedByPolicy(prefs, helper);
380
381 std::string app_id;
352 for (size_t i = 0; i < pinned->GetSize(); ++i) { 382 for (size_t i = 0; i < pinned->GetSize(); ++i) {
353 // We need to position the chrome icon relative to its place in the pinned 383 // We need to position the chrome icon relative to its place in the pinned
354 // preference list - even if an item of that list isn't shown yet. 384 // preference list - even if an item of that list isn't shown yet.
355 if (i == chrome_icon_index && !chrome_listed) { 385 if (i == chrome_icon_index && !chrome_listed) {
356 apps.push_back(extension_misc::kChromeAppId); 386 apps.push_back(extension_misc::kChromeAppId);
357 chrome_listed = true; 387 chrome_listed = true;
358 } 388 }
359 bool pinned_by_policy = false; 389 bool pinned_by_policy = false;
360 const base::DictionaryValue* dictionary = nullptr; 390 const base::DictionaryValue* dictionary = nullptr;
361 if (pinned->GetDictionary(i, &dictionary) && 391 if (pinned->GetDictionary(i, &dictionary) &&
362 dictionary->GetString(kPinnedAppsPrefAppIDPath, &app_id) && 392 dictionary->GetString(kPinnedAppsPrefAppIDPath, &app_id) &&
363 helper->IsValidIDForCurrentUser(app_id) && 393 helper->IsValidIDForCurrentUser(app_id) &&
364 std::find(apps.begin(), apps.end(), app_id) == apps.end() && 394 std::find(apps.begin(), apps.end(), app_id) == apps.end() &&
365 (!dictionary->GetBoolean(kPinnedAppsPrefPinnedByPolicy, 395 (!dictionary->GetBoolean(kPinnedAppsPrefPinnedByPolicy,
366 &pinned_by_policy) || 396 &pinned_by_policy) ||
367 !pinned_by_policy)) { 397 !pinned_by_policy)) {
368 apps.push_back(app_id); 398 apps.push_back(app_id);
369 } 399 }
370 } 400 }
371 401
372 if (arc::ArcAuthService::IsAllowedForProfile(helper->profile()) &&
373 helper->IsValidIDForCurrentUser(ArcSupportHost::kHostAppId)) {
374 apps.push_back(ArcSupportHost::kHostAppId);
375 }
376
377 // If not added yet, the chrome item will be the last item in the list. 402 // If not added yet, the chrome item will be the last item in the list.
378 if (!chrome_listed) 403 if (!chrome_listed)
379 apps.push_back(extension_misc::kChromeAppId); 404 apps.push_back(extension_misc::kChromeAppId);
380 405
381 // If not added yet, place the app list item at the beginning of the list. 406 // If not added yet, place the app list item at the beginning of the list.
382 if (std::find(apps.begin(), apps.end(), kPinnedAppsPlaceholder) == apps.end()) 407 if (std::find(apps.begin(), apps.end(), kPinnedAppsPlaceholder) == apps.end())
383 apps.insert(apps.begin(), kPinnedAppsPlaceholder); 408 apps.insert(apps.begin(), kPinnedAppsPlaceholder);
384 409
385 return apps; 410 return apps;
386 } 411 }
387 412
413 // Helper to creates pin position that stays before any synced app, even if
stevenjb 2016/06/10 18:00:40 s/creates/create/
khmel 2016/06/10 22:08:10 Done.
414 // app is not currently visbile on a device.
415 syncer::StringOrdinal CreateFirstPinPosition(Profile* profile) {
416 syncer::StringOrdinal position;
417 app_list::AppListSyncableService* app_service =
418 app_list::AppListSyncableService::Get(profile);
419 for (const auto& sync_peer : app_service->sync_items()) {
420 if (!sync_peer.second->item_pin_ordinal.IsValid())
421 continue;
422 if (!position.IsValid() ||
423 sync_peer.second->item_pin_ordinal.LessThan(position)) {
424 position = sync_peer.second->item_pin_ordinal;
425 }
426 }
427
428 return position.IsValid() ? position.CreateBefore()
429 : syncer::StringOrdinal::CreateInitialOrdinal();
430 }
431
432 // Helper to creates pin position that stays before any synced app, even if
433 // app is not currently visbile on a device.
434 syncer::StringOrdinal CreateLastPinPosition(Profile* profile) {
435 syncer::StringOrdinal position;
436 app_list::AppListSyncableService* app_service =
437 app_list::AppListSyncableService::Get(profile);
438 for (const auto& sync_peer : app_service->sync_items()) {
439 if (!sync_peer.second->item_pin_ordinal.IsValid())
440 continue;
441 if (!position.IsValid() ||
442 sync_peer.second->item_pin_ordinal.GreaterThan(position)) {
443 position = sync_peer.second->item_pin_ordinal;
444 }
445 }
446
447 return position.IsValid() ? position.CreateAfter()
448 : syncer::StringOrdinal::CreateInitialOrdinal();
449 }
450
451 std::vector<std::string> GetPinnedAppsFromPrefs(
452 const PrefService* prefs,
453 LauncherControllerHelper* helper) {
454 app_list::AppListSyncableService* app_service =
455 app_list::AppListSyncableService::Get(helper->profile());
456 // Some unit tests may not have it.
457 if (!app_service)
458 return std::vector<std::string>();
459
460 const std::vector<std::string> policy_apps =
461 GetAppsPinnedByPolicy(prefs, helper);
462
463 std::vector<PinInfo> pin_infos;
464
465 // Empty pins indicates that sync based pin model is used for the first
466 // time. In normal workflow we have at least Chrom browser pin info.
stevenjb 2016/06/10 18:00:41 Chrome
khmel 2016/06/10 22:08:10 Done.
467 bool first_run = true;
468
469 for (const auto& sync_peer : app_service->sync_items()) {
470 if (!sync_peer.second->item_pin_ordinal.IsValid())
471 continue;
472
473 first_run = false;
474 // Don't include apps that are currently do not exist on device.
stevenjb 2016/06/10 18:00:40 s/are//
khmel 2016/06/10 22:08:10 Done.
475 if (sync_peer.first != extension_misc::kChromeAppId &&
476 !helper->IsValidIDForCurrentUser(sync_peer.first)) {
477 continue;
478 }
479
480 const bool pin_by_policy = std::find(policy_apps.begin(), policy_apps.end(),
481 sync_peer.first) != policy_apps.end();
stevenjb 2016/06/10 18:00:40 If the app list gets large this could be expensive
482 // Check if item was pinned by policy only and currently is not in policy.
483 if (!pin_by_policy && sync_peer.second->item_pin_by_policy)
484 continue;
485
486 pin_infos.push_back(
487 PinInfo(sync_peer.first, sync_peer.second->item_pin_ordinal));
488 }
489
490 if (first_run) {
stevenjb 2016/06/10 18:00:41 We should wrap this into a separate function, e.g.
khmel 2016/06/10 22:08:10 Done.
491 // We need to import legacy pins model and convert it to sync based
492 // model.
493 std::vector<std::string> legacy_pins =
494 GetPinnedAppsFromPrefsDepricated(prefs, helper);
495 DCHECK(!legacy_pins.empty());
496
497 legacy_pins.erase(
498 std::remove_if(legacy_pins.begin(), legacy_pins.end(),
499 [](const std::string& app_id) {
500 return (app_id == kPinnedAppsPlaceholder);
501 }),
502 legacy_pins.end());
stevenjb 2016/06/10 18:00:41 We are already iterating over legacy_pins below, w
khmel 2016/06/10 22:08:10 Done. Refactored GetPinnedAppsFromPrefsLegacy not
503 DCHECK(!legacy_pins.empty());
504
505 syncer::StringOrdinal last_position;
506 // Convert to sync item record.
507 for (const auto& app_id : legacy_pins) {
508 last_position = last_position.IsValid()
509 ? last_position.CreateAfter()
510 : syncer::StringOrdinal::CreateInitialOrdinal();
stevenjb 2016/06/10 18:00:40 nit: Just initialize last_position to syncer::Stri
khmel 2016/06/10 22:08:11 That is nicer, thanks
511 const bool pin_by_policy =
512 std::find(policy_apps.begin(), policy_apps.end(), app_id) !=
513 policy_apps.end();
stevenjb 2016/06/10 18:00:41 This will also avoid an N^2 operation if policy_ap
khmel 2016/06/10 22:08:10 Done.
514 app_service->SetPinPosition(app_id, last_position, pin_by_policy);
515 }
516
517 // Now process default apps.
518 for (size_t i = 0; i < arraysize(kDefaultPinnedApps); ++i) {
519 const std::string& app_id = kDefaultPinnedApps[i];
520 // Check if it is already imported.
521 if (app_service->GetPinPosition(app_id).IsValid())
522 continue;
523 // Check if it is present but not in legacy pin.
524 if (helper->IsValidIDForCurrentUser(app_id))
525 continue;
526 DCHECK(last_position.IsValid());
stevenjb 2016/06/10 18:00:41 Just check this once above.
khmel 2016/06/10 22:08:10 Done.
527 last_position = last_position.CreateAfter();
528 app_service->SetPinPosition(app_id, last_position, false);
529 }
530
531 return legacy_pins;
532 }
533
534 // Sort pins according its ordinals.
stevenjb 2016/06/10 18:00:40 s/its/their/
khmel 2016/06/10 22:08:10 Done.
535 std::sort(pin_infos.begin(), pin_infos.end(), ComparePinInfo());
536
537 // Now insert Chrome browser app if needed.
538 syncer::StringOrdinal chrome_position =
539 app_service->GetPinPosition(extension_misc::kChromeAppId);
540 if (!chrome_position.IsValid()) {
541 chrome_position = CreateFirstPinPosition(helper->profile());
542 pin_infos.insert(pin_infos.begin(),
543 PinInfo(extension_misc::kChromeAppId, chrome_position));
544 app_service->SetPinPosition(extension_misc::kChromeAppId, chrome_position,
545 false);
546 }
547
548 // Policy apps must preserve order of appearance and be first app in the list.
549 // Validate that there have correct position and fix if needed.
stevenjb 2016/06/10 18:00:40 s/there have correct/they have a correct/
khmel 2016/06/10 22:08:10 Done.
khmel 2016/06/10 22:08:11 Done.
550 size_t shelf_index = 0;
551 for (const auto& app_id : policy_apps) {
552 if (app_id == kPinnedAppsPlaceholder)
553 continue;
554 if (app_id == extension_misc::kChromeAppId)
555 continue;
556
557 // Chrome browser app has right to appear between pinned by policy apps.
558 if (shelf_index < pin_infos.size() &&
559 pin_infos[shelf_index].app_id == extension_misc::kChromeAppId) {
560 ++shelf_index;
561 }
562
563 const bool need_position_item = shelf_index >= pin_infos.size() ||
564 app_id != pin_infos[shelf_index].app_id;
565 if (need_position_item) {
566 // Remove existing app that breaks the order from the list.
567 if (shelf_index < pin_infos.size()) {
568 pin_infos.erase(
569 std::remove_if(pin_infos.begin() + shelf_index + 1, pin_infos.end(),
570 [app_id](const PinInfo& pin_info) {
571 return (pin_info.app_id == app_id);
572 }),
573 pin_infos.end());
574 }
575
576 syncer::StringOrdinal new_shelf_ordinal;
577 if (shelf_index == 0) {
578 // First app.
579 new_shelf_ordinal = pin_infos.empty()
580 ? syncer::StringOrdinal::CreateInitialOrdinal()
581 : pin_infos.front().item_ordinal.CreateBefore();
582 } else if (shelf_index == pin_infos.size()) {
583 new_shelf_ordinal = pin_infos.back().item_ordinal.CreateAfter();
584 } else {
585 new_shelf_ordinal =
586 pin_infos[shelf_index - 1].item_ordinal.CreateBetween(
587 pin_infos[shelf_index].item_ordinal);
588 }
589 pin_infos.insert(pin_infos.begin() + shelf_index,
590 PinInfo(app_id, new_shelf_ordinal));
591 const bool pin_by_policy =
592 !app_service->GetPinPosition(app_id).IsValid() ||
593 app_service->GetPinByPolicy(app_id);
594 app_service->SetPinPosition(app_id, new_shelf_ordinal, pin_by_policy);
595 }
596 ++shelf_index;
597 }
598
599 if (arc::ArcAuthService::IsAllowedForProfile(helper->profile()) &&
600 helper->IsValidIDForCurrentUser(ArcSupportHost::kHostAppId)) {
601 if (!app_service->GetSyncItem(ArcSupportHost::kHostAppId)) {
602 const syncer::StringOrdinal arc_host_position =
603 CreateLastPinPosition(helper->profile());
604 pin_infos.insert(pin_infos.begin(),
605 PinInfo(ArcSupportHost::kHostAppId, arc_host_position));
606 app_service->SetPinPosition(ArcSupportHost::kHostAppId, arc_host_position,
607 false);
608 }
609 }
610
611 // Convert to string array.
612 std::vector<std::string> pins(pin_infos.size());
613 for (size_t i = 0; i < pin_infos.size(); ++i)
614 pins[i] = pin_infos[i].app_id;
615
616 return pins;
617 }
618
619 void RemovePinPosition(Profile* profile, const std::string& app_id) {
620 DCHECK(profile);
621 DCHECK(!app_id.empty());
622 app_list::AppListSyncableService* app_service =
623 app_list::AppListSyncableService::Get(profile);
624 app_service->SetPinPosition(app_id, syncer::StringOrdinal(), false);
625 }
626
627 void SetPinPosition(Profile* profile,
628 const std::string& app_id,
629 const std::string& app_id_before,
630 const std::string& app_id_after) {
631 DCHECK(profile);
632 DCHECK(!app_id.empty());
633 DCHECK_NE(app_id, app_id_before);
634 DCHECK_NE(app_id, app_id_after);
635 DCHECK(app_id_before.empty() || app_id_before != app_id_after);
636
637 app_list::AppListSyncableService* app_service =
638 app_list::AppListSyncableService::Get(profile);
639 // Some unit tests may not have this service.
640 if (!app_service)
641 return;
642
643 syncer::StringOrdinal position_before =
644 app_id_before.empty() ? syncer::StringOrdinal()
645 : app_service->GetPinPosition(app_id_before);
646 syncer::StringOrdinal position_after =
647 app_id_after.empty() ? syncer::StringOrdinal()
648 : app_service->GetPinPosition(app_id_after);
649
650 syncer::StringOrdinal pin_position;
651 if (position_before.IsValid() && position_after.IsValid())
652 pin_position = position_before.CreateBetween(position_after);
653 else if (position_before.IsValid())
654 pin_position = position_before.CreateAfter();
655 else if (position_after.IsValid())
656 pin_position = position_after.CreateBefore();
657 else
658 pin_position = syncer::StringOrdinal::CreateInitialOrdinal();
659 app_service->SetPinPosition(app_id, pin_position, false);
660 }
661
388 } // namespace ash 662 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698