| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 CHECK(bucket < extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); | 65 CHECK(bucket < extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); |
| 66 return bucket; | 66 return bucket; |
| 67 } | 67 } |
| 68 | 68 |
| 69 } // namespace | 69 } // namespace |
| 70 | 70 |
| 71 AppLauncherHandler::AppLauncherHandler(ExtensionService* extension_service) | 71 AppLauncherHandler::AppLauncherHandler(ExtensionService* extension_service) |
| 72 : extension_service_(extension_service), | 72 : extension_service_(extension_service), |
| 73 ignore_changes_(false), | 73 ignore_changes_(false), |
| 74 attempted_bookmark_app_install_(false), | 74 attempted_bookmark_app_install_(false), |
| 75 has_loaded_apps_(false) { | 75 has_loaded_apps_(false), |
| 76 uninstall_from_page_(false) { |
| 76 } | 77 } |
| 77 | 78 |
| 78 AppLauncherHandler::~AppLauncherHandler() {} | 79 AppLauncherHandler::~AppLauncherHandler() {} |
| 79 | 80 |
| 80 // Serializes |notification| into a new DictionaryValue which the caller then | 81 // Serializes |notification| into a new DictionaryValue which the caller then |
| 81 // owns. | 82 // owns. |
| 82 static DictionaryValue* SerializeNotification( | 83 static DictionaryValue* SerializeNotification( |
| 83 const AppNotification& notification) { | 84 const AppNotification& notification) { |
| 84 DictionaryValue* dictionary = new DictionaryValue(); | 85 DictionaryValue* dictionary = new DictionaryValue(); |
| 85 dictionary->SetString("title", notification.title()); | 86 dictionary->SetString("title", notification.title()); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 // Make sure every app has a launch index (some predate the launch index). | 159 // Make sure every app has a launch index (some predate the launch index). |
| 159 // The webstore's app launch index is set to -2 to make sure it's first. | 160 // The webstore's app launch index is set to -2 to make sure it's first. |
| 160 // The next time the user drags (any) app this will be set to something | 161 // The next time the user drags (any) app this will be set to something |
| 161 // sane (i.e. >= 0). | 162 // sane (i.e. >= 0). |
| 162 app_launch_index = extension->id() == extension_misc::kWebStoreAppId ? | 163 app_launch_index = extension->id() == extension_misc::kWebStoreAppId ? |
| 163 -2 : prefs->GetNextAppLaunchIndex(0); | 164 -2 : prefs->GetNextAppLaunchIndex(0); |
| 164 prefs->SetAppLaunchIndex(extension->id(), app_launch_index); | 165 prefs->SetAppLaunchIndex(extension->id(), app_launch_index); |
| 165 } | 166 } |
| 166 value->SetInteger("app_launch_index", app_launch_index); | 167 value->SetInteger("app_launch_index", app_launch_index); |
| 167 | 168 |
| 168 int page_index = prefs->GetPageIndex(extension->id()); | 169 EnsureAppHasPageIndex(service, extension->id()); |
| 169 if (page_index < 0) { | 170 value->SetInteger("page_index", prefs->GetPageIndex(extension->id())); |
| 170 // Make sure every app has a page index (some predate the page index). | |
| 171 // The webstore app should be on the first page. | |
| 172 page_index = extension->id() == extension_misc::kWebStoreAppId ? | |
| 173 0 : prefs->GetNaturalAppPageIndex(); | |
| 174 prefs->SetPageIndex(extension->id(), page_index); | |
| 175 } | |
| 176 value->SetInteger("page_index", page_index); | |
| 177 } | 171 } |
| 178 | 172 |
| 179 WebUIMessageHandler* AppLauncherHandler::Attach(WebUI* web_ui) { | 173 WebUIMessageHandler* AppLauncherHandler::Attach(WebUI* web_ui) { |
| 180 registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, | 174 registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, |
| 181 content::Source<TabContents>(web_ui->tab_contents())); | 175 content::Source<TabContents>(web_ui->tab_contents())); |
| 182 return WebUIMessageHandler::Attach(web_ui); | 176 return WebUIMessageHandler::Attach(web_ui); |
| 183 } | 177 } |
| 184 | 178 |
| 185 void AppLauncherHandler::RegisterMessages() { | 179 void AppLauncherHandler::RegisterMessages() { |
| 180 web_ui_->RegisterMessageCallback("deleteAppsPage", |
| 181 base::Bind(&AppLauncherHandler::HandleDeleteAppsPage, |
| 182 base::Unretained(this))); |
| 186 web_ui_->RegisterMessageCallback("getApps", | 183 web_ui_->RegisterMessageCallback("getApps", |
| 187 base::Bind(&AppLauncherHandler::HandleGetApps, | 184 base::Bind(&AppLauncherHandler::HandleGetApps, |
| 188 base::Unretained(this))); | 185 base::Unretained(this))); |
| 189 web_ui_->RegisterMessageCallback("launchApp", | 186 web_ui_->RegisterMessageCallback("launchApp", |
| 190 base::Bind(&AppLauncherHandler::HandleLaunchApp, | 187 base::Bind(&AppLauncherHandler::HandleLaunchApp, |
| 191 base::Unretained(this))); | 188 base::Unretained(this))); |
| 192 web_ui_->RegisterMessageCallback("setLaunchType", | 189 web_ui_->RegisterMessageCallback("setLaunchType", |
| 193 base::Bind(&AppLauncherHandler::HandleSetLaunchType, | 190 base::Bind(&AppLauncherHandler::HandleSetLaunchType, |
| 194 base::Unretained(this))); | 191 base::Unretained(this))); |
| 195 web_ui_->RegisterMessageCallback("uninstallApp", | 192 web_ui_->RegisterMessageCallback("uninstallApp", |
| 196 base::Bind(&AppLauncherHandler::HandleUninstallApp, | 193 base::Bind(&AppLauncherHandler::HandleUninstallApp, |
| 197 base::Unretained(this))); | 194 base::Unretained(this))); |
| 198 web_ui_->RegisterMessageCallback("hideAppsPromo", | 195 web_ui_->RegisterMessageCallback("hideAppsPromo", |
| 199 base::Bind(&AppLauncherHandler::HandleHideAppsPromo, | 196 base::Bind(&AppLauncherHandler::HandleHideAppsPromo, |
| 200 base::Unretained(this))); | 197 base::Unretained(this))); |
| 201 web_ui_->RegisterMessageCallback("createAppShortcut", | 198 web_ui_->RegisterMessageCallback("createAppShortcut", |
| 202 base::Bind(&AppLauncherHandler::HandleCreateAppShortcut, | 199 base::Bind(&AppLauncherHandler::HandleCreateAppShortcut, |
| 203 base::Unretained(this))); | 200 base::Unretained(this))); |
| 204 web_ui_->RegisterMessageCallback("reorderApps", | 201 web_ui_->RegisterMessageCallback("reorderApps", |
| 205 base::Bind(&AppLauncherHandler::HandleReorderApps, | 202 base::Bind(&AppLauncherHandler::HandleReorderApps, |
| 206 base::Unretained(this))); | 203 base::Unretained(this))); |
| 207 web_ui_->RegisterMessageCallback("setPageIndex", | 204 web_ui_->RegisterMessageCallback("setPageIndex", |
| 208 base::Bind(&AppLauncherHandler::HandleSetPageIndex, | 205 base::Bind(&AppLauncherHandler::HandleSetPageIndex, |
| 209 base::Unretained(this))); | 206 base::Unretained(this))); |
| 210 web_ui_->RegisterMessageCallback("promoSeen", | 207 web_ui_->RegisterMessageCallback("promoSeen", |
| 211 base::Bind(&AppLauncherHandler::HandlePromoSeen, | 208 base::Bind(&AppLauncherHandler::HandlePromoSeen, |
| 212 base::Unretained(this))); | 209 base::Unretained(this))); |
| 213 web_ui_->RegisterMessageCallback("saveAppPageName", | 210 web_ui_->RegisterMessageCallback("saveAppsPageName", |
| 214 base::Bind(&AppLauncherHandler::HandleSaveAppPageName, | 211 base::Bind(&AppLauncherHandler::HandleSaveAppsPageName, |
| 215 base::Unretained(this))); | 212 base::Unretained(this))); |
| 216 web_ui_->RegisterMessageCallback("generateAppForLink", | 213 web_ui_->RegisterMessageCallback("generateAppForLink", |
| 217 base::Bind(&AppLauncherHandler::HandleGenerateAppForLink, | 214 base::Bind(&AppLauncherHandler::HandleGenerateAppForLink, |
| 218 base::Unretained(this))); | 215 base::Unretained(this))); |
| 219 web_ui_->RegisterMessageCallback("recordAppLaunchByURL", | 216 web_ui_->RegisterMessageCallback("recordAppLaunchByURL", |
| 220 base::Bind(&AppLauncherHandler::HandleRecordAppLaunchByURL, | 217 base::Bind(&AppLauncherHandler::HandleRecordAppLaunchByURL, |
| 221 base::Unretained(this))); | 218 base::Unretained(this))); |
| 222 web_ui_->RegisterMessageCallback("closeNotification", | 219 web_ui_->RegisterMessageCallback("closeNotification", |
| 223 base::Bind(&AppLauncherHandler::HandleNotificationClose, | 220 base::Bind(&AppLauncherHandler::HandleNotificationClose, |
| 224 base::Unretained(this))); | 221 base::Unretained(this))); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 content::Details<UnloadedExtensionInfo>(details)->extension; | 279 content::Details<UnloadedExtensionInfo>(details)->extension; |
| 283 if (!extension->is_app()) | 280 if (!extension->is_app()) |
| 284 return; | 281 return; |
| 285 | 282 |
| 286 scoped_ptr<DictionaryValue> app_info(GetAppInfo(extension)); | 283 scoped_ptr<DictionaryValue> app_info(GetAppInfo(extension)); |
| 287 scoped_ptr<base::FundamentalValue> uninstall_value( | 284 scoped_ptr<base::FundamentalValue> uninstall_value( |
| 288 Value::CreateBooleanValue( | 285 Value::CreateBooleanValue( |
| 289 content::Details<UnloadedExtensionInfo>(details)->reason == | 286 content::Details<UnloadedExtensionInfo>(details)->reason == |
| 290 extension_misc::UNLOAD_REASON_UNINSTALL)); | 287 extension_misc::UNLOAD_REASON_UNINSTALL)); |
| 291 if (app_info.get()) { | 288 if (app_info.get()) { |
| 289 scoped_ptr<base::FundamentalValue> |
| 290 from_page(Value::CreateBooleanValue(uninstall_from_page_)); |
| 292 web_ui_->CallJavascriptFunction( | 291 web_ui_->CallJavascriptFunction( |
| 293 "ntp4.appRemoved", *app_info, *uninstall_value); | 292 "ntp4.appRemoved", *app_info, *uninstall_value, *from_page); |
| 293 uninstall_from_page_ = false; |
| 294 } | 294 } |
| 295 break; | 295 break; |
| 296 } | 296 } |
| 297 case chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED: | 297 case chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED: { |
| 298 // The promo may not load until a couple seconds after the first NTP view, | 298 DictionaryValue pages; |
| 299 // so we listen for the load notification and notify the NTP when ready. | 299 const ExtensionList* extensions = extension_service_->extensions(); |
| 300 case chrome::NOTIFICATION_WEB_STORE_PROMO_LOADED: | 300 ExtensionPrefs* prefs = extension_service_->extension_prefs(); |
| 301 // TODO(estade): try to get rid of this inefficient operation. | 301 for (ExtensionList::const_iterator it = extensions->begin(); |
| 302 it != extensions->end(); ++it) { |
| 303 if (!IsAppExcludedFromList(*it)) { |
| 304 std::string page_index = |
| 305 base::IntToString(prefs->GetPageIndex((*it)->id())); |
| 306 if (!pages.HasKey(page_index)) |
| 307 pages.Set(page_index, new DictionaryValue()); |
| 308 DictionaryValue* page; |
| 309 CHECK(pages.GetDictionary(page_index, &page)); |
| 310 page->SetString( |
| 311 base::IntToString(prefs->GetAppLaunchIndex((*it)->id())), |
| 312 (*it)->id()); |
| 313 } |
| 314 } |
| 315 web_ui_->CallJavascriptFunction("ntp4.appsReordered", pages); |
| 316 break; |
| 317 } |
| 318 case chrome::NOTIFICATION_WEB_STORE_PROMO_LOADED: { |
| 319 // The promo may not load until a couple seconds after the first NTP view, |
| 320 // so we listen for the load notification and notify the NTP when ready. |
| 302 HandleGetApps(NULL); | 321 HandleGetApps(NULL); |
| 303 break; | 322 break; |
| 323 } |
| 304 case chrome::NOTIFICATION_PREF_CHANGED: { | 324 case chrome::NOTIFICATION_PREF_CHANGED: { |
| 305 DictionaryValue dictionary; | 325 DictionaryValue dictionary; |
| 306 FillAppDictionary(&dictionary); | 326 FillAppDictionary(&dictionary); |
| 307 web_ui_->CallJavascriptFunction("appsPrefChangeCallback", dictionary); | 327 web_ui_->CallJavascriptFunction("appsPrefChangeCallback", dictionary); |
| 308 break; | 328 break; |
| 309 } | 329 } |
| 310 case chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR: { | 330 case chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR: { |
| 311 CrxInstaller* crx_installer = content::Source<CrxInstaller>(source).ptr(); | 331 CrxInstaller* crx_installer = content::Source<CrxInstaller>(source).ptr(); |
| 312 if (!Profile::FromWebUI(web_ui_)->IsSameProfile(crx_installer->profile())) | 332 if (!Profile::FromWebUI(web_ui_)->IsSameProfile(crx_installer->profile())) |
| 313 return; | 333 return; |
| 314 // Fall Through. | 334 // Fall Through. |
| 315 } | 335 } |
| 316 case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR: { | 336 case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR: { |
| 317 attempted_bookmark_app_install_ = false; | 337 attempted_bookmark_app_install_ = false; |
| 318 break; | 338 break; |
| 319 } | 339 } |
| 320 default: | 340 default: |
| 321 NOTREACHED(); | 341 NOTREACHED(); |
| 322 } | 342 } |
| 323 } | 343 } |
| 324 | 344 |
| 345 // static |
| 346 void AppLauncherHandler::EnsureAppHasPageIndex(ExtensionService* service, |
| 347 const std::string& id) { |
| 348 if (service->extension_prefs()->GetPageIndex(id) < 0) { |
| 349 // Make sure every app has a page index (some predate the page index). |
| 350 // The webstore app should be on the first page. |
| 351 int page_index = id == extension_misc::kWebStoreAppId ? |
| 352 0 : service->extension_prefs()->GetNaturalAppPageIndex(); |
| 353 service->extension_prefs()->SetPageIndex(id, page_index); |
| 354 } |
| 355 } |
| 356 |
| 325 void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) { | 357 void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) { |
| 326 // CreateAppInfo and ClearPageIndex can change the extension prefs. | 358 // CreateAppInfo and ClearPageIndex can change the extension prefs. |
| 327 AutoReset<bool> auto_reset(&ignore_changes_, true); | 359 AutoReset<bool> auto_reset(&ignore_changes_, true); |
| 328 | 360 |
| 329 ListValue* list = new ListValue(); | 361 ListValue* list = new ListValue(); |
| 330 const ExtensionList* extensions = extension_service_->extensions(); | 362 const ExtensionList* extensions = extension_service_->extensions(); |
| 331 ExtensionList::const_iterator it; | 363 ExtensionList::const_iterator it; |
| 332 for (it = extensions->begin(); it != extensions->end(); ++it) { | 364 for (it = extensions->begin(); it != extensions->end(); ++it) { |
| 333 if (!IsAppExcludedFromList(*it)) { | 365 if (!IsAppExcludedFromList(*it)) { |
| 334 DictionaryValue* app_info = GetAppInfo(*it); | 366 DictionaryValue* app_info = GetAppInfo(*it); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 extension_service_->apps_promo()->ShouldShowAppLauncher( | 421 extension_service_->apps_promo()->ShouldShowAppLauncher( |
| 390 extension_service_->GetAppIds())); | 422 extension_service_->GetAppIds())); |
| 391 | 423 |
| 392 PrefService* prefs = Profile::FromWebUI(web_ui_)->GetPrefs(); | 424 PrefService* prefs = Profile::FromWebUI(web_ui_)->GetPrefs(); |
| 393 const ListValue* app_page_names = prefs->GetList(prefs::kNTPAppPageNames); | 425 const ListValue* app_page_names = prefs->GetList(prefs::kNTPAppPageNames); |
| 394 if (!app_page_names || !app_page_names->GetSize()) { | 426 if (!app_page_names || !app_page_names->GetSize()) { |
| 395 ListPrefUpdate update(prefs, prefs::kNTPAppPageNames); | 427 ListPrefUpdate update(prefs, prefs::kNTPAppPageNames); |
| 396 ListValue* list = update.Get(); | 428 ListValue* list = update.Get(); |
| 397 list->Set(0, Value::CreateStringValue( | 429 list->Set(0, Value::CreateStringValue( |
| 398 l10n_util::GetStringUTF16(IDS_APP_DEFAULT_PAGE_NAME))); | 430 l10n_util::GetStringUTF16(IDS_APP_DEFAULT_PAGE_NAME))); |
| 399 dictionary->Set("appPageNames", | 431 dictionary->Set("appsPageNames", |
| 400 static_cast<ListValue*>(list->DeepCopy())); | 432 static_cast<ListValue*>(list->DeepCopy())); |
| 401 } else { | 433 } else { |
| 402 dictionary->Set("appPageNames", | 434 dictionary->Set("appsPageNames", |
| 403 static_cast<ListValue*>(app_page_names->DeepCopy())); | 435 static_cast<ListValue*>(app_page_names->DeepCopy())); |
| 404 } | 436 } |
| 405 } | 437 } |
| 406 | 438 |
| 407 DictionaryValue* AppLauncherHandler::GetAppInfo(const Extension* extension) { | 439 DictionaryValue* AppLauncherHandler::GetAppInfo(const Extension* extension) { |
| 408 AppNotificationManager* notification_manager = | 440 AppNotificationManager* notification_manager = |
| 409 extension_service_->app_notification_manager(); | 441 extension_service_->app_notification_manager(); |
| 410 DictionaryValue* app_info = new DictionaryValue(); | 442 DictionaryValue* app_info = new DictionaryValue(); |
| 411 // CreateAppInfo can change the extension prefs. | 443 // CreateAppInfo can change the extension prefs. |
| 412 AutoReset<bool> auto_reset(&ignore_changes_, true); | 444 AutoReset<bool> auto_reset(&ignore_changes_, true); |
| 413 CreateAppInfo(extension, | 445 CreateAppInfo(extension, |
| 414 notification_manager->GetLast(extension->id()), | 446 notification_manager->GetLast(extension->id()), |
| 415 extension_service_, | 447 extension_service_, |
| 416 app_info); | 448 app_info); |
| 417 return app_info; | 449 return app_info; |
| 418 } | 450 } |
| 419 | 451 |
| 420 void AppLauncherHandler::FillPromoDictionary(DictionaryValue* dictionary) { | 452 void AppLauncherHandler::FillPromoDictionary(DictionaryValue* dictionary) { |
| 421 AppsPromo::PromoData data = AppsPromo::GetPromo(); | 453 AppsPromo::PromoData data = AppsPromo::GetPromo(); |
| 422 dictionary->SetString("promoHeader", data.header); | 454 dictionary->SetString("promoHeader", data.header); |
| 423 dictionary->SetString("promoButton", data.button); | 455 dictionary->SetString("promoButton", data.button); |
| 424 dictionary->SetString("promoLink", data.link.spec()); | 456 dictionary->SetString("promoLink", data.link.spec()); |
| 425 dictionary->SetString("promoLogo", data.logo.spec()); | 457 dictionary->SetString("promoLogo", data.logo.spec()); |
| 426 dictionary->SetString("promoExpire", data.expire); | 458 dictionary->SetString("promoExpire", data.expire); |
| 427 } | 459 } |
| 428 | 460 |
| 461 void AppLauncherHandler::HandleDeleteAppsPage(const ListValue* args) { |
| 462 double page_index_double; |
| 463 CHECK(args->GetDouble(0, &page_index_double) && page_index_double >= 0); |
| 464 size_t page_index = static_cast<size_t>(page_index_double); |
| 465 |
| 466 AutoReset<bool> auto_reset(&ignore_changes_, true); |
| 467 |
| 468 DeleteAppsPageRange(page_index, 1); |
| 469 } |
| 470 |
| 471 void AppLauncherHandler::CondenseAppsPages() { |
| 472 std::vector<bool> has_apps; |
| 473 const ExtensionList* extensions = extension_service_->extensions(); |
| 474 for (ExtensionList::const_iterator it = extensions->begin(); |
| 475 it != extensions->end(); ++it) { |
| 476 if (!IsAppExcludedFromList(*it)) { |
| 477 EnsureAppHasPageIndex(extension_service_, (*it)->id()); |
| 478 size_t page_index = |
| 479 extension_service_->extension_prefs()->GetPageIndex((*it)->id()); |
| 480 if (has_apps.size() < page_index + 1) |
| 481 has_apps.resize(page_index + 1); |
| 482 has_apps[page_index] = true; |
| 483 } |
| 484 } |
| 485 |
| 486 // Delete empty ranges of apps pages. |
| 487 int first_empty = -1; |
| 488 for (size_t i = 0; i < has_apps.size(); ++i) { |
| 489 if (!has_apps[i]) { |
| 490 if (first_empty == -1) |
| 491 first_empty = i; |
| 492 } else if (first_empty != -1) { |
| 493 DeleteAppsPageRange(first_empty, i - first_empty); |
| 494 has_apps.erase(has_apps.begin() + first_empty, has_apps.begin() + i); |
| 495 i -= (i - first_empty); |
| 496 first_empty = -1; |
| 497 } |
| 498 } |
| 499 // Make sure there are no pending empty apps pages at the end of our list. |
| 500 CHECK_EQ(first_empty, -1); |
| 501 } |
| 502 |
| 503 void AppLauncherHandler::DeleteAppsPageRange(size_t index, size_t how_many) { |
| 504 // Delete the apps page name from our prefs. |
| 505 PrefService* prefs = Profile::FromWebUI(web_ui_)->GetPrefs(); |
| 506 ListPrefUpdate update(prefs, prefs::kNTPAppPageNames); |
| 507 ListValue* list = update.Get(); |
| 508 |
| 509 // Index checking is done within list->Remove() and will return false if an |
| 510 // index to remove is negative or larger than the size of the list. This is |
| 511 // intentionally left un-CHECK()-ed in the case that there's a skew between |
| 512 // the list pref size and the last page index of all the apps. |
| 513 for (size_t i = 0; i < how_many; ++i) |
| 514 list->Remove(index, NULL); |
| 515 |
| 516 // Move apps that were on a page past the one we're deleting to their newly |
| 517 // adjusted page index. |
| 518 ExtensionPrefs* ext_prefs = extension_service_->extension_prefs(); |
| 519 const ExtensionList* extensions = extension_service_->extensions(); |
| 520 for (ExtensionList::const_iterator it = extensions->begin(); |
| 521 it != extensions->end(); ++it) { |
| 522 // Ignore extensions and the cloud print app (but handle CWS app). |
| 523 if (!IsAppExcludedFromList(*it)) { |
| 524 size_t apps_page_index = |
| 525 static_cast<size_t>(ext_prefs->GetPageIndex((*it)->id())); |
| 526 // Don't delete pages with apps still on them. |
| 527 CHECK(apps_page_index < index || apps_page_index >= (index + how_many)); |
| 528 if (apps_page_index >= (index + how_many)) |
| 529 ext_prefs->SetPageIndex((*it)->id(), apps_page_index - how_many); |
| 530 } |
| 531 } |
| 532 } |
| 533 |
| 429 void AppLauncherHandler::HandleGetApps(const ListValue* args) { | 534 void AppLauncherHandler::HandleGetApps(const ListValue* args) { |
| 430 DictionaryValue dictionary; | 535 DictionaryValue dictionary; |
| 431 | 536 |
| 432 // Tell the client whether to show the promo for this view. We don't do this | 537 // Tell the client whether to show the promo for this view. We don't do this |
| 433 // in the case of PREF_CHANGED because: | 538 // in the case of PREF_CHANGED because: |
| 434 // | 539 // |
| 435 // a) At that point in time, depending on the pref that changed, it can look | 540 // a) At that point in time, depending on the pref that changed, it can look |
| 436 // like the set of apps installed has changed, and we will mark the promo | 541 // like the set of apps installed has changed, and we will mark the promo |
| 437 // expired. | 542 // expired. |
| 438 // b) Conceptually, it doesn't really make sense to count a | 543 // b) Conceptually, it doesn't really make sense to count a |
| (...skipping 10 matching lines...) Expand all Loading... |
| 449 } | 554 } |
| 450 | 555 |
| 451 // If the default apps have just expired (user viewed them too many times with | 556 // If the default apps have just expired (user viewed them too many times with |
| 452 // no interaction), then we uninstall them and focus the recent sites section. | 557 // no interaction), then we uninstall them and focus the recent sites section. |
| 453 if (apps_promo_just_expired) { | 558 if (apps_promo_just_expired) { |
| 454 ignore_changes_ = true; | 559 ignore_changes_ = true; |
| 455 UninstallDefaultApps(); | 560 UninstallDefaultApps(); |
| 456 ignore_changes_ = false; | 561 ignore_changes_ = false; |
| 457 } | 562 } |
| 458 | 563 |
| 564 CondenseAppsPages(); |
| 459 SetAppToBeHighlighted(); | 565 SetAppToBeHighlighted(); |
| 460 FillAppDictionary(&dictionary); | 566 FillAppDictionary(&dictionary); |
| 461 web_ui_->CallJavascriptFunction("getAppsCallback", dictionary); | 567 web_ui_->CallJavascriptFunction("getAppsCallback", dictionary); |
| 462 | 568 |
| 463 // First time we get here we set up the observer so that we can tell update | 569 // First time we get here we set up the observer so that we can tell update |
| 464 // the apps as they change. | 570 // the apps as they change. |
| 465 if (!has_loaded_apps_) { | 571 if (!has_loaded_apps_) { |
| 466 pref_change_registrar_.Init( | 572 pref_change_registrar_.Init( |
| 467 extension_service_->extension_prefs()->pref_service()); | 573 extension_service_->extension_prefs()->pref_service()); |
| 468 pref_change_registrar_.Add(ExtensionPrefs::kExtensionsPref, this); | 574 pref_change_registrar_.Add(ExtensionPrefs::kExtensionsPref, this); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 if (!extension_id_prompting_.empty()) | 716 if (!extension_id_prompting_.empty()) |
| 611 return; // Only one prompt at a time. | 717 return; // Only one prompt at a time. |
| 612 | 718 |
| 613 extension_id_prompting_ = extension_id; | 719 extension_id_prompting_ = extension_id; |
| 614 | 720 |
| 615 bool dont_confirm = false; | 721 bool dont_confirm = false; |
| 616 if (args->GetBoolean(1, &dont_confirm) && dont_confirm) { | 722 if (args->GetBoolean(1, &dont_confirm) && dont_confirm) { |
| 617 AutoReset<bool> auto_reset(&ignore_changes_, true); | 723 AutoReset<bool> auto_reset(&ignore_changes_, true); |
| 618 ExtensionUninstallAccepted(); | 724 ExtensionUninstallAccepted(); |
| 619 } else { | 725 } else { |
| 726 // We don't use an AutoReset<bool> here as the uninstall dialog runs in a |
| 727 // different thread so it's not sync. |
| 728 uninstall_from_page_ = true; |
| 620 GetExtensionUninstallDialog()->ConfirmUninstall(extension); | 729 GetExtensionUninstallDialog()->ConfirmUninstall(extension); |
| 621 } | 730 } |
| 622 } | 731 } |
| 623 | 732 |
| 624 void AppLauncherHandler::HandleHideAppsPromo(const ListValue* args) { | 733 void AppLauncherHandler::HandleHideAppsPromo(const ListValue* args) { |
| 625 // If the user has intentionally hidden the promotion, we'll uninstall all the | 734 // If the user has intentionally hidden the promotion, we'll uninstall all the |
| 626 // default apps (we know the user hasn't installed any apps on their own at | 735 // default apps (we know the user hasn't installed any apps on their own at |
| 627 // this point, or the promotion wouldn't have been shown). | 736 // this point, or the promotion wouldn't have been shown). |
| 628 // TODO(estade): this isn't used right now as we sort out the future of the | 737 // TODO(estade): this isn't used right now as we sort out the future of the |
| 629 // apps promo on ntp4. | 738 // apps promo on ntp4. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 680 extension_service_->extension_prefs()->SetPageIndex(extension_id, | 789 extension_service_->extension_prefs()->SetPageIndex(extension_id, |
| 681 static_cast<int>(page_index)); | 790 static_cast<int>(page_index)); |
| 682 } | 791 } |
| 683 | 792 |
| 684 void AppLauncherHandler::HandlePromoSeen(const ListValue* args) { | 793 void AppLauncherHandler::HandlePromoSeen(const ListValue* args) { |
| 685 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, | 794 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, |
| 686 extension_misc::PROMO_SEEN, | 795 extension_misc::PROMO_SEEN, |
| 687 extension_misc::PROMO_BUCKET_BOUNDARY); | 796 extension_misc::PROMO_BUCKET_BOUNDARY); |
| 688 } | 797 } |
| 689 | 798 |
| 690 void AppLauncherHandler::HandleSaveAppPageName(const ListValue* args) { | 799 void AppLauncherHandler::HandleSaveAppsPageName(const ListValue* args) { |
| 691 string16 name; | 800 string16 name; |
| 692 CHECK(args->GetString(0, &name)); | 801 CHECK(args->GetString(0, &name)); |
| 693 | 802 |
| 694 double page_index; | 803 double page_index; |
| 695 CHECK(args->GetDouble(1, &page_index)); | 804 CHECK(args->GetDouble(1, &page_index)); |
| 696 | 805 |
| 697 AutoReset<bool> auto_reset(&ignore_changes_, true); | 806 AutoReset<bool> auto_reset(&ignore_changes_, true); |
| 698 PrefService* prefs = Profile::FromWebUI(web_ui_)->GetPrefs(); | 807 PrefService* prefs = Profile::FromWebUI(web_ui_)->GetPrefs(); |
| 699 ListPrefUpdate update(prefs, prefs::kNTPAppPageNames); | 808 ListPrefUpdate update(prefs, prefs::kNTPAppPageNames); |
| 700 ListValue* list = update.Get(); | 809 ListValue* list = update.Get(); |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 953 | 1062 |
| 954 void AppLauncherHandler::UninstallDefaultApps() { | 1063 void AppLauncherHandler::UninstallDefaultApps() { |
| 955 AppsPromo* apps_promo = extension_service_->apps_promo(); | 1064 AppsPromo* apps_promo = extension_service_->apps_promo(); |
| 956 const ExtensionIdSet& app_ids = apps_promo->old_default_apps(); | 1065 const ExtensionIdSet& app_ids = apps_promo->old_default_apps(); |
| 957 for (ExtensionIdSet::const_iterator iter = app_ids.begin(); | 1066 for (ExtensionIdSet::const_iterator iter = app_ids.begin(); |
| 958 iter != app_ids.end(); ++iter) { | 1067 iter != app_ids.end(); ++iter) { |
| 959 if (extension_service_->GetExtensionById(*iter, true)) | 1068 if (extension_service_->GetExtensionById(*iter, true)) |
| 960 extension_service_->UninstallExtension(*iter, false, NULL); | 1069 extension_service_->UninstallExtension(*iter, false, NULL); |
| 961 } | 1070 } |
| 962 } | 1071 } |
| OLD | NEW |