14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/extension_app_model_builder.h" 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <algorithm> 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/auto_reset.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/prefs/pref_service.h" 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/chrome_notification_types.h" 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/extension_prefs.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/install_tracker.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/install_tracker_factory.h" 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_controller_delegate.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/extension_app_item.h" 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/common/extensions/extension_constants.h" 190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/common/extensions/extension_set.h" 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/common/pref_names.h" 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/notification_service.h" 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/gfx/image/image_skia.h" 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using extensions::Extension; 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace { 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool ShouldDisplayInAppLauncher(Profile* profile, 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<const Extension> app) { 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If it's the web store, check the policy. 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool blocked_by_policy = 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (app->id() == extension_misc::kWebStoreAppId || 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) app->id() == extension_misc::kEnterpriseWebStoreAppId) && 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) profile->GetPrefs()->GetBoolean(prefs::kHideWebStoreIcon); 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return app->ShouldDisplayInAppLauncher() && !blocked_by_policy; 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ExtensionAppModelBuilder::ExtensionAppModelBuilder( 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Profile* profile, 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) app_list::AppListModel* model, 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AppListControllerDelegate* controller) 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : profile_(profile), 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) controller_(controller), 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) model_(model), 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) highlighted_app_pending_(false), 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tracker_(NULL) { 501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) model_->item_list()->AddObserver(this); 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BuildModel(); 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ExtensionAppModelBuilder::~ExtensionAppModelBuilder() { 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OnShutdown(); 561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) model_->item_list()->RemoveObserver(this); 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ExtensionAppModelBuilder::OnBeginExtensionInstall( 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const ExtensionInstallParams& params) { 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!params.is_app || params.is_ephemeral) 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionAppItem* existing_item = GetExtensionAppItem(params.extension_id); 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (existing_item) { 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) existing_item->SetIsInstalling(true); 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) InsertApp(new ExtensionAppItem(profile_, 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) params.extension_id, 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) params.extension_name, 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) params.installing_icon, 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) params.is_platform_app)); 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SetHighlightedApp(params.extension_id); 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ExtensionAppModelBuilder::OnDownloadProgress( 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& extension_id, 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int percent_downloaded) { 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ExtensionAppItem* item = GetExtensionAppItem(extension_id); 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!item) 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) item->SetPercentDownloaded(percent_downloaded); 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ExtensionAppModelBuilder::OnInstallFailure( 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& extension_id) { 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) model_->item_list()->DeleteItem(extension_id); 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ExtensionAppModelBuilder::OnExtensionLoaded(const Extension* extension) { 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!extension->ShouldDisplayInAppLauncher()) 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ExtensionAppItem* existing_item = GetExtensionAppItem(extension->id()); 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (existing_item) { 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) existing_item->Reload(); 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) InsertApp(new ExtensionAppItem(profile_, 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) extension->id(), 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "", 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::ImageSkia(), 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) extension->is_platform_app())); 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateHighlight(); 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ExtensionAppModelBuilder::OnExtensionUnloaded(const Extension* extension) { 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ExtensionAppItem* item = GetExtensionAppItem(extension->id()); 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!item) 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) item->UpdateIcon(); 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ExtensionAppModelBuilder::OnExtensionUninstalled( 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const Extension* extension) { 1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) model_->item_list()->DeleteItem(extension->id()); 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ExtensionAppModelBuilder::OnAppsReordered() { 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Do nothing; App List order does not track extensions order. 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ExtensionAppModelBuilder::OnAppInstalledToAppList( 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& extension_id) { 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SetHighlightedApp(extension_id); 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ExtensionAppModelBuilder::OnShutdown() { 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (tracker_) { 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tracker_->RemoveObserver(this); 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tracker_ = NULL; 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ExtensionAppModelBuilder::AddApps(const ExtensionSet* extensions, 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ExtensionAppList* apps) { 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (ExtensionSet::const_iterator app = extensions->begin(); 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) app != extensions->end(); ++app) { 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (ShouldDisplayInAppLauncher(profile_, *app)) 1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) apps->push_back(new ExtensionAppItem(profile_, 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (*app)->id(), 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "", 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::ImageSkia(), 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (*app)->is_platform_app())); 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ExtensionAppModelBuilder::BuildModel() { 1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Delete any extension apps. 1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) model_->item_list()->DeleteItemsByType(ExtensionAppItem::kAppType); 1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (tracker_) 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tracker_->RemoveObserver(this); 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) tracker_ = controller_->GetInstallTrackerFor(profile_); 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PopulateApps(); 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateHighlight(); 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Start observing after model is built. 1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (tracker_) 1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tracker_->AddObserver(this); 1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ExtensionAppModelBuilder::PopulateApps() { 1690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ExtensionSet extensions; 1700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) controller_->GetApps(profile_, &extensions); 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ExtensionAppList apps; 1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) AddApps(&extensions, &apps); 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (apps.empty()) 1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < apps.size(); ++i) 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) InsertApp(apps[i]); 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ExtensionAppModelBuilder::InsertApp(ExtensionAppItem* app) { 1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) model_->item_list()->AddItem(app); 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ExtensionAppModelBuilder::SetHighlightedApp( 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& extension_id) { 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (extension_id == highlight_app_id_) 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ExtensionAppItem* old_app = GetExtensionAppItem(highlight_app_id_); 1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (old_app) 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) old_app->SetHighlighted(false); 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) highlight_app_id_ = extension_id; 1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ExtensionAppItem* new_app = GetExtensionAppItem(highlight_app_id_); 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) highlighted_app_pending_ = !new_app; 1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (new_app) 1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new_app->SetHighlighted(true); 1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ExtensionAppItem* ExtensionAppModelBuilder::GetExtensionAppItem( 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& extension_id) { 2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) app_list::AppListItemModel* item = 2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) model_->item_list()->FindItem(extension_id); 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG_IF(ERROR, item && 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) item->GetAppType() != ExtensionAppItem::kAppType) 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << "App Item matching id: " << extension_id 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << " has incorrect type: '" << item->GetAppType() << "'"; 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return static_cast<ExtensionAppItem*>(item); 2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ExtensionAppModelBuilder::UpdateHighlight() { 2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(model_); 2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!highlighted_app_pending_ || highlight_app_id_.empty()) 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ExtensionAppItem* item = GetExtensionAppItem(highlight_app_id_); 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!item) 2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) item->SetHighlighted(true); 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) highlighted_app_pending_ = false; 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ExtensionAppModelBuilder::OnListItemMoved( 2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t from_index, 2231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t to_index, 2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) app_list::AppListItemModel* item) { 2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // This will get called from AppListItemList::ListItemMoved after 2261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // set_position is called for the item. 2271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) app_list::AppListItemList* item_list = model_->item_list(); 2288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (item->GetAppType() != ExtensionAppItem::kAppType) 2298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 2308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ExtensionAppItem* prev = NULL; 2321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (size_t idx = to_index; idx > 0; --idx) { 2331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) app_list::AppListItemModel* item = item_list->item_at(idx - 1); 2348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (item->GetAppType() == ExtensionAppItem::kAppType) { 2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) prev = static_cast<ExtensionAppItem*>(item); 2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) break; 2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ExtensionAppItem* next = NULL; 2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (size_t idx = to_index; idx < item_list->item_count() - 1; ++idx) { 2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) app_list::AppListItemModel* item = item_list->item_at(idx + 1); 2428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (item->GetAppType() == ExtensionAppItem::kAppType) { 2438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) next = static_cast<ExtensionAppItem*>(item); 2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) break; 2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // item->Move will call set_position, overriding the item's position. 2488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (prev || next) 2498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) static_cast<ExtensionAppItem*>(item)->Move(prev, next); 2508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 251