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 |
+ } |
+} |