15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "apps/metrics_names.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/auto_reset.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/field_trial.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/browser_process.h" 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/crx_installer.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_system.h" 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/extensions/launch_util.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/favicon/favicon_service_factory.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_util.h" 298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/ui/browser_dialogs.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_tabstrip.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/extensions/application_launch.h" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/extensions/extension_enable_flow.h" 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/ui/webui/extensions/extension_basic_info.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/extensions/extension_icon_source.h" 38558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/new_tab_ui.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_icon_set.h" 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/app_launch_info.h" 439ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "chrome/common/favicon/favicon_types.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/common/web_application_info.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui.h" 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/favicon_url.h" 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/app_sorting.h" 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/management_policy.h" 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/constants.h" 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/browser_resources.h" 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h" 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/base/webui/web_ui_util.h" 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/favicon_size.h" 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using extensions::AppSorting; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::CrxInstaller; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::ExtensionPrefs; 661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using extensions::UnloadedExtensionInfo; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShouldDisplayInNewTabPage(const Extension* app, PrefService* prefs) { 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool blocked_by_policy = 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (app->id() == extension_misc::kWebStoreAppId || 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app->id() == extension_misc::kEnterpriseWebStoreAppId) && 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prefs->GetBoolean(prefs::kHideWebStoreIcon); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return app->ShouldDisplayInNewTabPage() && !blocked_by_policy; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid RecordAppLauncherPromoHistogram( 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch apps::AppLauncherPromoHistogramValues value) { 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_LT(value, apps::APP_LAUNCHER_PROMO_MAX); 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch UMA_HISTOGRAM_ENUMERATION( 827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "Apps.AppLauncherPromo", value, apps::APP_LAUNCHER_PROMO_MAX); 837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// This is used to avoid a DCHECK due to an unhandled WebUI callback. The 86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// JavaScript used to switch between pages sends "pageSelected" which is used 87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// in the context of the NTP for recording metrics we don't need here. 88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void NoOpCallback(const ListValue* args) {} 89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppLauncherHandler::AppInstallInfo::AppInstallInfo() {} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppLauncherHandler::AppInstallInfo::~AppInstallInfo() {} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppLauncherHandler::AppLauncherHandler(ExtensionService* extension_service) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : extension_service_(extension_service), 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignore_changes_(false), 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attempted_bookmark_app_install_(false), 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_loaded_apps_(false) { 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (IsAppLauncherEnabled()) 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch RecordAppLauncherPromoHistogram(apps::APP_LAUNCHER_PROMO_ALREADY_INSTALLED); 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) else if (ShouldShowAppLauncherPromo()) 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch RecordAppLauncherPromoHistogram(apps::APP_LAUNCHER_PROMO_SHOWN); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppLauncherHandler::~AppLauncherHandler() {} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::CreateAppInfo( 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionService* service, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* value) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->Clear(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The Extension class 'helpfully' wraps bidi control characters that 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // impede our ability to determine directionality. 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 short_name = UTF8ToUTF16(extension->short_name()); 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::i18n::UnadjustStringForLocaleDirection(&short_name); 119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) NewTabUI::SetUrlTitleAndDirection( 120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) value, 121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) short_name, 122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) extensions::AppLaunchInfo::GetFullLaunchURL(extension)); 123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 name = UTF8ToUTF16(extension->name()); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::i18n::UnadjustStringForLocaleDirection(&name); 126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) NewTabUI::SetFullNameAndDirection(name, value); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enabled = service->IsExtensionEnabled(extension->id()) && 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !service->GetTerminatedExtension(extension->id()); 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extensions::GetExtensionBasicInfo(extension, enabled, value); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetBoolean("mayDisable", extensions::ExtensionSystem::Get( 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service->profile())->management_policy()->UserMayModifySettings( 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension, NULL)); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool icon_big_exists = true; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Instead of setting grayscale here, we do it in apps_page.js. 138a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GURL icon_big = extensions::ExtensionIconSource::GetIconURL( 139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension, 140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension_misc::EXTENSION_ICON_LARGE, 141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ExtensionIconSet::MATCH_BIGGER, 142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) false, 143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &icon_big_exists); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetString("icon_big", icon_big.spec()); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetBoolean("icon_big_exists", icon_big_exists); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool icon_small_exists = true; 147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GURL icon_small = extensions::ExtensionIconSource::GetIconURL( 148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension, 149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension_misc::EXTENSION_ICON_BITTY, 150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ExtensionIconSet::MATCH_BIGGER, 151a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) false, 152a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &icon_small_exists); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetString("icon_small", icon_small.spec()); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetBoolean("icon_small_exists", icon_small_exists); 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) value->SetInteger("launch_container", 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extensions::AppLaunchInfo::GetLaunchContainer(extension)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionPrefs* prefs = service->extension_prefs(); 158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) value->SetInteger("launch_type", extensions::GetLaunchType(prefs, extension)); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetBoolean("is_component", 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->location() == extensions::Manifest::COMPONENT); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetBoolean("is_webstore", 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension->id() == extension_misc::kWebStoreAppId); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AppSorting* sorting = prefs->app_sorting(); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::StringOrdinal page_ordinal = sorting->GetPageOrdinal(extension->id()); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!page_ordinal.IsValid()) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure every app has a page ordinal (some predate the page ordinal). 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The webstore app should be on the first page. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page_ordinal = extension->id() == extension_misc::kWebStoreAppId ? 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->CreateFirstAppPageOrdinal() : 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->GetNaturalAppPageOrdinal(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->SetPageOrdinal(extension->id(), page_ordinal); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetInteger("page_index", 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->PageStringOrdinalAsInteger(page_ordinal)); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::StringOrdinal app_launch_ordinal = 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->GetAppLaunchOrdinal(extension->id()); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!app_launch_ordinal.IsValid()) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure every app has a launch ordinal (some predate the launch 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ordinal). The webstore's app launch ordinal is always set to the first 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // position. 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_launch_ordinal = extension->id() == extension_misc::kWebStoreAppId ? 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->CreateFirstAppLaunchOrdinal(page_ordinal) : 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->CreateNextAppLaunchOrdinal(page_ordinal); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->SetAppLaunchOrdinal(extension->id(), app_launch_ordinal); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetString("app_launch_ordinal", app_launch_ordinal.ToInternalValue()); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::RegisterMessages() { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<WebContents>(web_ui()->GetWebContents())); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Some tests don't have a local state. 1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_APP_LIST) 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (g_browser_process->local_state()) { 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) local_state_pref_change_registrar_.Init(g_browser_process->local_state()); 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) local_state_pref_change_registrar_.Add( 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) prefs::kShowAppLauncherPromo, 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&AppLauncherHandler::OnLocalStatePreferenceChanged, 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->RegisterMessageCallback("getApps", 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppLauncherHandler::HandleGetApps, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->RegisterMessageCallback("launchApp", 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppLauncherHandler::HandleLaunchApp, 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->RegisterMessageCallback("setLaunchType", 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppLauncherHandler::HandleSetLaunchType, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->RegisterMessageCallback("uninstallApp", 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppLauncherHandler::HandleUninstallApp, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->RegisterMessageCallback("createAppShortcut", 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppLauncherHandler::HandleCreateAppShortcut, 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->RegisterMessageCallback("reorderApps", 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppLauncherHandler::HandleReorderApps, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->RegisterMessageCallback("setPageIndex", 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppLauncherHandler::HandleSetPageIndex, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->RegisterMessageCallback("saveAppPageName", 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppLauncherHandler::HandleSaveAppPageName, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->RegisterMessageCallback("generateAppForLink", 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppLauncherHandler::HandleGenerateAppForLink, 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) web_ui()->RegisterMessageCallback("stopShowingAppLauncherPromo", 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&AppLauncherHandler::StopShowingAppLauncherPromo, 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch web_ui()->RegisterMessageCallback("onLearnMore", 236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&AppLauncherHandler::OnLearnMore, 237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Unretained(this))); 238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) web_ui()->RegisterMessageCallback("pageSelected", base::Bind(&NoOpCallback)); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::Observe(int type, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == chrome::NOTIFICATION_APP_INSTALLED_TO_NTP) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) highlight_app_id_ = *content::Details<const std::string>(details).ptr(); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_loaded_apps_) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAppToBeHighlighted(); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ignore_changes_ || !has_loaded_apps_) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_LOADED: { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<const Extension>(details).ptr(); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension->is_app()) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); 262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ShouldDisplayInNewTabPage(extension, prefs)) 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DictionaryValue> app_info(GetAppInfo(extension)); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (app_info.get()) { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visible_apps_.insert(extension->id()); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionPrefs* prefs = extension_service_->extension_prefs(); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::FundamentalValue> highlight(Value::CreateBooleanValue( 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs->IsFromBookmark(extension->id()) && 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attempted_bookmark_app_install_)); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attempted_bookmark_app_install_ = false; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->CallJavascriptFunction( 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ntp.appAdded", *app_info, *highlight); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_UNLOADED: 2813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: { 2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Extension* extension = NULL; 2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool uninstalled = false; 2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (type == chrome::NOTIFICATION_EXTENSION_UNINSTALLED) { 2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) extension = content::Details<const Extension>(details).ptr(); 2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) uninstalled = true; 2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { // NOTIFICATION_EXTENSION_UNLOADED 2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (content::Details<UnloadedExtensionInfo>(details)->reason == 2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UnloadedExtensionInfo::REASON_UNINSTALL) { 2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Uninstalls are tracked by NOTIFICATION_EXTENSION_UNINSTALLED. 2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) extension = content::Details<extensions::UnloadedExtensionInfo>( 2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) details)->extension; 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) uninstalled = false; 2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension->is_app()) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); 301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ShouldDisplayInNewTabPage(extension, prefs)) 302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DictionaryValue> app_info(GetAppInfo(extension)); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (app_info.get()) { 30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (uninstalled) 30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) visible_apps_.erase(extension->id()); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<base::FundamentalValue> uninstall_value( 3103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Value::CreateBooleanValue(uninstalled)); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::FundamentalValue> from_page( 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value::CreateBooleanValue(!extension_id_prompting_.empty())); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->CallJavascriptFunction( 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ntp.appRemoved", *app_info, *uninstall_value, *from_page); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED: { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string* id = 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<const std::string>(details).ptr(); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension_service_->GetInstalledExtension(*id); 3249ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch if (!extension) { 3259ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch // Extension could still be downloading or installing. 3269ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch return; 3279ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch } 3289ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue app_info; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateAppInfo(extension, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_service_, 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &app_info); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->CallJavascriptFunction("ntp.appMoved", app_info); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HandleGetApps(NULL); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR: { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrxInstaller* crx_installer = content::Source<CrxInstaller>(source).ptr(); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Profile::FromWebUI(web_ui())->IsSameProfile( 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crx_installer->profile())) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fall through. 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR: { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attempted_bookmark_app_install_ = false; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CreateAppInfo and ClearOrdinals can change the extension prefs. 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<bool> auto_reset(&ignore_changes_, true); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue* list = new ListValue(); 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<std::string>::iterator it = visible_apps_.begin(); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != visible_apps_.end(); ++it) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = extension_service_->GetInstalledExtension(*it); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension && ShouldDisplayInNewTabPage(extension, prefs)) { 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* app_info = GetAppInfo(extension); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list->Append(app_info); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary->Set("apps", list); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(estade): remove these settings when the old NTP is removed. The new 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NTP does it in js. 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // App windows are not yet implemented on mac. 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary->SetBoolean("disableAppWindowLaunch", true); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary->SetBoolean("disableCreateAppShortcut", true); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Making shortcut does not make sense on ChromeOS because it does not have 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a desktop. 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary->SetBoolean("disableCreateAppShortcut", true); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ListValue* app_page_names = prefs->GetList(prefs::kNtpAppPageNames); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!app_page_names || !app_page_names->GetSize()) { 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListPrefUpdate update(prefs, prefs::kNtpAppPageNames); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue* list = update.Get(); 392a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch list->Set(0, new base::StringValue( 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_APP_DEFAULT_PAGE_NAME))); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary->Set("appPageNames", 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<ListValue*>(list->DeepCopy())); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary->Set("appPageNames", 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<ListValue*>(app_page_names->DeepCopy())); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DictionaryValue* AppLauncherHandler::GetAppInfo(const Extension* extension) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* app_info = new DictionaryValue(); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CreateAppInfo can change the extension prefs. 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<bool> auto_reset(&ignore_changes_, true); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateAppInfo(extension, 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_service_, 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_info); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return app_info; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::HandleGetApps(const ListValue* args) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue dictionary; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell the client whether to show the promo for this view. We don't do this 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the case of PREF_CHANGED because: 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a) At that point in time, depending on the pref that changed, it can look 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // like the set of apps installed has changed, and we will mark the promo 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // expired. 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // b) Conceptually, it doesn't really make sense to count a 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // prefchange-triggered refresh as a promo 'view'. 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = Profile::FromWebUI(web_ui()); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first time we load the apps we must add all current app to the list 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of apps visible on the NTP. 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_loaded_apps_) { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExtensionSet* extensions = extension_service_->extensions(); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExtensionSet::const_iterator it = extensions->begin(); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != extensions->end(); ++it) { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visible_apps_.insert((*it)->id()); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions = extension_service_->disabled_extensions(); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExtensionSet::const_iterator it = extensions->begin(); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != extensions->end(); ++it) { 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visible_apps_.insert((*it)->id()); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions = extension_service_->terminated_extensions(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExtensionSet::const_iterator it = extensions->begin(); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != extensions->end(); ++it) { 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visible_apps_.insert((*it)->id()); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAppToBeHighlighted(); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillAppDictionary(&dictionary); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->CallJavascriptFunction("ntp.getAppsCallback", dictionary); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First time we get here we set up the observer so that we can tell update 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the apps as they change. 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_loaded_apps_) { 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Closure callback = base::Bind( 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &AppLauncherHandler::OnExtensionPreferenceChanged, 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this)); 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension_pref_change_registrar_.Init( 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_service_->extension_prefs()->pref_service()); 4593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) extension_pref_change_registrar_.Add(prefs::kExtensionsPref, callback); 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension_pref_change_registrar_.Add(prefs::kNtpAppPageNames, callback); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile)); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile)); 4663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED, 4673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::Source<Profile>(profile)); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED, 469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Source<AppSorting>( 470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension_service_->extension_prefs()->app_sorting())); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR, 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<CrxInstaller>(NULL)); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOAD_ERROR, 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile)); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_loaded_apps_ = true; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::HandleLaunchApp(const ListValue* args) { 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_id; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetString(0, &extension_id)); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double source = -1.0; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetDouble(1, &source)); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args->GetSize() > 2) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetString(2, &url)); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_misc::AppLaunchBucket launch_bucket = 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<extension_misc::AppLaunchBucket>( 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(source)); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(launch_bucket >= 0 && 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launch_bucket < extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_service_->GetExtensionById(extension_id, false); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prompt the user to re-enable the application if disabled. 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension) { 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PromptToEnableApp(extension_id); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = extension_service_->profile(); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowOpenDisposition disposition = args->GetSize() > 3 ? 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webui::GetDispositionFromClick(args, 3) : CURRENT_TAB; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_id != extension_misc::kWebStoreAppId) { 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_NE(launch_bucket, extension_misc::APP_LAUNCH_BUCKET_INVALID); 510558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CoreAppLauncherHandler::RecordAppLaunchType(launch_bucket, 511558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch extension->GetType()); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 513a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CoreAppLauncherHandler::RecordWebStoreLaunch(); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (disposition == NEW_FOREGROUND_TAB || disposition == NEW_BACKGROUND_TAB || 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disposition == NEW_WINDOW) { 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jamescook): Proper support for background tabs. 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppLaunchParams params(profile, extension, 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) disposition == NEW_WINDOW ? 521a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) extensions::LAUNCH_CONTAINER_WINDOW : 522a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) extensions::LAUNCH_CONTAINER_TAB, 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) disposition); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.override_url = GURL(url); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenApplication(params); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To give a more "launchy" experience when using the NTP launcher, we close 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it automatically. 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents( 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->GetWebContents()); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* old_contents = NULL; 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser) 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) old_contents = browser->tab_strip_model()->GetActiveWebContents(); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppLaunchParams params(profile, extension, 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) old_contents ? CURRENT_TAB : NEW_FOREGROUND_TAB); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.override_url = GURL(url); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* new_contents = OpenApplication(params); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will also destroy the handler, so do not perform any actions after. 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (new_contents != old_contents && browser && 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->tab_strip_model()->count() > 1) { 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::CloseWebContents(browser, old_contents, true); 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::HandleSetLaunchType(const ListValue* args) { 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_id; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double launch_type; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetString(0, &extension_id)); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetDouble(1, &launch_type)); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_service_->GetExtensionById(extension_id, true); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't update the page; it already knows about the launch type change. 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<bool> auto_reset(&ignore_changes_, true); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 562a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) extensions::SetLaunchType( 563a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) extension_service_->extension_prefs(), 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_id, 565a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static_cast<extensions::LaunchType>( 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(launch_type))); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::HandleUninstallApp(const ListValue* args) { 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_id; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetString(0, &extension_id)); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const Extension* extension = extension_service_->GetInstalledExtension( 5748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) extension_id); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extensions::ExtensionSystem::Get(extension_service_->profile())-> 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) management_policy()->UserMayModifySettings(extension, NULL)) { 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Attempt to uninstall an extension that is non-usermanagable " 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "was made. Extension id : " << extension->id(); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension_id_prompting_.empty()) 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Only one prompt at a time. 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_id_prompting_ = extension_id; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool dont_confirm = false; 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args->GetBoolean(1, &dont_confirm) && dont_confirm) { 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<bool> auto_reset(&ignore_changes_, true); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionUninstallAccepted(); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetExtensionUninstallDialog()->ConfirmUninstall(extension); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::HandleCreateAppShortcut(const ListValue* args) { 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_id; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetString(0, &extension_id)); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_service_->GetExtensionById(extension_id, true); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents( 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->GetWebContents()); 6098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) chrome::ShowCreateChromeAppShortcutsDialog( 6108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) browser->window()->GetNativeWindow(), browser->profile(), extension, 6118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Closure()); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::HandleReorderApps(const ListValue* args) { 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetSize() == 2); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dragged_app_id; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ListValue* app_order; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetString(0, &dragged_app_id)); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetList(1, &app_order)); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string predecessor_to_moved_ext; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string successor_to_moved_ext; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < app_order->GetSize(); ++i) { 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (app_order->GetString(i, &value) && value == dragged_app_id) { 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i > 0) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(app_order->GetString(i - 1, &predecessor_to_moved_ext)); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i + 1 < app_order->GetSize()) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(app_order->GetString(i + 1, &successor_to_moved_ext)); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't update the page; it already knows the apps have been reordered. 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<bool> auto_reset(&ignore_changes_, true); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_service_->extension_prefs()->SetAppDraggedByUser(dragged_app_id); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_service_->OnExtensionMoved(dragged_app_id, 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) predecessor_to_moved_ext, 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) successor_to_moved_ext); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::HandleSetPageIndex(const ListValue* args) { 644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AppSorting* app_sorting = 645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension_service_->extension_prefs()->app_sorting(); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_id; 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double page_index; 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetString(0, &extension_id)); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetDouble(1, &page_index)); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncer::StringOrdinal& page_ordinal = 652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) app_sorting->PageIntegerAsStringOrdinal(static_cast<size_t>(page_index)); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't update the page; it already knows the apps have been reordered. 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<bool> auto_reset(&ignore_changes_, true); 656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) app_sorting->SetPageOrdinal(extension_id, page_ordinal); 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::HandleSaveAppPageName(const ListValue* args) { 660a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 name; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetString(0, &name)); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double page_index; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetDouble(1, &page_index)); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<bool> auto_reset(&ignore_changes_, true); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListPrefUpdate update(prefs, prefs::kNtpAppPageNames); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue* list = update.Get(); 670a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch list->Set(static_cast<size_t>(page_index), new base::StringValue(name)); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::HandleGenerateAppForLink(const ListValue* args) { 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetString(0, &url)); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL launch_url(url); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 678a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 title; 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetString(1, &title)); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double page_index; 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args->GetDouble(2, &page_index)); 683f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AppSorting* app_sorting = 684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension_service_->extension_prefs()->app_sorting(); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncer::StringOrdinal& page_ordinal = 686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) app_sorting->PageIntegerAsStringOrdinal(static_cast<size_t>(page_index)); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = Profile::FromWebUI(web_ui()); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FaviconService* favicon_service = 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FaviconServiceFactory::GetForProfile(profile, Profile::EXPLICIT_ACCESS); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!favicon_service) { 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "No favicon service"; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AppInstallInfo> install_info(new AppInstallInfo()); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) install_info->is_bookmark_app = true; 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) install_info->title = title; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) install_info->app_url = launch_url; 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) install_info->page_ordinal = page_ordinal; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) favicon_service->GetFaviconImageForURL( 703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FaviconService::FaviconForURLParams(launch_url, 70490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::FAVICON, 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::kFaviconSize), 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&AppLauncherHandler::OnFaviconForApp, 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&install_info)), 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &cancelable_task_tracker_); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AppLauncherHandler::StopShowingAppLauncherPromo( 713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue* args) { 7144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_APP_LIST) 715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) g_browser_process->local_state()->SetBoolean( 7164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) prefs::kShowAppLauncherPromo, false); 717eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RecordAppLauncherPromoHistogram(apps::APP_LAUNCHER_PROMO_DISMISSED); 7184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 719eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 720eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 721eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid AppLauncherHandler::OnLearnMore(const base::ListValue* args) { 722eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RecordAppLauncherPromoHistogram(apps::APP_LAUNCHER_PROMO_LEARN_MORE); 723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::OnFaviconForApp( 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AppInstallInfo> install_info, 72790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const chrome::FaviconImageResult& image_result) { 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WebApplicationInfo> web_app(new WebApplicationInfo()); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_app->is_bookmark_app = install_info->is_bookmark_app; 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_app->title = install_info->title; 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_app->app_url = install_info->app_url; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_app->urls.push_back(install_info->app_url); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!image_result.image.IsEmpty()) { 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebApplicationInfo::IconInfo icon; 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon.data = image_result.image.AsBitmap(); 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon.width = icon.data.width(); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon.height = icon.data.height(); 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_app->icons.push_back(icon); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<CrxInstaller> installer( 743ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CrxInstaller::CreateSilent(extension_service_)); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->set_error_on_unsupported_requirements(true); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->set_page_ordinal(install_info->page_ordinal); 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->InstallWebApp(*web_app); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attempted_bookmark_app_install_ = true; 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::SetAppToBeHighlighted() { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (highlight_app_id_.empty()) 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringValue app_id(highlight_app_id_); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->CallJavascriptFunction("ntp.setAppToBeHighlighted", app_id); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) highlight_app_id_.clear(); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AppLauncherHandler::OnExtensionPreferenceChanged() { 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryValue dictionary; 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FillAppDictionary(&dictionary); 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_ui()->CallJavascriptFunction("ntp.appsPrefChangeCallback", dictionary); 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AppLauncherHandler::OnLocalStatePreferenceChanged() { 7664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_APP_LIST) 767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) web_ui()->CallJavascriptFunction( 768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "ntp.appLauncherPromoPrefChangeCallback", 769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FundamentalValue(g_browser_process->local_state()->GetBoolean( 7704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) prefs::kShowAppLauncherPromo))); 7714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::CleanupAfterUninstall() { 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_id_prompting_.clear(); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::PromptToEnableApp(const std::string& extension_id) { 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension_id_prompting_.empty()) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Only one prompt at a time. 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_id_prompting_ = extension_id; 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_enable_flow_.reset(new ExtensionEnableFlow( 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile::FromWebUI(web_ui()), extension_id, this)); 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_enable_flow_->StartForWebContents(web_ui()->GetWebContents()); 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::ExtensionUninstallAccepted() { 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do the uninstall work here. 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!extension_id_prompting_.empty()); 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The extension can be uninstalled in another window while the UI was 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // showing. Do nothing in that case. 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = 7958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) extension_service_->GetInstalledExtension(extension_id_prompting_); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension) 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_service_->UninstallExtension(extension_id_prompting_, 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /* external_uninstall */, NULL); 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CleanupAfterUninstall(); 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppLauncherHandler::ExtensionUninstallCanceled() { 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CleanupAfterUninstall(); 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppLauncherHandler::ExtensionEnableFlowFinished() { 8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(extension_id_prompting_, extension_enable_flow_->extension_id()); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We bounce this off the NTP so the browser can update the apps icon. 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we don't launch the app asynchronously, then the app's disabled 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // icon disappears but isn't replaced by the enabled icon, making a poor 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // visual experience. 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StringValue app_id(extension_id_prompting_); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->CallJavascriptFunction("ntp.launchAppAfterEnable", app_id); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_enable_flow_.reset(); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_id_prompting_ = ""; 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppLauncherHandler::ExtensionEnableFlowAborted(bool user_initiated) { 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(extension_id_prompting_, extension_enable_flow_->extension_id()); 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We record the histograms here because ExtensionUninstallCanceled is also 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // called when the extension uninstall dialog is canceled. 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_service_->GetExtensionById(extension_id_prompting_, true); 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string histogram_name = user_initiated ? 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Extensions.Permissions_ReEnableCancel" : 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Extensions.Permissions_ReEnableAbort"; 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionService::RecordPermissionMessagesHistogram( 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension, histogram_name.c_str()); 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_enable_flow_.reset(); 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CleanupAfterUninstall(); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionUninstallDialog* AppLauncherHandler::GetExtensionUninstallDialog() { 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension_uninstall_dialog_.get()) { 8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents( 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_ui()->GetWebContents()); 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_uninstall_dialog_.reset( 8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionUninstallDialog::Create(extension_service_->profile(), 8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser, this)); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension_uninstall_dialog_.get(); 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 849