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

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

Issue 6825052: Update the web store promo to be clearer and configurable at run-time. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Incorporate Aaron's feedback. Created 9 years, 8 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
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/app_launcher_handler.h" 5 #include "chrome/browser/ui/webui/app_launcher_handler.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/string_number_conversions.h" 11 #include "base/string_number_conversions.h"
12 #include "base/string_split.h" 12 #include "base/string_split.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "base/utf_string_conversions.h" 14 #include "base/utf_string_conversions.h"
15 #include "base/values.h" 15 #include "base/values.h"
16 #include "chrome/browser/extensions/default_apps.h" 16 #include "chrome/browser/extensions/apps_promo.h"
17 #include "chrome/browser/extensions/extension_prefs.h" 17 #include "chrome/browser/extensions/extension_prefs.h"
18 #include "chrome/browser/extensions/extension_service.h" 18 #include "chrome/browser/extensions/extension_service.h"
19 #include "chrome/browser/platform_util.h" 19 #include "chrome/browser/platform_util.h"
20 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/ui/browser.h" 21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/browser_list.h" 22 #include "chrome/browser/ui/browser_list.h"
23 #include "chrome/browser/ui/browser_window.h" 23 #include "chrome/browser/ui/browser_window.h"
24 #include "chrome/browser/ui/webui/extension_icon_source.h" 24 #include "chrome/browser/ui/webui/extension_icon_source.h"
25 #include "chrome/browser/ui/webui/shown_sections_handler.h" 25 #include "chrome/browser/ui/webui/shown_sections_handler.h"
26 #include "chrome/common/extensions/extension.h" 26 #include "chrome/common/extensions/extension.h"
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 return false; 138 return false;
139 139
140 CHECK(params.size() >= 2); 140 CHECK(params.size() >= 2);
141 141
142 bool is_promo_active = params.at(1) == "true"; 142 bool is_promo_active = params.at(1) == "true";
143 143
144 // At this point, the user must have used the app launcher, so we hide the 144 // At this point, the user must have used the app launcher, so we hide the
145 // promo if its still displayed. 145 // promo if its still displayed.
146 if (is_promo_active) { 146 if (is_promo_active) {
147 DCHECK(profile->GetExtensionService()); 147 DCHECK(profile->GetExtensionService());
148 profile->GetExtensionService()->default_apps()->SetPromoHidden(); 148 profile->GetExtensionService()->apps_promo()->ExpireDefaultApps();
149 } 149 }
150 150
151 if (is_web_store_ping) { 151 if (is_web_store_ping) {
152 RecordWebStoreLaunch(is_promo_active); 152 RecordWebStoreLaunch(is_promo_active);
153 } else { 153 } else {
154 CHECK(params.size() == 3); 154 CHECK(params.size() == 3);
155 RecordAppLaunchByID(is_promo_active, ParseLaunchSource(params.at(2))); 155 RecordAppLaunchByID(is_promo_active, ParseLaunchSource(params.at(2)));
156 } 156 }
157 157
158 return true; 158 return true;
(...skipping 14 matching lines...) Expand all
173 web_ui_->RegisterMessageCallback("uninstallApp", 173 web_ui_->RegisterMessageCallback("uninstallApp",
174 NewCallback(this, &AppLauncherHandler::HandleUninstallApp)); 174 NewCallback(this, &AppLauncherHandler::HandleUninstallApp));
175 web_ui_->RegisterMessageCallback("hideAppsPromo", 175 web_ui_->RegisterMessageCallback("hideAppsPromo",
176 NewCallback(this, &AppLauncherHandler::HandleHideAppsPromo)); 176 NewCallback(this, &AppLauncherHandler::HandleHideAppsPromo));
177 web_ui_->RegisterMessageCallback("createAppShortcut", 177 web_ui_->RegisterMessageCallback("createAppShortcut",
178 NewCallback(this, &AppLauncherHandler::HandleCreateAppShortcut)); 178 NewCallback(this, &AppLauncherHandler::HandleCreateAppShortcut));
179 web_ui_->RegisterMessageCallback("reorderApps", 179 web_ui_->RegisterMessageCallback("reorderApps",
180 NewCallback(this, &AppLauncherHandler::HandleReorderApps)); 180 NewCallback(this, &AppLauncherHandler::HandleReorderApps));
181 web_ui_->RegisterMessageCallback("setPageIndex", 181 web_ui_->RegisterMessageCallback("setPageIndex",
182 NewCallback(this, &AppLauncherHandler::HandleSetPageIndex)); 182 NewCallback(this, &AppLauncherHandler::HandleSetPageIndex));
183 web_ui_->RegisterMessageCallback("promoSeen",
184 NewCallback(this, &AppLauncherHandler::HandlePromoSeen));
183 } 185 }
184 186
185 void AppLauncherHandler::Observe(NotificationType type, 187 void AppLauncherHandler::Observe(NotificationType type,
186 const NotificationSource& source, 188 const NotificationSource& source,
187 const NotificationDetails& details) { 189 const NotificationDetails& details) {
188 if (ignore_changes_) 190 if (ignore_changes_)
189 return; 191 return;
190 192
191 switch (type.value) { 193 switch (type.value) {
192 case NotificationType::EXTENSION_LOADED: 194 case NotificationType::EXTENSION_LOADED:
193 case NotificationType::EXTENSION_UNLOADED: 195 case NotificationType::EXTENSION_UNLOADED:
194 case NotificationType::EXTENSION_LAUNCHER_REORDERED: 196 case NotificationType::EXTENSION_LAUNCHER_REORDERED:
197 // The promo may not load until a couple seconds after the first NTP view,
198 // so we listen for the load notification and notify the NTP when ready.
199 case NotificationType::WEB_STORE_PROMO_LOADED:
195 if (web_ui_->tab_contents()) 200 if (web_ui_->tab_contents())
196 HandleGetApps(NULL); 201 HandleGetApps(NULL);
197 break; 202 break;
198 case NotificationType::PREF_CHANGED: { 203 case NotificationType::PREF_CHANGED: {
199 if (!web_ui_->tab_contents()) 204 if (!web_ui_->tab_contents())
200 break; 205 break;
201 206
202 DictionaryValue dictionary; 207 DictionaryValue dictionary;
203 FillAppDictionary(&dictionary); 208 FillAppDictionary(&dictionary);
204 web_ui_->CallJavascriptFunction("appsPrefChangeCallback", dictionary); 209 web_ui_->CallJavascriptFunction("appsPrefChangeCallback", dictionary);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 #endif 246 #endif
242 247
243 #if defined(OS_CHROMEOS) 248 #if defined(OS_CHROMEOS)
244 // Making shortcut does not make sense on ChromeOS because it does not have 249 // Making shortcut does not make sense on ChromeOS because it does not have
245 // a desktop. 250 // a desktop.
246 dictionary->SetBoolean("disableCreateAppShortcut", true); 251 dictionary->SetBoolean("disableCreateAppShortcut", true);
247 #endif 252 #endif
248 253
249 dictionary->SetBoolean( 254 dictionary->SetBoolean(
250 "showLauncher", 255 "showLauncher",
251 extensions_service_->default_apps()->ShouldShowAppLauncher( 256 extensions_service_->apps_promo()->ShouldShowAppLauncher(
252 extensions_service_->GetAppIds())); 257 extensions_service_->GetAppIds()));
253 } 258 }
254 259
260 void AppLauncherHandler::FillPromoDictionary(DictionaryValue* dictionary) {
261 dictionary->SetString("promoHeader", AppsPromo::GetPromoHeaderText());
262 dictionary->SetString("promoButton", AppsPromo::GetPromoButtonText());
263 dictionary->SetString("promoLink", AppsPromo::GetPromoLink().spec());
264 dictionary->SetString("promoExpire", AppsPromo::GetPromoExpireText());
265 }
266
255 void AppLauncherHandler::HandleGetApps(const ListValue* args) { 267 void AppLauncherHandler::HandleGetApps(const ListValue* args) {
256 DictionaryValue dictionary; 268 DictionaryValue dictionary;
257 269
258 // Tell the client whether to show the promo for this view. We don't do this 270 // Tell the client whether to show the promo for this view. We don't do this
259 // in the case of PREF_CHANGED because: 271 // in the case of PREF_CHANGED because:
260 // 272 //
261 // a) At that point in time, depending on the pref that changed, it can look 273 // a) At that point in time, depending on the pref that changed, it can look
262 // like the set of apps installed has changed, and we will mark the promo 274 // like the set of apps installed has changed, and we will mark the promo
263 // expired. 275 // expired.
264 // b) Conceptually, it doesn't really make sense to count a 276 // b) Conceptually, it doesn't really make sense to count a
265 // prefchange-triggered refresh as a promo 'view'. 277 // prefchange-triggered refresh as a promo 'view'.
266 DefaultApps* default_apps = extensions_service_->default_apps(); 278 AppsPromo* apps_promo = extensions_service_->apps_promo();
267 bool promo_just_expired = false; 279 PrefService* prefs = web_ui_->GetProfile()->GetPrefs();
268 if (default_apps->ShouldShowPromo(extensions_service_->GetAppIds(), 280 bool apps_promo_just_expired = false;
269 &promo_just_expired)) { 281 if (apps_promo->ShouldShowPromo(extensions_service_->GetAppIds(),
282 &apps_promo_just_expired)) {
283 // Maximize the apps section on the first promo view.
284 apps_promo->MaximizeAppsIfFirstView();
270 dictionary.SetBoolean("showPromo", true); 285 dictionary.SetBoolean("showPromo", true);
286 FillPromoDictionary(&dictionary);
271 promo_active_ = true; 287 promo_active_ = true;
272 } else { 288 } else {
273 if (promo_just_expired) {
274 ignore_changes_ = true;
275 UninstallDefaultApps();
276 ignore_changes_ = false;
277 ShownSectionsHandler::SetShownSection(web_ui_->GetProfile()->GetPrefs(),
278 THUMB);
279 }
280 dictionary.SetBoolean("showPromo", false); 289 dictionary.SetBoolean("showPromo", false);
281 promo_active_ = false; 290 promo_active_ = false;
282 } 291 }
283 292
293 // If the default apps have just expired (user viewed them too many times with
294 // no interaction), then we uninstall them and focus the recent sites section.
295 if (apps_promo_just_expired) {
296 ignore_changes_ = true;
297 UninstallDefaultApps();
298 ignore_changes_ = false;
299 ShownSectionsHandler::SetShownSection(prefs, THUMB);
300 }
301
284 FillAppDictionary(&dictionary); 302 FillAppDictionary(&dictionary);
285 web_ui_->CallJavascriptFunction("getAppsCallback", dictionary); 303 web_ui_->CallJavascriptFunction("getAppsCallback", dictionary);
286 304
287 // First time we get here we set up the observer so that we can tell update 305 // First time we get here we set up the observer so that we can tell update
288 // the apps as they change. 306 // the apps as they change.
289 if (registrar_.IsEmpty()) { 307 if (registrar_.IsEmpty()) {
290 registrar_.Add(this, NotificationType::EXTENSION_LOADED, 308 registrar_.Add(this, NotificationType::EXTENSION_LOADED,
291 NotificationService::AllSources()); 309 NotificationService::AllSources());
292 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, 310 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
293 NotificationService::AllSources()); 311 NotificationService::AllSources());
294 registrar_.Add(this, NotificationType::EXTENSION_LAUNCHER_REORDERED, 312 registrar_.Add(this, NotificationType::EXTENSION_LAUNCHER_REORDERED,
295 NotificationService::AllSources()); 313 NotificationService::AllSources());
314 registrar_.Add(this, NotificationType::WEB_STORE_PROMO_LOADED,
315 NotificationService::AllSources());
296 } 316 }
297 if (pref_change_registrar_.IsEmpty()) { 317 if (pref_change_registrar_.IsEmpty()) {
298 pref_change_registrar_.Init( 318 pref_change_registrar_.Init(
299 extensions_service_->extension_prefs()->pref_service()); 319 extensions_service_->extension_prefs()->pref_service());
300 pref_change_registrar_.Add(ExtensionPrefs::kExtensionsPref, this); 320 pref_change_registrar_.Add(ExtensionPrefs::kExtensionsPref, this);
301 } 321 }
302 } 322 }
303 323
304 void AppLauncherHandler::HandleLaunchApp(const ListValue* args) { 324 void AppLauncherHandler::HandleLaunchApp(const ListValue* args) {
305 std::string extension_id; 325 std::string extension_id;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 359
340 // If the user pressed special keys when clicking, override the saved 360 // If the user pressed special keys when clicking, override the saved
341 // preference for launch container. 361 // preference for launch container.
342 bool middle_button = (button == 1.0); 362 bool middle_button = (button == 1.0);
343 WindowOpenDisposition disposition = 363 WindowOpenDisposition disposition =
344 disposition_utils::DispositionFromClick(middle_button, alt_key, 364 disposition_utils::DispositionFromClick(middle_button, alt_key,
345 ctrl_key, meta_key, shift_key); 365 ctrl_key, meta_key, shift_key);
346 366
347 if (extension_id != extension_misc::kWebStoreAppId) { 367 if (extension_id != extension_misc::kWebStoreAppId) {
348 RecordAppLaunchByID(promo_active_, launch_bucket); 368 RecordAppLaunchByID(promo_active_, launch_bucket);
349 extensions_service_->default_apps()->SetPromoHidden(); 369 extensions_service_->apps_promo()->ExpireDefaultApps();
350 } 370 }
351 371
352 if (disposition == NEW_FOREGROUND_TAB || disposition == NEW_BACKGROUND_TAB) { 372 if (disposition == NEW_FOREGROUND_TAB || disposition == NEW_BACKGROUND_TAB) {
353 // TODO(jamescook): Proper support for background tabs. 373 // TODO(jamescook): Proper support for background tabs.
354 Browser::OpenApplication( 374 Browser::OpenApplication(
355 profile, extension, extension_misc::LAUNCH_TAB, NULL); 375 profile, extension, extension_misc::LAUNCH_TAB, NULL);
356 } else if (disposition == NEW_WINDOW) { 376 } else if (disposition == NEW_WINDOW) {
357 // Force a new window open. 377 // Force a new window open.
358 Browser::OpenApplication( 378 Browser::OpenApplication(
359 profile, extension, extension_misc::LAUNCH_WINDOW, NULL); 379 profile, extension, extension_misc::LAUNCH_WINDOW, NULL);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 return; // Only one prompt at a time. 433 return; // Only one prompt at a time.
414 434
415 extension_id_prompting_ = extension_id; 435 extension_id_prompting_ = extension_id;
416 GetExtensionUninstallDialog()->ConfirmUninstall(this, extension); 436 GetExtensionUninstallDialog()->ConfirmUninstall(this, extension);
417 } 437 }
418 438
419 void AppLauncherHandler::HandleHideAppsPromo(const ListValue* args) { 439 void AppLauncherHandler::HandleHideAppsPromo(const ListValue* args) {
420 // If the user has intentionally hidden the promotion, we'll uninstall all the 440 // If the user has intentionally hidden the promotion, we'll uninstall all the
421 // default apps (we know the user hasn't installed any apps on their own at 441 // default apps (we know the user hasn't installed any apps on their own at
422 // this point, or the promotion wouldn't have been shown). 442 // this point, or the promotion wouldn't have been shown).
423 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
424 extension_misc::PROMO_CLOSE,
425 extension_misc::PROMO_BUCKET_BOUNDARY);
426
427 ShownSectionsHandler::SetShownSection(web_ui_->GetProfile()->GetPrefs(),
428 THUMB);
429 ignore_changes_ = true; 443 ignore_changes_ = true;
430 UninstallDefaultApps(); 444 UninstallDefaultApps();
431 extensions_service_->default_apps()->SetPromoHidden(); 445 extensions_service_->apps_promo()->HidePromo();
432 ignore_changes_ = false; 446 ignore_changes_ = false;
433 HandleGetApps(NULL); 447 HandleGetApps(NULL);
434 } 448 }
435 449
436 void AppLauncherHandler::HandleCreateAppShortcut(const ListValue* args) { 450 void AppLauncherHandler::HandleCreateAppShortcut(const ListValue* args) {
437 std::string extension_id; 451 std::string extension_id;
438 if (!args->GetString(0, &extension_id)) { 452 if (!args->GetString(0, &extension_id)) {
439 NOTREACHED(); 453 NOTREACHED();
440 return; 454 return;
441 } 455 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 void AppLauncherHandler::HandleSetPageIndex(const ListValue* args) { 487 void AppLauncherHandler::HandleSetPageIndex(const ListValue* args) {
474 std::string extension_id; 488 std::string extension_id;
475 double page_index; 489 double page_index;
476 CHECK(args->GetString(0, &extension_id)); 490 CHECK(args->GetString(0, &extension_id));
477 CHECK(args->GetDouble(1, &page_index)); 491 CHECK(args->GetDouble(1, &page_index));
478 492
479 extensions_service_->extension_prefs()->SetPageIndex(extension_id, 493 extensions_service_->extension_prefs()->SetPageIndex(extension_id,
480 static_cast<int>(page_index)); 494 static_cast<int>(page_index));
481 } 495 }
482 496
497 void AppLauncherHandler::HandlePromoSeen(const ListValue* args) {
498 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
499 extension_misc::PROMO_SEEN,
500 extension_misc::PROMO_BUCKET_BOUNDARY);
501 }
502
483 // static 503 // static
484 void AppLauncherHandler::RecordWebStoreLaunch(bool promo_active) { 504 void AppLauncherHandler::RecordWebStoreLaunch(bool promo_active) {
485 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram, 505 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
486 extension_misc::APP_LAUNCH_NTP_WEBSTORE, 506 extension_misc::APP_LAUNCH_NTP_WEBSTORE,
487 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); 507 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
488 508
489 if (!promo_active) return; 509 if (!promo_active) return;
490 510
491 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, 511 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
492 extension_misc::PROMO_LAUNCH_WEB_STORE, 512 extension_misc::PROMO_LAUNCH_WEB_STORE,
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 625
606 ExtensionInstallUI* AppLauncherHandler::GetExtensionInstallUI() { 626 ExtensionInstallUI* AppLauncherHandler::GetExtensionInstallUI() {
607 if (!extension_install_ui_.get()) { 627 if (!extension_install_ui_.get()) {
608 extension_install_ui_.reset( 628 extension_install_ui_.reset(
609 new ExtensionInstallUI(web_ui_->GetProfile())); 629 new ExtensionInstallUI(web_ui_->GetProfile()));
610 } 630 }
611 return extension_install_ui_.get(); 631 return extension_install_ui_.get();
612 } 632 }
613 633
614 void AppLauncherHandler::UninstallDefaultApps() { 634 void AppLauncherHandler::UninstallDefaultApps() {
615 DefaultApps* default_apps = extensions_service_->default_apps(); 635 AppsPromo* apps_promo = extensions_service_->apps_promo();
616 const ExtensionIdSet& app_ids = default_apps->default_apps(); 636 const ExtensionIdSet& app_ids = apps_promo->old_default_apps();
617 for (ExtensionIdSet::const_iterator iter = app_ids.begin(); 637 for (ExtensionIdSet::const_iterator iter = app_ids.begin();
618 iter != app_ids.end(); ++iter) { 638 iter != app_ids.end(); ++iter) {
619 if (extensions_service_->GetExtensionById(*iter, true)) 639 if (extensions_service_->GetExtensionById(*iter, true))
620 extensions_service_->UninstallExtension(*iter, false, NULL); 640 extensions_service_->UninstallExtension(*iter, false, NULL);
621 } 641 }
622 } 642 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/webui/app_launcher_handler.h ('k') | chrome/browser/ui/webui/ntp_resource_cache.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698