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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/sync/test/integration/sync_app_list_helper.h" 6 7 #include "base/strings/stringprintf.h" 8 #include "chrome/browser/profiles/profile.h" 9 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h" 10 #include "chrome/browser/sync/test/integration/sync_test.h" 11 #include "chrome/browser/ui/app_list/app_list_syncable_service.h" 12 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" 13 #include "chrome/common/extensions/sync_helper.h" 14 #include "extensions/browser/app_sorting.h" 15 #include "extensions/browser/extension_prefs.h" 16 #include "extensions/browser/extension_system.h" 17 #include "ui/app_list/app_list_folder_item.h" 18 #include "ui/app_list/app_list_item.h" 19 #include "ui/app_list/app_list_model.h" 20 21 using app_list::AppListFolderItem; 22 using app_list::AppListItem; 23 using app_list::AppListItemList; 24 using app_list::AppListSyncableService; 25 using app_list::AppListSyncableServiceFactory; 26 27 SyncAppListHelper* SyncAppListHelper::GetInstance() { 28 SyncAppListHelper* instance = Singleton<SyncAppListHelper>::get(); 29 instance->SetupIfNecessary(sync_datatype_helper::test()); 30 return instance; 31 } 32 33 SyncAppListHelper::SyncAppListHelper() : test_(NULL), setup_completed_(false) {} 34 35 SyncAppListHelper::~SyncAppListHelper() {} 36 37 void SyncAppListHelper::SetupIfNecessary(SyncTest* test) { 38 if (setup_completed_) { 39 DCHECK_EQ(test, test_); 40 return; 41 } 42 test_ = test; 43 44 for (int i = 0; i < test->num_clients(); ++i) { 45 extensions::ExtensionSystem::Get(test_->GetProfile(i)) 46 ->InitForRegularProfile(true); 47 } 48 extensions::ExtensionSystem::Get(test_->verifier()) 49 ->InitForRegularProfile(true); 50 51 setup_completed_ = true; 52 } 53 54 bool SyncAppListHelper::AppListMatchesVerifier(Profile* profile) { 55 AppListSyncableService* service = 56 AppListSyncableServiceFactory::GetForProfile(profile); 57 AppListSyncableService* verifier = 58 AppListSyncableServiceFactory::GetForProfile(test_->verifier()); 59 // Note: sync item entries may not exist in verifier, but item lists should 60 // match. 61 if (service->model()->top_level_item_list()->item_count() != 62 verifier->model()->top_level_item_list()->item_count()) { 63 LOG(ERROR) << "Model item count: " 64 << service->model()->top_level_item_list()->item_count() 65 << " != " 66 << verifier->model()->top_level_item_list()->item_count(); 67 return false; 68 } 69 bool res = true; 70 for (size_t i = 0; i < service->model()->top_level_item_list()->item_count(); 71 ++i) { 72 AppListItem* item1 = service->model()->top_level_item_list()->item_at(i); 73 AppListItem* item2 = verifier->model()->top_level_item_list()->item_at(i); 74 if (item1->CompareForTest(item2)) 75 continue; 76 77 LOG(ERROR) << "Item(" << i << "): " << item1->ToDebugString() 78 << " != " << item2->ToDebugString(); 79 size_t index2; 80 if (!verifier->model()->top_level_item_list()->FindItemIndex(item1->id(), 81 &index2)) { 82 LOG(ERROR) << " Item(" << i << "): " << item1->ToDebugString() 83 << " Not in verifier."; 84 } else { 85 LOG(ERROR) << " Item(" << i << "): " << item1->ToDebugString() 86 << " Has different verifier index: " << index2; 87 item2 = verifier->model()->top_level_item_list()->item_at(index2); 88 LOG(ERROR) << " Verifier Item(" << index2 89 << "): " << item2->ToDebugString(); 90 } 91 res = false; 92 } 93 return res; 94 } 95 96 bool SyncAppListHelper::AllProfilesHaveSameAppListAsVerifier() { 97 bool res = true; 98 for (int i = 0; i < test_->num_clients(); ++i) { 99 if (!AppListMatchesVerifier(test_->GetProfile(i))) { 100 LOG(ERROR) << "Profile " << i 101 << " doesn't have the same app list as the verifier profile."; 102 res = false; 103 } 104 } 105 if (!res) { 106 Profile* verifier = test_->verifier(); 107 VLOG(1) << "Verifier: " 108 << AppListSyncableServiceFactory::GetForProfile(verifier); 109 PrintAppList(test_->verifier()); 110 for (int i = 0; i < test_->num_clients(); ++i) { 111 Profile* profile = test_->GetProfile(i); 112 VLOG(1) << "Profile: " << i << ": " 113 << AppListSyncableServiceFactory::GetForProfile(profile); 114 PrintAppList(profile); 115 } 116 } 117 return res; 118 } 119 120 void SyncAppListHelper::MoveApp(Profile* profile, size_t from, size_t to) { 121 AppListSyncableService* service = 122 AppListSyncableServiceFactory::GetForProfile(profile); 123 service->model()->top_level_item_list()->MoveItem(from, to); 124 } 125 126 void SyncAppListHelper::MoveAppToFolder(Profile* profile, 127 size_t index, 128 const std::string& folder_id) { 129 AppListSyncableService* service = 130 AppListSyncableServiceFactory::GetForProfile(profile); 131 service->model()->MoveItemToFolder( 132 service->model()->top_level_item_list()->item_at(index), folder_id); 133 } 134 135 void SyncAppListHelper::MoveAppFromFolder(Profile* profile, 136 size_t index_in_folder, 137 const std::string& folder_id) { 138 AppListSyncableService* service = 139 AppListSyncableServiceFactory::GetForProfile(profile); 140 AppListFolderItem* folder = service->model()->FindFolderItem(folder_id); 141 if (!folder) { 142 LOG(ERROR) << "Folder not found: " << folder_id; 143 return; 144 } 145 service->model()->MoveItemToFolder( 146 folder->item_list()->item_at(index_in_folder), ""); 147 } 148 149 void SyncAppListHelper::CopyOrdinalsToVerifier(Profile* profile, 150 const std::string& id) { 151 AppListSyncableService* service = 152 AppListSyncableServiceFactory::GetForProfile(profile); 153 AppListSyncableService* verifier = 154 AppListSyncableServiceFactory::GetForProfile(test_->verifier()); 155 verifier->model()->top_level_item_list()->SetItemPosition( 156 verifier->model()->FindItem(id), 157 service->model()->FindItem(id)->position()); 158 } 159 160 void SyncAppListHelper::PrintAppList(Profile* profile) { 161 AppListSyncableService* service = 162 AppListSyncableServiceFactory::GetForProfile(profile); 163 for (size_t i = 0; i < service->model()->top_level_item_list()->item_count(); 164 ++i) { 165 AppListItem* item = service->model()->top_level_item_list()->item_at(i); 166 std::string label = base::StringPrintf("Item(%d): ", static_cast<int>(i)); 167 PrintItem(profile, item, label); 168 } 169 } 170 171 void SyncAppListHelper::PrintItem(Profile* profile, 172 AppListItem* item, 173 const std::string& label) { 174 extensions::AppSorting* s = 175 extensions::ExtensionPrefs::Get(profile)->app_sorting(); 176 std::string id = item->id(); 177 if (item->GetItemType() == AppListFolderItem::kItemType) { 178 VLOG(1) << label << item->ToDebugString(); 179 AppListFolderItem* folder = static_cast<AppListFolderItem*>(item); 180 for (size_t i = 0; i < folder->item_list()->item_count(); ++i) { 181 AppListItem* child = folder->item_list()->item_at(i); 182 std::string child_label = 183 base::StringPrintf(" Folder Item(%d): ", static_cast<int>(i)); 184 PrintItem(profile, child, child_label); 185 } 186 return; 187 } 188 VLOG(1) << label << item->ToDebugString() 189 << " Page: " << s->GetPageOrdinal(id).ToDebugString().substr(0, 8) 190 << " Item: " 191 << s->GetAppLaunchOrdinal(id).ToDebugString().substr(0, 8); 192 } 193