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

Side by Side Diff: chrome/browser/ui/app_list/app_list_syncable_service.cc

Issue 2416133002: Implement local storage for App List in case app sync is off. (Closed)
Patch Set: added extra sync test and rebased Created 4 years, 2 months 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/app_list/app_list_syncable_service.h" 5 #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "base/stl_util.h" 12 #include "base/stl_util.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "build/build_config.h" 14 #include "build/build_config.h"
15 #include "chrome/browser/apps/drive/drive_app_provider.h" 15 #include "chrome/browser/apps/drive/drive_app_provider.h"
16 #include "chrome/browser/extensions/extension_service.h" 16 #include "chrome/browser/extensions/extension_service.h"
17 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/app_list/app_list_service.h" 18 #include "chrome/browser/ui/app_list/app_list_service.h"
19 #include "chrome/browser/ui/app_list/extension_app_item.h" 19 #include "chrome/browser/ui/app_list/extension_app_item.h"
20 #include "chrome/browser/ui/app_list/extension_app_model_builder.h" 20 #include "chrome/browser/ui/app_list/extension_app_model_builder.h"
21 #include "chrome/common/chrome_switches.h" 21 #include "chrome/common/chrome_switches.h"
22 #include "chrome/common/extensions/extension_constants.h" 22 #include "chrome/common/extensions/extension_constants.h"
23 #include "chrome/common/pref_names.h"
23 #include "chrome/grit/generated_resources.h" 24 #include "chrome/grit/generated_resources.h"
25 #include "components/pref_registry/pref_registry_syncable.h"
24 #include "components/sync/model/sync_change_processor.h" 26 #include "components/sync/model/sync_change_processor.h"
25 #include "components/sync/model/sync_data.h" 27 #include "components/sync/model/sync_data.h"
26 #include "components/sync/model/sync_merge_result.h" 28 #include "components/sync/model/sync_merge_result.h"
27 #include "components/sync/protocol/sync.pb.h" 29 #include "components/sync/protocol/sync.pb.h"
28 #include "extensions/browser/extension_prefs.h" 30 #include "extensions/browser/extension_prefs.h"
29 #include "extensions/browser/extension_system.h" 31 #include "extensions/browser/extension_system.h"
30 #include "extensions/browser/uninstall_reason.h" 32 #include "extensions/browser/uninstall_reason.h"
31 #include "extensions/common/constants.h" 33 #include "extensions/common/constants.h"
32 #include "ui/app_list/app_list_folder_item.h" 34 #include "ui/app_list/app_list_folder_item.h"
33 #include "ui/app_list/app_list_item.h" 35 #include "ui/app_list/app_list_item.h"
(...skipping 12 matching lines...) Expand all
46 #endif 48 #endif
47 49
48 using syncer::SyncChange; 50 using syncer::SyncChange;
49 51
50 namespace app_list { 52 namespace app_list {
51 53
52 namespace { 54 namespace {
53 55
54 const char kOemFolderId[] = "ddb1da55-d478-4243-8642-56d3041f0263"; 56 const char kOemFolderId[] = "ddb1da55-d478-4243-8642-56d3041f0263";
55 57
58 const char kNameKey[] = "name";
59 const char kParentIdKey[] = "parent_id";
60 const char kPositionKey[] = "position";
61 const char kPinPositionKey[] = "pin_position";
62 const char kTypeKey[] = "type";
63
56 // Prefix for a sync id of a Drive app. Drive app ids are in a different 64 // Prefix for a sync id of a Drive app. Drive app ids are in a different
57 // format and have to be used because a Drive app could have only an URL 65 // format and have to be used because a Drive app could have only an URL
58 // without a matching Chrome app. To differentiate the Drive app id from 66 // without a matching Chrome app. To differentiate the Drive app id from
59 // Chrome app ids, this prefix will be added to create the sync item id 67 // Chrome app ids, this prefix will be added to create the sync item id
60 // for a Drive app item. 68 // for a Drive app item.
61 const char kDriveAppSyncIdPrefix[] = "drive-app-"; 69 const char kDriveAppSyncIdPrefix[] = "drive-app-";
62 70
63 void UpdateSyncItemFromSync(const sync_pb::AppListSpecifics& specifics, 71 void UpdateSyncItemFromSync(const sync_pb::AppListSpecifics& specifics,
64 AppListSyncableService::SyncItem* item) { 72 AppListSyncableService::SyncItem* item) {
65 DCHECK_EQ(item->item_id, specifics.item_id()); 73 DCHECK_EQ(item->item_id, specifics.item_id());
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 std::string GetDriveAppSyncId(const std::string& drive_app_id) { 174 std::string GetDriveAppSyncId(const std::string& drive_app_id) {
167 return kDriveAppSyncIdPrefix + drive_app_id; 175 return kDriveAppSyncIdPrefix + drive_app_id;
168 } 176 }
169 177
170 std::string GetDriveAppIdFromSyncId(const std::string& sync_id) { 178 std::string GetDriveAppIdFromSyncId(const std::string& sync_id) {
171 if (!IsDriveAppSyncId(sync_id)) 179 if (!IsDriveAppSyncId(sync_id))
172 return std::string(); 180 return std::string();
173 return sync_id.substr(strlen(kDriveAppSyncIdPrefix)); 181 return sync_id.substr(strlen(kDriveAppSyncIdPrefix));
174 } 182 }
175 183
184 void RemoveSyncItemFromLocalStorage(Profile* profile,
185 const std::string& item_id) {
186 DictionaryPrefUpdate(profile->GetPrefs(), prefs::kAppListLocalState)->
187 Remove(item_id, nullptr);
188 }
189
190 void UpdateSyncItemInLocalStorage(
191 Profile* profile,
192 const AppListSyncableService::SyncItem* sync_item) {
193 DictionaryPrefUpdate pref_update(profile->GetPrefs(),
194 prefs::kAppListLocalState);
195 base::DictionaryValue* dict_item = nullptr;
196 if (!pref_update->GetDictionaryWithoutPathExpansion(sync_item->item_id,
197 &dict_item)) {
198 dict_item = new base::DictionaryValue();
199 pref_update->SetWithoutPathExpansion(sync_item->item_id, dict_item);
200 }
201
202 dict_item->SetString(kNameKey, sync_item->item_name);
203 dict_item->SetString(kParentIdKey, sync_item->parent_id);
204 dict_item->SetString(kPositionKey,sync_item->item_ordinal.IsValid() ?
205 sync_item->item_ordinal.ToInternalValue() : std::string());
206 dict_item->SetString(kPinPositionKey, sync_item->item_pin_ordinal.IsValid() ?
207 sync_item->item_pin_ordinal.ToInternalValue() : std::string());
208 dict_item->SetInteger(kTypeKey, static_cast<int>(sync_item->item_type));
209 }
210
176 } // namespace 211 } // namespace
177 212
178 // AppListSyncableService::SyncItem 213 // AppListSyncableService::SyncItem
179 214
180 AppListSyncableService::SyncItem::SyncItem( 215 AppListSyncableService::SyncItem::SyncItem(
181 const std::string& id, 216 const std::string& id,
182 sync_pb::AppListSpecifics::AppListItemType type) 217 sync_pb::AppListSpecifics::AppListItemType type)
183 : item_id(id), 218 : item_id(id),
184 item_type(type) { 219 item_type(type) {
185 } 220 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 } 282 }
248 283
249 AppListSyncableService* owner_; 284 AppListSyncableService* owner_;
250 AppListItem* adding_item_; // Unowned pointer to item being added. 285 AppListItem* adding_item_; // Unowned pointer to item being added.
251 286
252 DISALLOW_COPY_AND_ASSIGN(ModelObserver); 287 DISALLOW_COPY_AND_ASSIGN(ModelObserver);
253 }; 288 };
254 289
255 // AppListSyncableService 290 // AppListSyncableService
256 291
292 // static
293 void AppListSyncableService::RegisterProfilePrefs(
294 user_prefs::PrefRegistrySyncable* registry) {
295 registry->RegisterDictionaryPref(prefs::kAppListLocalState);
296 }
297
257 AppListSyncableService::AppListSyncableService( 298 AppListSyncableService::AppListSyncableService(
258 Profile* profile, 299 Profile* profile,
259 extensions::ExtensionSystem* extension_system) 300 extensions::ExtensionSystem* extension_system)
260 : profile_(profile), 301 : profile_(profile),
261 extension_system_(extension_system), 302 extension_system_(extension_system),
262 model_(new AppListModel), 303 model_(new AppListModel),
263 initial_sync_data_processed_(false), 304 initial_sync_data_processed_(false),
264 first_app_list_sync_(true) { 305 first_app_list_sync_(true) {
265 if (!extension_system) { 306 if (!extension_system) {
266 LOG(ERROR) << "AppListSyncableService created with no ExtensionSystem"; 307 LOG(ERROR) << "AppListSyncableService created with no ExtensionSystem";
267 return; 308 return;
268 } 309 }
269 310
270 oem_folder_name_ = 311 oem_folder_name_ =
271 l10n_util::GetStringUTF8(IDS_APP_LIST_OEM_DEFAULT_FOLDER_NAME); 312 l10n_util::GetStringUTF8(IDS_APP_LIST_OEM_DEFAULT_FOLDER_NAME);
313
314 InitFromLocalStorage();
272 } 315 }
273 316
274 AppListSyncableService::~AppListSyncableService() { 317 AppListSyncableService::~AppListSyncableService() {
275 // Remove observers. 318 // Remove observers.
276 model_observer_.reset(); 319 model_observer_.reset();
277 } 320 }
278 321
322 void AppListSyncableService::InitFromLocalStorage() {
323 if (switches::IsFolderUIEnabled())
324 model_->SetFoldersEnabled(true);
stevenjb 2016/10/20 17:04:46 We will need to test this, but in theory with loca
khmel 2016/10/20 18:00:06 Right, we can move it into CTOR and drop settings
325 // Restore initial state from local storage.
326 const base::DictionaryValue* local_items = profile_->GetPrefs()->
327 GetDictionary(prefs::kAppListLocalState);
328 DCHECK(local_items);
329
330 for (base::DictionaryValue::Iterator item(*local_items); !item.IsAtEnd();
331 item.Advance()) {
332 const base::DictionaryValue* dict_item;
333 if (!item.value().GetAsDictionary(&dict_item)) {
334 LOG(ERROR) << "Dictionary not found for " << item.key() + ".";
335 continue;
336 }
337
338 int type;
339 if (!dict_item->GetInteger(kTypeKey, &type)) {
340 LOG(ERROR) << "Item type is not set in local storage for " << item.key()
341 << ".";
342 continue;
343 }
344
345 SyncItem* sync_item = CreateSyncItem(item.key(),
346 static_cast<sync_pb::AppListSpecifics::AppListItemType>(type));
347
348 dict_item->GetString(kNameKey, &sync_item->item_name);
349 dict_item->GetString(kParentIdKey, &sync_item->parent_id);
350 std::string position;
351 std::string pin_position;
352 dict_item->GetString(kPositionKey, &position);
353 dict_item->GetString(kPinPositionKey, &pin_position);
354 if (!position.empty())
355 sync_item->item_ordinal = syncer::StringOrdinal(position);
356 if (!pin_position.empty())
357 sync_item->item_pin_ordinal = syncer::StringOrdinal(pin_position);
358 ProcessNewSyncItem(sync_item);
359 }
360 }
361
279 void AppListSyncableService::BuildModel() { 362 void AppListSyncableService::BuildModel() {
280 // TODO(calamity): make this a DCHECK after a dev channel release. 363 // TODO(calamity): make this a DCHECK after a dev channel release.
281 CHECK(extension_system_->extension_service() && 364 CHECK(extension_system_->extension_service() &&
282 extension_system_->extension_service()->is_ready()); 365 extension_system_->extension_service()->is_ready());
283 AppListControllerDelegate* controller = NULL; 366 AppListControllerDelegate* controller = NULL;
284 AppListService* service = AppListService::Get(); 367 AppListService* service = AppListService::Get();
285 if (service) 368 if (service)
286 controller = service->GetControllerDelegate(); 369 controller = service->GetControllerDelegate();
287 apps_builder_.reset(new ExtensionAppModelBuilder(controller)); 370 apps_builder_.reset(new ExtensionAppModelBuilder(controller));
288 #if defined(OS_CHROMEOS) 371 #if defined(OS_CHROMEOS)
(...skipping 13 matching lines...) Expand all
302 VLOG(1) << this << ": AppListSyncableService: InitializeWithProfile."; 385 VLOG(1) << this << ": AppListSyncableService: InitializeWithProfile.";
303 apps_builder_->InitializeWithProfile(profile_, model_.get()); 386 apps_builder_->InitializeWithProfile(profile_, model_.get());
304 #if defined(OS_CHROMEOS) 387 #if defined(OS_CHROMEOS)
305 if (arc_apps_builder_.get()) 388 if (arc_apps_builder_.get())
306 arc_apps_builder_->InitializeWithProfile(profile_, model_.get()); 389 arc_apps_builder_->InitializeWithProfile(profile_, model_.get());
307 #endif 390 #endif
308 } 391 }
309 392
310 if (app_list::switches::IsDriveAppsInAppListEnabled()) 393 if (app_list::switches::IsDriveAppsInAppListEnabled())
311 drive_app_provider_.reset(new DriveAppProvider(profile_, this)); 394 drive_app_provider_.reset(new DriveAppProvider(profile_, this));
395
396 ResolveFolderPositions();
397
398 // Start observing app list model changes.
399 model_observer_.reset(new ModelObserver(this));
stevenjb 2016/10/20 17:04:46 If we start observing the model here, don't we nee
khmel 2016/10/20 18:00:06 With local storage support yes, we also need to re
stevenjb 2016/10/21 20:03:10 Is there any harm in requiring the model to be bui
khmel 2016/10/24 17:28:39 There is no harm to have model built before pin ac
312 } 400 }
313 401
314 void AppListSyncableService::AddObserverAndStart(Observer* observer) { 402 void AppListSyncableService::AddObserverAndStart(Observer* observer) {
315 observer_list_.AddObserver(observer); 403 observer_list_.AddObserver(observer);
316 SyncStarted(); 404 SyncStarted();
317 } 405 }
318 406
319 void AppListSyncableService::RemoveObserver(Observer* observer) { 407 void AppListSyncableService::RemoveObserver(Observer* observer) {
320 observer_list_.RemoveObserver(observer); 408 observer_list_.RemoveObserver(observer);
321 } 409 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 } 526 }
439 527
440 AppListSyncableService::SyncItem* 528 AppListSyncableService::SyncItem*
441 AppListSyncableService::CreateSyncItemFromAppItem(AppListItem* app_item) { 529 AppListSyncableService::CreateSyncItemFromAppItem(AppListItem* app_item) {
442 sync_pb::AppListSpecifics::AppListItemType type; 530 sync_pb::AppListSpecifics::AppListItemType type;
443 if (!GetAppListItemType(app_item, &type)) 531 if (!GetAppListItemType(app_item, &type))
444 return NULL; 532 return NULL;
445 VLOG(2) << this << " CreateSyncItemFromAppItem:" << app_item->ToDebugString(); 533 VLOG(2) << this << " CreateSyncItemFromAppItem:" << app_item->ToDebugString();
446 SyncItem* sync_item = CreateSyncItem(app_item->id(), type); 534 SyncItem* sync_item = CreateSyncItem(app_item->id(), type);
447 UpdateSyncItemFromAppItem(app_item, sync_item); 535 UpdateSyncItemFromAppItem(app_item, sync_item);
536 UpdateSyncItemInLocalStorage(profile_, sync_item);
448 SendSyncChange(sync_item, SyncChange::ACTION_ADD); 537 SendSyncChange(sync_item, SyncChange::ACTION_ADD);
449 return sync_item; 538 return sync_item;
450 } 539 }
451 540
452 syncer::StringOrdinal AppListSyncableService::GetPinPosition( 541 syncer::StringOrdinal AppListSyncableService::GetPinPosition(
453 const std::string& app_id) { 542 const std::string& app_id) {
454 SyncItem* sync_item = FindSyncItem(app_id); 543 SyncItem* sync_item = FindSyncItem(app_id);
455 if (!sync_item) 544 if (!sync_item)
456 return syncer::StringOrdinal(); 545 return syncer::StringOrdinal();
457 return sync_item->item_pin_ordinal; 546 return sync_item->item_pin_ordinal;
458 } 547 }
459 548
460 void AppListSyncableService::SetPinPosition( 549 void AppListSyncableService::SetPinPosition(
461 const std::string& app_id, 550 const std::string& app_id,
462 const syncer::StringOrdinal& item_pin_ordinal) { 551 const syncer::StringOrdinal& item_pin_ordinal) {
463 SyncItem* sync_item = FindSyncItem(app_id); 552 SyncItem* sync_item = FindSyncItem(app_id);
464 SyncChange::SyncChangeType sync_change_type; 553 SyncChange::SyncChangeType sync_change_type;
465 if (sync_item) { 554 if (sync_item) {
466 sync_change_type = SyncChange::ACTION_UPDATE; 555 sync_change_type = SyncChange::ACTION_UPDATE;
467 } else { 556 } else {
468 sync_item = CreateSyncItem(app_id, sync_pb::AppListSpecifics::TYPE_APP); 557 sync_item = CreateSyncItem(app_id, sync_pb::AppListSpecifics::TYPE_APP);
469 sync_change_type = SyncChange::ACTION_ADD; 558 sync_change_type = SyncChange::ACTION_ADD;
470 } 559 }
471 560
472 sync_item->item_pin_ordinal = item_pin_ordinal; 561 sync_item->item_pin_ordinal = item_pin_ordinal;
562 UpdateSyncItemInLocalStorage(profile_, sync_item);
473 SendSyncChange(sync_item, sync_change_type); 563 SendSyncChange(sync_item, sync_change_type);
474 } 564 }
475 565
476 void AppListSyncableService::AddOrUpdateFromSyncItem(AppListItem* app_item) { 566 void AppListSyncableService::AddOrUpdateFromSyncItem(AppListItem* app_item) {
477 // Do not create a sync item for the OEM folder here, do that in 567 // Do not create a sync item for the OEM folder here, do that in
478 // ResolveFolderPositions once the position has been resolved. 568 // ResolveFolderPositions once the position has been resolved.
479 if (app_item->id() == kOemFolderId) 569 if (app_item->id() == kOemFolderId)
480 return; 570 return;
481 571
482 SyncItem* sync_item = FindSyncItem(app_item->id()); 572 SyncItem* sync_item = FindSyncItem(app_item->id());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 LOG(ERROR) << "DeleteSyncItem: no sync item: " << item_id; 605 LOG(ERROR) << "DeleteSyncItem: no sync item: " << item_id;
516 return; 606 return;
517 } 607 }
518 if (SyncStarted()) { 608 if (SyncStarted()) {
519 VLOG(2) << this << " -> SYNC DELETE: " << sync_item->ToString(); 609 VLOG(2) << this << " -> SYNC DELETE: " << sync_item->ToString();
520 SyncChange sync_change(FROM_HERE, SyncChange::ACTION_DELETE, 610 SyncChange sync_change(FROM_HERE, SyncChange::ACTION_DELETE,
521 GetSyncDataFromSyncItem(sync_item)); 611 GetSyncDataFromSyncItem(sync_item));
522 sync_processor_->ProcessSyncChanges( 612 sync_processor_->ProcessSyncChanges(
523 FROM_HERE, syncer::SyncChangeList(1, sync_change)); 613 FROM_HERE, syncer::SyncChangeList(1, sync_change));
524 } 614 }
615 RemoveSyncItemFromLocalStorage(profile_, item_id);
525 sync_items_.erase(item_id); 616 sync_items_.erase(item_id);
526 } 617 }
527 618
528 void AppListSyncableService::UpdateSyncItem(AppListItem* app_item) { 619 void AppListSyncableService::UpdateSyncItem(AppListItem* app_item) {
529 SyncItem* sync_item = FindSyncItem(app_item->id()); 620 SyncItem* sync_item = FindSyncItem(app_item->id());
530 if (!sync_item) { 621 if (!sync_item) {
531 LOG(ERROR) << "UpdateItem: no sync item: " << app_item->id(); 622 LOG(ERROR) << "UpdateItem: no sync item: " << app_item->id();
532 return; 623 return;
533 } 624 }
534 bool changed = UpdateSyncItemFromAppItem(app_item, sync_item); 625 bool changed = UpdateSyncItemFromAppItem(app_item, sync_item);
535 if (!changed) { 626 if (!changed) {
536 DVLOG(2) << this << " - Update: SYNC NO CHANGE: " << sync_item->ToString(); 627 DVLOG(2) << this << " - Update: SYNC NO CHANGE: " << sync_item->ToString();
537 return; 628 return;
538 } 629 }
630 UpdateSyncItemInLocalStorage(profile_, sync_item);
539 SendSyncChange(sync_item, SyncChange::ACTION_UPDATE); 631 SendSyncChange(sync_item, SyncChange::ACTION_UPDATE);
540 } 632 }
541 633
542 void AppListSyncableService::RemoveItem(const std::string& id) { 634 void AppListSyncableService::RemoveItem(const std::string& id) {
543 RemoveSyncItem(id); 635 RemoveSyncItem(id);
544 model_->DeleteItem(id); 636 model_->DeleteItem(id);
545 PruneEmptySyncFolders(); 637 PruneEmptySyncFolders();
546 } 638 }
547 639
548 void AppListSyncableService::RemoveUninstalledItem(const std::string& id) { 640 void AppListSyncableService::RemoveUninstalledItem(const std::string& id) {
(...skipping 30 matching lines...) Expand all
579 return; 671 return;
580 } 672 }
581 673
582 if (type == sync_pb::AppListSpecifics::TYPE_APP && 674 if (type == sync_pb::AppListSpecifics::TYPE_APP &&
583 AppIsDefault(extension_system_->extension_service(), id)) { 675 AppIsDefault(extension_system_->extension_service(), id)) {
584 // This is a Default app; update the entry to a REMOVE_DEFAULT entry. This 676 // This is a Default app; update the entry to a REMOVE_DEFAULT entry. This
585 // will overwrite any existing entry for the item. 677 // will overwrite any existing entry for the item.
586 VLOG(2) << this << " -> SYNC UPDATE: REMOVE_DEFAULT: " 678 VLOG(2) << this << " -> SYNC UPDATE: REMOVE_DEFAULT: "
587 << sync_item->item_id; 679 << sync_item->item_id;
588 sync_item->item_type = sync_pb::AppListSpecifics::TYPE_REMOVE_DEFAULT_APP; 680 sync_item->item_type = sync_pb::AppListSpecifics::TYPE_REMOVE_DEFAULT_APP;
681 UpdateSyncItemInLocalStorage(profile_, sync_item);
589 SendSyncChange(sync_item, SyncChange::ACTION_UPDATE); 682 SendSyncChange(sync_item, SyncChange::ACTION_UPDATE);
590 return; 683 return;
591 } 684 }
592 685
593 DeleteSyncItem(iter->first); 686 DeleteSyncItem(iter->first);
594 } 687 }
595 688
596 void AppListSyncableService::ResolveFolderPositions() { 689 void AppListSyncableService::ResolveFolderPositions() {
597 if (!app_list::switches::IsFolderUIEnabled()) 690 if (!app_list::switches::IsFolderUIEnabled())
598 return; 691 return;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 const syncer::SyncDataList& initial_sync_data, 735 const syncer::SyncDataList& initial_sync_data,
643 std::unique_ptr<syncer::SyncChangeProcessor> sync_processor, 736 std::unique_ptr<syncer::SyncChangeProcessor> sync_processor,
644 std::unique_ptr<syncer::SyncErrorFactory> error_handler) { 737 std::unique_ptr<syncer::SyncErrorFactory> error_handler) {
645 DCHECK(!sync_processor_.get()); 738 DCHECK(!sync_processor_.get());
646 DCHECK(sync_processor.get()); 739 DCHECK(sync_processor.get());
647 DCHECK(error_handler.get()); 740 DCHECK(error_handler.get());
648 741
649 // Ensure the model is built. 742 // Ensure the model is built.
650 GetModel(); 743 GetModel();
651 744
745 // Reset local state and recreate from sync info.
746 DictionaryPrefUpdate pref_update(profile_->GetPrefs(),
747 prefs::kAppListLocalState);
748 pref_update->Clear();
749
652 sync_processor_ = std::move(sync_processor); 750 sync_processor_ = std::move(sync_processor);
653 sync_error_handler_ = std::move(error_handler); 751 sync_error_handler_ = std::move(error_handler);
654 if (switches::IsFolderUIEnabled()) 752 if (switches::IsFolderUIEnabled())
655 model_->SetFoldersEnabled(true); 753 model_->SetFoldersEnabled(true);
656 754
657 syncer::SyncMergeResult result = syncer::SyncMergeResult(type); 755 syncer::SyncMergeResult result = syncer::SyncMergeResult(type);
658 result.set_num_items_before_association(sync_items_.size()); 756 result.set_num_items_before_association(sync_items_.size());
659 VLOG(1) << this << ": MergeDataAndStartSyncing: " 757 VLOG(1) << this << ": MergeDataAndStartSyncing: "
660 << initial_sync_data.size(); 758 << initial_sync_data.size();
661 759
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 // Send unsynced items. Does not affect |result|. 797 // Send unsynced items. Does not affect |result|.
700 syncer::SyncChangeList change_list; 798 syncer::SyncChangeList change_list;
701 for (std::set<std::string>::iterator iter = unsynced_items.begin(); 799 for (std::set<std::string>::iterator iter = unsynced_items.begin();
702 iter != unsynced_items.end(); ++iter) { 800 iter != unsynced_items.end(); ++iter) {
703 SyncItem* sync_item = FindSyncItem(*iter); 801 SyncItem* sync_item = FindSyncItem(*iter);
704 // Sync can cause an item to change folders, causing an unsynced folder 802 // Sync can cause an item to change folders, causing an unsynced folder
705 // item to be removed. 803 // item to be removed.
706 if (!sync_item) 804 if (!sync_item)
707 continue; 805 continue;
708 VLOG(2) << this << " -> SYNC ADD: " << sync_item->ToString(); 806 VLOG(2) << this << " -> SYNC ADD: " << sync_item->ToString();
807 UpdateSyncItemInLocalStorage(profile_, sync_item);
709 change_list.push_back(SyncChange(FROM_HERE, SyncChange::ACTION_ADD, 808 change_list.push_back(SyncChange(FROM_HERE, SyncChange::ACTION_ADD,
710 GetSyncDataFromSyncItem(sync_item))); 809 GetSyncDataFromSyncItem(sync_item)));
711 } 810 }
712 sync_processor_->ProcessSyncChanges(FROM_HERE, change_list); 811 sync_processor_->ProcessSyncChanges(FROM_HERE, change_list);
713 812
714 // Adding items may have created folders without setting their positions 813 // Adding items may have created folders without setting their positions
715 // since we haven't started observing the item list yet. Resolve those. 814 // since we haven't started observing the item list yet. Resolve those.
716 ResolveFolderPositions(); 815 ResolveFolderPositions();
717 816
718 // Start observing app list model changes. 817 // Start observing app list model changes.
719 model_observer_.reset(new ModelObserver(this)); 818 model_observer_.reset(new ModelObserver(this));
720 819
721 NotifyObserversSyncUpdated(); 820 NotifyObserversSyncUpdated();
722 821
723 return result; 822 return result;
724 } 823 }
725 824
726 void AppListSyncableService::StopSyncing(syncer::ModelType type) { 825 void AppListSyncableService::StopSyncing(syncer::ModelType type) {
727 DCHECK_EQ(type, syncer::APP_LIST); 826 DCHECK_EQ(type, syncer::APP_LIST);
728 827
729 sync_processor_.reset(); 828 sync_processor_.reset();
730 sync_error_handler_.reset(); 829 sync_error_handler_.reset();
731 model_->SetFoldersEnabled(false);
732 } 830 }
733 831
734 syncer::SyncDataList AppListSyncableService::GetAllSyncData( 832 syncer::SyncDataList AppListSyncableService::GetAllSyncData(
735 syncer::ModelType type) const { 833 syncer::ModelType type) const {
736 DCHECK_EQ(syncer::APP_LIST, type); 834 DCHECK_EQ(syncer::APP_LIST, type);
737 835
738 VLOG(1) << this << ": GetAllSyncData: " << sync_items_.size(); 836 VLOG(1) << this << ": GetAllSyncData: " << sync_items_.size();
739 syncer::SyncDataList list; 837 syncer::SyncDataList list;
740 for (auto iter = sync_items_.begin(); iter != sync_items_.end(); ++iter) { 838 for (auto iter = sync_items_.begin(); iter != sync_items_.end(); ++iter) {
741 VLOG(2) << this << " -> SYNC: " << iter->second->ToString(); 839 VLOG(2) << this << " -> SYNC: " << iter->second->ToString();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 if (item_id.empty()) { 888 if (item_id.empty()) {
791 LOG(ERROR) << "AppList item with empty ID"; 889 LOG(ERROR) << "AppList item with empty ID";
792 return false; 890 return false;
793 } 891 }
794 SyncItem* sync_item = FindSyncItem(item_id); 892 SyncItem* sync_item = FindSyncItem(item_id);
795 if (sync_item) { 893 if (sync_item) {
796 // If an item of the same type exists, update it. 894 // If an item of the same type exists, update it.
797 if (sync_item->item_type == specifics.item_type()) { 895 if (sync_item->item_type == specifics.item_type()) {
798 UpdateSyncItemFromSync(specifics, sync_item); 896 UpdateSyncItemFromSync(specifics, sync_item);
799 ProcessExistingSyncItem(sync_item); 897 ProcessExistingSyncItem(sync_item);
898 UpdateSyncItemInLocalStorage(profile_, sync_item);
800 VLOG(2) << this << " <- SYNC UPDATE: " << sync_item->ToString(); 899 VLOG(2) << this << " <- SYNC UPDATE: " << sync_item->ToString();
801 return false; 900 return false;
802 } 901 }
803 // Otherwise, one of the entries should be TYPE_REMOVE_DEFAULT_APP. 902 // Otherwise, one of the entries should be TYPE_REMOVE_DEFAULT_APP.
804 if (sync_item->item_type != 903 if (sync_item->item_type !=
805 sync_pb::AppListSpecifics::TYPE_REMOVE_DEFAULT_APP && 904 sync_pb::AppListSpecifics::TYPE_REMOVE_DEFAULT_APP &&
806 specifics.item_type() != 905 specifics.item_type() !=
807 sync_pb::AppListSpecifics::TYPE_REMOVE_DEFAULT_APP) { 906 sync_pb::AppListSpecifics::TYPE_REMOVE_DEFAULT_APP) {
808 LOG(ERROR) << "Synced item type: " << specifics.item_type() 907 LOG(ERROR) << "Synced item type: " << specifics.item_type()
809 << " != existing sync item type: " << sync_item->item_type 908 << " != existing sync item type: " << sync_item->item_type
810 << " Deleting item from model!"; 909 << " Deleting item from model!";
811 model_->DeleteItem(item_id); 910 model_->DeleteItem(item_id);
812 } 911 }
813 VLOG(2) << this << " - ProcessSyncItem: Delete existing entry: " 912 VLOG(2) << this << " - ProcessSyncItem: Delete existing entry: "
814 << sync_item->ToString(); 913 << sync_item->ToString();
815 sync_items_.erase(item_id); 914 sync_items_.erase(item_id);
816 } 915 }
817 916
818 sync_item = CreateSyncItem(item_id, specifics.item_type()); 917 sync_item = CreateSyncItem(item_id, specifics.item_type());
819 UpdateSyncItemFromSync(specifics, sync_item); 918 UpdateSyncItemFromSync(specifics, sync_item);
820 ProcessNewSyncItem(sync_item); 919 ProcessNewSyncItem(sync_item);
920 UpdateSyncItemInLocalStorage(profile_, sync_item);
821 VLOG(2) << this << " <- SYNC ADD: " << sync_item->ToString(); 921 VLOG(2) << this << " <- SYNC ADD: " << sync_item->ToString();
822 return true; 922 return true;
823 } 923 }
824 924
825 void AppListSyncableService::ProcessNewSyncItem(SyncItem* sync_item) { 925 void AppListSyncableService::ProcessNewSyncItem(SyncItem* sync_item) {
826 VLOG(2) << "ProcessNewSyncItem: " << sync_item->ToString(); 926 VLOG(2) << "ProcessNewSyncItem: " << sync_item->ToString();
827 switch (sync_item->item_type) { 927 switch (sync_item->item_type) {
828 case sync_pb::AppListSpecifics::TYPE_APP: { 928 case sync_pb::AppListSpecifics::TYPE_APP: {
829 // New apps are added through ExtensionAppModelBuilder. 929 // New apps are added through ExtensionAppModelBuilder.
830 // TODO(stevenjb): Determine how to handle app items in sync that 930 // TODO(stevenjb): Determine how to handle app items in sync that
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 LOG(ERROR) << "Delete AppList item with empty ID"; 1062 LOG(ERROR) << "Delete AppList item with empty ID";
963 return; 1063 return;
964 } 1064 }
965 VLOG(2) << this << ": DeleteSyncItemSpecifics: " << item_id.substr(0, 8); 1065 VLOG(2) << this << ": DeleteSyncItemSpecifics: " << item_id.substr(0, 8);
966 auto iter = sync_items_.find(item_id); 1066 auto iter = sync_items_.find(item_id);
967 if (iter == sync_items_.end()) 1067 if (iter == sync_items_.end())
968 return; 1068 return;
969 sync_pb::AppListSpecifics::AppListItemType item_type = 1069 sync_pb::AppListSpecifics::AppListItemType item_type =
970 iter->second->item_type; 1070 iter->second->item_type;
971 VLOG(2) << this << " <- SYNC DELETE: " << iter->second->ToString(); 1071 VLOG(2) << this << " <- SYNC DELETE: " << iter->second->ToString();
1072 RemoveSyncItemFromLocalStorage(profile_, item_id);
972 sync_items_.erase(iter); 1073 sync_items_.erase(iter);
1074
973 // Only delete apps from the model. Folders will be deleted when all 1075 // Only delete apps from the model. Folders will be deleted when all
974 // children have been deleted. 1076 // children have been deleted.
975 if (item_type == sync_pb::AppListSpecifics::TYPE_APP) { 1077 if (item_type == sync_pb::AppListSpecifics::TYPE_APP) {
976 model_->DeleteItem(item_id); 1078 model_->DeleteItem(item_id);
977 } else if (item_type == sync_pb::AppListSpecifics::TYPE_REMOVE_DEFAULT_APP) { 1079 } else if (item_type == sync_pb::AppListSpecifics::TYPE_REMOVE_DEFAULT_APP) {
978 if (IsDriveAppSyncId(item_id) && drive_app_provider_) { 1080 if (IsDriveAppSyncId(item_id) && drive_app_provider_) {
979 drive_app_provider_->RemoveUninstalledDriveAppFromSync( 1081 drive_app_provider_->RemoveUninstalledDriveAppFromSync(
980 GetDriveAppIdFromSyncId(item_id)); 1082 GetDriveAppIdFromSyncId(item_id));
981 } 1083 }
982 } 1084 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 res += " { " + item_name + " }"; 1171 res += " { " + item_name + " }";
1070 res += " [" + item_ordinal.ToDebugString() + "]"; 1172 res += " [" + item_ordinal.ToDebugString() + "]";
1071 if (!parent_id.empty()) 1173 if (!parent_id.empty())
1072 res += " <" + parent_id.substr(0, 8) + ">"; 1174 res += " <" + parent_id.substr(0, 8) + ">";
1073 res += " [" + item_pin_ordinal.ToDebugString() + "]"; 1175 res += " [" + item_pin_ordinal.ToDebugString() + "]";
1074 } 1176 }
1075 return res; 1177 return res;
1076 } 1178 }
1077 1179
1078 } // namespace app_list 1180 } // namespace app_list
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698