| 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->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 | 
|---|