| Index: chrome/browser/dom_ui/app_launcher_handler.cc
|
| diff --git a/chrome/browser/dom_ui/app_launcher_handler.cc b/chrome/browser/dom_ui/app_launcher_handler.cc
|
| index 9bc27d250843a7881f8d5f725dd1338701c4aa54..f55052576f9365503d58708fa7c16d808294bb80 100644
|
| --- a/chrome/browser/dom_ui/app_launcher_handler.cc
|
| +++ b/chrome/browser/dom_ui/app_launcher_handler.cc
|
| @@ -5,7 +5,9 @@
|
| #include "chrome/browser/dom_ui/app_launcher_handler.h"
|
|
|
| #include "app/animation.h"
|
| +#include "base/metrics/histogram.h"
|
| #include "base/string_number_conversions.h"
|
| +#include "base/string_split.h"
|
| #include "base/string_util.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "base/values.h"
|
| @@ -32,6 +34,11 @@
|
|
|
| namespace {
|
|
|
| +// The URL prefixes used by the NTP to signal when the web store or an app
|
| +// has launched. These are used for histogram purposes.
|
| +const char* kLaunchAppPingURL = "record-app-launch";
|
| +const char* kLaunchWebStorePingURL = "record-webstore-launch";
|
| +
|
| // This extracts an int from a ListValue at the given |index|.
|
| bool ExtractInt(const ListValue* list, size_t index, int* out_int) {
|
| std::string string_value;
|
| @@ -53,14 +60,67 @@ std::string GetIconURL(const Extension* extension, Extension::Icons icon,
|
| return default_val;
|
| }
|
|
|
| +// Extracts the promo parameter from the |path| generated by a ping on the NTP.
|
| +bool IsPromoActive(const std::string& path) {
|
| + std::vector<std::string> params;
|
| + base::SplitString(path, '+', ¶ms);
|
| +
|
| + CHECK(params.size() == 2);
|
| +
|
| + return params.at(1) == "true";
|
| +}
|
| +
|
| } // namespace
|
|
|
| AppLauncherHandler::AppLauncherHandler(ExtensionsService* extension_service)
|
| - : extensions_service_(extension_service) {
|
| + : extensions_service_(extension_service),
|
| + promo_active_(false) {
|
| }
|
|
|
| AppLauncherHandler::~AppLauncherHandler() {}
|
|
|
| +// static
|
| +void AppLauncherHandler::CreateAppInfo(const Extension* extension,
|
| + ExtensionPrefs* extension_prefs,
|
| + DictionaryValue* value) {
|
| + value->Clear();
|
| + value->SetString("id", extension->id());
|
| + value->SetString("name", extension->name());
|
| + value->SetString("description", extension->description());
|
| + value->SetString("launch_url", extension->GetFullLaunchURL().spec());
|
| + value->SetString("options_url", extension->options_url().spec());
|
| + value->SetString("icon_big", GetIconURL(
|
| + extension, Extension::EXTENSION_ICON_LARGE,
|
| + "chrome://theme/IDR_APP_DEFAULT_ICON"));
|
| + value->SetString("icon_small", GetIconURL(
|
| + extension, Extension::EXTENSION_ICON_BITTY,
|
| + std::string("chrome://favicon/") + extension->GetFullLaunchURL().spec()));
|
| + value->SetInteger("launch_container", extension->launch_container());
|
| + value->SetInteger("launch_type",
|
| + extension_prefs->GetLaunchType(extension->id()));
|
| +
|
| + int app_launch_index = extension_prefs->GetAppLaunchIndex(extension->id());
|
| + if (app_launch_index == -1) {
|
| + // Make sure every app has a launch index (some predate the launch index).
|
| + app_launch_index = extension_prefs->GetNextAppLaunchIndex();
|
| + extension_prefs->SetAppLaunchIndex(extension->id(), app_launch_index);
|
| + }
|
| + value->SetInteger("app_launch_index", app_launch_index);
|
| +}
|
| +
|
| +// static
|
| +bool AppLauncherHandler::HandlePing(const std::string& path) {
|
| + if (path.find(kLaunchWebStorePingURL) != std::string::npos) {
|
| + RecordWebStoreLaunch(IsPromoActive(path));
|
| + return true;
|
| + } else if (path.find(kLaunchAppPingURL) != std::string::npos) {
|
| + RecordAppLaunch(IsPromoActive(path));
|
| + return true;
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| DOMMessageHandler* AppLauncherHandler::Attach(DOMUI* dom_ui) {
|
| // TODO(arv): Add initialization code to the Apps store etc.
|
| return DOMMessageHandler::Attach(dom_ui);
|
| @@ -102,35 +162,6 @@ void AppLauncherHandler::Observe(NotificationType type,
|
| }
|
| }
|
|
|
| -// static
|
| -void AppLauncherHandler::CreateAppInfo(const Extension* extension,
|
| - ExtensionPrefs* extension_prefs,
|
| - DictionaryValue* value) {
|
| - value->Clear();
|
| - value->SetString("id", extension->id());
|
| - value->SetString("name", extension->name());
|
| - value->SetString("description", extension->description());
|
| - value->SetString("launch_url", extension->GetFullLaunchURL().spec());
|
| - value->SetString("options_url", extension->options_url().spec());
|
| - value->SetString("icon_big", GetIconURL(
|
| - extension, Extension::EXTENSION_ICON_LARGE,
|
| - "chrome://theme/IDR_APP_DEFAULT_ICON"));
|
| - value->SetString("icon_small", GetIconURL(
|
| - extension, Extension::EXTENSION_ICON_BITTY,
|
| - std::string("chrome://favicon/") + extension->GetFullLaunchURL().spec()));
|
| - value->SetInteger("launch_container", extension->launch_container());
|
| - value->SetInteger("launch_type",
|
| - extension_prefs->GetLaunchType(extension->id()));
|
| -
|
| - int app_launch_index = extension_prefs->GetAppLaunchIndex(extension->id());
|
| - if (app_launch_index == -1) {
|
| - // Make sure every app has a launch index (some predate the launch index).
|
| - app_launch_index = extension_prefs->GetNextAppLaunchIndex();
|
| - extension_prefs->SetAppLaunchIndex(extension->id(), app_launch_index);
|
| - }
|
| - value->SetInteger("app_launch_index", app_launch_index);
|
| -}
|
| -
|
| void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) {
|
| ListValue* list = new ListValue();
|
| const ExtensionList* extensions = extensions_service_->extensions();
|
| @@ -150,8 +181,10 @@ void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) {
|
| if (default_apps->ShouldShowPromo(extensions_service_->GetAppIds())) {
|
| dictionary->SetBoolean("showPromo", true);
|
| default_apps->DidShowPromo();
|
| + promo_active_ = true;
|
| } else {
|
| dictionary->SetBoolean("showPromo", false);
|
| + promo_active_ = false;
|
| }
|
|
|
| bool showLauncher =
|
| @@ -220,6 +253,9 @@ void AppLauncherHandler::HandleLaunchApp(const ListValue* args) {
|
|
|
| if (new_contents != old_contents && browser->tab_count() > 1)
|
| browser->CloseTabContents(old_contents);
|
| +
|
| + if (extension_id != extension_misc::kWebStoreAppId)
|
| + RecordAppLaunch(promo_active_);
|
| }
|
|
|
| void AppLauncherHandler::HandleSetLaunchType(const ListValue* args) {
|
| @@ -240,19 +276,6 @@ void AppLauncherHandler::HandleSetLaunchType(const ListValue* args) {
|
| static_cast<ExtensionPrefs::LaunchType>(launch_type));
|
| }
|
|
|
| -void AppLauncherHandler::AnimateAppIcon(const Extension* extension,
|
| - const gfx::Rect& rect) {
|
| - // We make this check for the case of minimized windows, unit tests, etc.
|
| - if (platform_util::IsVisible(dom_ui_->tab_contents()->GetNativeView()) &&
|
| - Animation::ShouldRenderRichAnimation()) {
|
| -#if defined(OS_WIN)
|
| - AppLaunchedAnimation::Show(extension, rect);
|
| -#else
|
| - NOTIMPLEMENTED();
|
| -#endif
|
| - }
|
| -}
|
| -
|
| void AppLauncherHandler::HandleUninstallApp(const ListValue* args) {
|
| std::string extension_id = WideToUTF8(ExtractStringValue(args));
|
| const Extension* extension = extensions_service_->GetExtensionById(
|
| @@ -271,6 +294,9 @@ void AppLauncherHandler::HandleHideAppsPromo(const ListValue* args) {
|
| // If the user has intentionally hidden the promotion, we'll uninstall all the
|
| // default apps (we know the user hasn't installed any apps on their own at
|
| // this point, or the promotion wouldn't have been shown).
|
| + UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
|
| + extension_misc::PROMO_CLOSE,
|
| + extension_misc::PROMO_BUCKET_BOUNDARY);
|
| DefaultApps* default_apps = extensions_service_->default_apps();
|
| const ExtensionIdSet* app_ids = default_apps->GetDefaultApps();
|
| DCHECK(*app_ids == extensions_service_->GetAppIds());
|
| @@ -284,10 +310,25 @@ void AppLauncherHandler::HandleHideAppsPromo(const ListValue* args) {
|
| extensions_service_->default_apps()->SetPromoHidden();
|
| }
|
|
|
| -ExtensionInstallUI* AppLauncherHandler::GetExtensionInstallUI() {
|
| - if (!install_ui_.get())
|
| - install_ui_.reset(new ExtensionInstallUI(dom_ui_->GetProfile()));
|
| - return install_ui_.get();
|
| +//static
|
| +void AppLauncherHandler::RecordWebStoreLaunch(bool promo_active) {
|
| + if (!promo_active) return;
|
| +
|
| + UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
|
| + extension_misc::PROMO_LAUNCH_WEB_STORE,
|
| + extension_misc::PROMO_BUCKET_BOUNDARY);
|
| +}
|
| +
|
| +//static
|
| +void AppLauncherHandler::RecordAppLaunch(bool promo_active) {
|
| + // TODO(jstritar): record app launches that occur when the promo is not
|
| + // active using a different histogram.
|
| +
|
| + if (!promo_active) return;
|
| +
|
| + UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
|
| + extension_misc::PROMO_LAUNCH_APP,
|
| + extension_misc::PROMO_BUCKET_BOUNDARY);
|
| }
|
|
|
| void AppLauncherHandler::InstallUIProceed() {
|
| @@ -308,3 +349,22 @@ void AppLauncherHandler::InstallUIProceed() {
|
| void AppLauncherHandler::InstallUIAbort() {
|
| extension_id_prompting_ = "";
|
| }
|
| +
|
| +ExtensionInstallUI* AppLauncherHandler::GetExtensionInstallUI() {
|
| + if (!install_ui_.get())
|
| + install_ui_.reset(new ExtensionInstallUI(dom_ui_->GetProfile()));
|
| + return install_ui_.get();
|
| +}
|
| +
|
| +void AppLauncherHandler::AnimateAppIcon(const Extension* extension,
|
| + const gfx::Rect& rect) {
|
| + // We make this check for the case of minimized windows, unit tests, etc.
|
| + if (platform_util::IsVisible(dom_ui_->tab_contents()->GetNativeView()) &&
|
| + Animation::ShouldRenderRichAnimation()) {
|
| +#if defined(OS_WIN)
|
| + AppLaunchedAnimation::Show(extension, rect);
|
| +#else
|
| + NOTIMPLEMENTED();
|
| +#endif
|
| + }
|
| +}
|
|
|