OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/dom_ui/app_launcher_handler.h" | 5 #include "chrome/browser/dom_ui/app_launcher_handler.h" |
6 | 6 |
7 #include "app/animation.h" | 7 #include "app/animation.h" |
| 8 #include "base/metrics/histogram.h" |
8 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
| 10 #include "base/string_split.h" |
9 #include "base/string_util.h" | 11 #include "base/string_util.h" |
10 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
11 #include "base/values.h" | 13 #include "base/values.h" |
12 #include "chrome/browser/app_launched_animation.h" | 14 #include "chrome/browser/app_launched_animation.h" |
13 #include "chrome/browser/browser.h" | 15 #include "chrome/browser/browser.h" |
14 #include "chrome/browser/browser_list.h" | 16 #include "chrome/browser/browser_list.h" |
15 #include "chrome/browser/extensions/default_apps.h" | 17 #include "chrome/browser/extensions/default_apps.h" |
16 #include "chrome/browser/extensions/extension_prefs.h" | 18 #include "chrome/browser/extensions/extension_prefs.h" |
17 #include "chrome/browser/extensions/extensions_service.h" | 19 #include "chrome/browser/extensions/extensions_service.h" |
18 #include "chrome/browser/platform_util.h" | 20 #include "chrome/browser/platform_util.h" |
19 #include "chrome/browser/profile.h" | 21 #include "chrome/browser/profile.h" |
20 #include "chrome/browser/tab_contents/tab_contents.h" | 22 #include "chrome/browser/tab_contents/tab_contents.h" |
21 #include "chrome/common/chrome_switches.h" | 23 #include "chrome/common/chrome_switches.h" |
22 #include "chrome/common/extensions/extension.h" | 24 #include "chrome/common/extensions/extension.h" |
23 #include "chrome/common/extensions/extension_constants.h" | 25 #include "chrome/common/extensions/extension_constants.h" |
24 #include "chrome/common/extensions/extension_icon_set.h" | 26 #include "chrome/common/extensions/extension_icon_set.h" |
25 #include "chrome/common/extensions/extension_resource.h" | 27 #include "chrome/common/extensions/extension_resource.h" |
26 #include "chrome/common/notification_service.h" | 28 #include "chrome/common/notification_service.h" |
27 #include "chrome/common/notification_type.h" | 29 #include "chrome/common/notification_type.h" |
28 #include "chrome/common/url_constants.h" | 30 #include "chrome/common/url_constants.h" |
29 #include "gfx/rect.h" | 31 #include "gfx/rect.h" |
30 #include "grit/browser_resources.h" | 32 #include "grit/browser_resources.h" |
31 #include "grit/generated_resources.h" | 33 #include "grit/generated_resources.h" |
32 | 34 |
33 namespace { | 35 namespace { |
34 | 36 |
| 37 // The URL prefixes used by the NTP to signal when the web store or an app |
| 38 // has launched. These are used for histogram purposes. |
| 39 const char* kLaunchAppPingURL = "record-app-launch"; |
| 40 const char* kLaunchWebStorePingURL = "record-webstore-launch"; |
| 41 |
35 // This extracts an int from a ListValue at the given |index|. | 42 // This extracts an int from a ListValue at the given |index|. |
36 bool ExtractInt(const ListValue* list, size_t index, int* out_int) { | 43 bool ExtractInt(const ListValue* list, size_t index, int* out_int) { |
37 std::string string_value; | 44 std::string string_value; |
38 | 45 |
39 if (list->GetString(index, &string_value)) { | 46 if (list->GetString(index, &string_value)) { |
40 base::StringToInt(string_value, out_int); | 47 base::StringToInt(string_value, out_int); |
41 return true; | 48 return true; |
42 } | 49 } |
43 | 50 |
44 return false; | 51 return false; |
45 } | 52 } |
46 | 53 |
47 std::string GetIconURL(const Extension* extension, Extension::Icons icon, | 54 std::string GetIconURL(const Extension* extension, Extension::Icons icon, |
48 const std::string& default_val) { | 55 const std::string& default_val) { |
49 GURL url = extension->GetIconURL(icon, ExtensionIconSet::MATCH_EXACTLY); | 56 GURL url = extension->GetIconURL(icon, ExtensionIconSet::MATCH_EXACTLY); |
50 if (!url.is_empty()) | 57 if (!url.is_empty()) |
51 return url.spec(); | 58 return url.spec(); |
52 else | 59 else |
53 return default_val; | 60 return default_val; |
54 } | 61 } |
55 | 62 |
| 63 // Extracts the promo parameter from the |path| generated by a ping on the NTP. |
| 64 bool IsPromoActive(const std::string& path) { |
| 65 std::vector<std::string> params; |
| 66 base::SplitString(path, '+', ¶ms); |
| 67 |
| 68 CHECK(params.size() == 2); |
| 69 |
| 70 return params.at(1) == "true"; |
| 71 } |
| 72 |
56 } // namespace | 73 } // namespace |
57 | 74 |
58 AppLauncherHandler::AppLauncherHandler(ExtensionsService* extension_service) | 75 AppLauncherHandler::AppLauncherHandler(ExtensionsService* extension_service) |
59 : extensions_service_(extension_service) { | 76 : extensions_service_(extension_service), |
| 77 promo_active_(false) { |
60 } | 78 } |
61 | 79 |
62 AppLauncherHandler::~AppLauncherHandler() {} | 80 AppLauncherHandler::~AppLauncherHandler() {} |
63 | 81 |
64 DOMMessageHandler* AppLauncherHandler::Attach(DOMUI* dom_ui) { | 82 DOMMessageHandler* AppLauncherHandler::Attach(DOMUI* dom_ui) { |
65 // TODO(arv): Add initialization code to the Apps store etc. | 83 // TODO(arv): Add initialization code to the Apps store etc. |
66 return DOMMessageHandler::Attach(dom_ui); | 84 return DOMMessageHandler::Attach(dom_ui); |
67 } | 85 } |
68 | 86 |
69 void AppLauncherHandler::RegisterMessages() { | 87 void AppLauncherHandler::RegisterMessages() { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 CreateAppInfo(*it, extensions_service_->extension_prefs(), app_info); | 161 CreateAppInfo(*it, extensions_service_->extension_prefs(), app_info); |
144 list->Append(app_info); | 162 list->Append(app_info); |
145 } | 163 } |
146 } | 164 } |
147 dictionary->Set("apps", list); | 165 dictionary->Set("apps", list); |
148 | 166 |
149 DefaultApps* default_apps = extensions_service_->default_apps(); | 167 DefaultApps* default_apps = extensions_service_->default_apps(); |
150 if (default_apps->ShouldShowPromo(extensions_service_->GetAppIds())) { | 168 if (default_apps->ShouldShowPromo(extensions_service_->GetAppIds())) { |
151 dictionary->SetBoolean("showPromo", true); | 169 dictionary->SetBoolean("showPromo", true); |
152 default_apps->DidShowPromo(); | 170 default_apps->DidShowPromo(); |
| 171 promo_active_ = true; |
153 } else { | 172 } else { |
154 dictionary->SetBoolean("showPromo", false); | 173 dictionary->SetBoolean("showPromo", false); |
| 174 promo_active_ = false; |
155 } | 175 } |
156 | 176 |
157 bool showLauncher = | 177 bool showLauncher = |
158 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAppLauncher); | 178 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAppLauncher); |
159 dictionary->SetBoolean("showLauncher", showLauncher); | 179 dictionary->SetBoolean("showLauncher", showLauncher); |
160 } | 180 } |
161 | 181 |
162 void AppLauncherHandler::HandleGetApps(const ListValue* args) { | 182 void AppLauncherHandler::HandleGetApps(const ListValue* args) { |
163 DictionaryValue dictionary; | 183 DictionaryValue dictionary; |
164 FillAppDictionary(&dictionary); | 184 FillAppDictionary(&dictionary); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 TabContents* old_contents = NULL; | 233 TabContents* old_contents = NULL; |
214 if (browser) | 234 if (browser) |
215 old_contents = browser->GetSelectedTabContents(); | 235 old_contents = browser->GetSelectedTabContents(); |
216 | 236 |
217 AnimateAppIcon(extension, rect); | 237 AnimateAppIcon(extension, rect); |
218 TabContents* new_contents = Browser::OpenApplication( | 238 TabContents* new_contents = Browser::OpenApplication( |
219 profile, extension, extension->launch_container(), old_contents); | 239 profile, extension, extension->launch_container(), old_contents); |
220 | 240 |
221 if (new_contents != old_contents && browser->tab_count() > 1) | 241 if (new_contents != old_contents && browser->tab_count() > 1) |
222 browser->CloseTabContents(old_contents); | 242 browser->CloseTabContents(old_contents); |
| 243 |
| 244 if (extension_id != extension_misc::kWebStoreAppId) |
| 245 RecordAppLaunch(promo_active_); |
223 } | 246 } |
224 | 247 |
225 void AppLauncherHandler::HandleSetLaunchType(const ListValue* args) { | 248 void AppLauncherHandler::HandleSetLaunchType(const ListValue* args) { |
226 std::string extension_id; | 249 std::string extension_id; |
227 int launch_type; | 250 int launch_type; |
228 if (!args->GetString(0, &extension_id) || | 251 if (!args->GetString(0, &extension_id) || |
229 !ExtractInt(args, 1, &launch_type)) { | 252 !ExtractInt(args, 1, &launch_type)) { |
230 NOTREACHED(); | 253 NOTREACHED(); |
231 return; | 254 return; |
232 } | 255 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 return; // Only one prompt at a time. | 287 return; // Only one prompt at a time. |
265 | 288 |
266 extension_id_prompting_ = extension_id; | 289 extension_id_prompting_ = extension_id; |
267 GetExtensionInstallUI()->ConfirmUninstall(this, extension); | 290 GetExtensionInstallUI()->ConfirmUninstall(this, extension); |
268 } | 291 } |
269 | 292 |
270 void AppLauncherHandler::HandleHideAppsPromo(const ListValue* args) { | 293 void AppLauncherHandler::HandleHideAppsPromo(const ListValue* args) { |
271 // If the user has intentionally hidden the promotion, we'll uninstall all the | 294 // If the user has intentionally hidden the promotion, we'll uninstall all the |
272 // default apps (we know the user hasn't installed any apps on their own at | 295 // default apps (we know the user hasn't installed any apps on their own at |
273 // this point, or the promotion wouldn't have been shown). | 296 // this point, or the promotion wouldn't have been shown). |
| 297 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, |
| 298 extension_misc::PROMO_CLOSE, |
| 299 extension_misc::PROMO_BUCKET_BOUNDARY); |
274 DefaultApps* default_apps = extensions_service_->default_apps(); | 300 DefaultApps* default_apps = extensions_service_->default_apps(); |
275 const ExtensionIdSet* app_ids = default_apps->GetDefaultApps(); | 301 const ExtensionIdSet* app_ids = default_apps->GetDefaultApps(); |
276 DCHECK(*app_ids == extensions_service_->GetAppIds()); | 302 DCHECK(*app_ids == extensions_service_->GetAppIds()); |
277 | 303 |
278 for (ExtensionIdSet::const_iterator iter = app_ids->begin(); | 304 for (ExtensionIdSet::const_iterator iter = app_ids->begin(); |
279 iter != app_ids->end(); ++iter) { | 305 iter != app_ids->end(); ++iter) { |
280 if (extensions_service_->GetExtensionById(*iter, true)) | 306 if (extensions_service_->GetExtensionById(*iter, true)) |
281 extensions_service_->UninstallExtension(*iter, false); | 307 extensions_service_->UninstallExtension(*iter, false); |
282 } | 308 } |
283 | 309 |
284 extensions_service_->default_apps()->SetPromoHidden(); | 310 extensions_service_->default_apps()->SetPromoHidden(); |
285 } | 311 } |
286 | 312 |
| 313 // static |
| 314 bool AppLauncherHandler::HandlePing(const std::string& path) { |
| 315 if (path.find(kLaunchWebStorePingURL) != std::string::npos) { |
| 316 RecordWebStoreLaunch(IsPromoActive(path)); |
| 317 return true; |
| 318 } else if (path.find(kLaunchAppPingURL) != std::string::npos) { |
| 319 RecordAppLaunch(IsPromoActive(path)); |
| 320 return true; |
| 321 } |
| 322 |
| 323 return false; |
| 324 } |
| 325 |
287 ExtensionInstallUI* AppLauncherHandler::GetExtensionInstallUI() { | 326 ExtensionInstallUI* AppLauncherHandler::GetExtensionInstallUI() { |
288 if (!install_ui_.get()) | 327 if (!install_ui_.get()) |
289 install_ui_.reset(new ExtensionInstallUI(dom_ui_->GetProfile())); | 328 install_ui_.reset(new ExtensionInstallUI(dom_ui_->GetProfile())); |
290 return install_ui_.get(); | 329 return install_ui_.get(); |
291 } | 330 } |
292 | 331 |
293 void AppLauncherHandler::InstallUIProceed() { | 332 void AppLauncherHandler::InstallUIProceed() { |
294 DCHECK(!extension_id_prompting_.empty()); | 333 DCHECK(!extension_id_prompting_.empty()); |
295 | 334 |
296 // The extension can be uninstalled in another window while the UI was | 335 // The extension can be uninstalled in another window while the UI was |
297 // showing. Do nothing in that case. | 336 // showing. Do nothing in that case. |
298 const Extension* extension = | 337 const Extension* extension = |
299 extensions_service_->GetExtensionById(extension_id_prompting_, true); | 338 extensions_service_->GetExtensionById(extension_id_prompting_, true); |
300 if (!extension) | 339 if (!extension) |
301 return; | 340 return; |
302 | 341 |
303 extensions_service_->UninstallExtension(extension_id_prompting_, | 342 extensions_service_->UninstallExtension(extension_id_prompting_, |
304 false /* external_uninstall */); | 343 false /* external_uninstall */); |
305 extension_id_prompting_ = ""; | 344 extension_id_prompting_ = ""; |
306 } | 345 } |
307 | 346 |
308 void AppLauncherHandler::InstallUIAbort() { | 347 void AppLauncherHandler::InstallUIAbort() { |
309 extension_id_prompting_ = ""; | 348 extension_id_prompting_ = ""; |
310 } | 349 } |
| 350 |
| 351 //static |
| 352 void AppLauncherHandler::RecordWebStoreLaunch(bool promo_active) { |
| 353 if (!promo_active) return; |
| 354 |
| 355 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, |
| 356 extension_misc::PROMO_LAUNCH_WEB_STORE, |
| 357 extension_misc::PROMO_BUCKET_BOUNDARY); |
| 358 } |
| 359 |
| 360 //static |
| 361 void AppLauncherHandler::RecordAppLaunch(bool promo_active) { |
| 362 // TODO(jstritar): record app launches that occur when the promo is not |
| 363 // active using a different histogram. |
| 364 |
| 365 if (!promo_active) return; |
| 366 |
| 367 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, |
| 368 extension_misc::PROMO_LAUNCH_APP, |
| 369 extension_misc::PROMO_BUCKET_BOUNDARY); |
| 370 } |
OLD | NEW |