diff options
author | mad@chromium.org <mad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-26 21:38:15 +0000 |
---|---|---|
committer | mad@chromium.org <mad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-26 21:38:15 +0000 |
commit | a7c94bc9887ce9ab4afbaa7149b403db81940cac (patch) | |
tree | a2cc73c7560acb582769a4f78dfb3b5e18fa609c | |
parent | 6c6361d31df0f6397092bba0659230bcad7ef88c (diff) | |
download | chromium_src-a7c94bc9887ce9ab4afbaa7149b403db81940cac.zip chromium_src-a7c94bc9887ce9ab4afbaa7149b403db81940cac.tar.gz chromium_src-a7c94bc9887ce9ab4afbaa7149b403db81940cac.tar.bz2 |
Add a new App launcher promo to the apps page / NTP.
Simple change in chrome/browser/chrome_browser_main.cc
TBR=ben@chromium.org
BUG=180475
TEST=Make sure the apps promo only show on apps page of the NTP (or chrome://apps) and that it links to webstore (specific page to be added later on the webstore) and that it doesn't come back on a given installation of Chrome once dismissed with the X close button. That dimiss state can be reset with the command line switch --reset-show-apps-promo to help test it. Also, this shouldn't show when the App Launcher is installer... since no apps page should be shown anyway (tested with --show-app-list-shortcut)
Review URL: https://chromiumcodereview.appspot.com/12985002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@190772 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | apps/apps.gypi | 2 | ||||
-rw-r--r-- | apps/field_trial_names.cc | 19 | ||||
-rw-r--r-- | apps/field_trial_names.h | 18 | ||||
-rw-r--r-- | apps/pref_names.cc | 3 | ||||
-rw-r--r-- | apps/pref_names.h | 1 | ||||
-rw-r--r-- | apps/prefs.cc | 6 | ||||
-rw-r--r-- | chrome/app/generated_resources.grd | 4 | ||||
-rw-r--r-- | chrome/browser/chrome_browser_field_trials.cc | 24 | ||||
-rw-r--r-- | chrome/browser/chrome_browser_field_trials.h | 16 | ||||
-rw-r--r-- | chrome/browser/chrome_browser_main.cc | 6 | ||||
-rw-r--r-- | chrome/browser/resources/ntp4/app_launcher_promo.png | 0 | ||||
-rw-r--r-- | chrome/browser/resources/ntp4/apps_page.css | 62 | ||||
-rw-r--r-- | chrome/browser/resources/ntp4/new_tab.html | 11 | ||||
-rw-r--r-- | chrome/browser/resources/ntp4/new_tab.js | 13 | ||||
-rw-r--r-- | chrome/browser/resources/ntp4/page_list_view.js | 64 | ||||
-rw-r--r-- | chrome/browser/ui/webui/ntp/app_launcher_handler.cc | 37 | ||||
-rw-r--r-- | chrome/browser/ui/webui/ntp/app_launcher_handler.h | 12 | ||||
-rw-r--r-- | chrome/browser/ui/webui/ntp/ntp_resource_cache.cc | 34 | ||||
-rw-r--r-- | chrome/browser/ui/webui/ntp/ntp_resource_cache.h | 3 |
19 files changed, 291 insertions, 44 deletions
diff --git a/apps/apps.gypi b/apps/apps.gypi index 8760e17..61f42e9 100644 --- a/apps/apps.gypi +++ b/apps/apps.gypi @@ -34,6 +34,8 @@ 'app_shim/app_shim_host_mac.h', 'app_shim/app_shim_host_manager_mac.h', 'app_shim/app_shim_host_manager_mac.mm', + 'field_trial_names.cc', + 'field_trial_names.h', 'pref_names.cc', 'pref_names.h', 'prefs.cc', diff --git a/apps/field_trial_names.cc b/apps/field_trial_names.cc new file mode 100644 index 0000000..9e5cbcf --- /dev/null +++ b/apps/field_trial_names.cc @@ -0,0 +1,19 @@ +// 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 "apps/field_trial_names.h" + +namespace apps { + +// The field trial group name that enables showing the promo. +const char kShowLauncherPromoOnceGroupName[] = "ShowPromoUntilDismissed"; + +// The field trial group name that resets the pref to show the app launcher +// promo on every session startup. +const char kResetShowLauncherPromoPrefGroupName[] = "ResetShowPromoPref"; + +// The name of the field trial that controls showing the app launcher promo. +const char kLauncherPromoTrialName[] = "ShowAppLauncherPromo"; + +} // namespace apps diff --git a/apps/field_trial_names.h b/apps/field_trial_names.h new file mode 100644 index 0000000..568ae43d --- /dev/null +++ b/apps/field_trial_names.h @@ -0,0 +1,18 @@ +// 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 APPS_FIELD_TRIAL_NAMES_H_ +#define APPS_FIELD_TRIAL_NAMES_H_ + +namespace apps { + +// Alphabetical list of field trial names specific to Apps component. +// Keep alphabetized and document each one in the source file. +extern const char kShowLauncherPromoOnceGroupName[]; +extern const char kResetShowLauncherPromoPrefGroupName[]; +extern const char kLauncherPromoTrialName[]; + +} // namespace apps + +#endif // APPS_FIELD_TRIAL_NAMES_H_ diff --git a/apps/pref_names.cc b/apps/pref_names.cc index d4ac6fa..cb1cf93 100644 --- a/apps/pref_names.cc +++ b/apps/pref_names.cc @@ -21,6 +21,9 @@ const char kAppLaunchForMetroRestart[] = "apps.app_launch_for_metro_restart"; const char kAppLaunchForMetroRestartProfile[] = "apps.app_launch_for_metro_restart_profile"; +// A boolean identifying if we should show the app launcher promo or not. +const char kShowAppLauncherPromo[] = "app_launcher.show_promo"; + } // namespace prefs } // namespace apps diff --git a/apps/pref_names.h b/apps/pref_names.h index db6ad7c..db5d7c2 100644 --- a/apps/pref_names.h +++ b/apps/pref_names.h @@ -13,6 +13,7 @@ namespace prefs { extern const char kAppLauncherIsEnabled[]; extern const char kAppLaunchForMetroRestart[]; extern const char kAppLaunchForMetroRestartProfile[]; +extern const char kShowAppLauncherPromo[]; } // namespace prefs } // namespace apps diff --git a/apps/prefs.cc b/apps/prefs.cc index edaf119..2685860 100644 --- a/apps/prefs.cc +++ b/apps/prefs.cc @@ -20,11 +20,15 @@ void RegisterPrefs(PrefRegistrySimple* registry) { // GetIsAppLauncherEnabled(). registry->RegisterBooleanPref(prefs::kAppLauncherIsEnabled, MaybeIsAppLauncherEnabled()); - #if defined(OS_WIN) registry->RegisterStringPref(prefs::kAppLaunchForMetroRestart, ""); registry->RegisterStringPref(prefs::kAppLaunchForMetroRestartProfile, ""); #endif + + // Identifies whether we should show the app launcher promo or not. + // Now that a field trial also controls the showing, so the promo won't show + // unless the pref is set AND the field trial is set to a proper group. + registry->RegisterBooleanPref(prefs::kShowAppLauncherPromo, true); } } // namespace apps diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index f6769d8..0b631ce 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -11520,6 +11520,10 @@ experiment id: "<ph name="EXPERIMENT_ID">$5<ex>ar1</ex></ph>" desc="Title for accessibility of the 'page-switcher-start' or 'page-switcher-end' button when switching between pages which have the same title"> More <ph name="PAGE_TITLE">$1<ex>Apps</ex></ph> </message> + <message name="IDS_NEW_TAB_PAGE_APPS_PROMO_TITLE" + desc="Title for the app launcher promo box shown on apps pages."> + Discover the Chrome App Launcher + </message> <if expr="not pp_ifdef('use_titlecase')"> <message name="IDS_NEW_TAB_APP_OPTIONS" desc="Text for the context menu item that takes the user to the options of an app. (In sentence case.)"> diff --git a/chrome/browser/chrome_browser_field_trials.cc b/chrome/browser/chrome_browser_field_trials.cc index 0a0c9a8..3c53c56 100644 --- a/chrome/browser/chrome_browser_field_trials.cc +++ b/chrome/browser/chrome_browser_field_trials.cc @@ -6,8 +6,11 @@ #include <string> +#include "apps/field_trial_names.h" +#include "apps/pref_names.h" #include "base/command_line.h" #include "base/metrics/field_trial.h" +#include "base/prefs/pref_service.h" #include "base/string_util.h" #include "base/stringprintf.h" #include "base/strings/string_number_conversions.h" @@ -26,6 +29,7 @@ #include "chrome/common/chrome_version_info.h" #include "chrome/common/metrics/variations/uniformity_field_trials.h" #include "chrome/common/metrics/variations/variations_util.h" +#include "chrome/common/pref_names.h" #include "net/socket/client_socket_pool_base.h" #include "net/spdy/spdy_session.h" #include "ui/base/layout.h" @@ -56,16 +60,19 @@ ChromeBrowserFieldTrials::ChromeBrowserFieldTrials( ChromeBrowserFieldTrials::~ChromeBrowserFieldTrials() { } -void ChromeBrowserFieldTrials::SetupFieldTrials( - const base::Time& install_time) { +void ChromeBrowserFieldTrials::SetupFieldTrials(PrefService* local_state) { + const base::Time install_time = base::Time::FromTimeT( + local_state->GetInt64(prefs::kInstallDate)); + DCHECK(!install_time.is_null()); chrome_variations::SetupUniformityFieldTrials(install_time); SetUpSimpleCacheFieldTrial(); #if !defined(OS_ANDROID) - SetupDesktopFieldTrials(); + SetupDesktopFieldTrials(local_state); #endif // defined(OS_ANDROID) } -void ChromeBrowserFieldTrials::SetupDesktopFieldTrials() { +void ChromeBrowserFieldTrials::SetupDesktopFieldTrials( + PrefService* local_state) { prerender::ConfigurePrefetchAndPrerender(parsed_command_line_); SpdyFieldTrial(); WarmConnectionFieldTrial(); @@ -80,6 +87,15 @@ void ChromeBrowserFieldTrials::SetupDesktopFieldTrials() { OneClickSigninHelper::InitializeFieldTrial(); #endif InstantiateDynamicTrials(); + SetupAppLauncherFieldTrial(local_state); +} + +void ChromeBrowserFieldTrials::SetupAppLauncherFieldTrial( + PrefService* local_state) { + if (base::FieldTrialList::FindFullName(apps::kLauncherPromoTrialName) == + apps::kResetShowLauncherPromoPrefGroupName) { + local_state->SetBoolean(apps::prefs::kShowAppLauncherPromo, true); + } } // When --use-spdy not set, users will be in A/B test for spdy. diff --git a/chrome/browser/chrome_browser_field_trials.h b/chrome/browser/chrome_browser_field_trials.h index dc92241..bd0cf62 100644 --- a/chrome/browser/chrome_browser_field_trials.h +++ b/chrome/browser/chrome_browser_field_trials.h @@ -10,16 +10,16 @@ #include "base/gtest_prod_util.h" #include "base/time.h" +class PrefService; + class ChromeBrowserFieldTrials { public: explicit ChromeBrowserFieldTrials(const CommandLine& command_line); ~ChromeBrowserFieldTrials(); // Called by the browser main sequence to set up Field Trials for this client. - // |install_time| is the time this browser was installed (or the last time - // prefs was reset). |install_time| is used by trials that are only created - // for new installs of the browser. - void SetupFieldTrials(const base::Time& install_time); + // |local_state| is used to extract properties like install time. + void SetupFieldTrials(PrefService* local_state); private: FRIEND_TEST_ALL_PREFIXES(BrowserMainTest, @@ -30,7 +30,13 @@ class ChromeBrowserFieldTrials { // Sets up common desktop-only field trials. // Add an invocation of your field trial init function to this method, or to // SetupFieldTrials if it is for all platforms. - void SetupDesktopFieldTrials(); + // |local_state| is needed by some other methods called from within this one. + void SetupDesktopFieldTrials(PrefService* local_state); + + // This is not quite a field trial initialization, but it's an initialization + // that depends on a field trial, so why not? :-) + // |local_state| is needed to reset a local pref based on the chosen group. + void SetupAppLauncherFieldTrial(PrefService* local_state); // A/B test for spdy when --use-spdy not set. void SpdyFieldTrial(); diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index d7f2f648..4df00b0 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc @@ -680,10 +680,8 @@ void ChromeBrowserMainParts::SetupMetricsAndFieldTrials() { if (variations_service) variations_service->CreateTrialsFromSeed(); - const int64 install_date = local_state_->GetInt64(prefs::kInstallDate); - // This must be called after the pref is initialized. - DCHECK(install_date); - browser_field_trials_.SetupFieldTrials(base::Time::FromTimeT(install_date)); + // This must be called after the local state is initialized. + browser_field_trials_.SetupFieldTrials(local_state_); SetupPlatformFieldTrials(); diff --git a/chrome/browser/resources/ntp4/app_launcher_promo.png b/chrome/browser/resources/ntp4/app_launcher_promo.png new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/chrome/browser/resources/ntp4/app_launcher_promo.png diff --git a/chrome/browser/resources/ntp4/apps_page.css b/chrome/browser/resources/ntp4/apps_page.css index dbea2ba..bd2e9cc 100644 --- a/chrome/browser/resources/ntp4/apps_page.css +++ b/chrome/browser/resources/ntp4/apps_page.css @@ -99,3 +99,65 @@ .app .invisible { visibility: hidden; } + +#app-launcher-promo { + background-color: white; + border: 1px solid lightgray; + border-bottom-width: 3px; + border-radius: 2px; + border-top-width: 2px; + bottom: 90px; + font-family: Arial, Helvetica, sans-serif; + height: 120px; + left: 50%; + margin-left: -300px; + position: fixed; + width: 600px; +} + +#app-launcher-promo > .close-button { + position: absolute; + right: 10px; + top: 10px; + width: 14px; +} + +.apps-promo-text { + color: #222; + font-size: 16px; + left: 30px; + line-height: 24px; + position: absolute; + top: 30px; +} + +.apps-promo-learn-more { + background-color: rgb(77, 144, 254); + border: 1px solid rgb(47, 91, 183); + border-radius: 2px; + color: white; + cursor: default; + font-size: 11px; + font-weight: bold; + height: 27px; + left: 30px; + line-height: 27px; + padding: 0 8px; + position: absolute; + text-align: center; + text-decoration: none; + top: 70px; + width: 90px; +} + +.apps-promo-learn-more:hover { + background-image: -webkit-linear-gradient( + top, rgb(77, 144, 254), rgb(53, 122, 232)); + border: 1px solid rgb(47, 91, 183); +} + +#app-launcher-promo > img { + bottom: 0; + position: absolute; + right: 30px; +} diff --git a/chrome/browser/resources/ntp4/new_tab.html b/chrome/browser/resources/ntp4/new_tab.html index e5bb3e3..99f8fa7 100644 --- a/chrome/browser/resources/ntp4/new_tab.html +++ b/chrome/browser/resources/ntp4/new_tab.html @@ -93,6 +93,17 @@ </div> </div> + <div id="app-launcher-promo" hidden> + <div class="apps-promo-text" i18n-content="appsPromoTitle"></div> + <a href="https://chrome.google.com/webstore/launcher" + class="apps-promo-learn-more" i18n-content="learn_more"> + </a> + <img src="app_launcher_promo.png"> + <button class="close-button custom-appearance" + id="app-launcher-promo-close-button"> + </button> + </div> + <div id="footer"> <div id="footer-border"></div> <div id="footer-content"> diff --git a/chrome/browser/resources/ntp4/new_tab.js b/chrome/browser/resources/ntp4/new_tab.js index a930f2f..a0da4fe 100644 --- a/chrome/browser/resources/ntp4/new_tab.js +++ b/chrome/browser/resources/ntp4/new_tab.js @@ -127,8 +127,13 @@ cr.define('ntp', function() { sectionsToWaitFor = 0; if (loadTimeData.getBoolean('showMostvisited')) sectionsToWaitFor++; - if (loadTimeData.getBoolean('showApps')) + if (loadTimeData.getBoolean('showApps')) { sectionsToWaitFor++; + if (loadTimeData.getBoolean('showAppLauncherPromo')) { + $('app-launcher-promo-close-button').addEventListener('click', + function() { chrome.send('stopShowingAppLauncherPromo'); }); + } + } if (loadTimeData.getBoolean('isDiscoveryInNTPEnabled')) sectionsToWaitFor++; measureNavDots(); @@ -627,6 +632,11 @@ cr.define('ntp', function() { return newTabView.appsPrefChangedCallback.apply(newTabView, arguments); } + function appLauncherPromoPrefChangeCallback() { + return newTabView.appLauncherPromoPrefChangeCallback.apply(newTabView, + arguments); + } + function appsReordered() { return newTabView.appsReordered.apply(newTabView, arguments); } @@ -670,6 +680,7 @@ cr.define('ntp', function() { appMoved: appMoved, appRemoved: appRemoved, appsPrefChangeCallback: appsPrefChangeCallback, + appLauncherPromoPrefChangeCallback: appLauncherPromoPrefChangeCallback, enterRearrangeMode: enterRearrangeMode, getAppsCallback: getAppsCallback, getAppsPageIndex: getAppsPageIndex, diff --git a/chrome/browser/resources/ntp4/page_list_view.js b/chrome/browser/resources/ntp4/page_list_view.js index 8fd5940..b95825c 100644 --- a/chrome/browser/resources/ntp4/page_list_view.js +++ b/chrome/browser/resources/ntp4/page_list_view.js @@ -218,7 +218,7 @@ cr.define('ntp', function() { * * @param {TilePage} page The page element. * @param {string} title The title of the tile page. - * @param {bool} titleIsEditable If true, the title can be changed. + * @param {boolean} titleIsEditable If true, the title can be changed. * @param {TilePage} opt_refNode Optional reference node to insert in front * of. * When opt_refNode is falsey, |page| will just be appended to the end of @@ -412,6 +412,7 @@ cr.define('ntp', function() { this.appsLoaded_ = true; cr.dispatchSimpleEvent(document, 'sectionready', true, true); } + this.updateAppLauncherPromoHiddenState_(); }, /** @@ -475,6 +476,25 @@ cr.define('ntp', function() { }, /** + * Callback invoked by chrome whenever the app launcher promo pref changes. + * @param {boolean} show Identifies if we should show or hide the promo. + */ + appLauncherPromoPrefChangeCallback: function(show) { + loadTimeData.overrideValues({showAppLauncherPromo: show}); + this.updateAppLauncherPromoHiddenState_(); + }, + + /** + * Updates the hidden state of the app launcher promo based on the page + * shown and load data content. + */ + updateAppLauncherPromoHiddenState_: function() { + $('app-launcher-promo').hidden = + !loadTimeData.getBoolean('showAppLauncherPromo') || + this.shownPage != loadTimeData.getInteger('apps_page_id'); + }, + + /** * Invoked whenever the pages in apps-page-list have changed so that * the Slider knows about the new elements. */ @@ -483,20 +503,33 @@ cr.define('ntp', function() { this.tilePages.length - 1)); this.cardSlider.setCards(Array.prototype.slice.call(this.tilePages), pageNo); - switch (this.shownPage) { - case loadTimeData.getInteger('apps_page_id'): - this.cardSlider.selectCardByValue( - this.appsPages[Math.min(this.shownPageIndex, - this.appsPages.length - 1)]); - break; - case loadTimeData.getInteger('most_visited_page_id'): - if (this.mostVisitedPage) - this.cardSlider.selectCardByValue(this.mostVisitedPage); - break; - case loadTimeData.getInteger('suggestions_page_id'): - if (this.suggestionsPage) - this.cardSlider.selectCardByValue(this.suggestionsPage); - break; + // The shownPage property was potentially saved from a previous webui that + // didn't have the same set of pages as the current one. So we cascade + // from suggestions, to most visited and then to apps because we can have + // an page with apps only (e.g., chrome://apps) or one with only the most + // visited, but not one with only suggestions. And we alwayd default to + // most visited first when previously shown page is not availabel anymore. + // If most visited isn't there either, we go to apps. + if (this.shownPage == loadTimeData.getInteger('suggestions_page_id')) { + if (this.suggestionsPage) + this.cardSlider.selectCardByValue(this.suggestionsPage); + else + this.shownPage = loadTimeData.getInteger('most_visited_page_id'); + } + if (this.shownPage == loadTimeData.getInteger('most_visited_page_id')) { + if (this.mostVisitedPage) + this.cardSlider.selectCardByValue(this.mostVisitedPage); + else + this.shownPage = loadTimeData.getInteger('apps_page_id'); + } + if (this.shownPage == loadTimeData.getInteger('apps_page_id') && + loadTimeData.getBoolean('showApps')) { + this.cardSlider.selectCardByValue( + this.appsPages[Math.min(this.shownPageIndex, + this.appsPages.length - 1)]); + } else if (this.mostVisitedPage) { + this.shownPage = loadTimeData.getInteger('most_visited_page_id'); + this.cardSlider.selectCardByValue(this.mostVisitedPage); } }, @@ -651,6 +684,7 @@ cr.define('ntp', function() { this.shownPage = shownPage; this.shownPageIndex = shownPageIndex; chrome.send('pageSelected', [this.shownPage, this.shownPageIndex]); + this.updateAppLauncherPromoHiddenState_(); }, /** diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc index c969580..e6856f9 100644 --- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc +++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc @@ -6,6 +6,7 @@ #include <vector> +#include "apps/pref_names.h" #include "base/auto_reset.h" #include "base/bind.h" #include "base/bind_helpers.h" @@ -15,6 +16,7 @@ #include "base/prefs/pref_service.h" #include "base/utf_string_conversions.h" #include "base/values.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/extension_prefs.h" #include "chrome/browser/extensions/extension_service.h" @@ -164,6 +166,14 @@ void AppLauncherHandler::RegisterMessages() { registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, content::Source<WebContents>(web_ui()->GetWebContents())); + // Some tests don't have a local state. + if (g_browser_process->local_state()) { + local_state_pref_change_registrar_.Init(g_browser_process->local_state()); + local_state_pref_change_registrar_.Add( + apps::prefs::kShowAppLauncherPromo, + base::Bind(&AppLauncherHandler::OnLocalStatePreferenceChanged, + base::Unretained(this))); + } web_ui()->RegisterMessageCallback("getApps", base::Bind(&AppLauncherHandler::HandleGetApps, base::Unretained(this))); @@ -194,6 +204,9 @@ void AppLauncherHandler::RegisterMessages() { web_ui()->RegisterMessageCallback("recordAppLaunchByURL", base::Bind(&AppLauncherHandler::HandleRecordAppLaunchByUrl, base::Unretained(this))); + web_ui()->RegisterMessageCallback("stopShowingAppLauncherPromo", + base::Bind(&AppLauncherHandler::StopShowingAppLauncherPromo, + base::Unretained(this))); } void AppLauncherHandler::Observe(int type, @@ -391,12 +404,13 @@ void AppLauncherHandler::HandleGetApps(const ListValue* args) { // the apps as they change. if (!has_loaded_apps_) { base::Closure callback = base::Bind( - &AppLauncherHandler::OnPreferenceChanged, + &AppLauncherHandler::OnExtensionPreferenceChanged, base::Unretained(this)); - pref_change_registrar_.Init( + extension_pref_change_registrar_.Init( extension_service_->extension_prefs()->pref_service()); - pref_change_registrar_.Add(ExtensionPrefs::kExtensionsPref, callback); - pref_change_registrar_.Add(prefs::kNtpAppPageNames, callback); + extension_pref_change_registrar_.Add(ExtensionPrefs::kExtensionsPref, + callback); + extension_pref_change_registrar_.Add(prefs::kNtpAppPageNames, callback); registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, content::Source<Profile>(profile)); @@ -662,6 +676,12 @@ void AppLauncherHandler::HandleRecordAppLaunchByUrl( RecordAppLaunchByUrl(Profile::FromWebUI(web_ui()), url, bucket); } +void AppLauncherHandler::StopShowingAppLauncherPromo( + const base::ListValue* args) { + g_browser_process->local_state()->SetBoolean( + apps::prefs::kShowAppLauncherPromo, false); +} + void AppLauncherHandler::OnFaviconForApp( scoped_ptr<AppInstallInfo> install_info, const history::FaviconImageResult& image_result) { @@ -696,12 +716,19 @@ void AppLauncherHandler::SetAppToBeHighlighted() { highlight_app_id_.clear(); } -void AppLauncherHandler::OnPreferenceChanged() { +void AppLauncherHandler::OnExtensionPreferenceChanged() { DictionaryValue dictionary; FillAppDictionary(&dictionary); web_ui()->CallJavascriptFunction("ntp.appsPrefChangeCallback", dictionary); } +void AppLauncherHandler::OnLocalStatePreferenceChanged() { + web_ui()->CallJavascriptFunction( + "ntp.appLauncherPromoPrefChangeCallback", + base::FundamentalValue(g_browser_process->local_state()->GetBoolean( + apps::prefs::kShowAppLauncherPromo))); +} + // static void AppLauncherHandler::RegisterUserPrefs(PrefRegistrySyncable* registry) { registry->RegisterListPref(prefs::kNtpAppPageNames, diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.h b/chrome/browser/ui/webui/ntp/app_launcher_handler.h index 13ffd39..64faff8 100644 --- a/chrome/browser/ui/webui/ntp/app_launcher_handler.h +++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.h @@ -93,6 +93,9 @@ class AppLauncherHandler : public content::WebUIMessageHandler, // action for UMA. void HandleRecordAppLaunchByUrl(const base::ListValue* args); + // Callback for "stopShowingAppLauncherPromo" message. + void StopShowingAppLauncherPromo(const base::ListValue* args); + // Callback for "closeNotification" message. void HandleNotificationClose(const base::ListValue* args); @@ -151,7 +154,9 @@ class AppLauncherHandler : public content::WebUIMessageHandler, // Sends |highlight_app_id_| to the js. void SetAppToBeHighlighted(); - void OnPreferenceChanged(); + void OnExtensionPreferenceChanged(); + + void OnLocalStatePreferenceChanged(); // The apps are represented in the extensions model, which // outlives us since it's owned by our containing profile. @@ -162,7 +167,10 @@ class AppLauncherHandler : public content::WebUIMessageHandler, content::NotificationRegistrar registrar_; // Monitor extension preference changes so that the Web UI can be notified. - PrefChangeRegistrar pref_change_registrar_; + PrefChangeRegistrar extension_pref_change_registrar_; + + // Monitor the local state pref to control the app launcher promo. + PrefChangeRegistrar local_state_pref_change_registrar_; // Used to show confirmation UI for uninstalling extensions in incognito mode. scoped_ptr<ExtensionUninstallDialog> extension_uninstall_dialog_; diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc index 35c8db4..86e5ce1 100644 --- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc +++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc @@ -8,9 +8,12 @@ #include <vector> #include "apps/app_launcher.h" +#include "apps/field_trial_names.h" +#include "apps/pref_names.h" #include "base/command_line.h" #include "base/file_util.h" #include "base/memory/ref_counted_memory.h" +#include "base/metrics/field_trial.h" #include "base/prefs/pref_service.h" #include "base/string16.h" #include "base/stringprintf.h" @@ -180,12 +183,20 @@ NTPResourceCache::NTPResourceCache(Profile* profile) base::Unretained(this)); // Watch for pref changes that cause us to need to invalidate the HTML cache. - pref_change_registrar_.Init(profile_->GetPrefs()); - pref_change_registrar_.Add(prefs::kSyncAcknowledgedSyncTypes, callback); - pref_change_registrar_.Add(prefs::kShowBookmarkBar, callback); - pref_change_registrar_.Add(prefs::kNtpShownPage, callback); - pref_change_registrar_.Add(prefs::kSyncPromoShowNTPBubble, callback); - pref_change_registrar_.Add(prefs::kHideWebStoreIcon, callback); + profile_pref_change_registrar_.Init(profile_->GetPrefs()); + profile_pref_change_registrar_.Add(prefs::kSyncAcknowledgedSyncTypes, + callback); + profile_pref_change_registrar_.Add(prefs::kShowBookmarkBar, callback); + profile_pref_change_registrar_.Add(prefs::kNtpShownPage, callback); + profile_pref_change_registrar_.Add(prefs::kSyncPromoShowNTPBubble, callback); + profile_pref_change_registrar_.Add(prefs::kHideWebStoreIcon, callback); + + // Some tests don't have a local state. + if (g_browser_process->local_state()) { + local_state_pref_change_registrar_.Init(g_browser_process->local_state()); + local_state_pref_change_registrar_.Add(apps::prefs::kShowAppLauncherPromo, + callback); + } } NTPResourceCache::~NTPResourceCache() {} @@ -321,6 +332,7 @@ void NTPResourceCache::CreateNewTabHTML() { // Show the profile name in the title and most visited labels if the current // profile is not the default. PrefService* prefs = profile_->GetPrefs(); + PrefService* local_state = g_browser_process->local_state(); DictionaryValue load_time_data; load_time_data.SetBoolean("bookmarkbarattached", prefs->GetBoolean(prefs::kShowBookmarkBar)); @@ -328,6 +340,14 @@ void NTPResourceCache::CreateNewTabHTML() { ThemeServiceFactory::GetForProfile(profile_)->HasCustomImage( IDR_THEME_NTP_ATTRIBUTION)); load_time_data.SetBoolean("showMostvisited", should_show_most_visited_page_); + std::string app_launcher_promo_group_name = + base::FieldTrialList::FindFullName(apps::kLauncherPromoTrialName); + bool show_app_launcher_promo = + local_state->GetBoolean(apps::prefs::kShowAppLauncherPromo) && + (app_launcher_promo_group_name == apps::kShowLauncherPromoOnceGroupName || + app_launcher_promo_group_name == + apps::kResetShowLauncherPromoPrefGroupName); + load_time_data.SetBoolean("showAppLauncherPromo", show_app_launcher_promo); load_time_data.SetBoolean("showRecentlyClosed", should_show_recently_closed_menu_); load_time_data.SetString("title", @@ -406,6 +426,8 @@ void NTPResourceCache::CreateNewTabHTML() { l10n_util::GetStringUTF16(IDS_NEW_TAB_PAGE_SWITCHER_CHANGE_TITLE)); load_time_data.SetString("page_switcher_same_title", l10n_util::GetStringUTF16(IDS_NEW_TAB_PAGE_SWITCHER_SAME_TITLE)); + load_time_data.SetString("appsPromoTitle", + l10n_util::GetStringUTF16(IDS_NEW_TAB_PAGE_APPS_PROMO_TITLE)); // On Mac OS X 10.7+, horizontal scrolling can be treated as a back or // forward gesture. Pass through a flag that indicates whether or not that // feature is enabled. diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.h b/chrome/browser/ui/webui/ntp/ntp_resource_cache.h index cee7e0e..b30b41f 100644 --- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.h +++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.h @@ -75,7 +75,8 @@ class NTPResourceCache : public content::NotificationObserver, scoped_refptr<base::RefCountedMemory> new_tab_incognito_css_; scoped_refptr<base::RefCountedMemory> new_tab_css_; content::NotificationRegistrar registrar_; - PrefChangeRegistrar pref_change_registrar_; + PrefChangeRegistrar profile_pref_change_registrar_; + PrefChangeRegistrar local_state_pref_change_registrar_; #endif // Set based on platform_util::IsSwipeTrackingFromScrollEventsEnabled. |