1 // Copyright 2019 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 "components/sync/base/user_selectable_type.h"
6 
7 #include <type_traits>
8 
9 #include "base/notreached.h"
10 #include "base/optional.h"
11 #include "components/sync/base/model_type.h"
12 #include "components/sync/base/pref_names.h"
13 
14 #if defined(OS_CHROMEOS)
15 #include "chromeos/constants/chromeos_features.h"
16 #endif
17 
18 namespace syncer {
19 
20 namespace {
21 
22 struct UserSelectableTypeInfo {
23   const char* const type_name;
24   const ModelType canonical_model_type;
25   const ModelTypeSet model_type_group;
26 };
27 
28 constexpr char kBookmarksTypeName[] = "bookmarks";
29 constexpr char kPreferencesTypeName[] = "preferences";
30 constexpr char kPasswordsTypeName[] = "passwords";
31 constexpr char kAutofillTypeName[] = "autofill";
32 constexpr char kThemesTypeName[] = "themes";
33 constexpr char kTypedUrlsTypeName[] = "typedUrls";
34 constexpr char kExtensionsTypeName[] = "extensions";
35 constexpr char kAppsTypeName[] = "apps";
36 constexpr char kReadingListTypeName[] = "readingList";
37 constexpr char kTabsTypeName[] = "tabs";
38 constexpr char kWifiConfigurationsTypeName[] = "wifiConfigurations";
39 
GetUserSelectableTypeInfo(UserSelectableType type)40 UserSelectableTypeInfo GetUserSelectableTypeInfo(UserSelectableType type) {
41   // UserSelectableTypeInfo::type_name is used in js code and shouldn't be
42   // changed without updating js part.
43   switch (type) {
44     case UserSelectableType::kBookmarks:
45       return {kBookmarksTypeName, BOOKMARKS, {BOOKMARKS}};
46     case UserSelectableType::kPreferences: {
47       ModelTypeSet model_types = {PREFERENCES, DICTIONARY, PRIORITY_PREFERENCES,
48                                   SEARCH_ENGINES};
49 #if defined(OS_CHROMEOS)
50       // SplitSettingsSync makes Printers a separate OS setting.
51       if (!chromeos::features::IsSplitSettingsSyncEnabled())
52         model_types.Put(PRINTERS);
53 #endif
54       return {kPreferencesTypeName, PREFERENCES, model_types};
55     }
56     case UserSelectableType::kPasswords:
57       return {kPasswordsTypeName, PASSWORDS, {PASSWORDS}};
58     case UserSelectableType::kAutofill:
59       return {kAutofillTypeName,
60               AUTOFILL,
61               {AUTOFILL, AUTOFILL_PROFILE, AUTOFILL_WALLET_DATA,
62                AUTOFILL_WALLET_METADATA, AUTOFILL_WALLET_OFFER}};
63     case UserSelectableType::kThemes:
64       return {kThemesTypeName, THEMES, {THEMES}};
65     case UserSelectableType::kHistory:
66       return {kTypedUrlsTypeName,
67               TYPED_URLS,
68               {TYPED_URLS, HISTORY_DELETE_DIRECTIVES, SESSIONS,
69                DEPRECATED_FAVICON_IMAGES, DEPRECATED_FAVICON_TRACKING,
70                USER_EVENTS}};
71     case UserSelectableType::kExtensions:
72       return {
73           kExtensionsTypeName, EXTENSIONS, {EXTENSIONS, EXTENSION_SETTINGS}};
74     case UserSelectableType::kApps: {
75 #if defined(OS_CHROMEOS)
76       // SplitSettingsSync moves apps to Chrome OS settings.
77       if (chromeos::features::IsSplitSettingsSyncEnabled()) {
78         return {kAppsTypeName, UNSPECIFIED};
79       } else {
80         return {kAppsTypeName,
81                 APPS,
82                 {APP_LIST, APPS, APP_SETTINGS, ARC_PACKAGE, WEB_APPS}};
83       }
84 #else
85       return {kAppsTypeName, APPS, {APPS, APP_SETTINGS, WEB_APPS}};
86 #endif
87     }
88     case UserSelectableType::kReadingList:
89       return {kReadingListTypeName, READING_LIST, {READING_LIST}};
90     case UserSelectableType::kTabs:
91       return {kTabsTypeName,
92               PROXY_TABS,
93               {PROXY_TABS, SESSIONS, DEPRECATED_FAVICON_IMAGES,
94                DEPRECATED_FAVICON_TRACKING, SEND_TAB_TO_SELF}};
95     case UserSelectableType::kWifiConfigurations: {
96 #if defined(OS_CHROMEOS)
97       // SplitSettingsSync moves Wi-Fi configurations to Chrome OS settings.
98       if (chromeos::features::IsSplitSettingsSyncEnabled())
99         return {kWifiConfigurationsTypeName, UNSPECIFIED};
100 #endif
101       return {kWifiConfigurationsTypeName,
102               WIFI_CONFIGURATIONS,
103               {WIFI_CONFIGURATIONS}};
104     }
105   }
106   NOTREACHED();
107   return {nullptr, UNSPECIFIED};
108 }
109 
110 #if defined(OS_CHROMEOS)
111 constexpr char kOsAppsTypeName[] = "osApps";
112 constexpr char kOsPreferencesTypeName[] = "osPreferences";
113 constexpr char kOsWifiConfigurationsTypeName[] = "osWifiConfigurations";
114 
GetUserSelectableOsTypeInfo(UserSelectableOsType type)115 UserSelectableTypeInfo GetUserSelectableOsTypeInfo(UserSelectableOsType type) {
116   // UserSelectableTypeInfo::type_name is used in js code and shouldn't be
117   // changed without updating js part.
118   switch (type) {
119     case UserSelectableOsType::kOsApps:
120       return {kOsAppsTypeName,
121               APPS,
122               {APP_LIST, APPS, APP_SETTINGS, ARC_PACKAGE, WEB_APPS}};
123     case UserSelectableOsType::kOsPreferences:
124       return {kOsPreferencesTypeName,
125               OS_PREFERENCES,
126               {OS_PREFERENCES, OS_PRIORITY_PREFERENCES, PRINTERS}};
127     case UserSelectableOsType::kOsWifiConfigurations:
128       return {kOsWifiConfigurationsTypeName,
129               WIFI_CONFIGURATIONS,
130               {WIFI_CONFIGURATIONS}};
131   }
132 }
133 #endif  // defined(OS_CHROMEOS)
134 
135 }  // namespace
136 
GetUserSelectableTypeName(UserSelectableType type)137 const char* GetUserSelectableTypeName(UserSelectableType type) {
138   return GetUserSelectableTypeInfo(type).type_name;
139 }
140 
GetUserSelectableTypeFromString(const std::string & type)141 base::Optional<UserSelectableType> GetUserSelectableTypeFromString(
142     const std::string& type) {
143   if (type == kBookmarksTypeName) {
144     return UserSelectableType::kBookmarks;
145   }
146   if (type == kPreferencesTypeName) {
147     return UserSelectableType::kPreferences;
148   }
149   if (type == kPasswordsTypeName) {
150     return UserSelectableType::kPasswords;
151   }
152   if (type == kAutofillTypeName) {
153     return UserSelectableType::kAutofill;
154   }
155   if (type == kThemesTypeName) {
156     return UserSelectableType::kThemes;
157   }
158   if (type == kTypedUrlsTypeName) {
159     return UserSelectableType::kHistory;
160   }
161   if (type == kExtensionsTypeName) {
162     return UserSelectableType::kExtensions;
163   }
164   if (type == kAppsTypeName) {
165     return UserSelectableType::kApps;
166   }
167   if (type == kReadingListTypeName) {
168     return UserSelectableType::kReadingList;
169   }
170   if (type == kTabsTypeName) {
171     return UserSelectableType::kTabs;
172   }
173   if (type == kWifiConfigurationsTypeName) {
174     return UserSelectableType::kWifiConfigurations;
175   }
176   return base::nullopt;
177 }
178 
UserSelectableTypeSetToString(UserSelectableTypeSet types)179 std::string UserSelectableTypeSetToString(UserSelectableTypeSet types) {
180   std::string result;
181   for (UserSelectableType type : types) {
182     if (!result.empty()) {
183       result += ", ";
184     }
185     result += GetUserSelectableTypeName(type);
186   }
187   return result;
188 }
189 
UserSelectableTypeToAllModelTypes(UserSelectableType type)190 ModelTypeSet UserSelectableTypeToAllModelTypes(UserSelectableType type) {
191   return GetUserSelectableTypeInfo(type).model_type_group;
192 }
193 
UserSelectableTypeToCanonicalModelType(UserSelectableType type)194 ModelType UserSelectableTypeToCanonicalModelType(UserSelectableType type) {
195   return GetUserSelectableTypeInfo(type).canonical_model_type;
196 }
197 
UserSelectableTypeToHistogramInt(UserSelectableType type)198 int UserSelectableTypeToHistogramInt(UserSelectableType type) {
199   // TODO(crbug.com/1007293): Use ModelTypeHistogramValue instead of casting to
200   // int.
201   return static_cast<int>(
202       ModelTypeHistogramValue(UserSelectableTypeToCanonicalModelType(type)));
203 }
204 
205 #if defined(OS_CHROMEOS)
GetUserSelectableOsTypeName(UserSelectableOsType type)206 const char* GetUserSelectableOsTypeName(UserSelectableOsType type) {
207   return GetUserSelectableOsTypeInfo(type).type_name;
208 }
209 
GetUserSelectableOsTypeFromString(const std::string & type)210 base::Optional<UserSelectableOsType> GetUserSelectableOsTypeFromString(
211     const std::string& type) {
212   if (type == kOsAppsTypeName) {
213     return UserSelectableOsType::kOsApps;
214   }
215   if (type == kOsPreferencesTypeName) {
216     return UserSelectableOsType::kOsPreferences;
217   }
218   if (type == kOsWifiConfigurationsTypeName) {
219     return UserSelectableOsType::kOsWifiConfigurations;
220   }
221 
222   // Some pref types migrated from browser prefs to OS prefs. Map the browser
223   // type name to the OS type so that enterprise policy SyncTypesListDisabled
224   // still applies to the migrated names during SplitSettingsSync roll-out.
225   // TODO(https://crbug.com/1059309): Rename "osApps" to "apps" and
226   // "osWifiConfigurations" to "wifiConfigurations" after SplitSettingsSync is
227   // the default, and remove the mapping for "preferences".
228   if (type == kAppsTypeName) {
229     return UserSelectableOsType::kOsApps;
230   }
231   if (type == kWifiConfigurationsTypeName) {
232     return UserSelectableOsType::kOsWifiConfigurations;
233   }
234   if (type == kPreferencesTypeName) {
235     return UserSelectableOsType::kOsPreferences;
236   }
237   return base::nullopt;
238 }
239 
UserSelectableOsTypeToAllModelTypes(UserSelectableOsType type)240 ModelTypeSet UserSelectableOsTypeToAllModelTypes(UserSelectableOsType type) {
241   return GetUserSelectableOsTypeInfo(type).model_type_group;
242 }
243 
UserSelectableOsTypeToCanonicalModelType(UserSelectableOsType type)244 ModelType UserSelectableOsTypeToCanonicalModelType(UserSelectableOsType type) {
245   return GetUserSelectableOsTypeInfo(type).canonical_model_type;
246 }
247 #endif  // defined(OS_CHROMEOS)
248 
249 }  // namespace syncer
250