OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |