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

Side by Side Diff: chrome/installer/util/google_chrome_distribution.cc

Issue 10821007: The new toast experiments. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 4 months 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
« no previous file with comments | « chrome/installer/util/browser_distribution.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // This file defines specific implementation of BrowserDistribution class for 5 // This file defines specific implementation of BrowserDistribution class for
6 // Google Chrome. 6 // Google Chrome.
7 7
8 #include "chrome/installer/util/google_chrome_distribution.h" 8 #include "chrome/installer/util/google_chrome_distribution.h"
9 9
10 #include <vector> 10 #include <vector>
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 const wchar_t kCommandExecuteImplUuid[] = 53 const wchar_t kCommandExecuteImplUuid[] =
54 L"{5C65F4B0-3651-4514-B207-D10CB699B14B}"; 54 L"{5C65F4B0-3651-4514-B207-D10CB699B14B}";
55 const wchar_t kDelegateExecuteLibUuid[] = 55 const wchar_t kDelegateExecuteLibUuid[] =
56 L"{4E805ED8-EBA0-4601-9681-12815A56EBFD}"; 56 L"{4E805ED8-EBA0-4601-9681-12815A56EBFD}";
57 const wchar_t kDelegateExecuteLibVersion[] = L"1.0"; 57 const wchar_t kDelegateExecuteLibVersion[] = L"1.0";
58 const wchar_t kICommandExecuteImplUuid[] = 58 const wchar_t kICommandExecuteImplUuid[] =
59 L"{0BA0D4E9-2259-4963-B9AE-A839F7CB7544}"; 59 L"{0BA0D4E9-2259-4963-B9AE-A839F7CB7544}";
60 60
61 // The following strings are the possible outcomes of the toast experiment 61 // The following strings are the possible outcomes of the toast experiment
62 // as recorded in the |client| field. 62 // as recorded in the |client| field.
63 const wchar_t kToastExpControlGroup[] = L"01"; 63 const wchar_t kToastExpControlGroup[] = L"01";
64 const wchar_t kToastExpCancelGroup[] = L"02"; 64 const wchar_t kToastExpCancelGroup[] = L"02";
65 const wchar_t kToastExpUninstallGroup[] = L"04"; 65 const wchar_t kToastExpUninstallGroup[] = L"04";
66 const wchar_t kToastExpTriesOkGroup[] = L"18"; 66 const wchar_t kToastExpTriesOkGroup[] = L"18";
67 const wchar_t kToastExpTriesErrorGroup[] = L"28"; 67 const wchar_t kToastExpTriesErrorGroup[] = L"28";
68 const wchar_t kToastActiveGroup[] = L"40"; 68 const wchar_t kToastExpTriesOkDefaultGroup[] = L"48";
69 const wchar_t kToastUDDirFailure[] = L"40"; 69 const wchar_t kToastActiveGroup[] = L"40";
70 const wchar_t kToastExpBaseGroup[] = L"80"; 70 const wchar_t kToastUDDirFailure[] = L"40";
71 const wchar_t kToastExpBaseGroup[] = L"80";
71 72
72 // Substitute the locale parameter in uninstall URL with whatever 73 // Substitute the locale parameter in uninstall URL with whatever
73 // Google Update tells us is the locale. In case we fail to find 74 // Google Update tells us is the locale. In case we fail to find
74 // the locale, we use US English. 75 // the locale, we use US English.
75 string16 LocalizeUrl(const wchar_t* url) { 76 string16 LocalizeUrl(const wchar_t* url) {
76 string16 language; 77 string16 language;
77 if (!GoogleUpdateSettings::GetLanguage(&language)) 78 if (!GoogleUpdateSettings::GetLanguage(&language))
78 language = L"en-US"; // Default to US English. 79 language = L"en-US"; // Default to US English.
79 return ReplaceStringPlaceholders(url, language.c_str(), NULL); 80 return ReplaceStringPlaceholders(url, language.c_str(), NULL);
80 } 81 }
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 if (last_write) 606 if (last_write)
606 CloseHandle((HANDLE) reg_key_handle); 607 CloseHandle((HANDLE) reg_key_handle);
607 } else { 608 } else {
608 // Write to HKCU. 609 // Write to HKCU.
609 GoogleUpdateSettings::SetClient(experiment_group); 610 GoogleUpdateSettings::SetClient(experiment_group);
610 } 611 }
611 } 612 }
612 613
613 bool GoogleChromeDistribution::GetExperimentDetails( 614 bool GoogleChromeDistribution::GetExperimentDetails(
614 UserExperiment* experiment, int flavor) { 615 UserExperiment* experiment, int flavor) {
616 struct FlavorDetails {
617 int heading_id;
618 int flags;
619 };
615 // Maximum number of experiment flavors we support. 620 // Maximum number of experiment flavors we support.
616 static const int kMax = 4; 621 static const int kMax = 4;
617 // This struct determines which experiment flavors we show for each locale and 622 // This struct determines which experiment flavors we show for each locale and
618 // brand. 623 // brand.
619 // 624 //
620 // The big experiment in Dec 2009 used TGxx and THxx. 625 // The big experiment in Dec 2009 used TGxx and THxx.
621 // The big experiment in Feb 2010 used TKxx and TLxx. 626 // The big experiment in Feb 2010 used TKxx and TLxx.
622 // The big experiment in Apr 2010 used TMxx and TNxx. 627 // The big experiment in Apr 2010 used TMxx and TNxx.
623 // The big experiment in Oct 2010 used TVxx TWxx TXxx TYxx. 628 // The big experiment in Oct 2010 used TVxx TWxx TXxx TYxx.
624 // The big experiment in Feb 2011 used SJxx SKxx SLxx SMxx. 629 // The big experiment in Feb 2011 used SJxx SKxx SLxx SMxx.
625 // Note: the plugin infobar experiment uses PIxx codes. 630 // Note: the plugin infobar experiment uses PIxx codes.
626 using namespace attrition_experiments; 631 using namespace attrition_experiments;
632
627 static const struct UserExperimentDetails { 633 static const struct UserExperimentDetails {
628 const wchar_t* locale; // Locale to show this experiment for (* for all). 634 const wchar_t* locale; // Locale to show this experiment for (* for all).
629 const wchar_t* brands; // Brand codes show this experiment for (* for all). 635 const wchar_t* brands; // Brand codes show this experiment for (* for all).
630 int control_group; // Size of the control group, in percentages. 636 int control_group; // Size of the control group, in percentages.
631 const wchar_t prefix1; // The first letter for the experiment code. 637 const wchar_t* prefix; // The two letter experiment code. The second letter
632 const wchar_t prefix2; // The second letter for the experiment code. This 638 // will be incremented with the flavor.
633 // will be incremented by one for each additional 639 FlavorDetails flavors[kMax];
634 // experiment flavor beyond the first. 640 } kExperiments[] = {
635 int flavors; // Numbers of flavors for this experiment. Should 641 // The first match from top to bottom is used so this list should be ordered
636 // always be positive and never exceed the number 642 // most-specific rule first.
637 // of headings (below). 643 { L"*", L"CHMA", // All locales, CHMA brand.
638 int headings[kMax]; // A list of IDs per experiment. 0 == no heading. 644 25, // 25 percent control group.
639 } kExperimentFlavors[] = { 645 L"ZA", // Experiment is ZAxx, ZBxx, ZCxx, ZDxx etc.
640 // This list should be ordered most-specific rule first (catch-all, like all 646 // Three flavors.
641 // brands or all locales should be last). 647 { { IDS_TRY_TOAST_HEADING3, kDontBugMeAsButton | kUninstall | kWhyLink },
642 648 { IDS_TRY_TOAST_HEADING3, 0 },
643 // The experiment with the more compact bubble. This one is a bit special 649 { IDS_TRY_TOAST_HEADING3, kMakeDefault },
644 // because it is split into two: CAxx is regular style bubble and CBxx is 650 { 0, 0 },
645 // compact style bubble. See |compact_bubble| below. 651 }
646 {L"en-US", kBrief, 1, L'C', L'A', 2, { kEnUs3, kEnUs3, 0, 0 } }, 652 },
647 653 { L"*", L"GGRV", // All locales, GGRV is enterprise.
648 // Catch-all rules. 654 0, // 0 percent control group.
649 {kAll, kAll, 1, L'B', L'A', 1, {kEnUs3, 0, 0, 0} }, 655 L"EA", // Experiment is EAxx, EBxx, etc.
656 // No flavors means no experiment.
657 { { 0, 0 },
658 { 0, 0 },
659 { 0, 0 },
660 { 0, 0 }
661 }
662 }
650 }; 663 };
651 664
652 string16 locale; 665 string16 locale;
653 GoogleUpdateSettings::GetLanguage(&locale); 666 GoogleUpdateSettings::GetLanguage(&locale);
654 if (locale.empty() || (locale == ASCIIToWide("en"))) 667 if (locale.empty() || (locale == ASCIIToWide("en")))
655 locale = ASCIIToWide("en-US"); 668 locale = ASCIIToWide("en-US");
656 669
657 string16 brand; 670 string16 brand;
658 if (!GoogleUpdateSettings::GetBrand(&brand)) 671 if (!GoogleUpdateSettings::GetBrand(&brand))
659 brand = ASCIIToWide(""); // Could still be viable for catch-all rules. 672 brand = ASCIIToWide(""); // Could still be viable for catch-all rules.
660 if (brand == kEnterprise)
661 return false;
662 673
663 for (int i = 0; i < arraysize(kExperimentFlavors); ++i) { 674 for (int i = 0; i < arraysize(kExperiments); ++i) {
664 // A maximum of four flavors are supported at the moment. 675 if (kExperiments[i].locale != locale &&
665 CHECK_LE(kExperimentFlavors[i].flavors, kMax); 676 kExperiments[i].locale != ASCIIToWide("*"))
666 CHECK_GT(kExperimentFlavors[i].flavors, 0);
667 // Make sure each experiment has valid headings.
668 for (int f = 0; f < kMax; ++f) {
669 if (f < kExperimentFlavors[i].flavors) {
670 CHECK_GT(kExperimentFlavors[i].headings[f], 0);
671 } else {
672 CHECK_EQ(kExperimentFlavors[i].headings[f], 0);
673 }
674 }
675 // The prefix has to be a valid two letter combo.
676 CHECK(kExperimentFlavors[i].prefix1 >= 'A');
677 CHECK(kExperimentFlavors[i].prefix2 >= 'A');
678 CHECK(kExperimentFlavors[i].prefix2 +
679 kExperimentFlavors[i].flavors - 1 <= 'Z');
680
681 if (kExperimentFlavors[i].locale != locale &&
682 kExperimentFlavors[i].locale != ASCIIToWide("*"))
683 continue; 677 continue;
684 678
685 std::vector<string16> brand_codes; 679 std::vector<string16> brand_codes;
686 base::SplitString(kExperimentFlavors[i].brands, L',', &brand_codes); 680 base::SplitString(kExperiments[i].brands, L',', &brand_codes);
687 if (brand_codes.empty()) 681 if (brand_codes.empty())
688 return false; 682 return false;
689 for (std::vector<string16>::iterator it = brand_codes.begin(); 683 for (std::vector<string16>::iterator it = brand_codes.begin();
690 it != brand_codes.end(); ++it) { 684 it != brand_codes.end(); ++it) {
691 if (*it != brand && *it != L"*") 685 if (*it != brand && *it != L"*")
692 continue; 686 continue;
687 // We have found our match.
688 const UserExperimentDetails& match = kExperiments[i];
689 // Find out how many flavors we have. Zero means no experiment.
690 int num_flavors = 0;
691 while (match.flavors[num_flavors].heading_id) { ++num_flavors; }
692 if (!num_flavors)
693 return false;
693 694
694 // We have found our match.
695 if (flavor < 0) 695 if (flavor < 0)
696 flavor = base::RandInt(0, kExperimentFlavors[i].flavors - 1); 696 flavor = base::RandInt(0, num_flavors - 1);
697 experiment->flavor = flavor; 697 experiment->flavor = flavor;
698 experiment->heading = kExperimentFlavors[i].headings[flavor]; 698 experiment->heading = match.flavors[flavor].heading_id;
699 experiment->control_group = kExperimentFlavors[i].control_group; 699 experiment->control_group = match.control_group;
700 experiment->prefix.resize(2); 700 const wchar_t prefix[] = { match.prefix[0], match.prefix[1] + flavor, 0 };
701 experiment->prefix[0] = kExperimentFlavors[i].prefix1; 701 experiment->prefix = prefix;
702 experiment->prefix[1] = kExperimentFlavors[i].prefix2 + flavor; 702 experiment->flags = match.flavors[flavor].flags;
703 experiment->compact_bubble = (brand == kBrief) && (flavor == 1);
704 return true; 703 return true;
705 } 704 }
706 } 705 }
707 706
708 return false; 707 return false;
709 } 708 }
710 709
711 // Currently we only have one experiment: the inactive user toast. Which only 710 // Currently we only have one experiment: the inactive user toast. Which only
712 // applies for users doing upgrades. 711 // applies for users doing upgrades.
713 712
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 case chrome::RESULT_CODE_NORMAL_EXIT_CANCEL: 845 case chrome::RESULT_CODE_NORMAL_EXIT_CANCEL:
847 outcome = kToastExpCancelGroup; 846 outcome = kToastExpCancelGroup;
848 break; 847 break;
849 case chrome::RESULT_CODE_NORMAL_EXIT_EXP2: 848 case chrome::RESULT_CODE_NORMAL_EXIT_EXP2:
850 outcome = kToastExpUninstallGroup; 849 outcome = kToastExpUninstallGroup;
851 break; 850 break;
852 default: 851 default:
853 outcome = kToastExpTriesErrorGroup; 852 outcome = kToastExpTriesErrorGroup;
854 }; 853 };
855 854
855 if (outcome == kToastExpTriesOkGroup) {
856 // User tried chrome, but if it had the default group button it belongs
857 // to a different outcome group.
858 UserExperiment experiment;
859 if (GetExperimentDetails(&experiment, flavor)) {
860 outcome = experiment.flags & kMakeDefault ? kToastExpTriesOkDefaultGroup :
861 kToastExpTriesOkGroup;
862 }
863 }
864
856 // Write to the |client| key for the last time. 865 // Write to the |client| key for the last time.
857 SetClient(experiment_group + outcome, true); 866 SetClient(experiment_group + outcome, true);
858 867
859 if (outcome != kToastExpUninstallGroup) 868 if (outcome != kToastExpUninstallGroup)
860 return; 869 return;
861 870
862 // The user wants to uninstall. This is a best effort operation. Note that 871 // The user wants to uninstall. This is a best effort operation. Note that
863 // we waited for chrome to exit so the uninstall would not detect chrome 872 // we waited for chrome to exit so the uninstall would not detect chrome
864 // running. 873 // running.
865 bool system_level_toast = CommandLine::ForCurrentProcess()->HasSwitch( 874 bool system_level_toast = CommandLine::ForCurrentProcess()->HasSwitch(
866 installer::switches::kSystemLevelToast); 875 installer::switches::kSystemLevelToast);
867 876
868 CommandLine cmd(InstallUtil::GetChromeUninstallCmd(system_level_toast, 877 CommandLine cmd(InstallUtil::GetChromeUninstallCmd(system_level_toast,
869 GetType())); 878 GetType()));
870 base::LaunchProcess(cmd, base::LaunchOptions(), NULL); 879 base::LaunchProcess(cmd, base::LaunchOptions(), NULL);
871 } 880 }
872 #endif 881 #endif
OLDNEW
« no previous file with comments | « chrome/installer/util/browser_distribution.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698