X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fchrome%2Fbrowser%2Fui%2Fapp_list%2Fapp_list_syncable_service.cc;h=f97c94fc63f805c91e61ed89765d0360c98bcc98;hb=ff3e2503a20db9193d323c1d19c38c68004dec4a;hp=c7d96bdffdf3c9442dbf6e302a9ada3bc8981f56;hpb=7338fba38ba696536d1cc9d389afd716a6ab2fe6;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/chrome/browser/ui/app_list/app_list_syncable_service.cc b/src/chrome/browser/ui/app_list/app_list_syncable_service.cc index c7d96bd..f97c94f 100644 --- a/src/chrome/browser/ui/app_list/app_list_syncable_service.cc +++ b/src/chrome/browser/ui/app_list/app_list_syncable_service.cc @@ -7,7 +7,6 @@ #include "base/command_line.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/extensions/extension_system.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/app_list_service.h" #include "chrome/browser/ui/app_list/extension_app_item.h" @@ -16,6 +15,7 @@ #include "chrome/common/chrome_switches.h" #include "content/public/browser/notification_source.h" #include "extensions/browser/extension_prefs.h" +#include "extensions/browser/extension_system.h" #include "sync/api/sync_change_processor.h" #include "sync/api/sync_data.h" #include "sync/api/sync_merge_result.h" @@ -23,6 +23,8 @@ #include "ui/app_list/app_list_folder_item.h" #include "ui/app_list/app_list_item.h" #include "ui/app_list/app_list_model.h" +#include "ui/app_list/app_list_model_observer.h" +#include "ui/app_list/app_list_switches.h" using syncer::SyncChange; @@ -32,7 +34,7 @@ namespace { bool SyncAppListEnabled() { return CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableSyncAppList); + ::switches::kEnableSyncAppList); } void UpdateSyncItemFromSync(const sync_pb::AppListSpecifics& specifics, @@ -51,6 +53,11 @@ bool UpdateSyncItemFromAppItem(const AppListItem* app_item, AppListSyncableService::SyncItem* sync_item) { DCHECK_EQ(sync_item->item_id, app_item->id()); bool changed = false; + if (app_list::switches::IsFolderUIEnabled() && + sync_item->parent_id != app_item->folder_id()) { + sync_item->parent_id = app_item->folder_id(); + changed = true; + } if (sync_item->item_name != app_item->title()) { sync_item->item_name = app_item->title(); changed = true; @@ -60,7 +67,7 @@ bool UpdateSyncItemFromAppItem(const AppListItem* app_item, sync_item->item_ordinal = app_item->position(); changed = true; } - // TODO(stevenjb): Set parent_id and page_ordinal. + // TODO(stevenjb): Set page_ordinal. return changed; } @@ -123,38 +130,41 @@ AppListSyncableService::SyncItem::SyncItem( AppListSyncableService::SyncItem::~SyncItem() { } -// AppListSyncableService::ItemListObserver +// AppListSyncableService::ModelObserver -class AppListSyncableService::ItemListObserver - : public AppListItemListObserver { +class AppListSyncableService::ModelObserver : public AppListModelObserver { public: - explicit ItemListObserver(AppListSyncableService* owner) : owner_(owner) { - owner_->model()->item_list()->AddObserver(this); + explicit ModelObserver(AppListSyncableService* owner) + : owner_(owner) { + DVLOG(2) << owner_ << ": ModelObserver Added"; + owner_->model()->AddObserver(this); } - virtual ~ItemListObserver() { - owner_->model()->item_list()->RemoveObserver(this); + virtual ~ModelObserver() { + owner_->model()->RemoveObserver(this); + DVLOG(2) << owner_ << ": ModelObserver Removed"; } private: - // AppListItemListObserver - virtual void OnListItemAdded(size_t index, AppListItem* item) OVERRIDE { + // AppListModelObserver + virtual void OnAppListItemAdded(AppListItem* item) OVERRIDE { + DVLOG(2) << owner_ << " OnAppListItemAdded: " << item->ToDebugString(); owner_->AddOrUpdateFromSyncItem(item); } - virtual void OnListItemRemoved(size_t index, AppListItem* item) OVERRIDE { + virtual void OnAppListItemWillBeDeleted(AppListItem* item) OVERRIDE { + DVLOG(2) << owner_ << " OnAppListItemDeleted: " << item->ToDebugString(); owner_->RemoveSyncItem(item->id()); } - virtual void OnListItemMoved(size_t from_index, - size_t to_index, - AppListItem* item) OVERRIDE { + virtual void OnAppListItemUpdated(AppListItem* item) OVERRIDE { + DVLOG(2) << owner_ << " OnAppListItemUpdated: " << item->ToDebugString(); owner_->UpdateSyncItem(item); } AppListSyncableService* owner_; - DISALLOW_COPY_AND_ASSIGN(ItemListObserver); + DISALLOW_COPY_AND_ASSIGN(ModelObserver); }; // AppListSyncableService @@ -165,15 +175,16 @@ AppListSyncableService::AppListSyncableService( : profile_(profile), extension_system_(extension_system), model_(new AppListModel) { - if (!extension_system || !extension_system->extension_service()) { - LOG(WARNING) << "AppListSyncableService created with no ExtensionService"; + if (!extension_system) { + LOG(ERROR) << "AppListSyncableService created with no ExtensionSystem"; return; } - if (SyncAppListEnabled()) - item_list_observer_.reset(new ItemListObserver(this)); - - if (extension_system->extension_service()->is_ready()) { + // Note: model_observer_ is constructed after the initial sync changes are + // received in MergeDataAndStartSyncing(). Changes to the model before that + // will be synced after the initial sync occurs. + if (extension_system->extension_service() && + extension_system->extension_service()->is_ready()) { BuildModel(); return; } @@ -185,7 +196,7 @@ AppListSyncableService::AppListSyncableService( AppListSyncableService::~AppListSyncableService() { // Remove observers. - item_list_observer_.reset(); + model_observer_.reset(); STLDeleteContainerPairSecondPointers(sync_items_.begin(), sync_items_.end()); } @@ -231,21 +242,17 @@ AppListSyncableService::GetSyncItem(const std::string& id) const { return NULL; } -void AppListSyncableService::AddItem(AppListItem* app_item) { - SyncItem* sync_item = AddOrUpdateSyncItem(app_item); +void AppListSyncableService::AddItem(scoped_ptr app_item) { + SyncItem* sync_item = FindOrAddSyncItem(app_item.get()); if (!sync_item) return; // Item is not valid. DVLOG(1) << this << ": AddItem: " << sync_item->ToString(); - - // Add the item to the model if necessary. - if (!model_->item_list()->FindItem(app_item->id())) - model_->item_list()->AddItem(app_item); - else - model_->item_list()->SetItemPosition(app_item, sync_item->item_ordinal); + std::string folder_id = sync_item->parent_id; + model_->AddItemToFolder(app_item.Pass(), folder_id); } -AppListSyncableService::SyncItem* AppListSyncableService::AddOrUpdateSyncItem( +AppListSyncableService::SyncItem* AppListSyncableService::FindOrAddSyncItem( AppListItem* app_item) { const std::string& item_id = app_item->id(); if (item_id.empty()) { @@ -254,11 +261,10 @@ AppListSyncableService::SyncItem* AppListSyncableService::AddOrUpdateSyncItem( } SyncItem* sync_item = FindSyncItem(item_id); if (sync_item) { - // If there is an existing, non-REMOVE_DEFAULT entry, update it. + // If there is an existing, non-REMOVE_DEFAULT entry, return it. if (sync_item->item_type != sync_pb::AppListSpecifics::TYPE_REMOVE_DEFAULT_APP) { DVLOG(2) << this << ": AddItem already exists: " << sync_item->ToString(); - UpdateSyncItem(app_item); return sync_item; } @@ -343,7 +349,8 @@ void AppListSyncableService::UpdateSyncItem(AppListItem* app_item) { void AppListSyncableService::RemoveItem(const std::string& id) { RemoveSyncItem(id); - model_->item_list()->DeleteItem(id); + model_->DeleteItem(id); + PruneEmptySyncFolders(); } void AppListSyncableService::RemoveSyncItem(const std::string& id) { @@ -377,6 +384,41 @@ void AppListSyncableService::RemoveSyncItem(const std::string& id) { DeleteSyncItem(sync_item); } +void AppListSyncableService::ResolveFolderPositions() { + if (!app_list::switches::IsFolderUIEnabled()) + return; + + for (SyncItemMap::iterator iter = sync_items_.begin(); + iter != sync_items_.end(); ++iter) { + SyncItem* sync_item = iter->second; + if (sync_item->item_type != sync_pb::AppListSpecifics::TYPE_FOLDER) + continue; + AppListItem* app_item = model_->FindItem(sync_item->item_id); + if (!app_item) + continue; + UpdateAppItemFromSyncItem(sync_item, app_item); + } +} + +void AppListSyncableService::PruneEmptySyncFolders() { + if (!app_list::switches::IsFolderUIEnabled()) + return; + + std::set parent_ids; + for (SyncItemMap::iterator iter = sync_items_.begin(); + iter != sync_items_.end(); ++iter) { + parent_ids.insert(iter->second->parent_id); + } + for (SyncItemMap::iterator iter = sync_items_.begin(); + iter != sync_items_.end(); ) { + SyncItem* sync_item = (iter++)->second; + if (sync_item->item_type != sync_pb::AppListSpecifics::TYPE_FOLDER) + continue; + if (!ContainsKey(parent_ids, sync_item->item_id)) + DeleteSyncItem(sync_item); + } +} + // AppListSyncableService syncer::SyncableService syncer::SyncMergeResult AppListSyncableService::MergeDataAndStartSyncing( @@ -435,6 +477,13 @@ syncer::SyncMergeResult AppListSyncableService::MergeDataAndStartSyncing( } sync_processor_->ProcessSyncChanges(FROM_HERE, change_list); + // Adding items may have created folders without setting their positions + // since we haven't started observing the item list yet. Resolve those. + ResolveFolderPositions(); + + // Start observing app list model changes. + model_observer_.reset(new ModelObserver(this)); + return result; } @@ -469,6 +518,9 @@ syncer::SyncError AppListSyncableService::ProcessSyncChanges( syncer::APP_LIST); } + // Don't observe the model while processing incoming sync changes. + model_observer_.reset(); + DVLOG(1) << this << ": ProcessSyncChanges: " << change_list.size(); for (syncer::SyncChangeList::const_iterator iter = change_list.begin(); iter != change_list.end(); ++iter) { @@ -485,6 +537,10 @@ syncer::SyncError AppListSyncableService::ProcessSyncChanges( LOG(ERROR) << "Invalid sync change"; } } + + // Continue observing app list model changes. + model_observer_.reset(new ModelObserver(this)); + return syncer::SyncError(); } @@ -514,7 +570,7 @@ bool AppListSyncableService::ProcessSyncItemSpecifics( LOG(ERROR) << "Synced item type: " << specifics.item_type() << " != existing sync item type: " << sync_item->item_type << " Deleting item from model!"; - model_->item_list()->DeleteItem(item_id); + model_->DeleteItem(item_id); } DVLOG(2) << this << " - ProcessSyncItem: Delete existing entry: " << sync_item->ToString(); @@ -545,8 +601,10 @@ void AppListSyncableService::ProcessNewSyncItem(SyncItem* sync_item) { return; } case sync_pb::AppListSpecifics::TYPE_FOLDER: { - // TODO(stevenjb): Implement - LOG(WARNING) << "TYPE_FOLDER not supported"; + AppListItem* app_item = model_->FindItem(sync_item->item_id); + if (!app_item) + return; // Don't create new folders here, the model will do that. + UpdateAppItemFromSyncItem(sync_item, app_item); return; } case sync_pb::AppListSpecifics::TYPE_URL: { @@ -555,7 +613,7 @@ void AppListSyncableService::ProcessNewSyncItem(SyncItem* sync_item) { return; } } - NOTREACHED() << "Unrecoginized sync item type: " << sync_item->ToString(); + NOTREACHED() << "Unrecognized sync item type: " << sync_item->ToString(); } void AppListSyncableService::ProcessExistingSyncItem(SyncItem* sync_item) { @@ -564,11 +622,18 @@ void AppListSyncableService::ProcessExistingSyncItem(SyncItem* sync_item) { return; } DVLOG(2) << "ProcessExistingSyncItem: " << sync_item->ToString(); - AppListItem* app_item = model_->item_list()->FindItem(sync_item->item_id); + AppListItem* app_item = model_->FindItem(sync_item->item_id); + DVLOG(2) << " AppItem: " << app_item->ToDebugString(); if (!app_item) { LOG(ERROR) << "Item not found in model: " << sync_item->ToString(); return; } + // This is the only place where sync can cause an item to change folders. + if (app_list::switches::IsFolderUIEnabled() && + app_item->folder_id() != sync_item->parent_id) { + DVLOG(2) << " Moving Item To Folder: " << sync_item->parent_id; + model_->MoveItemToFolder(app_item, sync_item->parent_id); + } UpdateAppItemFromSyncItem(sync_item, app_item); } @@ -576,7 +641,7 @@ void AppListSyncableService::UpdateAppItemFromSyncItem( const AppListSyncableService::SyncItem* sync_item, AppListItem* app_item) { if (!app_item->position().Equals(sync_item->item_ordinal)) - model_->item_list()->SetItemPosition(app_item, sync_item->item_ordinal); + model_->SetItemPosition(app_item, sync_item->item_ordinal); } bool AppListSyncableService::SyncStarted() { @@ -642,8 +707,10 @@ void AppListSyncableService::DeleteSyncItemSpecifics( DVLOG(2) << this << " <- SYNC DELETE: " << iter->second->ToString(); delete iter->second; sync_items_.erase(iter); - if (item_type != sync_pb::AppListSpecifics::TYPE_REMOVE_DEFAULT_APP) - model_->item_list()->DeleteItem(item_id); + // Only delete apps from the model. Folders will be deleted when all + // children have been deleted. + if (item_type == sync_pb::AppListSpecifics::TYPE_APP) + model_->DeleteItem(item_id); } std::string AppListSyncableService::SyncItem::ToString() const { @@ -653,6 +720,8 @@ std::string AppListSyncableService::SyncItem::ToString() const { } else { res += " { " + item_name + " }"; res += " [" + item_ordinal.ToDebugString() + "]"; + if (!parent_id.empty()) + res += " <" + parent_id.substr(0, 8) + ">"; } return res; }