OLD | NEW |
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" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" | 47 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" |
48 #include "chrome/browser/ui/app_list/arc/arc_app_model_builder.h" | 48 #include "chrome/browser/ui/app_list/arc/arc_app_model_builder.h" |
49 #endif | 49 #endif |
50 | 50 |
51 using syncer::SyncChange; | 51 using syncer::SyncChange; |
52 | 52 |
53 namespace app_list { | 53 namespace app_list { |
54 | 54 |
55 namespace { | 55 namespace { |
56 | 56 |
57 const char kOemFolderId[] = "ddb1da55-d478-4243-8642-56d3041f0263"; | |
58 | |
59 const char kNameKey[] = "name"; | 57 const char kNameKey[] = "name"; |
60 const char kParentIdKey[] = "parent_id"; | 58 const char kParentIdKey[] = "parent_id"; |
61 const char kPositionKey[] = "position"; | 59 const char kPositionKey[] = "position"; |
62 const char kPinPositionKey[] = "pin_position"; | 60 const char kPinPositionKey[] = "pin_position"; |
63 const char kTypeKey[] = "type"; | 61 const char kTypeKey[] = "type"; |
64 | 62 |
65 // Prefix for a sync id of a Drive app. Drive app ids are in a different | 63 // Prefix for a sync id of a Drive app. Drive app ids are in a different |
66 // format and have to be used because a Drive app could have only an URL | 64 // format and have to be used because a Drive app could have only an URL |
67 // without a matching Chrome app. To differentiate the Drive app id from | 65 // without a matching Chrome app. To differentiate the Drive app id from |
68 // Chrome app ids, this prefix will be added to create the sync item id | 66 // Chrome app ids, this prefix will be added to create the sync item id |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 | 280 |
283 AppListSyncableService* owner_; | 281 AppListSyncableService* owner_; |
284 AppListItem* adding_item_; // Unowned pointer to item being added. | 282 AppListItem* adding_item_; // Unowned pointer to item being added. |
285 | 283 |
286 DISALLOW_COPY_AND_ASSIGN(ModelObserver); | 284 DISALLOW_COPY_AND_ASSIGN(ModelObserver); |
287 }; | 285 }; |
288 | 286 |
289 // AppListSyncableService | 287 // AppListSyncableService |
290 | 288 |
291 // static | 289 // static |
| 290 const char AppListSyncableService::kOemFolderId[] = |
| 291 "ddb1da55-d478-4243-8642-56d3041f0263"; |
| 292 |
| 293 // static |
292 void AppListSyncableService::RegisterProfilePrefs( | 294 void AppListSyncableService::RegisterProfilePrefs( |
293 user_prefs::PrefRegistrySyncable* registry) { | 295 user_prefs::PrefRegistrySyncable* registry) { |
294 registry->RegisterDictionaryPref(prefs::kAppListLocalState); | 296 registry->RegisterDictionaryPref(prefs::kAppListLocalState); |
295 } | 297 } |
296 | 298 |
297 AppListSyncableService::AppListSyncableService( | 299 AppListSyncableService::AppListSyncableService( |
298 Profile* profile, | 300 Profile* profile, |
299 extensions::ExtensionSystem* extension_system) | 301 extensions::ExtensionSystem* extension_system) |
300 : profile_(profile), | 302 : profile_(profile), |
301 extension_system_(extension_system), | 303 extension_system_(extension_system), |
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1136 GetDriveAppIdFromSyncId(item_id)); | 1138 GetDriveAppIdFromSyncId(item_id)); |
1137 } | 1139 } |
1138 } | 1140 } |
1139 } | 1141 } |
1140 | 1142 |
1141 std::string AppListSyncableService::FindOrCreateOemFolder() { | 1143 std::string AppListSyncableService::FindOrCreateOemFolder() { |
1142 AppListFolderItem* oem_folder = model_->FindFolderItem(kOemFolderId); | 1144 AppListFolderItem* oem_folder = model_->FindFolderItem(kOemFolderId); |
1143 if (!oem_folder) { | 1145 if (!oem_folder) { |
1144 std::unique_ptr<AppListFolderItem> new_folder(new AppListFolderItem( | 1146 std::unique_ptr<AppListFolderItem> new_folder(new AppListFolderItem( |
1145 kOemFolderId, AppListFolderItem::FOLDER_TYPE_OEM)); | 1147 kOemFolderId, AppListFolderItem::FOLDER_TYPE_OEM)); |
1146 oem_folder = | |
1147 static_cast<AppListFolderItem*>(model_->AddItem(std::move(new_folder))); | |
1148 SyncItem* oem_sync_item = FindSyncItem(kOemFolderId); | 1148 SyncItem* oem_sync_item = FindSyncItem(kOemFolderId); |
| 1149 syncer::StringOrdinal oem_position; |
1149 if (oem_sync_item) { | 1150 if (oem_sync_item) { |
| 1151 DCHECK(oem_sync_item->item_ordinal.IsValid()); |
1150 VLOG(1) << "Creating OEM folder from existing sync item: " | 1152 VLOG(1) << "Creating OEM folder from existing sync item: " |
1151 << oem_sync_item->item_ordinal.ToDebugString(); | 1153 << oem_sync_item->item_ordinal.ToDebugString(); |
1152 model_->SetItemPosition(oem_folder, oem_sync_item->item_ordinal); | 1154 oem_position = oem_sync_item->item_ordinal; |
1153 } else { | 1155 } else { |
1154 model_->SetItemPosition(oem_folder, GetOemFolderPos()); | 1156 oem_position = GetOemFolderPos(); |
1155 // Do not create a sync item for the OEM folder here, do it in | 1157 // Do not create a sync item for the OEM folder here, do it in |
1156 // ResolveFolderPositions() when the item position is finalized. | 1158 // ResolveFolderPositions() when the item position is finalized. |
1157 } | 1159 } |
| 1160 oem_folder = |
| 1161 static_cast<AppListFolderItem*>(model_->AddItem(std::move(new_folder))); |
| 1162 model_->SetItemPosition(oem_folder, oem_position); |
1158 } | 1163 } |
1159 model_->SetItemName(oem_folder, oem_folder_name_); | 1164 model_->SetItemName(oem_folder, oem_folder_name_); |
1160 return oem_folder->id(); | 1165 return oem_folder->id(); |
1161 } | 1166 } |
1162 | 1167 |
1163 syncer::StringOrdinal AppListSyncableService::GetOemFolderPos() { | 1168 syncer::StringOrdinal AppListSyncableService::GetOemFolderPos() { |
1164 VLOG(1) << "GetOemFolderPos: " << first_app_list_sync_; | 1169 VLOG(1) << "GetOemFolderPos: " << first_app_list_sync_; |
1165 if (!first_app_list_sync_) { | 1170 if (!first_app_list_sync_) { |
1166 VLOG(1) << "Sync items exist, placing OEM folder at end."; | 1171 VLOG(1) << "Sync items exist, placing OEM folder at end."; |
1167 syncer::StringOrdinal last; | 1172 syncer::StringOrdinal last; |
1168 for (const auto& sync_pair : sync_items_) { | 1173 for (const auto& sync_pair : sync_items_) { |
1169 SyncItem* sync_item = sync_pair.second.get(); | 1174 SyncItem* sync_item = sync_pair.second.get(); |
1170 if (sync_item->item_ordinal.IsValid() && | 1175 if (sync_item->item_ordinal.IsValid() && |
1171 (!last.IsValid() || sync_item->item_ordinal.GreaterThan(last))) { | 1176 (!last.IsValid() || sync_item->item_ordinal.GreaterThan(last))) { |
1172 last = sync_item->item_ordinal; | 1177 last = sync_item->item_ordinal; |
1173 } | 1178 } |
1174 } | 1179 } |
1175 if (last.IsValid()) | 1180 if (last.IsValid()) |
1176 return last.CreateAfter(); | 1181 return last.CreateAfter(); |
1177 } | 1182 } |
1178 | 1183 |
1179 // Place the OEM folder just after the web store, which should always be | 1184 // Place the OEM folder just after the web store, which should always be |
1180 // followed by a pre-installed app (e.g. Search), so the poosition should be | 1185 // followed by a pre-installed app (e.g. Search), so the poosition should be |
1181 // stable. TODO(stevenjb): consider explicitly setting the OEM folder location | 1186 // stable. TODO(stevenjb): consider explicitly setting the OEM folder location |
1182 // along with the name in ServicesCustomizationDocument::SetOemFolderName(). | 1187 // along with the name in ServicesCustomizationDocument::SetOemFolderName(). |
1183 AppListItemList* item_list = model_->top_level_item_list(); | 1188 AppListItemList* item_list = model_->top_level_item_list(); |
1184 if (item_list->item_count() == 0) | 1189 if (!item_list->item_count()) { |
1185 return syncer::StringOrdinal(); | 1190 LOG(ERROR) << "No top level item was found. " |
| 1191 << "Placing OEM folder at the beginning."; |
| 1192 return syncer::StringOrdinal::CreateInitialOrdinal(); |
| 1193 } |
1186 | 1194 |
1187 size_t oem_index = 0; | 1195 size_t web_store_app_index; |
1188 for (; oem_index < item_list->item_count() - 1; ++oem_index) { | 1196 if (!item_list->FindItemIndex(extensions::kWebStoreAppId, |
1189 AppListItem* cur_item = item_list->item_at(oem_index); | 1197 &web_store_app_index)) { |
1190 if (cur_item->id() == extensions::kWebStoreAppId) | 1198 LOG(ERROR) << "Web store position is not found it top items. " |
1191 break; | 1199 << "Placing OEM folder at the end."; |
| 1200 return item_list->item_at(item_list->item_count() - 1) |
| 1201 ->position() |
| 1202 .CreateAfter(); |
1192 } | 1203 } |
1193 syncer::StringOrdinal oem_ordinal; | 1204 |
1194 AppListItem* prev = item_list->item_at(oem_index); | 1205 // Skip items with the same position. |
1195 if (oem_index + 1 < item_list->item_count()) { | 1206 const AppListItem* web_store_app_item = |
1196 AppListItem* next = item_list->item_at(oem_index + 1); | 1207 item_list->item_at(web_store_app_index); |
1197 oem_ordinal = prev->position().CreateBetween(next->position()); | 1208 for (size_t j = web_store_app_index + 1; j < item_list->item_count(); ++j) { |
1198 } else { | 1209 const AppListItem* next_item = item_list->item_at(j); |
1199 oem_ordinal = prev->position().CreateAfter(); | 1210 DCHECK(next_item->position().IsValid()); |
| 1211 if (!next_item->position().Equals(web_store_app_item->position())) { |
| 1212 const syncer::StringOrdinal oem_ordinal = |
| 1213 web_store_app_item->position().CreateBetween(next_item->position()); |
| 1214 VLOG(1) << "Placing OEM Folder at: " << j |
| 1215 << " position: " << oem_ordinal.ToDebugString(); |
| 1216 return oem_ordinal; |
| 1217 } |
1200 } | 1218 } |
1201 VLOG(1) << "Placing OEM Folder at: " << oem_index | 1219 |
| 1220 const syncer::StringOrdinal oem_ordinal = |
| 1221 web_store_app_item->position().CreateAfter(); |
| 1222 VLOG(1) << "Placing OEM Folder at: " << item_list->item_count() |
1202 << " position: " << oem_ordinal.ToDebugString(); | 1223 << " position: " << oem_ordinal.ToDebugString(); |
1203 return oem_ordinal; | 1224 return oem_ordinal; |
1204 } | 1225 } |
1205 | 1226 |
1206 bool AppListSyncableService::AppIsOem(const std::string& id) { | 1227 bool AppListSyncableService::AppIsOem(const std::string& id) { |
1207 #if defined(OS_CHROMEOS) | 1228 #if defined(OS_CHROMEOS) |
1208 const ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get(profile_); | 1229 const ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get(profile_); |
1209 if (arc_prefs && arc_prefs->IsOem(id)) | 1230 if (arc_prefs && arc_prefs->IsOem(id)) |
1210 return true; | 1231 return true; |
1211 #endif | 1232 #endif |
(...skipping 13 matching lines...) Expand all Loading... |
1225 res += " { " + item_name + " }"; | 1246 res += " { " + item_name + " }"; |
1226 res += " [" + item_ordinal.ToDebugString() + "]"; | 1247 res += " [" + item_ordinal.ToDebugString() + "]"; |
1227 if (!parent_id.empty()) | 1248 if (!parent_id.empty()) |
1228 res += " <" + parent_id.substr(0, 8) + ">"; | 1249 res += " <" + parent_id.substr(0, 8) + ">"; |
1229 res += " [" + item_pin_ordinal.ToDebugString() + "]"; | 1250 res += " [" + item_pin_ordinal.ToDebugString() + "]"; |
1230 } | 1251 } |
1231 return res; | 1252 return res; |
1232 } | 1253 } |
1233 | 1254 |
1234 } // namespace app_list | 1255 } // namespace app_list |
OLD | NEW |