diff options
author | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-04 15:48:11 +0000 |
---|---|---|
committer | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-04 15:48:11 +0000 |
commit | b80965554a11ef9d71df551c993e67a9ebe56cf9 (patch) | |
tree | 845c29d921de66ac917cdf74d2018fbf922d3411 | |
parent | 96abd567af2702ae7dd7a657d99bde38616bb380 (diff) | |
download | chromium_src-b80965554a11ef9d71df551c993e67a9ebe56cf9.zip chromium_src-b80965554a11ef9d71df551c993e67a9ebe56cf9.tar.gz chromium_src-b80965554a11ef9d71df551c993e67a9ebe56cf9.tar.bz2 |
cros: Default pinned apps experiment.
- Setup default pinned apps field trial when a regular
user signs in;
- Existing user prior the trial goes to "Existing" group;
- New users split 50/50 to "Control" and "Alternate";
- "Alternate" group users get the alternate default pinned
apps;
- Add click UMA histogram to compare clicks on the shelf;
BUG=234415
Review URL: https://chromiumcodereview.appspot.com/14566003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198327 0039d316-1c4b-4281-b951-d872f2087c98
19 files changed, 478 insertions, 44 deletions
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index 4662315..a54caae 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc @@ -44,6 +44,7 @@ #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h" #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h" #include "chrome/browser/chromeos/login/authenticator.h" +#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" #include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/login_wizard.h" #include "chrome/browser/chromeos/login/screen_locker.h" @@ -487,7 +488,7 @@ void ChromeBrowserMainPartsChromeos::PreMainMessageLoopRun() { CrasAudioHandler::Initialize( AudioDevicesPrefHandler::Create(g_browser_process->local_state())); } else { - AudioHandler::Initialize( + AudioHandler::Initialize( AudioPrefHandler::Create(g_browser_process->local_state())); } @@ -851,6 +852,7 @@ void ChromeBrowserMainPartsChromeos::PostDestroyThreads() { void ChromeBrowserMainPartsChromeos::SetupPlatformFieldTrials() { SetupZramFieldTrial(); + default_pinned_apps_field_trial::SetupTrial(); } void ChromeBrowserMainPartsChromeos::SetupZramFieldTrial() { diff --git a/chrome/browser/chromeos/extensions/default_app_order.cc b/chrome/browser/chromeos/extensions/default_app_order.cc index 0d19745..a63df33 100644 --- a/chrome/browser/chromeos/extensions/default_app_order.cc +++ b/chrome/browser/chromeos/extensions/default_app_order.cc @@ -54,21 +54,21 @@ void GetDefault(std::vector<std::string>* app_ids) { const char* kDefaultAppOrder[] = { extension_misc::kChromeAppId, extension_misc::kWebStoreAppId, - "coobgpohoikkiipiblmjeljniedjpjpf", // Search - "blpcfgokakmgnkcojhhkbfbldkacnbeo", // Youtube - "pjkljhegncpnkpknbcohdijeoejaedia", // Gmail + extension_misc::kGoogleSearchAppId, + extension_misc::kYoutubeAppId, + extension_misc::kGmailAppId, "ejjicmeblgpmajnghnpcppodonldlgfn", // Calendar "kjebfhglflhjjjiceimfkgicifkhjlnm", // Scratchpad "lneaknkopdijkpnocmklfnjbeapigfbh", // Google Maps "apdfllckaahabafndbhieahigkjlhalf", // Drive - "aohghmighlieiainnegkcijnfilokake", // Docs - "felcaaldnbdncclmgdcncolpebgiejap", // Sheets - "aapocclcgogkmnckokdopfmhonfmgoek", // Slides + extension_misc::kGoogleDocAppId, + extension_misc::kGoogleSheetsAppId, + extension_misc::kGoogleSlidesAppId, "dlppkpafhbajpcmmoheippocdidnckmm", // Google+ "kbpgddbgniojgndnhlkjbkpknjhppkbk", // Google+ Hangouts "hhaomjibdihmijegdhdafkllkbggdgoj", // Files "hkhhlkdconhgemhegnplaldnmnmkaemd", // Tips & Tricks - "icppfcnhkcmnfdhfhphakoifcfokfdhg", // Play Music + extension_misc::kGooglePlayMusicAppId, "mmimngoggfoobjdlefbcabngfnmieonb", // Play Books "fppdphmgcddhjeddoeghpjefkdlccljb", // Play Movies "fobcpibfeplaikcclojfdhfdmbbeofai", // Games diff --git a/chrome/browser/chromeos/login/default_pinned_apps_field_trial.cc b/chrome/browser/chromeos/login/default_pinned_apps_field_trial.cc new file mode 100644 index 0000000..f963ac9 --- /dev/null +++ b/chrome/browser/chromeos/login/default_pinned_apps_field_trial.cc @@ -0,0 +1,175 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" + +#include "base/basictypes.h" +#include "base/command_line.h" +#include "base/memory/ref_counted.h" +#include "base/metrics/field_trial.h" +#include "base/metrics/histogram.h" +#include "base/prefs/pref_registry_simple.h" +#include "base/prefs/pref_service.h" +#include "base/values.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/prefs/scoped_user_pref_update.h" +#include "chrome/browser/ui/ash/chrome_launcher_prefs.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/extensions/extension_constants.h" + +namespace chromeos { +namespace default_pinned_apps_field_trial { + +namespace { + +// Name of the default pinned app experiment. +const char kExperimentName[] = "DefaultPinnedApps"; + +// Name of a local state pref to store the list of users that participate +// the experiment. +const char kExperimentUsers[] = "DefaultPinnedAppsExperimentUsers"; + +// Alternate default pinned apps. +const char* kAlternateDefaultPinnedApps[] = { + extension_misc::kGmailAppId, + extension_misc::kGoogleDocAppId, + extension_misc::kGoogleSheetsAppId, + extension_misc::kGoogleSlidesAppId, + extension_misc::kGooglePlayMusicAppId, +}; + +// Global state of trial setup. +bool trial_configured = false; +int alternate_group = base::FieldTrial::kNotFinalized; + +// Returns true if user participates the experiment. +bool IsUserInExperiment(const std::string& username) { + const base::ListValue* users = + g_browser_process->local_state()->GetList(kExperimentUsers); + return users && users->Find(base::StringValue(username)) != users->end(); +} + +// Adds user to the experiment user list. +void AddUserToExperiment(const std::string& username) { + ListPrefUpdate users(g_browser_process->local_state(), kExperimentUsers); + users->AppendString(username); +} + +// Gets click target type for given app id. Returns false if the app id is +// not interesting. +bool GetClickTargetForApp(const std::string& app_id, + ClickTarget* click_target) { + static const struct AppIdToClickTarget { + const char* app_id; + ClickTarget click_target; + } kApps[] = { + { extension_misc::kChromeAppId, CHROME }, + { extension_misc::kGmailAppId, GMAIL }, + { extension_misc::kGoogleSearchAppId, SEARCH }, + { extension_misc::kYoutubeAppId, YOUTUBE }, + { extension_misc::kGoogleDocAppId, DOC }, + { extension_misc::kGoogleSheetsAppId, SHEETS }, + { extension_misc::kGoogleSlidesAppId, SLIDES }, + { extension_misc::kGooglePlayMusicAppId, PLAY_MUSIC }, + }; + + // kApps should define an app id for all click types except APP_LAUNCHER. + COMPILE_ASSERT(ARRAYSIZE_UNSAFE(kApps) == CLICK_TARGET_COUNT - 1, + app_to_click_target_incorrect_size); + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kApps); ++i) { + if (app_id == kApps[i].app_id) { + *click_target = kApps[i].click_target; + return true; + } + } + + return false; +} + +} // namespace + +void RegisterPrefs(PrefRegistrySimple* registry) { + registry->RegisterListPref(kExperimentUsers); +} + +void SetupTrial() { + // No trial if multiple profiles are enabled. + if (CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles)) + return; + + // SetupForUser should only be called once for single profile mode. + DCHECK(!trial_configured); + + const base::FieldTrial::Probability kDivisor = 100; + scoped_refptr<base::FieldTrial> trial = + base::FieldTrialList::FactoryGetFieldTrial( + kExperimentName, kDivisor, "Existing", 2013, 12, 31, NULL); + trial->UseOneTimeRandomization(); + + // Split 50/50 between "Control" and "Alternamte" group for new user. + // Existing users already have their default pinned apps and have the trial + // disabled to go to "Existing" group. + trial->AppendGroup("Control", 50); + alternate_group = trial->AppendGroup("Alternate", 50); +} + +void SetupForUser(const std::string& username, bool is_new_user) { + base::FieldTrial* trial = base::FieldTrialList::Find(kExperimentName); + if (!trial) + return; + + trial_configured = true; + + if (is_new_user) { + AddUserToExperiment(username); + return; + } + + if (!IsUserInExperiment(username)) + trial->Disable(); +} + +base::ListValue* GetAlternateDefaultPinnedApps() { + // This function is called for login manager profile, which happens + // before any user signs in. Returns NULL in this case. The case is covered + // by NULL trial check below but checking a boolean flag is faster. + if (!trial_configured) + return NULL; + + base::FieldTrial* trial = base::FieldTrialList::Find(kExperimentName); + if (!trial || trial->group() != alternate_group) + return NULL; + + scoped_ptr<base::ListValue> apps(new base::ListValue); + for (size_t i = 0; i < arraysize(kAlternateDefaultPinnedApps); ++i) + apps->Append(ash::CreateAppDict(kAlternateDefaultPinnedApps[i])); + + return apps.release(); +} + +void RecordShelfClick(ClickTarget click_target) { + // The experiment does not include certain user types, such as public account, + // retail mode user, local user and ephemeral user. + if (!trial_configured) + return; + + UMA_HISTOGRAM_ENUMERATION("Cros.ClickOnShelf", + click_target, + CLICK_TARGET_COUNT); +} + +void RecordShelfAppClick(const std::string& app_id) { + ClickTarget click_target = CLICK_TARGET_COUNT; + if (GetClickTargetForApp(app_id, &click_target)) + RecordShelfClick(click_target); +} + +void ResetStateForTest() { + trial_configured = false; + alternate_group = base::FieldTrial::kNotFinalized; +} + +} // namespace default_pinned_apps_field_trial +} // namespace chromeos diff --git a/chrome/browser/chromeos/login/default_pinned_apps_field_trial.h b/chrome/browser/chromeos/login/default_pinned_apps_field_trial.h new file mode 100644 index 0000000..995bb96 --- /dev/null +++ b/chrome/browser/chromeos/login/default_pinned_apps_field_trial.h @@ -0,0 +1,59 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_DEFAULT_PINNED_APPS_FIELD_TRIAL_H_ +#define CHROME_BROWSER_CHROMEOS_LOGIN_DEFAULT_PINNED_APPS_FIELD_TRIAL_H_ + +#include <string> + +namespace base { +class ListValue; +} + +class PrefRegistrySimple; + +namespace chromeos { +namespace default_pinned_apps_field_trial { + +// Enumeration to track clicks on the shelf. +enum ClickTarget { + CHROME = 0, + APP_LAUNCHER = 1, + GMAIL = 2, + SEARCH = 3, + YOUTUBE = 4, + DOC = 5, + SHEETS = 6, + SLIDES = 7, + PLAY_MUSIC = 8, + CLICK_TARGET_COUNT = 9 +}; + +// Registers a local state that keeps track of users in experiment. +void RegisterPrefs(PrefRegistrySimple* registry); + +// Creates the trail and setup groups. +void SetupTrial(); + +// Sets up the trial for a user. |username| is the email of the user. +// |is_new_user| is a boolean flag to indicate whether the user is new to +// the device. It is true when the user signs in the device for the first time. +void SetupForUser(const std::string& username, bool is_new_user); + +// Returns the alternate default pinned apps if the current user is in +// "Alternate" group. Otherwise, returns NULL. The caller takes the ownership +// of the returned list. +base::ListValue* GetAlternateDefaultPinnedApps(); + +// Record UMA for shelf clicks. +void RecordShelfClick(ClickTarget click_target); +void RecordShelfAppClick(const std::string& app_id); + +// Resets global states from test. +void ResetStateForTest(); + +} // namespace default_pinned_apps_field_trial +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_DEFAULT_PINNED_APPS_FIELD_TRIAL_H_ diff --git a/chrome/browser/chromeos/login/default_pinned_apps_field_trial_unittest.cc b/chrome/browser/chromeos/login/default_pinned_apps_field_trial_unittest.cc new file mode 100644 index 0000000..1406ca7 --- /dev/null +++ b/chrome/browser/chromeos/login/default_pinned_apps_field_trial_unittest.cc @@ -0,0 +1,91 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" + +#include "base/memory/scoped_ptr.h" +#include "base/metrics/field_trial.h" +#include "base/prefs/testing_pref_service.h" +#include "chrome/common/metrics/entropy_provider.h" +#include "chrome/test/base/testing_browser_process.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { + +class DefaultPinnedAppsFieldTrialTest : public testing::Test { + public: + DefaultPinnedAppsFieldTrialTest() {} + virtual ~DefaultPinnedAppsFieldTrialTest() {} + + // testing::Test overrides: + virtual void SetUp() OVERRIDE { + CreateFieldTrialList(); + CreateLocalState(); + } + virtual void TearDown() OVERRIDE { + Reset(); + } + + void CreateFieldTrialList() { + if (trial_list_) + trial_list_.reset(); + trial_list_.reset(new base::FieldTrialList( + new metrics::SHA1EntropyProvider("client_id"))); + default_pinned_apps_field_trial::SetupTrial(); + } + + void CreateLocalState() { + local_state_.reset(new TestingPrefServiceSimple); + default_pinned_apps_field_trial::RegisterPrefs(local_state_->registry()); + TestingBrowserProcess::GetGlobal()->SetLocalState(local_state_.get()); + } + + void Reset() { + TestingBrowserProcess::GetGlobal()->SetLocalState(NULL); + local_state_.reset(); + trial_list_.reset(); + default_pinned_apps_field_trial::ResetStateForTest(); + } + + private: + scoped_ptr<base::FieldTrialList> trial_list_; + scoped_ptr<TestingPrefServiceSimple> local_state_; + + DISALLOW_COPY_AND_ASSIGN(DefaultPinnedAppsFieldTrialTest); +}; + +// Tests existing user gets to "Existing" group. +TEST_F(DefaultPinnedAppsFieldTrialTest, ExistingUser) { + default_pinned_apps_field_trial::SetupForUser("existing@gmail.com", + false /* is_new_user */); + base::FieldTrial* trial = base::FieldTrialList::Find("DefaultPinnedApps"); + ASSERT_TRUE(trial != NULL); + EXPECT_EQ("Existing", trial->group_name()); +} + +// Tests new user gets to either "Control" or "Alternate group. And the user +// should get to the same group all the time. +TEST_F(DefaultPinnedAppsFieldTrialTest, NewUser) { + const char* kTestUser = "new@gmail.com"; + default_pinned_apps_field_trial::SetupForUser(kTestUser, + true /* is_new_user */); + base::FieldTrial* trial = base::FieldTrialList::Find("DefaultPinnedApps"); + ASSERT_TRUE(trial != NULL); + const std::string allocated_group = trial->group_name(); + EXPECT_TRUE("Control" == allocated_group || "Alternate" == allocated_group); + + // Pretend user signs out and signs back in. + default_pinned_apps_field_trial::ResetStateForTest(); + CreateFieldTrialList(); + + // This time, the user is no longer a new user. + default_pinned_apps_field_trial::SetupForUser(kTestUser, + false /* is_new_user */); + + // But he/she should still be included in the trial and in the same group. + trial = base::FieldTrialList::Find("DefaultPinnedApps"); + EXPECT_EQ(allocated_group, trial->group_name()); +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/login/user_manager_impl.cc b/chrome/browser/chromeos/login/user_manager_impl.cc index addc810..cfdc9a9 100644 --- a/chrome/browser/chromeos/login/user_manager_impl.cc +++ b/chrome/browser/chromeos/login/user_manager_impl.cc @@ -27,6 +27,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/cros/cert_library.h" #include "chrome/browser/chromeos/cros/cros_library.h" +#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" #include "chrome/browser/chromeos/login/login_display.h" #include "chrome/browser/chromeos/login/remove_user_delegate.h" #include "chrome/browser/chromeos/login/user_image_manager_impl.h" @@ -1017,6 +1018,8 @@ void UserManagerImpl::RegularUserLoggedIn(const std::string& email, WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded(); } + default_pinned_apps_field_trial::SetupForUser(email, is_current_user_new_); + // Make sure that new data is persisted to Local State. g_browser_process->local_state()->CommitPendingWrite(); } diff --git a/chrome/browser/extensions/default_apps.cc b/chrome/browser/extensions/default_apps.cc index 3ecf9a0..9633d12 100644 --- a/chrome/browser/extensions/default_apps.cc +++ b/chrome/browser/extensions/default_apps.cc @@ -4,6 +4,9 @@ #include "chrome/browser/extensions/default_apps.h" +#include <set> +#include <string> + #include "base/command_line.h" #include "chrome/browser/browser_process.h" #include "components/user_prefs/pref_registry_syncable.h" @@ -20,14 +23,11 @@ namespace { -const char kGmailId[] = "pjkljhegncpnkpknbcohdijeoejaedia"; -const char kSearchId[] = "coobgpohoikkiipiblmjeljniedjpjpf"; -const char kYoutubeId[] = "blpcfgokakmgnkcojhhkbfbldkacnbeo"; - // Returns true if the app was a default app in Chrome 22 bool IsOldDefaultApp(const std::string& extension_id) { - return extension_id == kGmailId || extension_id == kSearchId - || extension_id == kYoutubeId; + return extension_id == extension_misc::kGmailAppId || + extension_id == extension_misc::kGoogleSearchAppId || + extension_id == extension_misc::kYoutubeAppId; } bool IsLocaleSupported() { @@ -45,7 +45,7 @@ bool IsLocaleSupported() { return true; } -} // namespace +} // namespace namespace default_apps { diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index fac503e..77581f3 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc @@ -122,6 +122,7 @@ #include "chrome/browser/chromeos/audio/audio_pref_handler_impl.h" #include "chrome/browser/chromeos/customization_document.h" #include "chrome/browser/chromeos/display/display_preferences.h" +#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" #include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/oauth2_login_manager.h" #include "chrome/browser/chromeos/login/startup_utils.h" @@ -247,6 +248,7 @@ void RegisterLocalState(PrefRegistrySimple* registry) { chromeos::DataPromoNotification::RegisterPrefs(registry); chromeos::DeviceOAuth2TokenService::RegisterPrefs(registry); chromeos::device_settings_cache::RegisterPrefs(registry); + chromeos::default_pinned_apps_field_trial::RegisterPrefs(registry); chromeos::language_prefs::RegisterPrefs(registry); chromeos::KioskAppManager::RegisterPrefs(registry); chromeos::LoginUtils::RegisterPrefs(registry); diff --git a/chrome/browser/ui/ash/chrome_launcher_prefs.cc b/chrome/browser/ui/ash/chrome_launcher_prefs.cc index 05994ea..b0dfdba 100644 --- a/chrome/browser/ui/ash/chrome_launcher_prefs.cc +++ b/chrome/browser/ui/ash/chrome_launcher_prefs.cc @@ -7,20 +7,32 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "base/values.h" +#include "chrome/common/extensions/extension_constants.h" #include "chrome/common/pref_names.h" #include "components/user_prefs/pref_registry_syncable.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" +#endif + namespace { // App ID of default pinned apps. const char* kDefaultPinnedApps[] = { - "pjkljhegncpnkpknbcohdijeoejaedia", // Gmail - "coobgpohoikkiipiblmjeljniedjpjpf", // Search - "apdfllckaahabafndbhieahigkjlhalf", // Doc - "blpcfgokakmgnkcojhhkbfbldkacnbeo", // YouTube + extension_misc::kGmailAppId, + extension_misc::kGoogleSearchAppId, + extension_misc::kGoogleDocAppId, + extension_misc::kYoutubeAppId, }; base::ListValue* CreateDefaultPinnedAppsList() { +#if defined(OS_CHROMEOS) + base::ListValue* alternate = chromeos::default_pinned_apps_field_trial:: + GetAlternateDefaultPinnedApps(); + if (alternate) + return alternate; +#endif + scoped_ptr<base::ListValue> apps(new base::ListValue); for (size_t i = 0; i < arraysize(kDefaultPinnedApps); ++i) apps->Append(ash::CreateAppDict(kDefaultPinnedApps[i])); diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index 8657a67..56c4486 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc @@ -50,6 +50,10 @@ #include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" +#endif + // static ChromeShellDelegate* ChromeShellDelegate::instance_ = NULL; @@ -270,6 +274,10 @@ void ChromeShellDelegate::RecordUserMetricsAction( case ash::UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON: content::RecordAction( content::UserMetricsAction("Launcher_ClickOnApplistButton")); +#if defined(OS_CHROMEOS) + chromeos::default_pinned_apps_field_trial::RecordShelfClick( + chromeos::default_pinned_apps_field_trial::APP_LAUNCHER); +#endif break; case ash::UMA_MINIMIZE_PER_KEY: content::RecordAction(content::UserMetricsAction("Minimize_UsingKey")); diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.cc index f449388..c44eab4 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.cc @@ -72,14 +72,16 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/views/corewm/window_animations.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" +#endif + using extensions::Extension; +using extension_misc::kGmailAppId; using content::WebContents; namespace { -// The App ID for of the gMail application. -const char kGmailAppId[] = "pjkljhegncpnkpknbcohdijeoejaedia"; - std::string GetPrefKeyForRootWindow(aura::RootWindow* root_window) { gfx::Display display = gfx::Screen::GetScreenFor( root_window)->GetDisplayNearestWindow(root_window); @@ -901,6 +903,10 @@ void ChromeLauncherControllerPerApp::ActivateWindowOrMinimizeIfActive( void ChromeLauncherControllerPerApp::OnBrowserShortcutClicked( int event_flags) { +#if defined(OS_CHROMEOS) + chromeos::default_pinned_apps_field_trial::RecordShelfClick( + chromeos::default_pinned_apps_field_trial::CHROME); +#endif if (event_flags & ui::EF_CONTROL_DOWN) { CreateNewWindow(); return; @@ -927,7 +933,14 @@ void ChromeLauncherControllerPerApp::ItemSelected(const ash::LauncherItem& item, return; } DCHECK(HasItemController(item.id)); - id_to_item_controller_map_[item.id]->Clicked(event); + LauncherItemController* item_controller = id_to_item_controller_map_[item.id]; +#if defined(OS_CHROMEOS) + if (!item_controller->app_id().empty()) { + chromeos::default_pinned_apps_field_trial::RecordShelfAppClick( + item_controller->app_id()); + } +#endif + item_controller->Clicked(event); } int ChromeLauncherControllerPerApp::GetBrowserShortcutResourceId() { @@ -1300,7 +1313,7 @@ ChromeLauncherControllerPerApp::CreateAppShortcutLauncherItemWithType( void ChromeLauncherControllerPerApp::UpdateBrowserItemStatus() { // Determine the new browser's active state and change if necessary. size_t browser_index = ash::launcher::GetBrowserItemIndex(*model_); - DCHECK(browser_index >= 0); + DCHECK_GE(browser_index, 0u); ash::LauncherItem browser_item = model_->items()[browser_index]; ash::LauncherItemStatus browser_status = ash::STATUS_CLOSED; diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app_unittest.cc index eab87b9..d97c0df 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app_unittest.cc @@ -43,7 +43,6 @@ using extensions::Manifest; namespace { const int kExpectedAppIndex = 1; -const char* gmail_app_id = "pjkljhegncpnkpknbcohdijeoejaedia"; const char* offline_gmail_url = "https://mail.google.com/mail/mu/u"; const char* gmail_url = "https://mail.google.com/mail/u"; } @@ -187,14 +186,14 @@ class ChromeLauncherControllerPerAppTest : public BrowserWithTestWindowTest { extension3_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, manifest_gmail, Extension::NO_FLAGS, - gmail_app_id, + extension_misc::kGmailAppId, &error); // Fake search extension. extension4_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, manifest, Extension::NO_FLAGS, - "coobgpohoikkiipiblmjeljniedjpjpf", + extension_misc::kGoogleSearchAppId, &error); // Create a default launcher controller; some tests will call diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.cc index 734035a..8e2eaca 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.cc @@ -55,6 +55,10 @@ #include "ui/aura/root_window.h" #include "ui/aura/window.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" +#endif + using content::WebContents; using extensions::Extension; @@ -862,6 +866,10 @@ void ChromeLauncherControllerPerBrowser::ActivateWindowOrMinimizeIfActive( void ChromeLauncherControllerPerBrowser::OnBrowserShortcutClicked( int event_flags) { +#if defined(OS_CHROMEOS) + chromeos::default_pinned_apps_field_trial::RecordShelfClick( + chromeos::default_pinned_apps_field_trial::CHROME); +#endif if (event_flags & ui::EF_CONTROL_DOWN) { CreateNewWindow(); return; @@ -884,7 +892,14 @@ void ChromeLauncherControllerPerBrowser::ItemSelected( const ash::LauncherItem& item, const ui::Event& event) { DCHECK(HasItemController(item.id)); - id_to_item_controller_map_[item.id]->Clicked(event); + LauncherItemController* item_controller = id_to_item_controller_map_[item.id]; +#if defined(OS_CHROMEOS) + if (!item_controller->app_id().empty()) { + chromeos::default_pinned_apps_field_trial::RecordShelfAppClick( + item_controller->app_id()); + } +#endif + item_controller->Clicked(event); } int ChromeLauncherControllerPerBrowser::GetBrowserShortcutResourceId() { diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser_unittest.cc index dea21489..b71fa11 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser_unittest.cc @@ -72,13 +72,13 @@ class ChromeLauncherControllerPerBrowserTest : public testing::Test { extension3_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, manifest, Extension::NO_FLAGS, - "pjkljhegncpnkpknbcohdijeoejaedia", + extension_misc::kGmailAppId, &error); // Fake search extension. extension4_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, manifest, Extension::NO_FLAGS, - "coobgpohoikkiipiblmjeljniedjpjpf", + extension_misc::kGoogleSearchAppId, &error); } diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index 0180d89..50e8a30 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi @@ -388,6 +388,8 @@ 'browser/chromeos/login/captive_portal_window_proxy.h', 'browser/chromeos/login/chrome_restart_request.cc', 'browser/chromeos/login/chrome_restart_request.h', + 'browser/chromeos/login/default_pinned_apps_field_trial.cc', + 'browser/chromeos/login/default_pinned_apps_field_trial.h', 'browser/chromeos/login/default_user_images.cc', 'browser/chromeos/login/default_user_images.h', 'browser/chromeos/login/enrollment/enrollment_screen.cc', diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 25f7754..ce7d17a 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -626,6 +626,7 @@ 'browser/chromeos/kiosk_mode/kiosk_mode_idle_logout_unittest.cc', 'browser/chromeos/kiosk_mode/kiosk_mode_settings_unittest.cc', 'browser/chromeos/language_preferences_unittest.cc', + 'browser/chromeos/login/default_pinned_apps_field_trial_unittest.cc', 'browser/chromeos/login/existing_user_controller_auto_login_unittest.cc', 'browser/chromeos/login/hwid_checker_unittest.cc', 'browser/chromeos/login/merge_session_load_page_unittest.cc', diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index c6e8847..844197b 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc @@ -105,7 +105,7 @@ const char kGeneratedBackgroundPageFilename[] = const char kModulesDir[] = "_modules"; -} +} // namespace extension_filenames // These must match the values expected by the chrome.management extension API. namespace extension_info_keys { @@ -124,11 +124,20 @@ namespace extension_info_keys { } // namespace extension_filenames namespace extension_misc { + const char kBookmarkManagerId[] = "eemcgdkfndhakfknompkggombfjjjeno"; +const char kChromeAppId[] = "mgndgikekgjfcpckkfioiadnlibdjbkf"; const char kCitrixReceiverAppId[] = "haiffjcadagjlijoggckpgfnoeiflnem"; const char kCitrixReceiverAppBetaId[] = "gnedhmakppccajfpfiihfcdlnpgomkcf"; const char kCitrixReceiverAppDevId[] = "fjcibdnjlbfnbfdjneajpipnlcppleek"; +const char kCloudPrintAppId[] = "mfehgcgbbipciphmccgaenjidiccnmng"; const char kEnterpriseWebStoreAppId[] = "afchcafgojfnemjkcbhfekplkmjaldaa"; +const char kGmailAppId[] = "pjkljhegncpnkpknbcohdijeoejaedia"; +const char kGoogleDocAppId[] = "aohghmighlieiainnegkcijnfilokake"; +const char kGooglePlayMusicAppId[] = "icppfcnhkcmnfdhfhphakoifcfokfdhg"; +const char kGoogleSearchAppId[] = "coobgpohoikkiipiblmjeljniedjpjpf"; +const char kGoogleSheetsAppId[] = "felcaaldnbdncclmgdcncolpebgiejap"; +const char kGoogleSlidesAppId[] = "aapocclcgogkmnckokdopfmhonfmgoek"; const char kHTermAppId[] = "pnhechapfaindjhompbnflcldabbghjo"; const char kHTermDevAppId[] = "okddffdblfhhnmhodogpojmfkjmhinfp"; const char kCroshBuiltinAppId[] = "nkoccljplnhpfnfiajclkommnmllphnl"; @@ -136,12 +145,12 @@ const char kQuickOfficeComponentExtensionId[] = "bpmcpldpdmajfigpchkicefoigmkfalc"; const char kQuickOfficeDevExtensionId[] = "ionpfmkccalenbmnddpbmocokhaknphg"; const char kQuickOfficeExtensionId[] = "gbkeegbaiigmenfmjfclcdgdpimamgkj"; +const char kSettingsAppId[] = "ennkphjdgehloodpbhlhldgbnhmacadg"; const char kStreamsPrivateTestExtensionId[] = "oickdpebdnfbgkcaoklfcdhjniefkcji"; const char kWebStoreAppId[] = "ahfgeienlihckogmohjhadlkjgocpleb"; -const char kCloudPrintAppId[] = "mfehgcgbbipciphmccgaenjidiccnmng"; -const char kChromeAppId[] = "mgndgikekgjfcpckkfioiadnlibdjbkf"; -const char kSettingsAppId[] = "ennkphjdgehloodpbhlhldgbnhmacadg"; +const char kYoutubeAppId[] = "blpcfgokakmgnkcojhhkbfbldkacnbeo"; + const char kAppLaunchHistogram[] = "Extensions.AppLaunch"; const char kPlatformAppLaunchHistogram[] = "Apps.AppLaunch"; #if defined(OS_CHROMEOS) diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index 8ce965f..9566f17 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h @@ -94,6 +94,9 @@ namespace extension_misc { // The extension id of the bookmark manager. extern const char kBookmarkManagerId[]; + // The extension id of the Chrome component application. + extern const char kChromeAppId[]; + // The extension id of the Citrix Receiver application. extern const char kCitrixReceiverAppId[]; @@ -103,9 +106,30 @@ namespace extension_misc { // The extension id of the dev Citrix Receiver application. extern const char kCitrixReceiverAppDevId[]; + // The extension id of the Cloud Print component application. + extern const char kCloudPrintAppId[]; + // The extension id of the Enterprise Web Store component application. extern const char kEnterpriseWebStoreAppId[]; + // The extension id of GMail application. + extern const char kGmailAppId[]; + + // The extension id of the Google Doc application. + extern const char kGoogleDocAppId[]; + + // The extension id of the Google Play Music application. + extern const char kGooglePlayMusicAppId[]; + + // The extension id of the Google Search application. + extern const char kGoogleSearchAppId[]; + + // The extension id of the Google Sheets application. + extern const char kGoogleSheetsAppId[]; + + // The extension id of the Google Slides application. + extern const char kGoogleSlidesAppId[]; + // The extension id of the HTerm app for ChromeOS. extern const char kHTermAppId[]; @@ -124,20 +148,17 @@ namespace extension_misc { // The extension id of the Office Viewer extension. extern const char kQuickOfficeExtensionId[]; + // The extension id of the settings application. + extern const char kSettingsAppId[]; + // The extension id used for testing streamsPrivate extern const char kStreamsPrivateTestExtensionId[]; // The extension id of the Web Store component application. extern const char kWebStoreAppId[]; - // The extension id of the Cloud Print component application. - extern const char kCloudPrintAppId[]; - - // The extension id of the Chrome component application. - extern const char kChromeAppId[]; - - // The extension id of the settings application. - extern const char kSettingsAppId[]; + // The extension id of the Youtube application. + extern const char kYoutubeAppId[]; // Note: this structure is an ASN.1 which encodes the algorithm used // with its parameters. This is defined in PKCS #1 v2.1 (RFC 3447). @@ -305,7 +326,6 @@ namespace extension_misc { // List of sizes for extension icons that can be defined in the manifest. extern const int kScriptBadgeIconSizes[]; extern const size_t kNumScriptBadgeIconSizes; - -} // extension_misc +} // namespace extension_misc #endif // CHROME_COMMON_EXTENSIONS_EXTENSION_CONSTANTS_H_ diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 524912e..5952c4c 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -459,6 +459,10 @@ other types of suffix sets. </summary> </histogram> +<histogram name="Cros.ClickOnShelf" enum="CrosShelfClickTarget"> + <summary>Chrome OS shelf clicks.</summary> +</histogram> + <histogram name="CrosDisks.ArchiveType" enum="CrosDisksArchiveType"> <summary> The type of archive file that Chrome OS cros-disks daemon is requested to @@ -7680,6 +7684,18 @@ other types of suffix sets. <int value="0" label="ModemManagerCommandSendFailure"/> </enum> +<enum name="CrosShelfClickTarget" type="int"> + <int value="0" label="Chrome"/> + <int value="1" label="AppLauncher"/> + <int value="2" label="Gmail"/> + <int value="3" label="Search"/> + <int value="4" label="Youtube"/> + <int value="5" label="Doc"/> + <int value="6" label="Sheets"/> + <int value="7" label="Slides"/> + <int value="8" label="PlayMusic"/> +</enum> + <enum name="DomainBoundCerts.GetCertResult" type="int"> <int value="0" label="SYNC_SUCCESS"/> <int value="1" label="ASYNC_SUCCESS"/> @@ -10933,6 +10949,13 @@ other types of suffix sets. <affected-histogram name="PLT.LoadType"/> </fieldtrial> +<fieldtrial name="DefaultPinnedApps"> + <group name="Existing"/> + <group name="Control"/> + <group name="Alternate"/> + <affected-histogram name="Cros.ClickOnShelf"/> +</fieldtrial> + <fieldtrial name="DnsImpact2"> <group name="disabled_prefetch" label="DNS pre-resolving is disabled in these clients"/> |