Chromium Code Reviews| 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/ntp/app_launcher_handler.h" | 5 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 146 ExtensionPrefs::LAUNCH_DEFAULT)); | 146 ExtensionPrefs::LAUNCH_DEFAULT)); |
| 147 value->SetBoolean("offline_enabled", extension->offline_enabled()); | 147 value->SetBoolean("offline_enabled", extension->offline_enabled()); |
| 148 value->SetBoolean("is_component", | 148 value->SetBoolean("is_component", |
| 149 extension->location() == Extension::COMPONENT); | 149 extension->location() == Extension::COMPONENT); |
| 150 value->SetBoolean("is_webstore", | 150 value->SetBoolean("is_webstore", |
| 151 extension->id() == extension_misc::kWebStoreAppId); | 151 extension->id() == extension_misc::kWebStoreAppId); |
| 152 | 152 |
| 153 if (notification) | 153 if (notification) |
| 154 value->Set("notification", SerializeNotification(*notification)); | 154 value->Set("notification", SerializeNotification(*notification)); |
| 155 | 155 |
| 156 int app_launch_index = prefs->GetAppLaunchIndex(extension->id()); | 156 StringOrdinal page_ordinal = prefs->GetPageOrdinal(extension->id()); |
| 157 if (app_launch_index == -1) { | 157 if (!page_ordinal.IsValid()) { |
| 158 // Make sure every app has a launch index (some predate the launch index). | 158 // Make sure every app has a page ordinal (some predate the page ordinal). |
| 159 // The webstore's app launch index is set to -2 to make sure it's first. | 159 // The webstore app should be on the first page. |
| 160 // The next time the user drags (any) app this will be set to something | 160 page_ordinal = extension->id() == extension_misc::kWebStoreAppId ? |
| 161 // sane (i.e. >= 0). | 161 prefs->CreateFirstAppPageOrdinal() : prefs->GetNaturalAppPageOrdinal(); |
| 162 app_launch_index = extension->id() == extension_misc::kWebStoreAppId ? | 162 prefs->SetPageOrdinal(extension->id(), page_ordinal); |
| 163 -2 : prefs->GetNextAppLaunchIndex(0); | |
| 164 prefs->SetAppLaunchIndex(extension->id(), app_launch_index); | |
| 165 } | 163 } |
| 166 value->SetInteger("app_launch_index", app_launch_index); | 164 // We convert the page_ordinal to an integer because the pages are referenced |
| 165 // from within an array in the javascript code, which can't be easily | |
| 166 // changed to handle the StringOrdinal values, so we do the conversion here. | |
| 167 value->SetInteger("page_index", | |
| 168 prefs->PageStringOrdinalAsInteger(page_ordinal)); | |
| 167 | 169 |
| 168 int page_index = prefs->GetPageIndex(extension->id()); | 170 StringOrdinal app_launch_ordinal = |
| 169 if (page_index < 0) { | 171 prefs->GetAppLaunchOrdinal(extension->id()); |
| 170 // Make sure every app has a page index (some predate the page index). | 172 if (!app_launch_ordinal.IsValid()) { |
| 171 // The webstore app should be on the first page. | 173 // Make sure every app has a launch ordinal (some predate the launch |
| 172 page_index = extension->id() == extension_misc::kWebStoreAppId ? | 174 // ordinal). The webstore's app launch ordinal is always set to the first |
| 173 0 : prefs->GetNaturalAppPageIndex(); | 175 // position. |
| 174 prefs->SetPageIndex(extension->id(), page_index); | 176 app_launch_ordinal = extension->id() == extension_misc::kWebStoreAppId ? |
| 177 prefs->CreateFirstAppLaunchOrdinal(page_ordinal) : | |
| 178 prefs->CreateNextAppLaunchOrdinal(page_ordinal); | |
| 179 prefs->SetAppLaunchOrdinal(extension->id(), app_launch_ordinal); | |
| 175 } | 180 } |
| 176 value->SetInteger("page_index", page_index); | 181 value->SetString("app_launch_ordinal", app_launch_ordinal.ToString()); |
| 177 } | 182 } |
| 178 | 183 |
| 179 WebUIMessageHandler* AppLauncherHandler::Attach(WebUI* web_ui) { | 184 WebUIMessageHandler* AppLauncherHandler::Attach(WebUI* web_ui) { |
| 180 registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, | 185 registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, |
| 181 content::Source<TabContents>(web_ui->tab_contents())); | 186 content::Source<TabContents>(web_ui->tab_contents())); |
| 182 return WebUIMessageHandler::Attach(web_ui); | 187 return WebUIMessageHandler::Attach(web_ui); |
| 183 } | 188 } |
| 184 | 189 |
| 185 void AppLauncherHandler::RegisterMessages() { | 190 void AppLauncherHandler::RegisterMessages() { |
| 186 web_ui_->RegisterMessageCallback("getApps", | 191 web_ui_->RegisterMessageCallback("getApps", |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 316 case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR: { | 321 case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR: { |
| 317 attempted_bookmark_app_install_ = false; | 322 attempted_bookmark_app_install_ = false; |
| 318 break; | 323 break; |
| 319 } | 324 } |
| 320 default: | 325 default: |
| 321 NOTREACHED(); | 326 NOTREACHED(); |
| 322 } | 327 } |
| 323 } | 328 } |
| 324 | 329 |
| 325 void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) { | 330 void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) { |
| 326 // CreateAppInfo and ClearPageIndex can change the extension prefs. | 331 // CreateAppInfo and ClearPageOrdinal can change the extension prefs. |
| 327 AutoReset<bool> auto_reset(&ignore_changes_, true); | 332 AutoReset<bool> auto_reset(&ignore_changes_, true); |
| 328 | 333 |
| 329 ListValue* list = new ListValue(); | 334 ListValue* list = new ListValue(); |
| 330 const ExtensionList* extensions = extension_service_->extensions(); | 335 const ExtensionList* extensions = extension_service_->extensions(); |
| 331 ExtensionList::const_iterator it; | 336 ExtensionList::const_iterator it; |
| 332 for (it = extensions->begin(); it != extensions->end(); ++it) { | 337 for (it = extensions->begin(); it != extensions->end(); ++it) { |
| 333 if (!IsAppExcludedFromList(*it)) { | 338 if (!IsAppExcludedFromList(*it)) { |
| 334 DictionaryValue* app_info = GetAppInfo(*it); | 339 DictionaryValue* app_info = GetAppInfo(*it); |
| 335 list->Append(app_info); | 340 list->Append(app_info); |
| 336 } else { | 341 } else { |
| 337 // This is necessary because in some previous versions of chrome, we set a | 342 // This is necessary because in some previous versions of chrome, we set a |
| 338 // page index for non-app extensions. Old profiles can persist this error, | 343 // page index for non-app extensions. Old profiles can persist this error, |
| 339 // and this fixes it. If we don't fix it, GetNaturalAppPageIndex() doesn't | 344 // and this fixes it. This caused GetNaturalAppPageIndex() to break |
| 340 // work. See http://crbug.com/98325 | 345 // (see http://crbug.com/98325) before it was an ordinal value. |
| 341 ExtensionPrefs* prefs = extension_service_->extension_prefs(); | 346 ExtensionPrefs* prefs = extension_service_->extension_prefs(); |
| 342 if (prefs->GetPageIndex((*it)->id()) != -1) | 347 if (prefs->GetPageOrdinal((*it)->id()).IsValid()) |
| 343 prefs->ClearPageIndex((*it)->id()); | 348 prefs->ClearPageOrdinal((*it)->id()); |
| 344 } | 349 } |
| 345 } | 350 } |
| 346 | 351 |
| 347 extensions = extension_service_->disabled_extensions(); | 352 extensions = extension_service_->disabled_extensions(); |
| 348 for (it = extensions->begin(); it != extensions->end(); ++it) { | 353 for (it = extensions->begin(); it != extensions->end(); ++it) { |
| 349 if (!IsAppExcludedFromList(*it)) { | 354 if (!IsAppExcludedFromList(*it)) { |
| 350 DictionaryValue* app_info = new DictionaryValue(); | 355 DictionaryValue* app_info = new DictionaryValue(); |
| 351 CreateAppInfo(*it, | 356 CreateAppInfo(*it, |
| 352 NULL, | 357 NULL, |
| 353 extension_service_, | 358 extension_service_, |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 649 } | 654 } |
| 650 | 655 |
| 651 void AppLauncherHandler::HandleReorderApps(const ListValue* args) { | 656 void AppLauncherHandler::HandleReorderApps(const ListValue* args) { |
| 652 CHECK(args->GetSize() == 2); | 657 CHECK(args->GetSize() == 2); |
| 653 | 658 |
| 654 std::string dragged_app_id; | 659 std::string dragged_app_id; |
| 655 ListValue* app_order; | 660 ListValue* app_order; |
| 656 CHECK(args->GetString(0, &dragged_app_id)); | 661 CHECK(args->GetString(0, &dragged_app_id)); |
| 657 CHECK(args->GetList(1, &app_order)); | 662 CHECK(args->GetList(1, &app_order)); |
| 658 | 663 |
| 659 std::vector<std::string> extension_ids; | 664 std::string predecessor_to_moved_ext; |
| 665 std::string successor_to_moved_ext; | |
| 660 for (size_t i = 0; i < app_order->GetSize(); ++i) { | 666 for (size_t i = 0; i < app_order->GetSize(); ++i) { |
| 661 std::string value; | 667 std::string value; |
| 662 if (app_order->GetString(i, &value)) | 668 if (app_order->GetString(i, &value) && value == dragged_app_id) { |
| 663 extension_ids.push_back(value); | 669 // We don't worry about checking if the gets work because if they fail |
|
akalin
2011/12/06 17:48:24
Hmm, prefer explicit checking here. GetString may
csharp
2011/12/06 19:06:50
Done.
| |
| 670 // the strings stay empty, which is what we want to use to indicate | |
| 671 // no app as a predecessor or successor. | |
| 672 app_order->GetString(i - 1, &predecessor_to_moved_ext); | |
| 673 app_order->GetString(i + 1, &successor_to_moved_ext); | |
| 674 break; | |
| 675 } | |
| 664 } | 676 } |
| 665 | 677 |
| 666 // Don't update the page; it already knows the apps have been reordered. | 678 // Don't update the page; it already knows the apps have been reordered. |
| 667 AutoReset<bool> auto_reset(&ignore_changes_, true); | 679 AutoReset<bool> auto_reset(&ignore_changes_, true); |
| 668 extension_service_->extension_prefs()->SetAppDraggedByUser(dragged_app_id); | 680 extension_service_->extension_prefs()->SetAppDraggedByUser(dragged_app_id); |
| 669 extension_service_->extension_prefs()->SetAppLauncherOrder(extension_ids); | 681 extension_service_->extension_prefs()->OnExtensionMoved( |
| 682 dragged_app_id, | |
| 683 predecessor_to_moved_ext, | |
| 684 successor_to_moved_ext); | |
| 670 } | 685 } |
| 671 | 686 |
| 672 void AppLauncherHandler::HandleSetPageIndex(const ListValue* args) { | 687 void AppLauncherHandler::HandleSetPageIndex(const ListValue* args) { |
| 673 std::string extension_id; | 688 std::string extension_id; |
| 674 double page_index; | 689 double page_index; |
| 675 CHECK(args->GetString(0, &extension_id)); | 690 CHECK(args->GetString(0, &extension_id)); |
| 676 CHECK(args->GetDouble(1, &page_index)); | 691 CHECK(args->GetDouble(1, &page_index)); |
| 692 const StringOrdinal& page_ordinal = | |
| 693 extension_service_->extension_prefs()->PageIntegerAsStringOrdinal( | |
| 694 static_cast<size_t>(page_index)); | |
| 677 | 695 |
| 678 // Don't update the page; it already knows the apps have been reordered. | 696 // Don't update the page; it already knows the apps have been reordered. |
| 679 AutoReset<bool> auto_reset(&ignore_changes_, true); | 697 AutoReset<bool> auto_reset(&ignore_changes_, true); |
| 680 extension_service_->extension_prefs()->SetPageIndex(extension_id, | 698 extension_service_->extension_prefs()->SetPageOrdinal(extension_id, |
| 681 static_cast<int>(page_index)); | 699 page_ordinal); |
| 682 } | 700 } |
| 683 | 701 |
| 684 void AppLauncherHandler::HandlePromoSeen(const ListValue* args) { | 702 void AppLauncherHandler::HandlePromoSeen(const ListValue* args) { |
| 685 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, | 703 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, |
| 686 extension_misc::PROMO_SEEN, | 704 extension_misc::PROMO_SEEN, |
| 687 extension_misc::PROMO_BUCKET_BOUNDARY); | 705 extension_misc::PROMO_BUCKET_BOUNDARY); |
| 688 } | 706 } |
| 689 | 707 |
| 690 void AppLauncherHandler::HandleSaveAppPageName(const ListValue* args) { | 708 void AppLauncherHandler::HandleSaveAppPageName(const ListValue* args) { |
| 691 string16 name; | 709 string16 name; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 704 void AppLauncherHandler::HandleGenerateAppForLink(const ListValue* args) { | 722 void AppLauncherHandler::HandleGenerateAppForLink(const ListValue* args) { |
| 705 std::string url; | 723 std::string url; |
| 706 CHECK(args->GetString(0, &url)); | 724 CHECK(args->GetString(0, &url)); |
| 707 GURL launch_url(url); | 725 GURL launch_url(url); |
| 708 | 726 |
| 709 string16 title; | 727 string16 title; |
| 710 CHECK(args->GetString(1, &title)); | 728 CHECK(args->GetString(1, &title)); |
| 711 | 729 |
| 712 double page_index; | 730 double page_index; |
| 713 CHECK(args->GetDouble(2, &page_index)); | 731 CHECK(args->GetDouble(2, &page_index)); |
| 732 const StringOrdinal& page_ordinal = | |
| 733 extension_service_->extension_prefs()->PageIntegerAsStringOrdinal( | |
| 734 static_cast<size_t>(page_index)); | |
| 714 | 735 |
| 715 Profile* profile = Profile::FromWebUI(web_ui_); | 736 Profile* profile = Profile::FromWebUI(web_ui_); |
| 716 FaviconService* favicon_service = | 737 FaviconService* favicon_service = |
| 717 profile->GetFaviconService(Profile::EXPLICIT_ACCESS); | 738 profile->GetFaviconService(Profile::EXPLICIT_ACCESS); |
| 718 if (!favicon_service) { | 739 if (!favicon_service) { |
| 719 LOG(ERROR) << "No favicon service"; | 740 LOG(ERROR) << "No favicon service"; |
| 720 return; | 741 return; |
| 721 } | 742 } |
| 722 | 743 |
| 723 scoped_ptr<AppInstallInfo> install_info(new AppInstallInfo()); | 744 scoped_ptr<AppInstallInfo> install_info(new AppInstallInfo()); |
| 724 install_info->is_bookmark_app = true; | 745 install_info->is_bookmark_app = true; |
| 725 install_info->title = title; | 746 install_info->title = title; |
| 726 install_info->app_url = launch_url; | 747 install_info->app_url = launch_url; |
| 727 install_info->page_index = static_cast<int>(page_index); | 748 install_info->page_ordinal = page_ordinal; |
| 728 | 749 |
| 729 FaviconService::Handle h = favicon_service->GetFaviconForURL( | 750 FaviconService::Handle h = favicon_service->GetFaviconForURL( |
| 730 launch_url, history::FAVICON, &favicon_consumer_, | 751 launch_url, history::FAVICON, &favicon_consumer_, |
| 731 base::Bind(&AppLauncherHandler::OnFaviconForApp, base::Unretained(this))); | 752 base::Bind(&AppLauncherHandler::OnFaviconForApp, base::Unretained(this))); |
| 732 favicon_consumer_.SetClientData(favicon_service, h, install_info.release()); | 753 favicon_consumer_.SetClientData(favicon_service, h, install_info.release()); |
| 733 } | 754 } |
| 734 | 755 |
| 735 void AppLauncherHandler::HandleRecordAppLaunchByURL( | 756 void AppLauncherHandler::HandleRecordAppLaunchByURL( |
| 736 const base::ListValue* args) { | 757 const base::ListValue* args) { |
| 737 std::string url; | 758 std::string url; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 777 &(web_app->icons[0].data))) { | 798 &(web_app->icons[0].data))) { |
| 778 web_app->icons[0].url = GURL(); | 799 web_app->icons[0].url = GURL(); |
| 779 web_app->icons[0].width = web_app->icons[0].data.width(); | 800 web_app->icons[0].width = web_app->icons[0].data.width(); |
| 780 web_app->icons[0].height = web_app->icons[0].data.height(); | 801 web_app->icons[0].height = web_app->icons[0].data.height(); |
| 781 } else { | 802 } else { |
| 782 web_app->icons.clear(); | 803 web_app->icons.clear(); |
| 783 } | 804 } |
| 784 | 805 |
| 785 scoped_refptr<CrxInstaller> installer( | 806 scoped_refptr<CrxInstaller> installer( |
| 786 CrxInstaller::Create(extension_service_, NULL)); | 807 CrxInstaller::Create(extension_service_, NULL)); |
| 787 installer->set_page_index(install_info->page_index); | 808 installer->set_page_ordinal(install_info->page_ordinal); |
| 788 installer->InstallWebApp(*web_app); | 809 installer->InstallWebApp(*web_app); |
| 789 attempted_bookmark_app_install_ = true; | 810 attempted_bookmark_app_install_ = true; |
| 790 } | 811 } |
| 791 | 812 |
| 792 void AppLauncherHandler::SetAppToBeHighlighted() { | 813 void AppLauncherHandler::SetAppToBeHighlighted() { |
| 793 if (highlight_app_id_.empty()) | 814 if (highlight_app_id_.empty()) |
| 794 return; | 815 return; |
| 795 | 816 |
| 796 StringValue app_id(highlight_app_id_); | 817 StringValue app_id(highlight_app_id_); |
| 797 web_ui_->CallJavascriptFunction("ntp4.setAppToBeHighlighted", app_id); | 818 web_ui_->CallJavascriptFunction("ntp4.setAppToBeHighlighted", app_id); |
| 798 highlight_app_id_.clear(); | 819 highlight_app_id_.clear(); |
| 799 } | 820 } |
| 800 | 821 |
| 801 // static | 822 // static |
| 802 void AppLauncherHandler::RegisterUserPrefs(PrefService* pref_service) { | 823 void AppLauncherHandler::RegisterUserPrefs(PrefService* pref_service) { |
| 803 // TODO(csilv): We will want this to be a syncable preference instead. | 824 // TODO(csilv): We will want this to be a syncable preference instead. |
| 804 pref_service->RegisterListPref(prefs::kNTPAppPageNames, | 825 pref_service->RegisterListPref(prefs::kNTPAppPageNames, |
| 805 PrefService::UNSYNCABLE_PREF); | 826 PrefService::UNSYNCABLE_PREF); |
| 806 } | 827 } |
| 807 | 828 |
| 808 // statiic | 829 // static |
| 809 void AppLauncherHandler::RecordWebStoreLaunch(bool promo_active) { | 830 void AppLauncherHandler::RecordWebStoreLaunch(bool promo_active) { |
| 810 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram, | 831 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram, |
| 811 extension_misc::APP_LAUNCH_NTP_WEBSTORE, | 832 extension_misc::APP_LAUNCH_NTP_WEBSTORE, |
| 812 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); | 833 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); |
| 813 | 834 |
| 814 if (!promo_active) return; | 835 if (!promo_active) return; |
| 815 | 836 |
| 816 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, | 837 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, |
| 817 extension_misc::PROMO_LAUNCH_WEB_STORE, | 838 extension_misc::PROMO_LAUNCH_WEB_STORE, |
| 818 extension_misc::PROMO_BUCKET_BOUNDARY); | 839 extension_misc::PROMO_BUCKET_BOUNDARY); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 953 | 974 |
| 954 void AppLauncherHandler::UninstallDefaultApps() { | 975 void AppLauncherHandler::UninstallDefaultApps() { |
| 955 AppsPromo* apps_promo = extension_service_->apps_promo(); | 976 AppsPromo* apps_promo = extension_service_->apps_promo(); |
| 956 const ExtensionIdSet& app_ids = apps_promo->old_default_apps(); | 977 const ExtensionIdSet& app_ids = apps_promo->old_default_apps(); |
| 957 for (ExtensionIdSet::const_iterator iter = app_ids.begin(); | 978 for (ExtensionIdSet::const_iterator iter = app_ids.begin(); |
| 958 iter != app_ids.end(); ++iter) { | 979 iter != app_ids.end(); ++iter) { |
| 959 if (extension_service_->GetExtensionById(*iter, true)) | 980 if (extension_service_->GetExtensionById(*iter, true)) |
| 960 extension_service_->UninstallExtension(*iter, false, NULL); | 981 extension_service_->UninstallExtension(*iter, false, NULL); |
| 961 } | 982 } |
| 962 } | 983 } |
| OLD | NEW |