sync_app_list_helper.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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
21using app_list::AppListFolderItem;
22using app_list::AppListItem;
23using app_list::AppListItemList;
24using app_list::AppListSyncableService;
25using app_list::AppListSyncableServiceFactory;
26
27SyncAppListHelper* SyncAppListHelper::GetInstance() {
28  SyncAppListHelper* instance = Singleton<SyncAppListHelper>::get();
29  instance->SetupIfNecessary(sync_datatype_helper::test());
30  return instance;
31}
32
33SyncAppListHelper::SyncAppListHelper() : test_(NULL), setup_completed_(false) {}
34
35SyncAppListHelper::~SyncAppListHelper() {}
36
37void 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
54bool 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
96bool 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
120void 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
126void 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
135void 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
149void 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
160void 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
171void 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