Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: chrome/browser/ui/webui/ntp/app_launcher_handler.cc

Issue 8526017: Append parameters to webstore URL to indicate launch source. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: compile fixes Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/ui/webui/ntp/app_launcher_handler.h" 5 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 #include "grit/browser_resources.h" 46 #include "grit/browser_resources.h"
47 #include "grit/generated_resources.h" 47 #include "grit/generated_resources.h"
48 #include "net/base/escape.h" 48 #include "net/base/escape.h"
49 #include "ui/base/animation/animation.h" 49 #include "ui/base/animation/animation.h"
50 #include "ui/base/l10n/l10n_util.h" 50 #include "ui/base/l10n/l10n_util.h"
51 #include "ui/gfx/codec/png_codec.h" 51 #include "ui/gfx/codec/png_codec.h"
52 #include "webkit/glue/window_open_disposition.h" 52 #include "webkit/glue/window_open_disposition.h"
53 53
54 namespace { 54 namespace {
55 55
56 // The URL prefixes used by the NTP to signal when the web store or an app
57 // has launched so we can record the proper histogram.
58 const char* kPingLaunchAppByID = "record-app-launch-by-id";
59 const char* kPingLaunchWebStore = "record-webstore-launch";
60 const char* kPingLaunchAppByURL = "record-app-launch-by-url";
61
62 const UnescapeRule::Type kUnescapeRules = 56 const UnescapeRule::Type kUnescapeRules =
63 UnescapeRule::NORMAL | UnescapeRule::URL_SPECIAL_CHARS; 57 UnescapeRule::NORMAL | UnescapeRule::URL_SPECIAL_CHARS;
64 58
65 extension_misc::AppLaunchBucket ParseLaunchSource( 59 extension_misc::AppLaunchBucket ParseLaunchSource(
66 const std::string& launch_source) { 60 const std::string& launch_source) {
67 int bucket_num = extension_misc::APP_LAUNCH_BUCKET_INVALID; 61 int bucket_num = extension_misc::APP_LAUNCH_BUCKET_INVALID;
68 base::StringToInt(launch_source, &bucket_num); 62 base::StringToInt(launch_source, &bucket_num);
69 extension_misc::AppLaunchBucket bucket = 63 extension_misc::AppLaunchBucket bucket =
70 static_cast<extension_misc::AppLaunchBucket>(bucket_num); 64 static_cast<extension_misc::AppLaunchBucket>(bucket_num);
71 CHECK(bucket < extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); 65 CHECK(bucket < extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
72 return bucket; 66 return bucket;
73 } 67 }
74 68
75 } // namespace 69 } // namespace
76 70
77 AppLauncherHandler::AppLauncherHandler(ExtensionService* extension_service) 71 AppLauncherHandler::AppLauncherHandler(ExtensionService* extension_service)
78 : extension_service_(extension_service), 72 : extension_service_(extension_service),
79 promo_active_(false),
80 ignore_changes_(false), 73 ignore_changes_(false),
81 attempted_bookmark_app_install_(false), 74 attempted_bookmark_app_install_(false),
82 has_loaded_apps_(false) { 75 has_loaded_apps_(false) {
83 } 76 }
84 77
85 AppLauncherHandler::~AppLauncherHandler() {} 78 AppLauncherHandler::~AppLauncherHandler() {}
86 79
87 // Serializes |notification| into a new DictionaryValue which the caller then 80 // Serializes |notification| into a new DictionaryValue which the caller then
88 // owns. 81 // owns.
89 static DictionaryValue* SerializeNotification( 82 static DictionaryValue* SerializeNotification(
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 if (page_index < 0) { 176 if (page_index < 0) {
184 // Make sure every app has a page index (some predate the page index). 177 // Make sure every app has a page index (some predate the page index).
185 // The webstore app should be on the first page. 178 // The webstore app should be on the first page.
186 page_index = extension->id() == extension_misc::kWebStoreAppId ? 179 page_index = extension->id() == extension_misc::kWebStoreAppId ?
187 0 : prefs->GetNaturalAppPageIndex(); 180 0 : prefs->GetNaturalAppPageIndex();
188 prefs->SetPageIndex(extension->id(), page_index); 181 prefs->SetPageIndex(extension->id(), page_index);
189 } 182 }
190 value->SetInteger("page_index", page_index); 183 value->SetInteger("page_index", page_index);
191 } 184 }
192 185
193 // TODO(estade): remove this. We record app launches via js calls rather than
194 // pings for ntp4.
195 // static
196 bool AppLauncherHandler::HandlePing(Profile* profile, const std::string& path) {
197 std::vector<std::string> params;
198 base::SplitString(path, '+', &params);
199
200 // Check if the user launched an app from the most visited or recently
201 // closed sections.
202 if (kPingLaunchAppByURL == params.at(0)) {
203 CHECK(params.size() == 3);
204 RecordAppLaunchByURL(
205 profile, params.at(1), ParseLaunchSource(params.at(2)));
206 return true;
207 }
208
209 bool is_web_store_ping = kPingLaunchWebStore == params.at(0);
210 bool is_app_launch_ping = kPingLaunchAppByID == params.at(0);
211
212 if (!is_web_store_ping && !is_app_launch_ping)
213 return false;
214
215 CHECK(params.size() >= 2);
216
217 bool is_promo_active = params.at(1) == "true";
218
219 // At this point, the user must have used the app launcher, so we hide the
220 // promo if its still displayed.
221 if (is_promo_active) {
222 DCHECK(profile->GetExtensionService());
223 profile->GetExtensionService()->apps_promo()->ExpireDefaultApps();
224 }
225
226 if (is_web_store_ping) {
227 RecordWebStoreLaunch(is_promo_active);
228 } else {
229 CHECK(params.size() == 3);
230 RecordAppLaunchByID(is_promo_active, ParseLaunchSource(params.at(2)));
231 }
232
233 return true;
234 }
235
236 WebUIMessageHandler* AppLauncherHandler::Attach(WebUI* web_ui) { 186 WebUIMessageHandler* AppLauncherHandler::Attach(WebUI* web_ui) {
237 registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, 187 registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_NTP,
238 content::Source<TabContents>(web_ui->tab_contents())); 188 content::Source<TabContents>(web_ui->tab_contents()));
239 return WebUIMessageHandler::Attach(web_ui); 189 return WebUIMessageHandler::Attach(web_ui);
240 } 190 }
241 191
242 void AppLauncherHandler::RegisterMessages() { 192 void AppLauncherHandler::RegisterMessages() {
243 web_ui_->RegisterMessageCallback("getApps", 193 web_ui_->RegisterMessageCallback("getApps",
244 base::Bind(&AppLauncherHandler::HandleGetApps, 194 base::Bind(&AppLauncherHandler::HandleGetApps,
245 base::Unretained(this))); 195 base::Unretained(this)));
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 // expired. 457 // expired.
508 // b) Conceptually, it doesn't really make sense to count a 458 // b) Conceptually, it doesn't really make sense to count a
509 // prefchange-triggered refresh as a promo 'view'. 459 // prefchange-triggered refresh as a promo 'view'.
510 AppsPromo* apps_promo = extension_service_->apps_promo(); 460 AppsPromo* apps_promo = extension_service_->apps_promo();
511 Profile* profile = Profile::FromWebUI(web_ui_); 461 Profile* profile = Profile::FromWebUI(web_ui_);
512 bool apps_promo_just_expired = false; 462 bool apps_promo_just_expired = false;
513 if (apps_promo->ShouldShowPromo(extension_service_->GetAppIds(), 463 if (apps_promo->ShouldShowPromo(extension_service_->GetAppIds(),
514 &apps_promo_just_expired)) { 464 &apps_promo_just_expired)) {
515 dictionary.SetBoolean("showPromo", true); 465 dictionary.SetBoolean("showPromo", true);
516 FillPromoDictionary(&dictionary); 466 FillPromoDictionary(&dictionary);
517 promo_active_ = true;
518 } else { 467 } else {
519 dictionary.SetBoolean("showPromo", false); 468 dictionary.SetBoolean("showPromo", false);
520 promo_active_ = false;
521 } 469 }
522 470
523 // If the default apps have just expired (user viewed them too many times with 471 // If the default apps have just expired (user viewed them too many times with
524 // no interaction), then we uninstall them and focus the recent sites section. 472 // no interaction), then we uninstall them and focus the recent sites section.
525 if (apps_promo_just_expired) { 473 if (apps_promo_just_expired) {
526 ignore_changes_ = true; 474 ignore_changes_ = true;
527 UninstallDefaultApps(); 475 UninstallDefaultApps();
528 ignore_changes_ = false; 476 ignore_changes_ = false;
529 } 477 }
530 478
(...skipping 24 matching lines...) Expand all
555 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOAD_ERROR, 503 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOAD_ERROR,
556 content::Source<Profile>(profile)); 504 content::Source<Profile>(profile));
557 } 505 }
558 506
559 has_loaded_apps_ = true; 507 has_loaded_apps_ = true;
560 } 508 }
561 509
562 void AppLauncherHandler::HandleLaunchApp(const ListValue* args) { 510 void AppLauncherHandler::HandleLaunchApp(const ListValue* args) {
563 std::string extension_id; 511 std::string extension_id;
564 double source = -1.0; 512 double source = -1.0;
513 std::string url;
565 bool alt_key = false; 514 bool alt_key = false;
566 bool ctrl_key = false; 515 bool ctrl_key = false;
567 bool meta_key = false; 516 bool meta_key = false;
568 bool shift_key = false; 517 bool shift_key = false;
569 double button = 0.0; 518 double button = 0.0;
570 519
571 CHECK(args->GetString(0, &extension_id)); 520 CHECK(args->GetString(0, &extension_id));
572 CHECK(args->GetDouble(1, &source)); 521 CHECK(args->GetDouble(1, &source));
573 if (args->GetSize() > 2) { 522 if (args->GetSize() > 2)
574 CHECK(args->GetBoolean(2, &alt_key)); 523 CHECK(args->GetString(2, &url));
575 CHECK(args->GetBoolean(3, &ctrl_key)); 524 if (args->GetSize() > 3) {
576 CHECK(args->GetBoolean(4, &meta_key)); 525 CHECK(args->GetBoolean(3, &alt_key));
577 CHECK(args->GetBoolean(5, &shift_key)); 526 CHECK(args->GetBoolean(4, &ctrl_key));
578 CHECK(args->GetDouble(6, &button)); 527 CHECK(args->GetBoolean(5, &meta_key));
528 CHECK(args->GetBoolean(6, &shift_key));
529 CHECK(args->GetDouble(7, &button));
579 } 530 }
580 531
581 extension_misc::AppLaunchBucket launch_bucket = 532 extension_misc::AppLaunchBucket launch_bucket =
582 static_cast<extension_misc::AppLaunchBucket>( 533 static_cast<extension_misc::AppLaunchBucket>(
583 static_cast<int>(source)); 534 static_cast<int>(source));
584 CHECK(launch_bucket >= 0 && 535 CHECK(launch_bucket >= 0 &&
585 launch_bucket < extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); 536 launch_bucket < extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
586 537
587 const Extension* extension = 538 const Extension* extension =
588 extension_service_->GetExtensionById(extension_id, false); 539 extension_service_->GetExtensionById(extension_id, false);
589 540
590 // Prompt the user to re-enable the application if disabled. 541 // Prompt the user to re-enable the application if disabled.
591 if (!extension) { 542 if (!extension) {
592 PromptToEnableApp(extension_id); 543 PromptToEnableApp(extension_id);
593 return; 544 return;
594 } 545 }
595 546
596 Profile* profile = extension_service_->profile(); 547 Profile* profile = extension_service_->profile();
597 548
598 // If the user pressed special keys when clicking, override the saved 549 // If the user pressed special keys when clicking, override the saved
599 // preference for launch container. 550 // preference for launch container.
600 bool middle_button = (button == 1.0); 551 bool middle_button = (button == 1.0);
601 WindowOpenDisposition disposition = 552 WindowOpenDisposition disposition =
602 disposition_utils::DispositionFromClick(middle_button, alt_key, 553 disposition_utils::DispositionFromClick(middle_button, alt_key,
603 ctrl_key, meta_key, shift_key); 554 ctrl_key, meta_key, shift_key);
604 555
605 if (extension_id != extension_misc::kWebStoreAppId) { 556 if (extension_id != extension_misc::kWebStoreAppId) {
606 RecordAppLaunchByID(promo_active_, launch_bucket); 557 RecordAppLaunchByID(launch_bucket);
607 extension_service_->apps_promo()->ExpireDefaultApps(); 558 extension_service_->apps_promo()->ExpireDefaultApps();
608 } else if (NewTabUI::NTP4Enabled()) { 559 } else if (NewTabUI::NTP4Enabled()) {
609 RecordWebStoreLaunch(promo_active_); 560 RecordWebStoreLaunch(url.find("chrome-ntp-promo") != std::string::npos);
610 } 561 }
611 562
612 if (disposition == NEW_FOREGROUND_TAB || disposition == NEW_BACKGROUND_TAB) { 563 if (disposition == NEW_FOREGROUND_TAB || disposition == NEW_BACKGROUND_TAB) {
613 // TODO(jamescook): Proper support for background tabs. 564 // TODO(jamescook): Proper support for background tabs.
614 Browser::OpenApplication( 565 Browser::OpenApplication(
615 profile, extension, extension_misc::LAUNCH_TAB, disposition); 566 profile, extension, extension_misc::LAUNCH_TAB, GURL(url), disposition);
616 } else if (disposition == NEW_WINDOW) { 567 } else if (disposition == NEW_WINDOW) {
617 // Force a new window open. 568 // Force a new window open.
618 Browser::OpenApplication( 569 Browser::OpenApplication(
619 profile, extension, extension_misc::LAUNCH_WINDOW, disposition); 570 profile, extension, extension_misc::LAUNCH_WINDOW, GURL(url),
571 disposition);
620 } else { 572 } else {
621 // Look at preference to find the right launch container. If no preference 573 // Look at preference to find the right launch container. If no preference
622 // is set, launch as a regular tab. 574 // is set, launch as a regular tab.
623 extension_misc::LaunchContainer launch_container = 575 extension_misc::LaunchContainer launch_container =
624 extension_service_->extension_prefs()->GetLaunchContainer( 576 extension_service_->extension_prefs()->GetLaunchContainer(
625 extension, ExtensionPrefs::LAUNCH_REGULAR); 577 extension, ExtensionPrefs::LAUNCH_REGULAR);
626 578
627 // To give a more "launchy" experience when using the NTP launcher, we close 579 // To give a more "launchy" experience when using the NTP launcher, we close
628 // it automatically. 580 // it automatically.
629 Browser* browser = BrowserList::GetLastActiveWithProfile(profile); 581 Browser* browser = BrowserList::GetLastActiveWithProfile(profile);
630 TabContents* old_contents = NULL; 582 TabContents* old_contents = NULL;
631 if (browser) 583 if (browser)
632 old_contents = browser->GetSelectedTabContents(); 584 old_contents = browser->GetSelectedTabContents();
633 585
634 TabContents* new_contents = Browser::OpenApplication( 586 TabContents* new_contents = Browser::OpenApplication(
635 profile, extension, launch_container, 587 profile, extension, launch_container, GURL(url),
636 old_contents ? CURRENT_TAB : NEW_FOREGROUND_TAB); 588 old_contents ? CURRENT_TAB : NEW_FOREGROUND_TAB);
637 589
638 // This will also destroy the handler, so do not perform any actions after. 590 // This will also destroy the handler, so do not perform any actions after.
639 if (new_contents != old_contents && browser && browser->tab_count() > 1) 591 if (new_contents != old_contents && browser && browser->tab_count() > 1)
640 browser->CloseTabContents(old_contents); 592 browser->CloseTabContents(old_contents);
641 } 593 }
642 } 594 }
643 595
644 void AppLauncherHandler::HandleSetLaunchType(const ListValue* args) { 596 void AppLauncherHandler::HandleSetLaunchType(const ListValue* args) {
645 std::string extension_id; 597 std::string extension_id;
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 855
904 if (!promo_active) return; 856 if (!promo_active) return;
905 857
906 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, 858 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
907 extension_misc::PROMO_LAUNCH_WEB_STORE, 859 extension_misc::PROMO_LAUNCH_WEB_STORE,
908 extension_misc::PROMO_BUCKET_BOUNDARY); 860 extension_misc::PROMO_BUCKET_BOUNDARY);
909 } 861 }
910 862
911 // static 863 // static
912 void AppLauncherHandler::RecordAppLaunchByID( 864 void AppLauncherHandler::RecordAppLaunchByID(
913 bool promo_active, extension_misc::AppLaunchBucket bucket) { 865 extension_misc::AppLaunchBucket bucket) {
914 CHECK(bucket != extension_misc::APP_LAUNCH_BUCKET_INVALID); 866 CHECK(bucket != extension_misc::APP_LAUNCH_BUCKET_INVALID);
915 867
916 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram, bucket, 868 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram, bucket,
917 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); 869 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
918
919 if (!promo_active) return;
920
921 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
922 extension_misc::PROMO_LAUNCH_APP,
923 extension_misc::PROMO_BUCKET_BOUNDARY);
924 } 870 }
925 871
926 // static 872 // static
927 void AppLauncherHandler::RecordAppLaunchByURL( 873 void AppLauncherHandler::RecordAppLaunchByURL(
928 Profile* profile, 874 Profile* profile,
929 std::string escaped_url, 875 std::string escaped_url,
930 extension_misc::AppLaunchBucket bucket) { 876 extension_misc::AppLaunchBucket bucket) {
931 CHECK(bucket != extension_misc::APP_LAUNCH_BUCKET_INVALID); 877 CHECK(bucket != extension_misc::APP_LAUNCH_BUCKET_INVALID);
932 878
933 GURL url(net::UnescapeURLComponent(escaped_url, kUnescapeRules)); 879 GURL url(net::UnescapeURLComponent(escaped_url, kUnescapeRules));
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 995
1050 void AppLauncherHandler::UninstallDefaultApps() { 996 void AppLauncherHandler::UninstallDefaultApps() {
1051 AppsPromo* apps_promo = extension_service_->apps_promo(); 997 AppsPromo* apps_promo = extension_service_->apps_promo();
1052 const ExtensionIdSet& app_ids = apps_promo->old_default_apps(); 998 const ExtensionIdSet& app_ids = apps_promo->old_default_apps();
1053 for (ExtensionIdSet::const_iterator iter = app_ids.begin(); 999 for (ExtensionIdSet::const_iterator iter = app_ids.begin();
1054 iter != app_ids.end(); ++iter) { 1000 iter != app_ids.end(); ++iter) {
1055 if (extension_service_->GetExtensionById(*iter, true)) 1001 if (extension_service_->GetExtensionById(*iter, true))
1056 extension_service_->UninstallExtension(*iter, false, NULL); 1002 extension_service_->UninstallExtension(*iter, false, NULL);
1057 } 1003 }
1058 } 1004 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/webui/ntp/app_launcher_handler.h ('k') | chrome/browser/ui/webui/ntp/new_tab_ui.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698