| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |