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