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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 int bucket_num = extension_misc::APP_LAUNCH_BUCKET_INVALID; | 60 int bucket_num = extension_misc::APP_LAUNCH_BUCKET_INVALID; |
61 base::StringToInt(launch_source, &bucket_num); | 61 base::StringToInt(launch_source, &bucket_num); |
62 extension_misc::AppLaunchBucket bucket = | 62 extension_misc::AppLaunchBucket bucket = |
63 static_cast<extension_misc::AppLaunchBucket>(bucket_num); | 63 static_cast<extension_misc::AppLaunchBucket>(bucket_num); |
64 CHECK(bucket < extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); | 64 CHECK(bucket < extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); |
65 return bucket; | 65 return bucket; |
66 } | 66 } |
67 | 67 |
68 } // namespace | 68 } // namespace |
69 | 69 |
70 AppLauncherHandler::AppInstallInfo::AppInstallInfo() {} | |
71 | |
72 AppLauncherHandler::AppInstallInfo::~AppInstallInfo() {} | |
73 | |
74 AppLauncherHandler::AppLauncherHandler(ExtensionService* extension_service) | 70 AppLauncherHandler::AppLauncherHandler(ExtensionService* extension_service) |
75 : extension_service_(extension_service), | 71 : extension_service_(extension_service), |
76 ignore_changes_(false), | 72 ignore_changes_(false), |
77 attempted_bookmark_app_install_(false), | 73 attempted_bookmark_app_install_(false), |
78 has_loaded_apps_(false) { | 74 has_loaded_apps_(false) { |
79 } | 75 } |
80 | 76 |
81 AppLauncherHandler::~AppLauncherHandler() {} | 77 AppLauncherHandler::~AppLauncherHandler() {} |
82 | 78 |
83 // Serializes |notification| into a new DictionaryValue which the caller then | 79 // Serializes |notification| into a new DictionaryValue which the caller then |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 | 151 |
156 if (extension->HasAPIPermission(ExtensionAPIPermission::kAppNotifications)) { | 152 if (extension->HasAPIPermission(ExtensionAPIPermission::kAppNotifications)) { |
157 ExtensionPrefs* prefs = service->extension_prefs(); | 153 ExtensionPrefs* prefs = service->extension_prefs(); |
158 value->SetBoolean("notifications_disabled", | 154 value->SetBoolean("notifications_disabled", |
159 prefs->IsAppNotificationDisabled(extension->id())); | 155 prefs->IsAppNotificationDisabled(extension->id())); |
160 } | 156 } |
161 | 157 |
162 if (notification) | 158 if (notification) |
163 value->Set("notification", SerializeNotification(*notification)); | 159 value->Set("notification", SerializeNotification(*notification)); |
164 | 160 |
165 StringOrdinal page_ordinal = prefs->GetPageOrdinal(extension->id()); | 161 int app_launch_index = prefs->GetAppLaunchIndex(extension->id()); |
166 if (!page_ordinal.IsValid()) { | 162 if (app_launch_index == -1) { |
167 // Make sure every app has a page ordinal (some predate the page ordinal). | 163 // Make sure every app has a launch index (some predate the launch index). |
| 164 // The webstore's app launch index is set to -2 to make sure it's first. |
| 165 // The next time the user drags (any) app this will be set to something |
| 166 // sane (i.e. >= 0). |
| 167 app_launch_index = extension->id() == extension_misc::kWebStoreAppId ? |
| 168 -2 : prefs->GetNextAppLaunchIndex(0); |
| 169 prefs->SetAppLaunchIndex(extension->id(), app_launch_index); |
| 170 } |
| 171 value->SetInteger("app_launch_index", app_launch_index); |
| 172 |
| 173 int page_index = prefs->GetPageIndex(extension->id()); |
| 174 if (page_index < 0) { |
| 175 // Make sure every app has a page index (some predate the page index). |
168 // The webstore app should be on the first page. | 176 // The webstore app should be on the first page. |
169 page_ordinal = extension->id() == extension_misc::kWebStoreAppId ? | 177 page_index = extension->id() == extension_misc::kWebStoreAppId ? |
170 prefs->CreateFirstAppPageOrdinal() : prefs->GetNaturalAppPageOrdinal(); | 178 0 : prefs->GetNaturalAppPageIndex(); |
171 prefs->SetPageOrdinal(extension->id(), page_ordinal); | 179 prefs->SetPageIndex(extension->id(), page_index); |
172 } | 180 } |
173 // We convert the page_ordinal to an integer because the pages are referenced | 181 value->SetInteger("page_index", page_index); |
174 // from within an array in the javascript code, which can't be easily | |
175 // changed to handle the StringOrdinal values, so we do the conversion here. | |
176 value->SetInteger("page_index", | |
177 prefs->PageStringOrdinalAsInteger(page_ordinal)); | |
178 | |
179 StringOrdinal app_launch_ordinal = | |
180 prefs->GetAppLaunchOrdinal(extension->id()); | |
181 if (!app_launch_ordinal.IsValid()) { | |
182 // Make sure every app has a launch ordinal (some predate the launch | |
183 // ordinal). The webstore's app launch ordinal is always set to the first | |
184 // position. | |
185 app_launch_ordinal = extension->id() == extension_misc::kWebStoreAppId ? | |
186 prefs->CreateFirstAppLaunchOrdinal(page_ordinal) : | |
187 prefs->CreateNextAppLaunchOrdinal(page_ordinal); | |
188 prefs->SetAppLaunchOrdinal(extension->id(), app_launch_ordinal); | |
189 } | |
190 value->SetString("app_launch_ordinal", app_launch_ordinal.ToString()); | |
191 } | 182 } |
192 | 183 |
193 WebUIMessageHandler* AppLauncherHandler::Attach(WebUI* web_ui) { | 184 WebUIMessageHandler* AppLauncherHandler::Attach(WebUI* web_ui) { |
194 registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, | 185 registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, |
195 content::Source<TabContents>(web_ui->tab_contents())); | 186 content::Source<TabContents>(web_ui->tab_contents())); |
196 return WebUIMessageHandler::Attach(web_ui); | 187 return WebUIMessageHandler::Attach(web_ui); |
197 } | 188 } |
198 | 189 |
199 void AppLauncherHandler::RegisterMessages() { | 190 void AppLauncherHandler::RegisterMessages() { |
200 web_ui_->RegisterMessageCallback("getApps", | 191 web_ui_->RegisterMessageCallback("getApps", |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR: { | 320 case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR: { |
330 attempted_bookmark_app_install_ = false; | 321 attempted_bookmark_app_install_ = false; |
331 break; | 322 break; |
332 } | 323 } |
333 default: | 324 default: |
334 NOTREACHED(); | 325 NOTREACHED(); |
335 } | 326 } |
336 } | 327 } |
337 | 328 |
338 void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) { | 329 void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) { |
339 // CreateAppInfo and ClearPageOrdinal can change the extension prefs. | 330 // CreateAppInfo and ClearPageIndex can change the extension prefs. |
340 AutoReset<bool> auto_reset(&ignore_changes_, true); | 331 AutoReset<bool> auto_reset(&ignore_changes_, true); |
341 | 332 |
342 ListValue* list = new ListValue(); | 333 ListValue* list = new ListValue(); |
343 const ExtensionSet* extensions = extension_service_->extensions(); | 334 const ExtensionSet* extensions = extension_service_->extensions(); |
344 ExtensionSet::const_iterator it; | 335 ExtensionSet::const_iterator it; |
345 for (it = extensions->begin(); it != extensions->end(); ++it) { | 336 for (it = extensions->begin(); it != extensions->end(); ++it) { |
346 const Extension* extension = *it; | 337 const Extension* extension = *it; |
347 if (!IsAppExcludedFromList(extension)) { | 338 if (!IsAppExcludedFromList(extension)) { |
348 DictionaryValue* app_info = GetAppInfo(extension); | 339 DictionaryValue* app_info = GetAppInfo(extension); |
349 list->Append(app_info); | 340 list->Append(app_info); |
350 } else { | 341 } else { |
351 // 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 |
352 // 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, |
353 // and this fixes it. This caused GetNaturalAppPageIndex() to break | 344 // and this fixes it. If we don't fix it, GetNaturalAppPageIndex() doesn't |
354 // (see http://crbug.com/98325) before it was an ordinal value. | 345 // work. See http://crbug.com/98325 |
355 ExtensionPrefs* prefs = extension_service_->extension_prefs(); | 346 ExtensionPrefs* prefs = extension_service_->extension_prefs(); |
356 if (prefs->GetPageOrdinal(extension->id()).IsValid()) | 347 if (prefs->GetPageIndex(extension->id()) != -1) |
357 prefs->ClearPageOrdinal(extension->id()); | 348 prefs->ClearPageIndex(extension->id()); |
358 } | 349 } |
359 } | 350 } |
360 | 351 |
361 extensions = extension_service_->disabled_extensions(); | 352 extensions = extension_service_->disabled_extensions(); |
362 for (it = extensions->begin(); it != extensions->end(); ++it) { | 353 for (it = extensions->begin(); it != extensions->end(); ++it) { |
363 if (!IsAppExcludedFromList(*it)) { | 354 if (!IsAppExcludedFromList(*it)) { |
364 DictionaryValue* app_info = new DictionaryValue(); | 355 DictionaryValue* app_info = new DictionaryValue(); |
365 CreateAppInfo(*it, | 356 CreateAppInfo(*it, |
366 NULL, | 357 NULL, |
367 extension_service_, | 358 extension_service_, |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 } | 636 } |
646 | 637 |
647 void AppLauncherHandler::HandleReorderApps(const ListValue* args) { | 638 void AppLauncherHandler::HandleReorderApps(const ListValue* args) { |
648 CHECK(args->GetSize() == 2); | 639 CHECK(args->GetSize() == 2); |
649 | 640 |
650 std::string dragged_app_id; | 641 std::string dragged_app_id; |
651 ListValue* app_order; | 642 ListValue* app_order; |
652 CHECK(args->GetString(0, &dragged_app_id)); | 643 CHECK(args->GetString(0, &dragged_app_id)); |
653 CHECK(args->GetList(1, &app_order)); | 644 CHECK(args->GetList(1, &app_order)); |
654 | 645 |
655 std::string predecessor_to_moved_ext; | 646 std::vector<std::string> extension_ids; |
656 std::string successor_to_moved_ext; | |
657 for (size_t i = 0; i < app_order->GetSize(); ++i) { | 647 for (size_t i = 0; i < app_order->GetSize(); ++i) { |
658 std::string value; | 648 std::string value; |
659 if (app_order->GetString(i, &value) && value == dragged_app_id) { | 649 if (app_order->GetString(i, &value)) |
660 if (i > 0) | 650 extension_ids.push_back(value); |
661 CHECK(app_order->GetString(i - 1, &predecessor_to_moved_ext)); | |
662 if (i + 1 < app_order->GetSize()) | |
663 CHECK(app_order->GetString(i + 1, &successor_to_moved_ext)); | |
664 break; | |
665 } | |
666 } | 651 } |
667 | 652 |
668 // Don't update the page; it already knows the apps have been reordered. | 653 // Don't update the page; it already knows the apps have been reordered. |
669 AutoReset<bool> auto_reset(&ignore_changes_, true); | 654 AutoReset<bool> auto_reset(&ignore_changes_, true); |
670 extension_service_->extension_prefs()->SetAppDraggedByUser(dragged_app_id); | 655 extension_service_->extension_prefs()->SetAppDraggedByUser(dragged_app_id); |
671 extension_service_->extension_prefs()->OnExtensionMoved( | 656 extension_service_->extension_prefs()->SetAppLauncherOrder(extension_ids); |
672 dragged_app_id, | |
673 predecessor_to_moved_ext, | |
674 successor_to_moved_ext); | |
675 } | 657 } |
676 | 658 |
677 void AppLauncherHandler::HandleSetPageIndex(const ListValue* args) { | 659 void AppLauncherHandler::HandleSetPageIndex(const ListValue* args) { |
678 std::string extension_id; | 660 std::string extension_id; |
679 double page_index; | 661 double page_index; |
680 CHECK(args->GetString(0, &extension_id)); | 662 CHECK(args->GetString(0, &extension_id)); |
681 CHECK(args->GetDouble(1, &page_index)); | 663 CHECK(args->GetDouble(1, &page_index)); |
682 const StringOrdinal& page_ordinal = | |
683 extension_service_->extension_prefs()->PageIntegerAsStringOrdinal( | |
684 static_cast<size_t>(page_index)); | |
685 | 664 |
686 // Don't update the page; it already knows the apps have been reordered. | 665 // Don't update the page; it already knows the apps have been reordered. |
687 AutoReset<bool> auto_reset(&ignore_changes_, true); | 666 AutoReset<bool> auto_reset(&ignore_changes_, true); |
688 extension_service_->extension_prefs()->SetPageOrdinal(extension_id, | 667 extension_service_->extension_prefs()->SetPageIndex(extension_id, |
689 page_ordinal); | 668 static_cast<int>(page_index)); |
690 } | 669 } |
691 | 670 |
692 void AppLauncherHandler::HandlePromoSeen(const ListValue* args) { | 671 void AppLauncherHandler::HandlePromoSeen(const ListValue* args) { |
693 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, | 672 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, |
694 extension_misc::PROMO_SEEN, | 673 extension_misc::PROMO_SEEN, |
695 extension_misc::PROMO_BUCKET_BOUNDARY); | 674 extension_misc::PROMO_BUCKET_BOUNDARY); |
696 } | 675 } |
697 | 676 |
698 void AppLauncherHandler::HandleSaveAppPageName(const ListValue* args) { | 677 void AppLauncherHandler::HandleSaveAppPageName(const ListValue* args) { |
699 string16 name; | 678 string16 name; |
(...skipping 12 matching lines...) Expand all Loading... |
712 void AppLauncherHandler::HandleGenerateAppForLink(const ListValue* args) { | 691 void AppLauncherHandler::HandleGenerateAppForLink(const ListValue* args) { |
713 std::string url; | 692 std::string url; |
714 CHECK(args->GetString(0, &url)); | 693 CHECK(args->GetString(0, &url)); |
715 GURL launch_url(url); | 694 GURL launch_url(url); |
716 | 695 |
717 string16 title; | 696 string16 title; |
718 CHECK(args->GetString(1, &title)); | 697 CHECK(args->GetString(1, &title)); |
719 | 698 |
720 double page_index; | 699 double page_index; |
721 CHECK(args->GetDouble(2, &page_index)); | 700 CHECK(args->GetDouble(2, &page_index)); |
722 const StringOrdinal& page_ordinal = | |
723 extension_service_->extension_prefs()->PageIntegerAsStringOrdinal( | |
724 static_cast<size_t>(page_index)); | |
725 | 701 |
726 Profile* profile = Profile::FromWebUI(web_ui_); | 702 Profile* profile = Profile::FromWebUI(web_ui_); |
727 FaviconService* favicon_service = | 703 FaviconService* favicon_service = |
728 profile->GetFaviconService(Profile::EXPLICIT_ACCESS); | 704 profile->GetFaviconService(Profile::EXPLICIT_ACCESS); |
729 if (!favicon_service) { | 705 if (!favicon_service) { |
730 LOG(ERROR) << "No favicon service"; | 706 LOG(ERROR) << "No favicon service"; |
731 return; | 707 return; |
732 } | 708 } |
733 | 709 |
734 scoped_ptr<AppInstallInfo> install_info(new AppInstallInfo()); | 710 scoped_ptr<AppInstallInfo> install_info(new AppInstallInfo()); |
735 install_info->is_bookmark_app = true; | 711 install_info->is_bookmark_app = true; |
736 install_info->title = title; | 712 install_info->title = title; |
737 install_info->app_url = launch_url; | 713 install_info->app_url = launch_url; |
738 install_info->page_ordinal = page_ordinal; | 714 install_info->page_index = static_cast<int>(page_index); |
739 | 715 |
740 FaviconService::Handle h = favicon_service->GetFaviconForURL( | 716 FaviconService::Handle h = favicon_service->GetFaviconForURL( |
741 launch_url, history::FAVICON, &favicon_consumer_, | 717 launch_url, history::FAVICON, &favicon_consumer_, |
742 base::Bind(&AppLauncherHandler::OnFaviconForApp, base::Unretained(this))); | 718 base::Bind(&AppLauncherHandler::OnFaviconForApp, base::Unretained(this))); |
743 favicon_consumer_.SetClientData(favicon_service, h, install_info.release()); | 719 favicon_consumer_.SetClientData(favicon_service, h, install_info.release()); |
744 } | 720 } |
745 | 721 |
746 void AppLauncherHandler::HandleRecordAppLaunchByURL( | 722 void AppLauncherHandler::HandleRecordAppLaunchByURL( |
747 const base::ListValue* args) { | 723 const base::ListValue* args) { |
748 std::string url; | 724 std::string url; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 &(web_app->icons[0].data))) { | 778 &(web_app->icons[0].data))) { |
803 web_app->icons[0].url = GURL(); | 779 web_app->icons[0].url = GURL(); |
804 web_app->icons[0].width = web_app->icons[0].data.width(); | 780 web_app->icons[0].width = web_app->icons[0].data.width(); |
805 web_app->icons[0].height = web_app->icons[0].data.height(); | 781 web_app->icons[0].height = web_app->icons[0].data.height(); |
806 } else { | 782 } else { |
807 web_app->icons.clear(); | 783 web_app->icons.clear(); |
808 } | 784 } |
809 | 785 |
810 scoped_refptr<CrxInstaller> installer( | 786 scoped_refptr<CrxInstaller> installer( |
811 CrxInstaller::Create(extension_service_, NULL)); | 787 CrxInstaller::Create(extension_service_, NULL)); |
812 installer->set_page_ordinal(install_info->page_ordinal); | 788 installer->set_page_index(install_info->page_index); |
813 installer->InstallWebApp(*web_app); | 789 installer->InstallWebApp(*web_app); |
814 attempted_bookmark_app_install_ = true; | 790 attempted_bookmark_app_install_ = true; |
815 } | 791 } |
816 | 792 |
817 void AppLauncherHandler::SetAppToBeHighlighted() { | 793 void AppLauncherHandler::SetAppToBeHighlighted() { |
818 if (highlight_app_id_.empty()) | 794 if (highlight_app_id_.empty()) |
819 return; | 795 return; |
820 | 796 |
821 StringValue app_id(highlight_app_id_); | 797 StringValue app_id(highlight_app_id_); |
822 web_ui_->CallJavascriptFunction("ntp4.setAppToBeHighlighted", app_id); | 798 web_ui_->CallJavascriptFunction("ntp4.setAppToBeHighlighted", app_id); |
823 highlight_app_id_.clear(); | 799 highlight_app_id_.clear(); |
824 } | 800 } |
825 | 801 |
826 // static | 802 // static |
827 void AppLauncherHandler::RegisterUserPrefs(PrefService* pref_service) { | 803 void AppLauncherHandler::RegisterUserPrefs(PrefService* pref_service) { |
828 // TODO(csharp): We will want this to be a syncable preference instead. | 804 // TODO(csilv): We will want this to be a syncable preference instead. |
829 pref_service->RegisterListPref(prefs::kNTPAppPageNames, | 805 pref_service->RegisterListPref(prefs::kNTPAppPageNames, |
830 PrefService::UNSYNCABLE_PREF); | 806 PrefService::UNSYNCABLE_PREF); |
831 } | 807 } |
832 | 808 |
833 // static | 809 // statiic |
834 void AppLauncherHandler::RecordWebStoreLaunch(bool promo_active) { | 810 void AppLauncherHandler::RecordWebStoreLaunch(bool promo_active) { |
835 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram, | 811 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram, |
836 extension_misc::APP_LAUNCH_NTP_WEBSTORE, | 812 extension_misc::APP_LAUNCH_NTP_WEBSTORE, |
837 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); | 813 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); |
838 | 814 |
839 if (!promo_active) return; | 815 if (!promo_active) return; |
840 | 816 |
841 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, | 817 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, |
842 extension_misc::PROMO_LAUNCH_WEB_STORE, | 818 extension_misc::PROMO_LAUNCH_WEB_STORE, |
843 extension_misc::PROMO_BUCKET_BOUNDARY); | 819 extension_misc::PROMO_BUCKET_BOUNDARY); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 | 954 |
979 void AppLauncherHandler::UninstallDefaultApps() { | 955 void AppLauncherHandler::UninstallDefaultApps() { |
980 AppsPromo* apps_promo = extension_service_->apps_promo(); | 956 AppsPromo* apps_promo = extension_service_->apps_promo(); |
981 const ExtensionIdSet& app_ids = apps_promo->old_default_apps(); | 957 const ExtensionIdSet& app_ids = apps_promo->old_default_apps(); |
982 for (ExtensionIdSet::const_iterator iter = app_ids.begin(); | 958 for (ExtensionIdSet::const_iterator iter = app_ids.begin(); |
983 iter != app_ids.end(); ++iter) { | 959 iter != app_ids.end(); ++iter) { |
984 if (extension_service_->GetExtensionById(*iter, true)) | 960 if (extension_service_->GetExtensionById(*iter, true)) |
985 extension_service_->UninstallExtension(*iter, false, NULL); | 961 extension_service_->UninstallExtension(*iter, false, NULL); |
986 } | 962 } |
987 } | 963 } |
OLD | NEW |