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

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

Issue 23580008: Fixed problems with pin/unpin preferences changing for not running applications & icon order chang… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 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 | Annotate | Revision Log
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 <vector> 7 #include <vector>
8 8
9 #include "ash/ash_switches.h" 9 #include "ash/ash_switches.h"
10 #include "ash/desktop_background/desktop_background_controller.h" 10 #include "ash/desktop_background/desktop_background_controller.h"
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 void ChromeLauncherController::Unpin(ash::LauncherID id) { 435 void ChromeLauncherController::Unpin(ash::LauncherID id) {
436 DCHECK(HasItemController(id)); 436 DCHECK(HasItemController(id));
437 437
438 LauncherItemController* controller = id_to_item_controller_map_[id]; 438 LauncherItemController* controller = id_to_item_controller_map_[id];
439 if (controller->type() == LauncherItemController::TYPE_APP) { 439 if (controller->type() == LauncherItemController::TYPE_APP) {
440 int index = model_->ItemIndexByID(id); 440 int index = model_->ItemIndexByID(id);
441 DCHECK_GE(index, 0); 441 DCHECK_GE(index, 0);
442 ash::LauncherItem item = model_->items()[index]; 442 ash::LauncherItem item = model_->items()[index];
443 item.type = ash::TYPE_PLATFORM_APP; 443 item.type = ash::TYPE_PLATFORM_APP;
444 model_->Set(index, item); 444 model_->Set(index, item);
445 } else { 445 } else {
oshima 2013/09/19 21:42:11 can you expland if else like if (... == TYPE_APP)
Mr4D (OOO till 08-26) 2013/09/19 22:31:50 Ahhh! Good one! case combined!
446 // Prevent the removal of items upon unpin if it is locked by a running 446 // Prevent the removal of items upon unpin if it is locked by a running
447 // windowed V1 app. 447 // windowed V1 app.
448 if (!controller->locked()) { 448 if (!controller->locked())
449 LauncherItemClosed(id); 449 LauncherItemClosed(id);
450 } else { 450 else
451 int index = model_->ItemIndexByID(id); 451 UnpinRunningAppInternal(model_->ItemIndexByID(id));
452 DCHECK_GE(index, 0);
453 ash::LauncherItem item = model_->items()[index];
454 item.type = ash::TYPE_WINDOWED_APP;
455 model_->Set(index, item);
456 }
457 } 452 }
458 if (CanPin()) 453 if (CanPin())
459 PersistPinnedState(); 454 PersistPinnedState();
460 } 455 }
461 456
462 bool ChromeLauncherController::IsPinned(ash::LauncherID id) { 457 bool ChromeLauncherController::IsPinned(ash::LauncherID id) {
463 int index = model_->ItemIndexByID(id); 458 int index = model_->ItemIndexByID(id);
464 if (index < 0) 459 if (index < 0)
465 return false; 460 return false;
466 ash::LauncherItemType type = model_->items()[index].type; 461 ash::LauncherItemType type = model_->items()[index].type;
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 if (ignore_persist_pinned_state_change_) 728 if (ignore_persist_pinned_state_change_)
734 return; 729 return;
735 // It is a coding error to call PersistPinnedState() if the pinned apps are 730 // It is a coding error to call PersistPinnedState() if the pinned apps are
736 // not user-editable. The code should check earlier and not perform any 731 // not user-editable. The code should check earlier and not perform any
737 // modification actions that trigger persisting the state. 732 // modification actions that trigger persisting the state.
738 if (!CanPin()) { 733 if (!CanPin()) {
739 NOTREACHED() << "Can't pin but pinned state being updated"; 734 NOTREACHED() << "Can't pin but pinned state being updated";
740 return; 735 return;
741 } 736 }
742 737
738 // With the alternate shelf layout, the app list is locked in position #0.
739 // Since the app list does not have any impact on the rest of the order,
740 // we need to keep track of its appearance so that the chrome icon position
741 // is at the proper location (backwards compatible).
742 int app_list_found = 0;
oshima 2013/09/19 21:42:11 maybe app_list_index_found, or found_app_list_inde
Mr4D (OOO till 08-26) 2013/09/19 22:31:50 Done.
743
743 // Mutating kPinnedLauncherApps is going to notify us and trigger us to 744 // Mutating kPinnedLauncherApps is going to notify us and trigger us to
744 // process the change. We don't want that to happen so remove ourselves as a 745 // process the change. We don't want that to happen so remove ourselves as a
745 // listener. 746 // listener.
746 pref_change_registrar_.Remove(prefs::kPinnedLauncherApps); 747 pref_change_registrar_.Remove(prefs::kPinnedLauncherApps);
747 { 748 {
748 ListPrefUpdate updater(profile_->GetPrefs(), prefs::kPinnedLauncherApps); 749 ListPrefUpdate updater(profile_->GetPrefs(), prefs::kPinnedLauncherApps);
749 updater->Clear(); 750 updater->Clear();
750 for (size_t i = 0; i < model_->items().size(); ++i) { 751 for (size_t i = 0; i < model_->items().size(); ++i) {
751 if (model_->items()[i].type == ash::TYPE_APP_SHORTCUT) { 752 if (model_->items()[i].type == ash::TYPE_APP_SHORTCUT) {
752 ash::LauncherID id = model_->items()[i].id; 753 ash::LauncherID id = model_->items()[i].id;
753 if (HasItemController(id) && IsPinned(id)) { 754 if (HasItemController(id) && IsPinned(id)) {
754 base::DictionaryValue* app_value = ash::CreateAppDict( 755 base::DictionaryValue* app_value = ash::CreateAppDict(
755 id_to_item_controller_map_[id]->app_id()); 756 id_to_item_controller_map_[id]->app_id());
756 if (app_value) 757 if (app_value)
757 updater->Append(app_value); 758 updater->Append(app_value);
758 } 759 }
759 } else if (model_->items()[i].type == ash::TYPE_BROWSER_SHORTCUT) { 760 } else if (model_->items()[i].type == ash::TYPE_BROWSER_SHORTCUT) {
760 PersistChromeItemIndex(i); 761 PersistChromeItemIndex(i - app_list_found);
762 } else if (model_->items()[i].type == ash::TYPE_APP_LIST &&
763 ash::switches::UseAlternateShelfLayout()) {
764 // With the new alternate shelf layout the app list can be pinned to the
765 // position 0 and should not be taken into account.
766 app_list_found = 1;
oshima 2013/09/19 21:42:11 why this is 1 not i?
Mr4D (OOO till 08-26) 2013/09/19 22:31:50 Because all we do is to subtract 1 if the app list
761 } 767 }
762 } 768 }
763 } 769 }
764 pref_change_registrar_.Add( 770 pref_change_registrar_.Add(
765 prefs::kPinnedLauncherApps, 771 prefs::kPinnedLauncherApps,
766 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, 772 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref,
767 base::Unretained(this))); 773 base::Unretained(this)));
768 } 774 }
769 775
770 ash::LauncherModel* ChromeLauncherController::model() { 776 ash::LauncherModel* ChromeLauncherController::model() {
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 PersistPinnedState(); 1308 PersistPinnedState();
1303 } 1309 }
1304 } 1310 }
1305 1311
1306 void ChromeLauncherController::DoUnpinAppWithID(const std::string& app_id) { 1312 void ChromeLauncherController::DoUnpinAppWithID(const std::string& app_id) {
1307 ash::LauncherID launcher_id = GetLauncherIDForAppID(app_id); 1313 ash::LauncherID launcher_id = GetLauncherIDForAppID(app_id);
1308 if (launcher_id && IsPinned(launcher_id)) 1314 if (launcher_id && IsPinned(launcher_id))
1309 Unpin(launcher_id); 1315 Unpin(launcher_id);
1310 } 1316 }
1311 1317
1318 int ChromeLauncherController::PinRunningAppInternal(
1319 int index,
1320 ash::LauncherID launcher_id) {
1321 int running_index = model_->ItemIndexByID(launcher_id);
1322 ash::LauncherItem item = model_->items()[running_index];
1323 DCHECK(item.type == ash::TYPE_WINDOWED_APP ||
1324 item.type == ash::TYPE_PLATFORM_APP);
1325 item.type = ash::TYPE_APP_SHORTCUT;
1326 model_->Set(running_index, item);
1327 // The |LauncherModel|'s weight system might reposition the item to a
1328 // new index, so we get the index again.
1329 running_index = model_->ItemIndexByID(launcher_id);
1330 if (running_index < index)
1331 --index;
1332 if (running_index != index)
1333 MoveItemWithoutPinnedStateChangeNotification(running_index, index);
1334 return index;
1335 }
1336
1337 void ChromeLauncherController::UnpinRunningAppInternal(int index) {
1338 DCHECK_GE(index, 0);
1339 ash::LauncherItem item = model_->items()[index];
1340 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT);
1341 item.type = ash::TYPE_WINDOWED_APP;
1342 // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such
1343 // we have to check here what this was before it got a shortcut.
1344 if (HasItemController(item.id) &&
1345 id_to_item_controller_map_[item.id]->type() ==
1346 LauncherItemController::TYPE_APP)
1347 item.type = ash::TYPE_PLATFORM_APP;
1348 model_->Set(index, item);
1349 }
1350
1312 void ChromeLauncherController::UpdateAppLaunchersFromPref() { 1351 void ChromeLauncherController::UpdateAppLaunchersFromPref() {
1313 // Construct a vector representation of to-be-pinned apps from the pref. 1352 // Note: This function has to make sure that it never changes a state which
1353 // calls |PersistPinnedState()| - otherwise all kinds of problems can arise.
oshima 2013/09/19 21:42:11 add reference to bug? (assuming one of bugs listed
Mr4D (OOO till 08-26) 2013/09/19 22:31:50 No it is not. This was meant to be a helper commen
1354 // If it happens (due to some complicated observer interactions) it would be
1355 // best to either add here
1356 // base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_,
1357 // true);
1358 // or call |PersistPinnedState()| at the end. For now this is not necessary.
1314 std::vector<std::string> pinned_apps; 1359 std::vector<std::string> pinned_apps;
1315 int chrome_icon_index = GetChromeIconIndexFromPref(); 1360 GetListOfPinnedAppsAndBrowser(&pinned_apps);
1361
1316 int index = 0; 1362 int index = 0;
1317 int max_index = model_->item_count(); 1363 int max_index = model_->item_count();
1318 // Using the alternate shelf layout the App Icon should be the first item in 1364
1319 // the list thus start adding items at slot 1 (instead of slot 0). 1365 // Using the alternate shelf layout the app list Icon should be the first item
1366 // in the list thus start adding items at slot 1 (instead of slot 0).
1320 if (ash::switches::UseAlternateShelfLayout()) { 1367 if (ash::switches::UseAlternateShelfLayout()) {
1321 ++index; 1368 ++index;
1322 ++max_index; 1369 ++max_index;
1323 // The alternate shelf layout's icon position will always include the
1324 // AppLauncher which needs to be subtracted here.
1325 if (chrome_icon_index > 0)
1326 --chrome_icon_index;
1327 }
1328 const base::ListValue* pinned_apps_pref =
1329 profile_->GetPrefs()->GetList(prefs::kPinnedLauncherApps);
1330 for (base::ListValue::const_iterator it(pinned_apps_pref->begin());
1331 it != pinned_apps_pref->end(); ++it) {
1332 // To preserve the Chrome icon position, we insert a dummy slot for it - if
1333 // the model has a Chrome item. While initializing we can come here with no
1334 // item in which case the count would be 1 or below.
1335 if (it - pinned_apps_pref->begin() == chrome_icon_index &&
1336 model_->item_count() > 1) {
1337 pinned_apps.push_back(extension_misc::kChromeAppId);
1338 }
1339
1340 DictionaryValue* app = NULL;
1341 std::string app_id;
1342 if ((*it)->GetAsDictionary(&app) &&
1343 app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id) &&
1344 std::find(pinned_apps.begin(), pinned_apps.end(), app_id) ==
1345 pinned_apps.end() &&
1346 app_tab_helper_->IsValidID(app_id)) {
1347 pinned_apps.push_back(app_id);
1348 }
1349 } 1370 }
1350 1371
1351 // Walk the model and |pinned_apps| from the pref lockstep, adding and 1372 // Walk the model and |pinned_apps| from the pref lockstep, adding and
1352 // removing items as necessary. NB: This code uses plain old indexing instead 1373 // removing items as necessary. NB: This code uses plain old indexing instead
1353 // of iterators because of model mutations as part of the loop. 1374 // of iterators because of model mutations as part of the loop.
1354 std::vector<std::string>::const_iterator pref_app_id(pinned_apps.begin()); 1375 std::vector<std::string>::const_iterator pref_app_id(pinned_apps.begin());
1355 for (; index < max_index && pref_app_id != pinned_apps.end(); ++index) { 1376 for (; index < max_index && pref_app_id != pinned_apps.end(); ++index) {
1356 // If the next app launcher according to the pref is present in the model, 1377 // If the next app launcher according to the pref is present in the model,
1357 // delete all app launcher entries in between. 1378 // delete all app launcher entries in between.
1358 if (*pref_app_id == extension_misc::kChromeAppId || 1379 if (*pref_app_id == extension_misc::kChromeAppId ||
(...skipping 12 matching lines...) Expand all
1371 entry->second->app_id() == *pref_app_id)) { 1392 entry->second->app_id() == *pref_app_id)) {
1372 ++pref_app_id; 1393 ++pref_app_id;
1373 break; 1394 break;
1374 } else { 1395 } else {
1375 if (item.type == ash::TYPE_BROWSER_SHORTCUT) { 1396 if (item.type == ash::TYPE_BROWSER_SHORTCUT) {
1376 // We cannot delete the browser shortcut. As such we move it up by 1397 // We cannot delete the browser shortcut. As such we move it up by
1377 // one. To avoid any side effects from our pinned state observer, we 1398 // one. To avoid any side effects from our pinned state observer, we
1378 // do not call the model directly. 1399 // do not call the model directly.
1379 MoveItemWithoutPinnedStateChangeNotification(index, index + 1); 1400 MoveItemWithoutPinnedStateChangeNotification(index, index + 1);
1380 } else { 1401 } else {
1381 LauncherItemClosed(item.id); 1402 // Check if this is a platform or a windowed app.
1382 --max_index; 1403 if (item.type == ash::TYPE_APP_SHORTCUT &&
1404 (id_to_item_controller_map_[item.id]->locked() ||
1405 id_to_item_controller_map_[item.id]->type() ==
1406 LauncherItemController::TYPE_APP)) {
1407 // Note: This will not change the amount of items (|max_index|).
1408 // Even changes to the actual |index| due to item weighting
1409 // changes should be fine.
1410 UnpinRunningAppInternal(index);
1411 } else {
1412 LauncherItemClosed(item.id);
1413 --max_index;
1414 }
1383 } 1415 }
1384 --index; 1416 --index;
1385 } 1417 }
1386 } 1418 }
1387 // If the item wasn't found, that means id_to_item_controller_map_ 1419 // If the item wasn't found, that means id_to_item_controller_map_
1388 // is out of sync. 1420 // is out of sync.
1389 DCHECK(index <= max_index); 1421 DCHECK(index <= max_index);
1390 } else { 1422 } else {
1391 // This app wasn't pinned before, insert a new entry. 1423 // Check if the item was already running but not yet pinned.
1392 ash::LauncherID id = CreateAppShortcutLauncherItem(*pref_app_id, index); 1424 ash::LauncherID launcher_id = GetLauncherIDForAppID(*pref_app_id);
1393 index = model_->ItemIndexByID(id); 1425 if (launcher_id) {
1426 // This app is running but not yet pinned. So pin and move it.
1427 index = PinRunningAppInternal(index, launcher_id);
1428 } else {
1429 // This app wasn't pinned before, insert a new entry.
1430 launcher_id = CreateAppShortcutLauncherItem(*pref_app_id, index);
1431 index = model_->ItemIndexByID(launcher_id);
1432 }
1394 ++pref_app_id; 1433 ++pref_app_id;
1395 } 1434 }
1396 } 1435 }
1397 1436
1437 // Since we are removing the currently existing shortcuts, but the chrome item
1438 // might be in the middle of that area, we need to keep track of it, so that
1439 // it can be shifted to the correct location afterwards.
1440 // Note: This might still produce location shifts with windowed V1
1441 // applications since they will be grouped at the moment between shortcuts.
1442 // To address that problem we could either group them separately again - or
1443 // we will have to remember all shelf item locations.
1444 int chrome_index = -1;
1445
1398 // Remove any trailing existing items. 1446 // Remove any trailing existing items.
1399 while (index < model_->item_count()) { 1447 while (index < model_->item_count()) {
1400 const ash::LauncherItem& item(model_->items()[index]); 1448 const ash::LauncherItem& item(model_->items()[index]);
1401 if (item.type == ash::TYPE_APP_SHORTCUT) 1449 if (item.type == ash::TYPE_APP_SHORTCUT) {
1402 LauncherItemClosed(item.id); 1450 if (id_to_item_controller_map_[item.id]->locked() ||
1403 else 1451 id_to_item_controller_map_[item.id]->type() ==
1452 LauncherItemController::TYPE_APP)
1453 UnpinRunningAppInternal(index);
1454 else
1455 LauncherItemClosed(item.id);
1456 } else {
1457 if (item.type == ash::TYPE_BROWSER_SHORTCUT)
1458 chrome_index = index;
1404 ++index; 1459 ++index;
1460 }
1405 } 1461 }
1406 1462
1407 // Append unprocessed items from the pref to the end of the model. 1463 // Append unprocessed items from the pref to the end of the model.
1408 for (; pref_app_id != pinned_apps.end(); ++pref_app_id) { 1464 for (; pref_app_id != pinned_apps.end(); ++pref_app_id) {
1409 // Ignore the chrome icon. 1465 // All items but the chrome shortcut needs to be added.
1410 if (*pref_app_id != extension_misc::kChromeAppId) 1466 if (*pref_app_id != extension_misc::kChromeAppId) {
1411 DoPinAppWithID(*pref_app_id); 1467 DoPinAppWithID(*pref_app_id);
1468 } else if (chrome_index != -1) {
1469 // The chrome item was in the middle of the to be removed items and needs
1470 // now to be moved to the last possible location.
1471 MoveItemWithoutPinnedStateChangeNotification(chrome_index,
1472 model_->item_count() - 1);
oshima 2013/09/19 21:42:11 indent
Mr4D (OOO till 08-26) 2013/09/19 22:31:50 Done.
1473 }
1412 } 1474 }
1413
1414 } 1475 }
1415 1476
1416 void ChromeLauncherController::SetShelfAutoHideBehaviorPrefs( 1477 void ChromeLauncherController::SetShelfAutoHideBehaviorPrefs(
1417 ash::ShelfAutoHideBehavior behavior, 1478 ash::ShelfAutoHideBehavior behavior,
1418 aura::RootWindow* root_window) { 1479 aura::RootWindow* root_window) {
1419 const char* value = NULL; 1480 const char* value = NULL;
1420 switch (behavior) { 1481 switch (behavior) {
1421 case ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS: 1482 case ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS:
1422 value = ash::kShelfAutoHideBehaviorAlways; 1483 value = ash::kShelfAutoHideBehaviorAlways;
1423 break; 1484 break;
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1555 return static_cast<BrowserShortcutLauncherItemController*>( 1616 return static_cast<BrowserShortcutLauncherItemController*>(
1556 id_to_item_controller_map_[id]); 1617 id_to_item_controller_map_[id]);
1557 } 1618 }
1558 1619
1559 ash::LauncherID ChromeLauncherController::CreateBrowserShortcutLauncherItem() { 1620 ash::LauncherID ChromeLauncherController::CreateBrowserShortcutLauncherItem() {
1560 ash::LauncherItem browser_shortcut; 1621 ash::LauncherItem browser_shortcut;
1561 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT; 1622 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT;
1562 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 1623 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
1563 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32); 1624 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32);
1564 ash::LauncherID id = model_->next_id(); 1625 ash::LauncherID id = model_->next_id();
1565 size_t index = GetChromeIconIndexFromPref(); 1626 size_t index = GetChromeIconIndexForCreation();
1566 model_->AddAt(index, browser_shortcut); 1627 model_->AddAt(index, browser_shortcut);
1567 browser_item_controller_.reset( 1628 browser_item_controller_.reset(
1568 new BrowserShortcutLauncherItemController(this, profile_)); 1629 new BrowserShortcutLauncherItemController(this, profile_));
1569 id_to_item_controller_map_[id] = browser_item_controller_.get(); 1630 id_to_item_controller_map_[id] = browser_item_controller_.get();
1570 id_to_item_controller_map_[id]->set_launcher_id(id); 1631 id_to_item_controller_map_[id]->set_launcher_id(id);
1571 return id; 1632 return id;
1572 } 1633 }
1573 1634
1574 void ChromeLauncherController::PersistChromeItemIndex(int index) { 1635 void ChromeLauncherController::PersistChromeItemIndex(int index) {
1575 profile_->GetPrefs()->SetInteger(prefs::kShelfChromeIconIndex, index); 1636 profile_->GetPrefs()->SetInteger(prefs::kShelfChromeIconIndex, index);
1576 } 1637 }
1577 1638
1578 int ChromeLauncherController::GetChromeIconIndexFromPref() const { 1639 int ChromeLauncherController::GetChromeIconIndexFromPref() const {
1579 size_t index = profile_->GetPrefs()->GetInteger(prefs::kShelfChromeIconIndex); 1640 size_t index = profile_->GetPrefs()->GetInteger(prefs::kShelfChromeIconIndex);
1580 const base::ListValue* pinned_apps_pref = 1641 const base::ListValue* pinned_apps_pref =
1581 profile_->GetPrefs()->GetList(prefs::kPinnedLauncherApps); 1642 profile_->GetPrefs()->GetList(prefs::kPinnedLauncherApps);
1582 if (ash::switches::UseAlternateShelfLayout())
1583 return std::max(static_cast<size_t>(1),
1584 std::min(pinned_apps_pref->GetSize() + 1, index));
1585 return std::max(static_cast<size_t>(0), 1643 return std::max(static_cast<size_t>(0),
1586 std::min(pinned_apps_pref->GetSize(), index)); 1644 std::min(pinned_apps_pref->GetSize(), index));
1587 } 1645 }
1588 1646
1647 int ChromeLauncherController::GetChromeIconIndexForCreation() {
1648 // We get the list of pinned apps as they currently would get pinned.
1649 // Within this list the chrome icon will be the correct location.
1650 std::vector<std::string> pinned_apps;
1651 GetListOfPinnedAppsAndBrowser(&pinned_apps);
1652
1653 std::vector<std::string>::iterator it =
1654 std::find(pinned_apps.begin(),
1655 pinned_apps.end(),
1656 extension_misc::kChromeAppId);
1657 DCHECK(it != pinned_apps.end());
1658 int index = it - pinned_apps.begin();
1659
1660 // Since this function returns the index of the item within the shelf, the
1661 // app list item must be taken into account and for now the app list is always
1662 // the left most item in the list.
1663 if (ash::switches::UseAlternateShelfLayout())
1664 ++index;
1665
1666 // We should do here a comparison between the is state and the "want to be"
1667 // state since some apps might be able to pin but are not yet. Instead - for
1668 // the time being we clamp against the amount of known items and wait for the
1669 // next |UpdateAppLaunchersFromPref()| call to correct it - it will come since
1670 // the pinning will be done then.
1671 return std::min(model_->item_count(), index);
1672 }
1673
1674 void ChromeLauncherController::GetListOfPinnedAppsAndBrowser(
1675 std::vector<std::string>* pinned_apps) {
1676 const base::ListValue* pinned_apps_pref =
1677 profile_->GetPrefs()->GetList(prefs::kPinnedLauncherApps);
1678
1679 // Keep track of the addition of the chrome icon.
1680 bool chrome_icon_added = false;
1681 int chrome_icon_index = GetChromeIconIndexFromPref();
1682 // Note: We do not need special handling for the app List here since it is
1683 // either always at the start or the end of the list and it is not part of
1684 // the pinned 'dynamic' items.
1685 for (base::ListValue::const_iterator it(pinned_apps_pref->begin());
1686 it != pinned_apps_pref->end(); ++it) {
oshima 2013/09/19 21:42:11 since you need index anyway, using size_t index wo
Mr4D (OOO till 08-26) 2013/09/19 22:31:50 Done.
1687 // We need to position the chrome icon relative to it's place in the pinned
1688 // preference list - even if an item of that list isn't shown yet.
1689 if (it - pinned_apps_pref->begin() == chrome_icon_index &&
1690 model_->item_count() > 1) {
1691 pinned_apps->push_back(extension_misc::kChromeAppId);
1692 chrome_icon_added = true;
1693 }
1694
1695 DictionaryValue* app = NULL;
1696 std::string app_id;
1697 if ((*it)->GetAsDictionary(&app) &&
1698 app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id) &&
1699 (std::find(pinned_apps->begin(), pinned_apps->end(), app_id) ==
1700 pinned_apps->end()) && app_tab_helper_->IsValidID(app_id))
1701 pinned_apps->push_back(app_id);
1702 }
1703
1704 // If not added yet, the chrome item will be the final item in the list.
1705 if (!chrome_icon_added)
1706 pinned_apps->push_back(extension_misc::kChromeAppId);
1707 }
1708
1589 bool ChromeLauncherController::IsIncognito( 1709 bool ChromeLauncherController::IsIncognito(
1590 content::WebContents* web_contents) const { 1710 content::WebContents* web_contents) const {
1591 const Profile* profile = 1711 const Profile* profile =
1592 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 1712 Profile::FromBrowserContext(web_contents->GetBrowserContext());
1593 return profile->IsOffTheRecord() && !profile->IsGuestSession(); 1713 return profile->IsOffTheRecord() && !profile->IsGuestSession();
1594 } 1714 }
1595 1715
1596 void ChromeLauncherController::CloseWindowedAppsFromRemovedExtension( 1716 void ChromeLauncherController::CloseWindowedAppsFromRemovedExtension(
1597 const std::string& app_id) { 1717 const std::string& app_id) {
1598 // This function cannot rely on the controller's enumeration functionality 1718 // This function cannot rely on the controller's enumeration functionality
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1674 } 1794 }
1675 1795
1676 void ChromeLauncherController::ReleaseProfile() { 1796 void ChromeLauncherController::ReleaseProfile() {
1677 if (app_sync_ui_state_) 1797 if (app_sync_ui_state_)
1678 app_sync_ui_state_->RemoveObserver(this); 1798 app_sync_ui_state_->RemoveObserver(this);
1679 1799
1680 PrefServiceSyncable::FromProfile(profile_)->RemoveObserver(this); 1800 PrefServiceSyncable::FromProfile(profile_)->RemoveObserver(this);
1681 1801
1682 pref_change_registrar_.RemoveAll(); 1802 pref_change_registrar_.RemoveAll();
1683 } 1803 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698