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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 ExtensionPrefs::LAUNCH_DEFAULT)); | 153 ExtensionPrefs::LAUNCH_DEFAULT)); |
154 value->SetBoolean("offline_enabled", extension->offline_enabled()); | 154 value->SetBoolean("offline_enabled", extension->offline_enabled()); |
155 value->SetBoolean("is_component", | 155 value->SetBoolean("is_component", |
156 extension->location() == Extension::COMPONENT); | 156 extension->location() == Extension::COMPONENT); |
157 value->SetBoolean("is_webstore", | 157 value->SetBoolean("is_webstore", |
158 extension->id() == extension_misc::kWebStoreAppId); | 158 extension->id() == extension_misc::kWebStoreAppId); |
159 | 159 |
160 if (notification) | 160 if (notification) |
161 value->Set("notification", SerializeNotification(*notification)); | 161 value->Set("notification", SerializeNotification(*notification)); |
162 | 162 |
163 int app_launch_index = prefs->GetAppLaunchIndex(extension->id()); | 163 StringOrdinal page_ordinal = prefs->GetPageOrdinal(extension->id()); |
164 if (app_launch_index == -1) { | 164 if (!page_ordinal.IsValid()) { |
165 // Make sure every app has a launch index (some predate the launch index). | 165 // Make sure every app has a page ordinal (some predate the page ordinal). |
166 // The webstore's app launch index is set to -2 to make sure it's first. | 166 // The webstore app should be on the first page. |
167 // The next time the user drags (any) app this will be set to something | 167 page_ordinal = extension->id() == extension_misc::kWebStoreAppId ? |
168 // sane (i.e. >= 0). | 168 prefs->CreateFirstAppPage() : prefs->GetNaturalAppPageOrdinal(); |
169 app_launch_index = extension->id() == extension_misc::kWebStoreAppId ? | 169 prefs->SetPageOrdinal(extension->id(), page_ordinal); |
170 -2 : prefs->GetNextAppLaunchIndex(0); | |
171 prefs->SetAppLaunchIndex(extension->id(), app_launch_index); | |
172 } | 170 } |
173 value->SetInteger("app_launch_index", app_launch_index); | 171 // We convert the page_ordinal to an integer because the pages are referenced |
| 172 // from within an array in the javascript code, which can't be easily |
| 173 // changed to handle the StringOrdinal values, so we do the conversion here. |
| 174 value->SetInteger("page_index", |
| 175 prefs->PageStringOrdinalAsInteger(page_ordinal)); |
174 | 176 |
175 int page_index = prefs->GetPageIndex(extension->id()); | 177 StringOrdinal app_launch_ordinal = |
176 if (page_index < 0) { | 178 prefs->GetAppLaunchOrdinal(extension->id()); |
177 // Make sure every app has a page index (some predate the page index). | 179 if (!app_launch_ordinal.IsValid()) { |
178 // The webstore app should be on the first page. | 180 // Make sure every app has a launch ordinal (some predate the launch |
179 page_index = extension->id() == extension_misc::kWebStoreAppId ? | 181 // ordinal). The webstore's app launch ordinal is always set to the first |
180 0 : prefs->GetNaturalAppPageIndex(); | 182 // position. |
181 prefs->SetPageIndex(extension->id(), page_index); | 183 app_launch_ordinal = extension->id() == extension_misc::kWebStoreAppId ? |
| 184 prefs->CreateFirstAppLaunchOrdinal(page_ordinal) : |
| 185 prefs->CreateNextAppLaunchOrdinal(page_ordinal); |
| 186 prefs->SetAppLaunchOrdinal(extension->id(), app_launch_ordinal); |
182 } | 187 } |
183 value->SetInteger("page_index", page_index); | 188 value->SetString("app_launch_ordinal", app_launch_ordinal.ToString()); |
184 } | 189 } |
185 | 190 |
186 WebUIMessageHandler* AppLauncherHandler::Attach(WebUI* web_ui) { | 191 WebUIMessageHandler* AppLauncherHandler::Attach(WebUI* web_ui) { |
187 registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, | 192 registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, |
188 content::Source<TabContents>(web_ui->tab_contents())); | 193 content::Source<TabContents>(web_ui->tab_contents())); |
189 return WebUIMessageHandler::Attach(web_ui); | 194 return WebUIMessageHandler::Attach(web_ui); |
190 } | 195 } |
191 | 196 |
192 void AppLauncherHandler::RegisterMessages() { | 197 void AppLauncherHandler::RegisterMessages() { |
193 web_ui_->RegisterMessageCallback("getApps", | 198 web_ui_->RegisterMessageCallback("getApps", |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR: { | 339 case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR: { |
335 attempted_bookmark_app_install_ = false; | 340 attempted_bookmark_app_install_ = false; |
336 break; | 341 break; |
337 } | 342 } |
338 default: | 343 default: |
339 NOTREACHED(); | 344 NOTREACHED(); |
340 } | 345 } |
341 } | 346 } |
342 | 347 |
343 void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) { | 348 void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) { |
344 // CreateAppInfo and ClearPageIndex can change the extension prefs. | 349 // CreateAppInfo and ClearPageOrdinal can change the extension prefs. |
345 AutoReset<bool> auto_reset(&ignore_changes_, true); | 350 AutoReset<bool> auto_reset(&ignore_changes_, true); |
346 | 351 |
347 ListValue* list = new ListValue(); | 352 ListValue* list = new ListValue(); |
348 const ExtensionList* extensions = extension_service_->extensions(); | 353 const ExtensionList* extensions = extension_service_->extensions(); |
349 ExtensionList::const_iterator it; | 354 ExtensionList::const_iterator it; |
350 for (it = extensions->begin(); it != extensions->end(); ++it) { | 355 for (it = extensions->begin(); it != extensions->end(); ++it) { |
351 if (!IsAppExcludedFromList(*it)) { | 356 if (!IsAppExcludedFromList(*it)) { |
352 DictionaryValue* app_info = GetAppInfo(*it); | 357 DictionaryValue* app_info = GetAppInfo(*it); |
353 list->Append(app_info); | 358 list->Append(app_info); |
354 } else { | 359 } else { |
355 // This is necessary because in some previous versions of chrome, we set a | 360 // This is necessary because in some previous versions of chrome, we set a |
356 // page index for non-app extensions. Old profiles can persist this error, | 361 // page index for non-app extensions. Old profiles can persist this error, |
357 // and this fixes it. If we don't fix it, GetNaturalAppPageIndex() doesn't | 362 // and this fixes it. This caused GetNaturalAppPageIndex() to break |
358 // work. See http://crbug.com/98325 | 363 // (see http://crbug.com/98325) before it was an ordinal value. |
359 ExtensionPrefs* prefs = extension_service_->extension_prefs(); | 364 ExtensionPrefs* prefs = extension_service_->extension_prefs(); |
360 if (prefs->GetPageIndex((*it)->id()) != -1) | 365 if (prefs->GetPageOrdinal((*it)->id()).IsValid()) |
361 prefs->ClearPageIndex((*it)->id()); | 366 prefs->ClearPageOrdinal((*it)->id()); |
362 } | 367 } |
363 } | 368 } |
364 | 369 |
365 extensions = extension_service_->disabled_extensions(); | 370 extensions = extension_service_->disabled_extensions(); |
366 for (it = extensions->begin(); it != extensions->end(); ++it) { | 371 for (it = extensions->begin(); it != extensions->end(); ++it) { |
367 if (!IsAppExcludedFromList(*it)) { | 372 if (!IsAppExcludedFromList(*it)) { |
368 DictionaryValue* app_info = new DictionaryValue(); | 373 DictionaryValue* app_info = new DictionaryValue(); |
369 CreateAppInfo(*it, | 374 CreateAppInfo(*it, |
370 NULL, | 375 NULL, |
371 extension_service_, | 376 extension_service_, |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 } | 690 } |
686 | 691 |
687 void AppLauncherHandler::HandleReorderApps(const ListValue* args) { | 692 void AppLauncherHandler::HandleReorderApps(const ListValue* args) { |
688 CHECK(args->GetSize() == 2); | 693 CHECK(args->GetSize() == 2); |
689 | 694 |
690 std::string dragged_app_id; | 695 std::string dragged_app_id; |
691 ListValue* app_order; | 696 ListValue* app_order; |
692 CHECK(args->GetString(0, &dragged_app_id)); | 697 CHECK(args->GetString(0, &dragged_app_id)); |
693 CHECK(args->GetList(1, &app_order)); | 698 CHECK(args->GetList(1, &app_order)); |
694 | 699 |
695 std::vector<std::string> extension_ids; | 700 std::string predecessor_to_moved_ext; |
| 701 std::string successor_to_moved_ext; |
696 for (size_t i = 0; i < app_order->GetSize(); ++i) { | 702 for (size_t i = 0; i < app_order->GetSize(); ++i) { |
697 std::string value; | 703 std::string value; |
698 if (app_order->GetString(i, &value)) | 704 if (app_order->GetString(i, &value) && value == dragged_app_id) { |
699 extension_ids.push_back(value); | 705 // We don't worry about checking if the gets work because if they fail |
| 706 // the strings stay empty, which is what we want to use to indicate |
| 707 // no app as a predecessor or successor. |
| 708 app_order->GetString(i - 1, &predecessor_to_moved_ext); |
| 709 app_order->GetString(i + 1, &successor_to_moved_ext); |
| 710 break; |
| 711 } |
700 } | 712 } |
701 | 713 |
702 // Don't update the page; it already knows the apps have been reordered. | 714 // Don't update the page; it already knows the apps have been reordered. |
703 scoped_ptr<AutoReset<bool> > auto_reset; | 715 scoped_ptr<AutoReset<bool> > auto_reset; |
704 if (NewTabUI::NTP4Enabled()) | 716 if (NewTabUI::NTP4Enabled()) |
705 auto_reset.reset(new AutoReset<bool>(&ignore_changes_, true)); | 717 auto_reset.reset(new AutoReset<bool>(&ignore_changes_, true)); |
706 | 718 |
707 extension_service_->extension_prefs()->SetAppDraggedByUser(dragged_app_id); | 719 extension_service_->extension_prefs()->SetAppDraggedByUser(dragged_app_id); |
708 extension_service_->extension_prefs()->SetAppLauncherOrder(extension_ids); | 720 extension_service_->extension_prefs()->OnExtensionMoved( |
| 721 dragged_app_id, |
| 722 predecessor_to_moved_ext, |
| 723 successor_to_moved_ext); |
709 } | 724 } |
710 | 725 |
711 void AppLauncherHandler::HandleSetPageIndex(const ListValue* args) { | 726 void AppLauncherHandler::HandleSetPageIndex(const ListValue* args) { |
712 std::string extension_id; | 727 std::string extension_id; |
713 double page_index; | 728 double page_index; |
714 CHECK(args->GetString(0, &extension_id)); | 729 CHECK(args->GetString(0, &extension_id)); |
715 CHECK(args->GetDouble(1, &page_index)); | 730 CHECK(args->GetDouble(1, &page_index)); |
| 731 const StringOrdinal& page_ordinal = |
| 732 extension_service_->extension_prefs()->PageIntegerAsStringOrdinal( |
| 733 static_cast<size_t>(page_index)); |
716 | 734 |
717 // Don't update the page; it already knows the apps have been reordered. | 735 // Don't update the page; it already knows the apps have been reordered. |
718 scoped_ptr<AutoReset<bool> > auto_reset; | 736 scoped_ptr<AutoReset<bool> > auto_reset; |
719 if (NewTabUI::NTP4Enabled()) | 737 if (NewTabUI::NTP4Enabled()) |
720 auto_reset.reset(new AutoReset<bool>(&ignore_changes_, true)); | 738 auto_reset.reset(new AutoReset<bool>(&ignore_changes_, true)); |
721 | 739 |
722 extension_service_->extension_prefs()->SetPageIndex(extension_id, | 740 extension_service_->extension_prefs()->SetPageOrdinal(extension_id, |
723 static_cast<int>(page_index)); | 741 page_ordinal); |
724 } | 742 } |
725 | 743 |
726 void AppLauncherHandler::HandlePromoSeen(const ListValue* args) { | 744 void AppLauncherHandler::HandlePromoSeen(const ListValue* args) { |
727 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, | 745 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, |
728 extension_misc::PROMO_SEEN, | 746 extension_misc::PROMO_SEEN, |
729 extension_misc::PROMO_BUCKET_BOUNDARY); | 747 extension_misc::PROMO_BUCKET_BOUNDARY); |
730 } | 748 } |
731 | 749 |
732 void AppLauncherHandler::HandleSaveAppPageName(const ListValue* args) { | 750 void AppLauncherHandler::HandleSaveAppPageName(const ListValue* args) { |
733 string16 name; | 751 string16 name; |
(...skipping 12 matching lines...) Expand all Loading... |
746 void AppLauncherHandler::HandleGenerateAppForLink(const ListValue* args) { | 764 void AppLauncherHandler::HandleGenerateAppForLink(const ListValue* args) { |
747 std::string url; | 765 std::string url; |
748 CHECK(args->GetString(0, &url)); | 766 CHECK(args->GetString(0, &url)); |
749 GURL launch_url(url); | 767 GURL launch_url(url); |
750 | 768 |
751 string16 title; | 769 string16 title; |
752 CHECK(args->GetString(1, &title)); | 770 CHECK(args->GetString(1, &title)); |
753 | 771 |
754 double page_index; | 772 double page_index; |
755 CHECK(args->GetDouble(2, &page_index)); | 773 CHECK(args->GetDouble(2, &page_index)); |
| 774 const StringOrdinal& page_ordinal = |
| 775 extension_service_->extension_prefs()->PageIntegerAsStringOrdinal( |
| 776 static_cast<int>(page_index)); |
756 | 777 |
757 Profile* profile = Profile::FromWebUI(web_ui_); | 778 Profile* profile = Profile::FromWebUI(web_ui_); |
758 FaviconService* favicon_service = | 779 FaviconService* favicon_service = |
759 profile->GetFaviconService(Profile::EXPLICIT_ACCESS); | 780 profile->GetFaviconService(Profile::EXPLICIT_ACCESS); |
760 if (!favicon_service) { | 781 if (!favicon_service) { |
761 LOG(ERROR) << "No favicon service"; | 782 LOG(ERROR) << "No favicon service"; |
762 return; | 783 return; |
763 } | 784 } |
764 | 785 |
765 scoped_ptr<AppInstallInfo> install_info(new AppInstallInfo()); | 786 scoped_ptr<AppInstallInfo> install_info(new AppInstallInfo()); |
766 install_info->is_bookmark_app = true; | 787 install_info->is_bookmark_app = true; |
767 install_info->title = title; | 788 install_info->title = title; |
768 install_info->app_url = launch_url; | 789 install_info->app_url = launch_url; |
769 install_info->page_index = static_cast<int>(page_index); | 790 install_info->page_ordinal = page_ordinal; |
770 | 791 |
771 FaviconService::Handle h = favicon_service->GetFaviconForURL( | 792 FaviconService::Handle h = favicon_service->GetFaviconForURL( |
772 launch_url, history::FAVICON, &favicon_consumer_, | 793 launch_url, history::FAVICON, &favicon_consumer_, |
773 base::Bind(&AppLauncherHandler::OnFaviconForApp, base::Unretained(this))); | 794 base::Bind(&AppLauncherHandler::OnFaviconForApp, base::Unretained(this))); |
774 favicon_consumer_.SetClientData(favicon_service, h, install_info.release()); | 795 favicon_consumer_.SetClientData(favicon_service, h, install_info.release()); |
775 } | 796 } |
776 | 797 |
777 void AppLauncherHandler::HandleRecordAppLaunchByURL( | 798 void AppLauncherHandler::HandleRecordAppLaunchByURL( |
778 const base::ListValue* args) { | 799 const base::ListValue* args) { |
779 std::string url; | 800 std::string url; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 &(web_app->icons[0].data))) { | 840 &(web_app->icons[0].data))) { |
820 web_app->icons[0].url = GURL(); | 841 web_app->icons[0].url = GURL(); |
821 web_app->icons[0].width = web_app->icons[0].data.width(); | 842 web_app->icons[0].width = web_app->icons[0].data.width(); |
822 web_app->icons[0].height = web_app->icons[0].data.height(); | 843 web_app->icons[0].height = web_app->icons[0].data.height(); |
823 } else { | 844 } else { |
824 web_app->icons.clear(); | 845 web_app->icons.clear(); |
825 } | 846 } |
826 | 847 |
827 scoped_refptr<CrxInstaller> installer( | 848 scoped_refptr<CrxInstaller> installer( |
828 CrxInstaller::Create(extension_service_, NULL)); | 849 CrxInstaller::Create(extension_service_, NULL)); |
829 installer->set_page_index(install_info->page_index); | 850 installer->set_page_ordinal(install_info->page_ordinal); |
830 installer->InstallWebApp(*web_app); | 851 installer->InstallWebApp(*web_app); |
831 attempted_bookmark_app_install_ = true; | 852 attempted_bookmark_app_install_ = true; |
832 } | 853 } |
833 | 854 |
834 void AppLauncherHandler::SetAppToBeHighlighted() { | 855 void AppLauncherHandler::SetAppToBeHighlighted() { |
835 if (highlight_app_id_.empty()) | 856 if (highlight_app_id_.empty()) |
836 return; | 857 return; |
837 | 858 |
838 StringValue app_id(highlight_app_id_); | 859 StringValue app_id(highlight_app_id_); |
839 web_ui_->CallJavascriptFunction("ntp4.setAppToBeHighlighted", app_id); | 860 web_ui_->CallJavascriptFunction("ntp4.setAppToBeHighlighted", app_id); |
840 highlight_app_id_.clear(); | 861 highlight_app_id_.clear(); |
841 } | 862 } |
842 | 863 |
843 // static | 864 // static |
844 void AppLauncherHandler::RegisterUserPrefs(PrefService* pref_service) { | 865 void AppLauncherHandler::RegisterUserPrefs(PrefService* pref_service) { |
845 // TODO(csilv): We will want this to be a syncable preference instead. | 866 // TODO(csilv): We will want this to be a syncable preference instead. |
846 pref_service->RegisterListPref(prefs::kNTPAppPageNames, | 867 pref_service->RegisterListPref(prefs::kNTPAppPageNames, |
847 PrefService::UNSYNCABLE_PREF); | 868 PrefService::UNSYNCABLE_PREF); |
848 } | 869 } |
849 | 870 |
850 // statiic | 871 // static |
851 void AppLauncherHandler::RecordWebStoreLaunch(bool promo_active) { | 872 void AppLauncherHandler::RecordWebStoreLaunch(bool promo_active) { |
852 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram, | 873 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram, |
853 extension_misc::APP_LAUNCH_NTP_WEBSTORE, | 874 extension_misc::APP_LAUNCH_NTP_WEBSTORE, |
854 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); | 875 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); |
855 | 876 |
856 if (!promo_active) return; | 877 if (!promo_active) return; |
857 | 878 |
858 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, | 879 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, |
859 extension_misc::PROMO_LAUNCH_WEB_STORE, | 880 extension_misc::PROMO_LAUNCH_WEB_STORE, |
860 extension_misc::PROMO_BUCKET_BOUNDARY); | 881 extension_misc::PROMO_BUCKET_BOUNDARY); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
995 | 1016 |
996 void AppLauncherHandler::UninstallDefaultApps() { | 1017 void AppLauncherHandler::UninstallDefaultApps() { |
997 AppsPromo* apps_promo = extension_service_->apps_promo(); | 1018 AppsPromo* apps_promo = extension_service_->apps_promo(); |
998 const ExtensionIdSet& app_ids = apps_promo->old_default_apps(); | 1019 const ExtensionIdSet& app_ids = apps_promo->old_default_apps(); |
999 for (ExtensionIdSet::const_iterator iter = app_ids.begin(); | 1020 for (ExtensionIdSet::const_iterator iter = app_ids.begin(); |
1000 iter != app_ids.end(); ++iter) { | 1021 iter != app_ids.end(); ++iter) { |
1001 if (extension_service_->GetExtensionById(*iter, true)) | 1022 if (extension_service_->GetExtensionById(*iter, true)) |
1002 extension_service_->UninstallExtension(*iter, false, NULL); | 1023 extension_service_->UninstallExtension(*iter, false, NULL); |
1003 } | 1024 } |
1004 } | 1025 } |
OLD | NEW |