diff options
author | yoz@chromium.org <yoz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-03 22:57:43 +0000 |
---|---|---|
committer | yoz@chromium.org <yoz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-03 22:57:43 +0000 |
commit | 5806150245765654705eec1736d99ed797d074ec (patch) | |
tree | b33d32f3e2de65a67218a1f08894bd2c280f1026 | |
parent | 29ce8a20147c4051f28480819e98f3740f51676f (diff) | |
download | chromium_src-5806150245765654705eec1736d99ed797d074ec.zip chromium_src-5806150245765654705eec1736d99ed797d074ec.tar.gz chromium_src-5806150245765654705eec1736d99ed797d074ec.tar.bz2 |
Reland 'Show crashed apps on NTP, desaturated. Click to reload.'
Refactor CreateAppInfo less, since pyauto functional tests for the NTP expect it to still return something for special apps like the Webstore.
original CL at http://codereview.chromium.org/7517019
reverted CL at http://codereview.chromium.org/7553001
BUG=90433
TEST=Crash a packaged app with a background page. It appears on the NTP, and clicking its icon relaunches it. ntp pyauto functional tests also pass.
Review URL: http://codereview.chromium.org/7542027
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95348 0039d316-1c4b-4281-b951-d872f2087c98
4 files changed, 104 insertions, 68 deletions
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc index 155af6c..63cbdd2 100644 --- a/chrome/browser/automation/automation_provider_observers.cc +++ b/chrome/browser/automation/automation_provider_observers.cc @@ -2064,6 +2064,17 @@ NTPInfoObserver::NTPInfoObserver( apps_list->Append(*app); } delete disabled_apps; + // Process terminated extensions. + const ExtensionList* terminated_extensions = + ext_service->terminated_extensions(); + std::vector<DictionaryValue*>* terminated_apps = GetAppInfoFromExtensions( + terminated_extensions, ext_service); + for (std::vector<DictionaryValue*>::const_iterator app = + terminated_apps->begin(); app != terminated_apps->end(); ++app) { + (*app)->SetBoolean("is_disabled", true); + apps_list->Append(*app); + } + delete terminated_apps; ntp_info_->Set("apps", apps_list); // Get the info that would be displayed in the recently closed section. diff --git a/chrome/browser/ui/webui/extension_icon_source.cc b/chrome/browser/ui/webui/extension_icon_source.cc index 78c7b27..482c3ee 100644 --- a/chrome/browser/ui/webui/extension_icon_source.cc +++ b/chrome/browser/ui/webui/extension_icon_source.cc @@ -278,7 +278,7 @@ bool ExtensionIconSource::ParseData(const std::string& path, std::string extension_id = path_parts.at(0); const Extension* extension = - profile_->GetExtensionService()->GetExtensionById(extension_id, true); + profile_->GetExtensionService()->GetInstalledExtension(extension_id); if (!extension) return false; diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc index 2c9745c..f7a5e8f 100644 --- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc +++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc @@ -74,7 +74,7 @@ extension_misc::AppLaunchBucket ParseLaunchSource( } // namespace AppLauncherHandler::AppLauncherHandler(ExtensionService* extension_service) - : extensions_service_(extension_service), + : extension_service_(extension_service), promo_active_(false), ignore_changes_(false) { } @@ -96,11 +96,26 @@ static DictionaryValue* SerializeNotification( } // static +bool AppLauncherHandler::IsAppExcludedFromList(const Extension* extension) { + // Don't include the WebStore and the Cloud Print app. + // The WebStore launcher gets special treatment in ntp/apps.js. + // The Cloud Print app should never be displayed in the NTP. + bool ntp3 = + !CommandLine::ForCurrentProcess()->HasSwitch(switches::kNewTabPage4); + if (!extension->is_app() || + (ntp3 && extension->id() == extension_misc::kWebStoreAppId) || + (extension->id() == extension_misc::kCloudPrintAppId)) { + return false; + } + return true; +} + void AppLauncherHandler::CreateAppInfo(const Extension* extension, const AppNotification* notification, ExtensionService* service, DictionaryValue* value) { - bool enabled = service->IsExtensionEnabled(extension->id()); + bool enabled = service->IsExtensionEnabled(extension->id()) && + !service->GetTerminatedExtension(extension->id()); GURL icon_big = ExtensionIconSource::GetIconURL(extension, Extension::EXTENSION_ICON_LARGE, @@ -232,7 +247,7 @@ void AppLauncherHandler::Observe(int type, case chrome::NOTIFICATION_APP_NOTIFICATION_STATE_CHANGED: { const std::string& id = *Details<const std::string>(details).ptr(); const AppNotification* notification = - extensions_service_->app_notification_manager()->GetLast(id); + extension_service_->app_notification_manager()->GetLast(id); ListValue args; args.Append(new StringValue(id)); if (notification) @@ -293,29 +308,34 @@ void AppLauncherHandler::Observe(int type, void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) { ListValue* list = new ListValue(); - const ExtensionList* extensions = extensions_service_->extensions(); + const ExtensionList* extensions = extension_service_->extensions(); ExtensionList::const_iterator it; for (it = extensions->begin(); it != extensions->end(); ++it) { - // Don't include the WebStore and the Cloud Print app. - // The WebStore launcher gets special treatment in ntp/apps.js. - // The Cloud Print app should never be displayed in the NTP. - const Extension* extension = *it; - DictionaryValue* app_info = GetAppInfo(extension); - if (app_info) + if (!IsAppExcludedFromList(*it)) { + DictionaryValue* app_info = GetAppInfo(*it); + list->Append(app_info); + } + } + + extensions = extension_service_->disabled_extensions(); + for (it = extensions->begin(); it != extensions->end(); ++it) { + if (!IsAppExcludedFromList(*it)) { + DictionaryValue* app_info = new DictionaryValue(); + CreateAppInfo(*it, + NULL, + extension_service_, + app_info); list->Append(app_info); + } } - extensions = extensions_service_->disabled_extensions(); + extensions = extension_service_->terminated_extensions(); for (it = extensions->begin(); it != extensions->end(); ++it) { - bool ntp3 = - !CommandLine::ForCurrentProcess()->HasSwitch(switches::kNewTabPage4); - if ((*it)->is_app() && - !(ntp3 && (*it)->id() == extension_misc::kWebStoreAppId) && - ((*it)->id() != extension_misc::kCloudPrintAppId)) { + if (!IsAppExcludedFromList(*it)) { DictionaryValue* app_info = new DictionaryValue(); CreateAppInfo(*it, NULL, - extensions_service_, + extension_service_, app_info); list->Append(app_info); } @@ -339,8 +359,8 @@ void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) { dictionary->SetBoolean( "showLauncher", - extensions_service_->apps_promo()->ShouldShowAppLauncher( - extensions_service_->GetAppIds())); + extension_service_->apps_promo()->ShouldShowAppLauncher( + extension_service_->GetAppIds())); if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNewTabPage4)) { PrefService* prefs = web_ui_->GetProfile()->GetPrefs(); @@ -353,20 +373,12 @@ void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) { } DictionaryValue* AppLauncherHandler::GetAppInfo(const Extension* extension) { - bool ntp3 = - !CommandLine::ForCurrentProcess()->HasSwitch(switches::kNewTabPage4); - if (!extension->is_app() || - (ntp3 && extension->id() == extension_misc::kWebStoreAppId) || - (extension->id() == extension_misc::kCloudPrintAppId)) { - return NULL; - } - - DictionaryValue* app_info = new DictionaryValue(); AppNotificationManager* notification_manager = - extensions_service_->app_notification_manager(); + extension_service_->app_notification_manager(); + DictionaryValue* app_info = new DictionaryValue(); CreateAppInfo(extension, notification_manager->GetLast(extension->id()), - extensions_service_, + extension_service_, app_info); return app_info; } @@ -390,10 +402,10 @@ void AppLauncherHandler::HandleGetApps(const ListValue* args) { // expired. // b) Conceptually, it doesn't really make sense to count a // prefchange-triggered refresh as a promo 'view'. - AppsPromo* apps_promo = extensions_service_->apps_promo(); + AppsPromo* apps_promo = extension_service_->apps_promo(); PrefService* prefs = web_ui_->GetProfile()->GetPrefs(); bool apps_promo_just_expired = false; - if (apps_promo->ShouldShowPromo(extensions_service_->GetAppIds(), + if (apps_promo->ShouldShowPromo(extension_service_->GetAppIds(), &apps_promo_just_expired)) { apps_promo->MaximizeAppsIfNecessary(); dictionary.SetBoolean("showPromo", true); @@ -432,7 +444,7 @@ void AppLauncherHandler::HandleGetApps(const ListValue* args) { } if (pref_change_registrar_.IsEmpty()) { pref_change_registrar_.Init( - extensions_service_->extension_prefs()->pref_service()); + extension_service_->extension_prefs()->pref_service()); pref_change_registrar_.Add(ExtensionPrefs::kExtensionsPref, this); pref_change_registrar_.Add(prefs::kNTPAppPageNames, this); } @@ -464,7 +476,7 @@ void AppLauncherHandler::HandleLaunchApp(const ListValue* args) { launch_bucket < extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); const Extension* extension = - extensions_service_->GetExtensionById(extension_id, false); + extension_service_->GetExtensionById(extension_id, false); // Prompt the user to re-enable the application if disabled. if (!extension) { @@ -472,7 +484,7 @@ void AppLauncherHandler::HandleLaunchApp(const ListValue* args) { return; } - Profile* profile = extensions_service_->profile(); + Profile* profile = extension_service_->profile(); // If the user pressed special keys when clicking, override the saved // preference for launch container. @@ -483,7 +495,7 @@ void AppLauncherHandler::HandleLaunchApp(const ListValue* args) { if (extension_id != extension_misc::kWebStoreAppId) { RecordAppLaunchByID(promo_active_, launch_bucket); - extensions_service_->apps_promo()->ExpireDefaultApps(); + extension_service_->apps_promo()->ExpireDefaultApps(); } if (disposition == NEW_FOREGROUND_TAB || disposition == NEW_BACKGROUND_TAB) { @@ -498,7 +510,7 @@ void AppLauncherHandler::HandleLaunchApp(const ListValue* args) { // Look at preference to find the right launch container. If no preference // is set, launch as a regular tab. extension_misc::LaunchContainer launch_container = - extensions_service_->extension_prefs()->GetLaunchContainer( + extension_service_->extension_prefs()->GetLaunchContainer( extension, ExtensionPrefs::LAUNCH_REGULAR); // To give a more "launchy" experience when using the NTP launcher, we close @@ -525,7 +537,7 @@ void AppLauncherHandler::HandleSetLaunchType(const ListValue* args) { CHECK(args->GetDouble(1, &launch_type)); const Extension* extension = - extensions_service_->GetExtensionById(extension_id, true); + extension_service_->GetExtensionById(extension_id, true); CHECK(extension); // Don't update the page; it already knows about the launch type change. @@ -533,7 +545,7 @@ void AppLauncherHandler::HandleSetLaunchType(const ListValue* args) { if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNewTabPage4)) auto_reset.reset(new AutoReset<bool>(&ignore_changes_, true)); - extensions_service_->extension_prefs()->SetLaunchType( + extension_service_->extension_prefs()->SetLaunchType( extension_id, static_cast<ExtensionPrefs::LaunchType>( static_cast<int>(launch_type))); @@ -543,7 +555,7 @@ void AppLauncherHandler::HandleUninstallApp(const ListValue* args) { std::string extension_id; CHECK(args->GetString(0, &extension_id)); - const Extension* extension = extensions_service_->GetExtensionById( + const Extension* extension = extension_service_->GetExtensionById( extension_id, true); if (!extension) return; @@ -575,7 +587,7 @@ void AppLauncherHandler::HandleHideAppsPromo(const ListValue* args) { // this point, or the promotion wouldn't have been shown). ignore_changes_ = true; UninstallDefaultApps(); - extensions_service_->apps_promo()->HidePromo(); + extension_service_->apps_promo()->HidePromo(); ignore_changes_ = false; HandleGetApps(NULL); } @@ -588,7 +600,7 @@ void AppLauncherHandler::HandleCreateAppShortcut(const ListValue* args) { } const Extension* extension = - extensions_service_->GetExtensionById(extension_id, true); + extension_service_->GetExtensionById(extension_id, true); CHECK(extension); Browser* browser = BrowserList::GetLastActive(); @@ -618,8 +630,8 @@ void AppLauncherHandler::HandleReorderApps(const ListValue* args) { if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNewTabPage4)) auto_reset.reset(new AutoReset<bool>(&ignore_changes_, true)); - extensions_service_->extension_prefs()->SetAppDraggedByUser(dragged_app_id); - extensions_service_->extension_prefs()->SetAppLauncherOrder(extension_ids); + extension_service_->extension_prefs()->SetAppDraggedByUser(dragged_app_id); + extension_service_->extension_prefs()->SetAppLauncherOrder(extension_ids); } void AppLauncherHandler::HandleSetPageIndex(const ListValue* args) { @@ -633,7 +645,7 @@ void AppLauncherHandler::HandleSetPageIndex(const ListValue* args) { if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNewTabPage4)) auto_reset.reset(new AutoReset<bool>(&ignore_changes_, true)); - extensions_service_->extension_prefs()->SetPageIndex(extension_id, + extension_service_->extension_prefs()->SetPageIndex(extension_id, static_cast<int>(page_index)); } @@ -681,7 +693,7 @@ void AppLauncherHandler::HandleGenerateAppForLink(const ListValue* args) { if (!favicon_service) { LOG(ERROR) << "No favicon service"; scoped_refptr<CrxInstaller> installer( - extensions_service_->MakeCrxInstaller(NULL)); + extension_service_->MakeCrxInstaller(NULL)); installer->InstallWebApp(*web_app); return; } @@ -707,7 +719,7 @@ void AppLauncherHandler::OnFaviconForApp(FaviconService::Handle handle, } scoped_refptr<CrxInstaller> installer( - extensions_service_->MakeCrxInstaller(NULL)); + extension_service_->MakeCrxInstaller(NULL)); installer->InstallWebApp(*web_app); } @@ -764,16 +776,24 @@ void AppLauncherHandler::RecordAppLaunchByURL( void AppLauncherHandler::PromptToEnableApp(const std::string& extension_id) { const Extension* extension = - extensions_service_->GetExtensionById(extension_id, true); - CHECK(extension); + extension_service_->GetExtensionById(extension_id, true); + if (!extension) { + extension = extension_service_->GetTerminatedExtension(extension_id); + CHECK(extension); + // If the app was terminated, reload it first. (This reallocates the + // Extension object.) + extension_service_->ReloadExtension(extension_id); + extension = extension_service_->GetExtensionById(extension_id, true); + } - ExtensionPrefs* extension_prefs = extensions_service_->extension_prefs(); + ExtensionPrefs* extension_prefs = extension_service_->extension_prefs(); if (!extension_prefs->DidExtensionEscalatePermissions(extension_id)) { // Enable the extension immediately if its privileges weren't escalated. - extensions_service_->EnableExtension(extension_id); + // This is a no-op if the extension was previously terminated. + extension_service_->EnableExtension(extension_id); // Launch app asynchronously so the image will update. - StringValue* app_id = Value::CreateStringValue(extension->id()); + StringValue* app_id = Value::CreateStringValue(extension_id); web_ui_->CallJavascriptFunction("launchAppAfterEnable", *app_id); return; } @@ -792,12 +812,12 @@ void AppLauncherHandler::ExtensionDialogAccepted() { // The extension can be uninstalled in another window while the UI was // showing. Do nothing in that case. const Extension* extension = - extensions_service_->GetExtensionById(extension_id_prompting_, true); + extension_service_->GetExtensionById(extension_id_prompting_, true); if (!extension) return; - extensions_service_->UninstallExtension(extension_id_prompting_, - false /* external_uninstall */, NULL); + extension_service_->UninstallExtension(extension_id_prompting_, + false /* external_uninstall */, NULL); extension_id_prompting_ = ""; } @@ -813,11 +833,11 @@ void AppLauncherHandler::InstallUIProceed() { // The extension can be uninstalled in another window while the UI was // showing. Do nothing in that case. const Extension* extension = - extensions_service_->GetExtensionById(extension_id_prompting_, true); + extension_service_->GetExtensionById(extension_id_prompting_, true); if (!extension) return; - extensions_service_->GrantPermissionsAndEnableExtension(extension); + extension_service_->GrantPermissionsAndEnableExtension(extension); // We bounce this off the NTP so the browser can update the apps icon. // If we don't launch the app asynchronously, then the app's disabled @@ -833,7 +853,7 @@ void AppLauncherHandler::InstallUIAbort(bool user_initiated) { // We record the histograms here because ExtensionDialogCanceled is also // called when the extension uninstall dialog is canceled. const Extension* extension = - extensions_service_->GetExtensionById(extension_id_prompting_, true); + extension_service_->GetExtensionById(extension_id_prompting_, true); std::string histogram_name = user_initiated ? "Extensions.Permissions_ReEnableCancel" : "Extensions.Permissions_ReEnableAbort"; @@ -860,11 +880,11 @@ ExtensionInstallUI* AppLauncherHandler::GetExtensionInstallUI() { } void AppLauncherHandler::UninstallDefaultApps() { - AppsPromo* apps_promo = extensions_service_->apps_promo(); + AppsPromo* apps_promo = extension_service_->apps_promo(); const ExtensionIdSet& app_ids = apps_promo->old_default_apps(); for (ExtensionIdSet::const_iterator iter = app_ids.begin(); iter != app_ids.end(); ++iter) { - if (extensions_service_->GetExtensionById(*iter, true)) - extensions_service_->UninstallExtension(*iter, false, NULL); + if (extension_service_->GetExtensionById(*iter, true)) + extension_service_->UninstallExtension(*iter, false, NULL); } } diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.h b/chrome/browser/ui/webui/ntp/app_launcher_handler.h index 7d6305c..5801f6f 100644 --- a/chrome/browser/ui/webui/ntp/app_launcher_handler.h +++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.h @@ -40,11 +40,16 @@ class AppLauncherHandler : public WebUIMessageHandler, explicit AppLauncherHandler(ExtensionService* extension_service); virtual ~AppLauncherHandler(); + // Whether the app should be excluded from the "apps" list because + // it is special (such as the Web Store app). + static bool IsAppExcludedFromList(const Extension* extension); + // Populate a dictionary with the information from an extension. - static void CreateAppInfo(const Extension* extension, - const AppNotification* notification, - ExtensionService* service, - base::DictionaryValue* value); + static void CreateAppInfo( + const Extension* extension, + const AppNotification* notification, + ExtensionService* service, + base::DictionaryValue* value); // Callback for pings related to launching apps on the NTP. static bool HandlePing(Profile* profile, const std::string& path); @@ -148,8 +153,8 @@ class AppLauncherHandler : public WebUIMessageHandler, history::FaviconData data); // The apps are represented in the extensions model, which - // outlives us since its owned by our containing profile. - ExtensionService* const extensions_service_; + // outlives us since it's owned by our containing profile. + ExtensionService* const extension_service_; // We monitor changes to the extension system so that we can reload the apps // when necessary. |