Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Side by Side Diff: chrome/browser/ui/webui/ntp/app_launcher_handler.cc

Issue 8637001: [NTP4] Auto-deletion of empty apps panes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more fixes and typos from reviewing myself Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
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::AppLauncherHandler(ExtensionService* extension_service) 70 AppLauncherHandler::AppLauncherHandler(ExtensionService* extension_service)
71 : extension_service_(extension_service), 71 : extension_service_(extension_service),
72 ignore_changes_(false), 72 ignore_changes_(false),
73 attempted_bookmark_app_install_(false), 73 attempted_bookmark_app_install_(false),
74 has_loaded_apps_(false) { 74 has_loaded_apps_(false),
75 uninstall_from_page_(false) {
75 } 76 }
76 77
77 AppLauncherHandler::~AppLauncherHandler() {} 78 AppLauncherHandler::~AppLauncherHandler() {}
78 79
79 // Serializes |notification| into a new DictionaryValue which the caller then 80 // Serializes |notification| into a new DictionaryValue which the caller then
80 // owns. 81 // owns.
81 static DictionaryValue* SerializeNotification( 82 static DictionaryValue* SerializeNotification(
82 const AppNotification& notification) { 83 const AppNotification& notification) {
83 DictionaryValue* dictionary = new DictionaryValue(); 84 DictionaryValue* dictionary = new DictionaryValue();
84 dictionary->SetString("title", notification.title()); 85 dictionary->SetString("title", notification.title());
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 // Make sure every app has a launch index (some predate the launch index). 164 // 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 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 // The next time the user drags (any) app this will be set to something
166 // sane (i.e. >= 0). 167 // sane (i.e. >= 0).
167 app_launch_index = extension->id() == extension_misc::kWebStoreAppId ? 168 app_launch_index = extension->id() == extension_misc::kWebStoreAppId ?
168 -2 : prefs->GetNextAppLaunchIndex(0); 169 -2 : prefs->GetNextAppLaunchIndex(0);
169 prefs->SetAppLaunchIndex(extension->id(), app_launch_index); 170 prefs->SetAppLaunchIndex(extension->id(), app_launch_index);
170 } 171 }
171 value->SetInteger("app_launch_index", app_launch_index); 172 value->SetInteger("app_launch_index", app_launch_index);
172 173
173 int page_index = prefs->GetPageIndex(extension->id()); 174 EnsureAppHasPageIndex(service, extension->id());
174 if (page_index < 0) { 175 value->SetInteger("page_index", prefs->GetPageIndex(extension->id()));
175 // Make sure every app has a page index (some predate the page index).
176 // The webstore app should be on the first page.
177 page_index = extension->id() == extension_misc::kWebStoreAppId ?
178 0 : prefs->GetNaturalAppPageIndex();
179 prefs->SetPageIndex(extension->id(), page_index);
180 }
181 value->SetInteger("page_index", page_index);
182 } 176 }
183 177
184 WebUIMessageHandler* AppLauncherHandler::Attach(WebUI* web_ui) { 178 WebUIMessageHandler* AppLauncherHandler::Attach(WebUI* web_ui) {
185 registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_NTP, 179 registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_NTP,
186 content::Source<TabContents>(web_ui->tab_contents())); 180 content::Source<TabContents>(web_ui->tab_contents()));
187 return WebUIMessageHandler::Attach(web_ui); 181 return WebUIMessageHandler::Attach(web_ui);
188 } 182 }
189 183
190 void AppLauncherHandler::RegisterMessages() { 184 void AppLauncherHandler::RegisterMessages() {
185 web_ui_->RegisterMessageCallback("deleteAppsPage",
186 base::Bind(&AppLauncherHandler::HandleDeleteAppsPage,
187 base::Unretained(this)));
191 web_ui_->RegisterMessageCallback("getApps", 188 web_ui_->RegisterMessageCallback("getApps",
192 base::Bind(&AppLauncherHandler::HandleGetApps, 189 base::Bind(&AppLauncherHandler::HandleGetApps,
193 base::Unretained(this))); 190 base::Unretained(this)));
194 web_ui_->RegisterMessageCallback("launchApp", 191 web_ui_->RegisterMessageCallback("launchApp",
195 base::Bind(&AppLauncherHandler::HandleLaunchApp, 192 base::Bind(&AppLauncherHandler::HandleLaunchApp,
196 base::Unretained(this))); 193 base::Unretained(this)));
197 web_ui_->RegisterMessageCallback("setLaunchType", 194 web_ui_->RegisterMessageCallback("setLaunchType",
198 base::Bind(&AppLauncherHandler::HandleSetLaunchType, 195 base::Bind(&AppLauncherHandler::HandleSetLaunchType,
199 base::Unretained(this))); 196 base::Unretained(this)));
200 web_ui_->RegisterMessageCallback("uninstallApp", 197 web_ui_->RegisterMessageCallback("uninstallApp",
201 base::Bind(&AppLauncherHandler::HandleUninstallApp, 198 base::Bind(&AppLauncherHandler::HandleUninstallApp,
202 base::Unretained(this))); 199 base::Unretained(this)));
203 web_ui_->RegisterMessageCallback("hideAppsPromo", 200 web_ui_->RegisterMessageCallback("hideAppsPromo",
204 base::Bind(&AppLauncherHandler::HandleHideAppsPromo, 201 base::Bind(&AppLauncherHandler::HandleHideAppsPromo,
205 base::Unretained(this))); 202 base::Unretained(this)));
206 web_ui_->RegisterMessageCallback("createAppShortcut", 203 web_ui_->RegisterMessageCallback("createAppShortcut",
207 base::Bind(&AppLauncherHandler::HandleCreateAppShortcut, 204 base::Bind(&AppLauncherHandler::HandleCreateAppShortcut,
208 base::Unretained(this))); 205 base::Unretained(this)));
209 web_ui_->RegisterMessageCallback("reorderApps", 206 web_ui_->RegisterMessageCallback("reorderApps",
210 base::Bind(&AppLauncherHandler::HandleReorderApps, 207 base::Bind(&AppLauncherHandler::HandleReorderApps,
211 base::Unretained(this))); 208 base::Unretained(this)));
212 web_ui_->RegisterMessageCallback("setPageIndex", 209 web_ui_->RegisterMessageCallback("setPageIndex",
213 base::Bind(&AppLauncherHandler::HandleSetPageIndex, 210 base::Bind(&AppLauncherHandler::HandleSetPageIndex,
214 base::Unretained(this))); 211 base::Unretained(this)));
215 web_ui_->RegisterMessageCallback("promoSeen", 212 web_ui_->RegisterMessageCallback("promoSeen",
216 base::Bind(&AppLauncherHandler::HandlePromoSeen, 213 base::Bind(&AppLauncherHandler::HandlePromoSeen,
217 base::Unretained(this))); 214 base::Unretained(this)));
218 web_ui_->RegisterMessageCallback("saveAppPageName", 215 web_ui_->RegisterMessageCallback("saveAppsPageName",
219 base::Bind(&AppLauncherHandler::HandleSaveAppPageName, 216 base::Bind(&AppLauncherHandler::HandleSaveAppsPageName,
220 base::Unretained(this))); 217 base::Unretained(this)));
221 web_ui_->RegisterMessageCallback("generateAppForLink", 218 web_ui_->RegisterMessageCallback("generateAppForLink",
222 base::Bind(&AppLauncherHandler::HandleGenerateAppForLink, 219 base::Bind(&AppLauncherHandler::HandleGenerateAppForLink,
223 base::Unretained(this))); 220 base::Unretained(this)));
224 web_ui_->RegisterMessageCallback("recordAppLaunchByURL", 221 web_ui_->RegisterMessageCallback("recordAppLaunchByURL",
225 base::Bind(&AppLauncherHandler::HandleRecordAppLaunchByURL, 222 base::Bind(&AppLauncherHandler::HandleRecordAppLaunchByURL,
226 base::Unretained(this))); 223 base::Unretained(this)));
227 web_ui_->RegisterMessageCallback("closeNotification", 224 web_ui_->RegisterMessageCallback("closeNotification",
228 base::Bind(&AppLauncherHandler::HandleNotificationClose, 225 base::Bind(&AppLauncherHandler::HandleNotificationClose,
229 base::Unretained(this))); 226 base::Unretained(this)));
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 content::Details<UnloadedExtensionInfo>(details)->extension; 283 content::Details<UnloadedExtensionInfo>(details)->extension;
287 if (!extension->is_app()) 284 if (!extension->is_app())
288 return; 285 return;
289 286
290 scoped_ptr<DictionaryValue> app_info(GetAppInfo(extension)); 287 scoped_ptr<DictionaryValue> app_info(GetAppInfo(extension));
291 scoped_ptr<base::FundamentalValue> uninstall_value( 288 scoped_ptr<base::FundamentalValue> uninstall_value(
292 Value::CreateBooleanValue( 289 Value::CreateBooleanValue(
293 content::Details<UnloadedExtensionInfo>(details)->reason == 290 content::Details<UnloadedExtensionInfo>(details)->reason ==
294 extension_misc::UNLOAD_REASON_UNINSTALL)); 291 extension_misc::UNLOAD_REASON_UNINSTALL));
295 if (app_info.get()) { 292 if (app_info.get()) {
293 scoped_ptr<base::FundamentalValue> from_page(
294 Value::CreateBooleanValue(uninstall_from_page_));
296 web_ui_->CallJavascriptFunction( 295 web_ui_->CallJavascriptFunction(
297 "ntp4.appRemoved", *app_info, *uninstall_value); 296 "ntp4.appRemoved", *app_info, *uninstall_value, *from_page);
298 } 297 }
299 break; 298 break;
300 } 299 }
301 case chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED: 300 case chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED: {
302 // The promo may not load until a couple seconds after the first NTP view, 301 DictionaryValue pages;
303 // so we listen for the load notification and notify the NTP when ready. 302 const ExtensionSet* extensions = extension_service_->extensions();
304 case chrome::NOTIFICATION_WEB_STORE_PROMO_LOADED: 303 ExtensionPrefs* prefs = extension_service_->extension_prefs();
305 // TODO(estade): try to get rid of this inefficient operation. 304 for (ExtensionSet::const_iterator it = extensions->begin();
305 it != extensions->end(); ++it) {
306 if (!IsAppExcludedFromList(*it)) {
307 std::string page_index =
308 base::IntToString(prefs->GetPageIndex((*it)->id()));
309 if (!pages.HasKey(page_index))
310 pages.Set(page_index, new DictionaryValue());
311 DictionaryValue* page;
312 CHECK(pages.GetDictionary(page_index, &page));
313 page->SetString(
314 base::IntToString(prefs->GetAppLaunchIndex((*it)->id())),
315 (*it)->id());
316 }
317 }
318 web_ui_->CallJavascriptFunction("ntp4.appsReordered", pages);
319 break;
320 }
321 case chrome::NOTIFICATION_WEB_STORE_PROMO_LOADED: {
322 // The promo may not load until a couple seconds after the first NTP view,
323 // so we listen for the load notification and notify the NTP when ready.
306 HandleGetApps(NULL); 324 HandleGetApps(NULL);
307 break; 325 break;
326 }
308 case chrome::NOTIFICATION_PREF_CHANGED: { 327 case chrome::NOTIFICATION_PREF_CHANGED: {
309 DictionaryValue dictionary; 328 DictionaryValue dictionary;
310 FillAppDictionary(&dictionary); 329 FillAppDictionary(&dictionary);
311 web_ui_->CallJavascriptFunction("appsPrefChangeCallback", dictionary); 330 web_ui_->CallJavascriptFunction("appsPrefChangeCallback", dictionary);
312 break; 331 break;
313 } 332 }
314 case chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR: { 333 case chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR: {
315 CrxInstaller* crx_installer = content::Source<CrxInstaller>(source).ptr(); 334 CrxInstaller* crx_installer = content::Source<CrxInstaller>(source).ptr();
316 if (!Profile::FromWebUI(web_ui_)->IsSameProfile(crx_installer->profile())) 335 if (!Profile::FromWebUI(web_ui_)->IsSameProfile(crx_installer->profile()))
317 return; 336 return;
318 // Fall Through. 337 // Fall Through.
319 } 338 }
320 case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR: { 339 case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR: {
321 attempted_bookmark_app_install_ = false; 340 attempted_bookmark_app_install_ = false;
322 break; 341 break;
323 } 342 }
324 default: 343 default:
325 NOTREACHED(); 344 NOTREACHED();
326 } 345 }
327 } 346 }
328 347
348 // static
349 void AppLauncherHandler::EnsureAppHasPageIndex(ExtensionService* service,
350 const std::string& id) {
351 if (service->extension_prefs()->GetPageIndex(id) < 0) {
352 // Make sure every app has a page index (some predate the page index).
353 // The webstore app should be on the first page.
354 int page_index = id == extension_misc::kWebStoreAppId ?
355 0 : service->extension_prefs()->GetNaturalAppPageIndex();
356 service->extension_prefs()->SetPageIndex(id, page_index);
357 }
358 }
359
329 void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) { 360 void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) {
330 // CreateAppInfo and ClearPageIndex can change the extension prefs. 361 // CreateAppInfo and ClearPageIndex can change the extension prefs.
331 AutoReset<bool> auto_reset(&ignore_changes_, true); 362 AutoReset<bool> auto_reset(&ignore_changes_, true);
332 363
333 ListValue* list = new ListValue(); 364 ListValue* list = new ListValue();
334 const ExtensionSet* extensions = extension_service_->extensions(); 365 const ExtensionSet* extensions = extension_service_->extensions();
335 ExtensionSet::const_iterator it; 366 ExtensionSet::const_iterator it;
336 for (it = extensions->begin(); it != extensions->end(); ++it) { 367 for (it = extensions->begin(); it != extensions->end(); ++it) {
337 const Extension* extension = *it; 368 const Extension* extension = *it;
338 if (!IsAppExcludedFromList(extension)) { 369 if (!IsAppExcludedFromList(extension)) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 extension_service_->apps_promo()->ShouldShowAppLauncher( 425 extension_service_->apps_promo()->ShouldShowAppLauncher(
395 extension_service_->GetAppIds())); 426 extension_service_->GetAppIds()));
396 427
397 PrefService* prefs = Profile::FromWebUI(web_ui_)->GetPrefs(); 428 PrefService* prefs = Profile::FromWebUI(web_ui_)->GetPrefs();
398 const ListValue* app_page_names = prefs->GetList(prefs::kNTPAppPageNames); 429 const ListValue* app_page_names = prefs->GetList(prefs::kNTPAppPageNames);
399 if (!app_page_names || !app_page_names->GetSize()) { 430 if (!app_page_names || !app_page_names->GetSize()) {
400 ListPrefUpdate update(prefs, prefs::kNTPAppPageNames); 431 ListPrefUpdate update(prefs, prefs::kNTPAppPageNames);
401 ListValue* list = update.Get(); 432 ListValue* list = update.Get();
402 list->Set(0, Value::CreateStringValue( 433 list->Set(0, Value::CreateStringValue(
403 l10n_util::GetStringUTF16(IDS_APP_DEFAULT_PAGE_NAME))); 434 l10n_util::GetStringUTF16(IDS_APP_DEFAULT_PAGE_NAME)));
404 dictionary->Set("appPageNames", 435 dictionary->Set("appsPageNames",
405 static_cast<ListValue*>(list->DeepCopy())); 436 static_cast<ListValue*>(list->DeepCopy()));
406 } else { 437 } else {
407 dictionary->Set("appPageNames", 438 dictionary->Set("appsPageNames",
408 static_cast<ListValue*>(app_page_names->DeepCopy())); 439 static_cast<ListValue*>(app_page_names->DeepCopy()));
409 } 440 }
410 } 441 }
411 442
412 DictionaryValue* AppLauncherHandler::GetAppInfo(const Extension* extension) { 443 DictionaryValue* AppLauncherHandler::GetAppInfo(const Extension* extension) {
413 AppNotificationManager* notification_manager = 444 AppNotificationManager* notification_manager =
414 extension_service_->app_notification_manager(); 445 extension_service_->app_notification_manager();
415 DictionaryValue* app_info = new DictionaryValue(); 446 DictionaryValue* app_info = new DictionaryValue();
416 // CreateAppInfo can change the extension prefs. 447 // CreateAppInfo can change the extension prefs.
417 AutoReset<bool> auto_reset(&ignore_changes_, true); 448 AutoReset<bool> auto_reset(&ignore_changes_, true);
418 CreateAppInfo(extension, 449 CreateAppInfo(extension,
419 notification_manager->GetLast(extension->id()), 450 notification_manager->GetLast(extension->id()),
420 extension_service_, 451 extension_service_,
421 app_info); 452 app_info);
422 return app_info; 453 return app_info;
423 } 454 }
424 455
425 void AppLauncherHandler::FillPromoDictionary(DictionaryValue* dictionary) { 456 void AppLauncherHandler::FillPromoDictionary(DictionaryValue* dictionary) {
426 AppsPromo::PromoData data = AppsPromo::GetPromo(); 457 AppsPromo::PromoData data = AppsPromo::GetPromo();
427 dictionary->SetString("promoHeader", data.header); 458 dictionary->SetString("promoHeader", data.header);
428 dictionary->SetString("promoButton", data.button); 459 dictionary->SetString("promoButton", data.button);
429 dictionary->SetString("promoLink", data.link.spec()); 460 dictionary->SetString("promoLink", data.link.spec());
430 dictionary->SetString("promoLogo", data.logo.spec()); 461 dictionary->SetString("promoLogo", data.logo.spec());
431 dictionary->SetString("promoExpire", data.expire); 462 dictionary->SetString("promoExpire", data.expire);
432 } 463 }
433 464
465 void AppLauncherHandler::HandleDeleteAppsPage(const ListValue* args) {
466 double page_index_double;
467 CHECK(args->GetDouble(0, &page_index_double) && page_index_double >= 0);
468 size_t page_index = static_cast<size_t>(page_index_double);
469
470 AutoReset<bool> auto_reset(&ignore_changes_, true);
471
472 DeleteAppsPageRange(page_index, 1);
473 }
474
475 void AppLauncherHandler::CleanupAfterUninstall() {
476 uninstall_from_page_ = false;
477 extension_id_prompting_ = "";
478 }
479
480 void AppLauncherHandler::CondenseAppsPages() {
481 std::vector<bool> has_apps;
482 const ExtensionSet* extensions = extension_service_->extensions();
483 for (ExtensionSet::const_iterator it = extensions->begin();
484 it != extensions->end(); ++it) {
485 if (!IsAppExcludedFromList(*it)) {
486 EnsureAppHasPageIndex(extension_service_, (*it)->id());
487 size_t page_index =
488 extension_service_->extension_prefs()->GetPageIndex((*it)->id());
489 if (has_apps.size() < page_index + 1)
490 has_apps.resize(page_index + 1);
491 has_apps[page_index] = true;
492 }
493 }
494
495 // Delete empty ranges of apps pages.
496 int first_empty = -1;
497 for (size_t i = 0; i < has_apps.size(); ++i) {
498 if (!has_apps[i]) {
499 if (first_empty == -1)
500 first_empty = i;
501 } else if (first_empty != -1) {
502 DeleteAppsPageRange(first_empty, i - first_empty);
503 has_apps.erase(has_apps.begin() + first_empty, has_apps.begin() + i);
504 i -= (i - first_empty);
505 first_empty = -1;
506 }
507 }
508 // Make sure there are no pending empty apps pages at the end of our list.
509 CHECK_EQ(first_empty, -1);
510 }
511
512 void AppLauncherHandler::DeleteAppsPageRange(size_t index, size_t how_many) {
513 // Delete the apps page name from our prefs.
514 PrefService* prefs = Profile::FromWebUI(web_ui_)->GetPrefs();
515 ListPrefUpdate update(prefs, prefs::kNTPAppPageNames);
516 ListValue* list = update.Get();
517
518 // Index checking is done within list->Remove() and will return false if an
519 // index to remove is negative or larger than the size of the list. This is
520 // intentionally left un-CHECK()-ed in the case that there's a skew between
521 // the list pref size and the last page index of all the apps.
522 for (size_t i = 0; i < how_many; ++i)
523 list->Remove(index, NULL);
524
525 // Move apps that were on a page past the one we're deleting to their newly
526 // adjusted page index.
527 ExtensionPrefs* ext_prefs = extension_service_->extension_prefs();
528 const ExtensionSet* extensions = extension_service_->extensions();
529 for (ExtensionSet::const_iterator it = extensions->begin();
530 it != extensions->end(); ++it) {
531 // Ignore extensions and the cloud print app (but handle CWS app).
532 if (!IsAppExcludedFromList(*it)) {
533 size_t apps_page_index =
534 static_cast<size_t>(ext_prefs->GetPageIndex((*it)->id()));
535 // Don't delete pages with apps still on them.
536 CHECK(apps_page_index < index || apps_page_index >= (index + how_many));
537 if (apps_page_index >= (index + how_many))
538 ext_prefs->SetPageIndex((*it)->id(), apps_page_index - how_many);
539 }
540 }
541 }
542
434 void AppLauncherHandler::HandleGetApps(const ListValue* args) { 543 void AppLauncherHandler::HandleGetApps(const ListValue* args) {
435 DictionaryValue dictionary; 544 DictionaryValue dictionary;
436 545
437 // Tell the client whether to show the promo for this view. We don't do this 546 // Tell the client whether to show the promo for this view. We don't do this
438 // in the case of PREF_CHANGED because: 547 // in the case of PREF_CHANGED because:
439 // 548 //
440 // a) At that point in time, depending on the pref that changed, it can look 549 // a) At that point in time, depending on the pref that changed, it can look
441 // like the set of apps installed has changed, and we will mark the promo 550 // like the set of apps installed has changed, and we will mark the promo
442 // expired. 551 // expired.
443 // b) Conceptually, it doesn't really make sense to count a 552 // b) Conceptually, it doesn't really make sense to count a
(...skipping 10 matching lines...) Expand all
454 } 563 }
455 564
456 // If the default apps have just expired (user viewed them too many times with 565 // If the default apps have just expired (user viewed them too many times with
457 // no interaction), then we uninstall them and focus the recent sites section. 566 // no interaction), then we uninstall them and focus the recent sites section.
458 if (apps_promo_just_expired) { 567 if (apps_promo_just_expired) {
459 ignore_changes_ = true; 568 ignore_changes_ = true;
460 UninstallDefaultApps(); 569 UninstallDefaultApps();
461 ignore_changes_ = false; 570 ignore_changes_ = false;
462 } 571 }
463 572
573 CondenseAppsPages();
464 SetAppToBeHighlighted(); 574 SetAppToBeHighlighted();
465 FillAppDictionary(&dictionary); 575 FillAppDictionary(&dictionary);
466 web_ui_->CallJavascriptFunction("getAppsCallback", dictionary); 576 web_ui_->CallJavascriptFunction("getAppsCallback", dictionary);
467 577
468 // First time we get here we set up the observer so that we can tell update 578 // First time we get here we set up the observer so that we can tell update
469 // the apps as they change. 579 // the apps as they change.
470 if (!has_loaded_apps_) { 580 if (!has_loaded_apps_) {
471 pref_change_registrar_.Init( 581 pref_change_registrar_.Init(
472 extension_service_->extension_prefs()->pref_service()); 582 extension_service_->extension_prefs()->pref_service());
473 pref_change_registrar_.Add(ExtensionPrefs::kExtensionsPref, this); 583 pref_change_registrar_.Add(ExtensionPrefs::kExtensionsPref, this);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 if (!extension_id_prompting_.empty()) 707 if (!extension_id_prompting_.empty())
598 return; // Only one prompt at a time. 708 return; // Only one prompt at a time.
599 709
600 extension_id_prompting_ = extension_id; 710 extension_id_prompting_ = extension_id;
601 711
602 bool dont_confirm = false; 712 bool dont_confirm = false;
603 if (args->GetBoolean(1, &dont_confirm) && dont_confirm) { 713 if (args->GetBoolean(1, &dont_confirm) && dont_confirm) {
604 AutoReset<bool> auto_reset(&ignore_changes_, true); 714 AutoReset<bool> auto_reset(&ignore_changes_, true);
605 ExtensionUninstallAccepted(); 715 ExtensionUninstallAccepted();
606 } else { 716 } else {
717 // We don't use an AutoReset<bool> here as the uninstall dialog runs in a
718 // different thread so it's not sync.
719 uninstall_from_page_ = true;
607 GetExtensionUninstallDialog()->ConfirmUninstall(extension); 720 GetExtensionUninstallDialog()->ConfirmUninstall(extension);
608 } 721 }
609 } 722 }
610 723
611 void AppLauncherHandler::HandleHideAppsPromo(const ListValue* args) { 724 void AppLauncherHandler::HandleHideAppsPromo(const ListValue* args) {
612 // If the user has intentionally hidden the promotion, we'll uninstall all the 725 // If the user has intentionally hidden the promotion, we'll uninstall all the
613 // default apps (we know the user hasn't installed any apps on their own at 726 // default apps (we know the user hasn't installed any apps on their own at
614 // this point, or the promotion wouldn't have been shown). 727 // this point, or the promotion wouldn't have been shown).
615 // TODO(estade): this isn't used right now as we sort out the future of the 728 // TODO(estade): this isn't used right now as we sort out the future of the
616 // apps promo on ntp4. 729 // apps promo on ntp4.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 extension_service_->extension_prefs()->SetPageIndex(extension_id, 780 extension_service_->extension_prefs()->SetPageIndex(extension_id,
668 static_cast<int>(page_index)); 781 static_cast<int>(page_index));
669 } 782 }
670 783
671 void AppLauncherHandler::HandlePromoSeen(const ListValue* args) { 784 void AppLauncherHandler::HandlePromoSeen(const ListValue* args) {
672 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, 785 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
673 extension_misc::PROMO_SEEN, 786 extension_misc::PROMO_SEEN,
674 extension_misc::PROMO_BUCKET_BOUNDARY); 787 extension_misc::PROMO_BUCKET_BOUNDARY);
675 } 788 }
676 789
677 void AppLauncherHandler::HandleSaveAppPageName(const ListValue* args) { 790 void AppLauncherHandler::HandleSaveAppsPageName(const ListValue* args) {
678 string16 name; 791 string16 name;
679 CHECK(args->GetString(0, &name)); 792 CHECK(args->GetString(0, &name));
680 793
681 double page_index; 794 double page_index_double;
682 CHECK(args->GetDouble(1, &page_index)); 795 CHECK(args->GetDouble(1, &page_index_double));
683 796
684 AutoReset<bool> auto_reset(&ignore_changes_, true); 797 AutoReset<bool> auto_reset(&ignore_changes_, true);
685 PrefService* prefs = Profile::FromWebUI(web_ui_)->GetPrefs(); 798 PrefService* prefs = Profile::FromWebUI(web_ui_)->GetPrefs();
686 ListPrefUpdate update(prefs, prefs::kNTPAppPageNames); 799 ListPrefUpdate update(prefs, prefs::kNTPAppPageNames);
687 ListValue* list = update.Get(); 800 ListValue* list = update.Get();
688 list->Set(static_cast<size_t>(page_index), Value::CreateStringValue(name)); 801 size_t page_index = static_cast<size_t>(page_index_double);
802 // Though it's valid to set items of a list at a non-existent positive index
803 // (that's greater than the current length), this is not desired in this case
804 // as it creates null values in the middle of the list. Instead, only allow a
805 // save to act as an append when the page being saved is exactly equal to the
806 // length of the list.
807 CHECK(page_index <= list->GetSize());
808 list->Set(page_index, Value::CreateStringValue(name));
689 } 809 }
690 810
691 void AppLauncherHandler::HandleGenerateAppForLink(const ListValue* args) { 811 void AppLauncherHandler::HandleGenerateAppForLink(const ListValue* args) {
692 std::string url; 812 std::string url;
693 CHECK(args->GetString(0, &url)); 813 CHECK(args->GetString(0, &url));
694 GURL launch_url(url); 814 GURL launch_url(url);
695 815
696 string16 title; 816 string16 title;
697 CHECK(args->GetString(1, &title)); 817 CHECK(args->GetString(1, &title));
698 818
699 double page_index; 819 double page_index;
700 CHECK(args->GetDouble(2, &page_index)); 820 CHECK(args->GetDouble(2, &page_index));
701 821
822 // TODO(dbeam): Handle third argument (app_launch_index) and pass through
823 // the installation process.
824
702 Profile* profile = Profile::FromWebUI(web_ui_); 825 Profile* profile = Profile::FromWebUI(web_ui_);
703 FaviconService* favicon_service = 826 FaviconService* favicon_service =
704 profile->GetFaviconService(Profile::EXPLICIT_ACCESS); 827 profile->GetFaviconService(Profile::EXPLICIT_ACCESS);
705 if (!favicon_service) { 828 if (!favicon_service) {
706 LOG(ERROR) << "No favicon service"; 829 LOG(ERROR) << "No favicon service";
707 return; 830 return;
708 } 831 }
709 832
710 scoped_ptr<AppInstallInfo> install_info(new AppInstallInfo()); 833 scoped_ptr<AppInstallInfo> install_info(new AppInstallInfo());
711 install_info->is_bookmark_app = true; 834 install_info->is_bookmark_app = true;
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 1007
885 // The extension can be uninstalled in another window while the UI was 1008 // The extension can be uninstalled in another window while the UI was
886 // showing. Do nothing in that case. 1009 // showing. Do nothing in that case.
887 const Extension* extension = 1010 const Extension* extension =
888 extension_service_->GetExtensionById(extension_id_prompting_, true); 1011 extension_service_->GetExtensionById(extension_id_prompting_, true);
889 if (!extension) 1012 if (!extension)
890 return; 1013 return;
891 1014
892 extension_service_->UninstallExtension(extension_id_prompting_, 1015 extension_service_->UninstallExtension(extension_id_prompting_,
893 false /* external_uninstall */, NULL); 1016 false /* external_uninstall */, NULL);
894 1017 CleanupAfterUninstall();
895 extension_id_prompting_ = "";
896 } 1018 }
897 1019
898 void AppLauncherHandler::ExtensionUninstallCanceled() { 1020 void AppLauncherHandler::ExtensionUninstallCanceled() {
899 extension_id_prompting_ = ""; 1021 CleanupAfterUninstall();
900 } 1022 }
901 1023
902 void AppLauncherHandler::InstallUIProceed() { 1024 void AppLauncherHandler::InstallUIProceed() {
903 // Do the re-enable work here. 1025 // Do the re-enable work here.
904 DCHECK(!extension_id_prompting_.empty()); 1026 DCHECK(!extension_id_prompting_.empty());
905 1027
906 // The extension can be uninstalled in another window while the UI was 1028 // The extension can be uninstalled in another window while the UI was
907 // showing. Do nothing in that case. 1029 // showing. Do nothing in that case.
908 const Extension* extension = 1030 const Extension* extension =
909 extension_service_->GetExtensionById(extension_id_prompting_, true); 1031 extension_service_->GetExtensionById(extension_id_prompting_, true);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 1076
955 void AppLauncherHandler::UninstallDefaultApps() { 1077 void AppLauncherHandler::UninstallDefaultApps() {
956 AppsPromo* apps_promo = extension_service_->apps_promo(); 1078 AppsPromo* apps_promo = extension_service_->apps_promo();
957 const ExtensionIdSet& app_ids = apps_promo->old_default_apps(); 1079 const ExtensionIdSet& app_ids = apps_promo->old_default_apps();
958 for (ExtensionIdSet::const_iterator iter = app_ids.begin(); 1080 for (ExtensionIdSet::const_iterator iter = app_ids.begin();
959 iter != app_ids.end(); ++iter) { 1081 iter != app_ids.end(); ++iter) {
960 if (extension_service_->GetExtensionById(*iter, true)) 1082 if (extension_service_->GetExtensionById(*iter, true))
961 extension_service_->UninstallExtension(*iter, false, NULL); 1083 extension_service_->UninstallExtension(*iter, false, NULL);
962 } 1084 }
963 } 1085 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698