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