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 package org.chromium.sync.internal_api.pub.base; 6 7 import android.util.Log; 8 9 import com.google.ipc.invalidation.external.client.types.ObjectId; 10 import com.google.protos.ipc.invalidation.Types; 11 12 import org.chromium.base.FieldTrialList; 13 import org.chromium.base.VisibleForTesting; 14 import org.chromium.base.library_loader.LibraryLoader; 15 16 import java.util.Collection; 17 import java.util.EnumSet; 18 import java.util.HashSet; 19 import java.util.Set; 20 21 /** 22 * The model types that are synced in Chrome for Android. 23 */ 24 public enum ModelType { 25 /** 26 * An autofill object. 27 */ 28 AUTOFILL("AUTOFILL"), 29 /** 30 * An autofill profile object. 31 */ 32 AUTOFILL_PROFILE("AUTOFILL_PROFILE"), 33 /** 34 * A bookmark folder or a bookmark URL object. 35 */ 36 BOOKMARK("BOOKMARK"), 37 /** 38 * Flags to enable experimental features. 39 */ 40 EXPERIMENTS("EXPERIMENTS"), 41 /** 42 * An object representing a set of Nigori keys. 43 */ 44 NIGORI("NIGORI"), 45 /** 46 * A password entry. 47 */ 48 PASSWORD("PASSWORD"), 49 /** 50 * An object representing a browser session or tab. 51 */ 52 SESSION("SESSION"), 53 /** 54 * A typed_url folder or a typed_url object. 55 */ 56 TYPED_URL("TYPED_URL"), 57 /** 58 * A history delete directive object. 59 */ 60 HISTORY_DELETE_DIRECTIVE("HISTORY_DELETE_DIRECTIVE"), 61 /** 62 * A device info object. 63 */ 64 DEVICE_INFO("DEVICE_INFO"), 65 /** 66 * A proxy tabs object (placeholder for sessions). 67 */ 68 PROXY_TABS("NULL", true), 69 /** 70 * A favicon image object. 71 */ 72 FAVICON_IMAGE("FAVICON_IMAGE"), 73 /** 74 * A favicon tracking object. 75 */ 76 FAVICON_TRACKING("FAVICON_TRACKING"), 77 /** 78 * A supervised user setting object. The old name "managed user" is used for backwards 79 * compatibility. 80 */ 81 MANAGED_USER_SETTING("MANAGED_USER_SETTING"); 82 83 /** Special type representing all possible types. */ 84 public static final String ALL_TYPES_TYPE = "ALL_TYPES"; 85 86 private static final String TAG = "ModelType"; 87 88 private final String mModelType; 89 90 private final boolean mNonInvalidationType; 91 92 ModelType(String modelType, boolean nonInvalidationType) { 93 assert nonInvalidationType || name().equals(modelType); 94 mModelType = modelType; 95 mNonInvalidationType = nonInvalidationType; 96 } 97 98 ModelType(String modelType) { 99 this(modelType, false); 100 } 101 102 private boolean isNonInvalidationType() { 103 if ((this == SESSION || this == FAVICON_TRACKING) && LibraryLoader.isInitialized()) { 104 return FieldTrialList 105 .findFullName("AndroidSessionNotifications") 106 .equals("Disabled"); 107 } 108 return mNonInvalidationType; 109 } 110 111 /** 112 * Returns the {@link ObjectId} representation of this {@link ModelType}. 113 * 114 * This should be used with caution, since it converts even {@link ModelType} instances with 115 * |mNonInvalidationType| set. For automatically stripping such {@link ModelType} entries out, 116 * use {@link ModelType#modelTypesToObjectIds(java.util.Set)} instead. 117 */ 118 @VisibleForTesting 119 public ObjectId toObjectId() { 120 return ObjectId.newInstance(Types.ObjectSource.CHROME_SYNC, mModelType.getBytes()); 121 } 122 123 public static ModelType fromObjectId(ObjectId objectId) { 124 try { 125 return valueOf(new String(objectId.getName())); 126 } catch (IllegalArgumentException e) { 127 return null; 128 } 129 } 130 131 /** 132 * Converts string representations of types to sync to {@link ModelType}s. 133 * <p> 134 * If {@code syncTypes} contains {@link #ALL_TYPES_TYPE}, then the returned 135 * set contains all values of the {@code ModelType} enum. 136 * <p> 137 * Otherwise, the returned set contains the {@code ModelType} values for all elements of 138 * {@code syncTypes} for which {@link ModelType#valueOf(String)} successfully returns; other 139 * elements are dropped. 140 */ 141 public static Set<ModelType> syncTypesToModelTypes(Collection<String> syncTypes) { 142 if (syncTypes.contains(ALL_TYPES_TYPE)) { 143 return EnumSet.allOf(ModelType.class); 144 } else { 145 Set<ModelType> modelTypes = new HashSet<ModelType>(syncTypes.size()); 146 for (String syncType : syncTypes) { 147 try { 148 modelTypes.add(valueOf(syncType)); 149 } catch (IllegalArgumentException exception) { 150 // Drop invalid sync types. 151 Log.w(TAG, "Could not translate sync type to model type: " + syncType); 152 } 153 } 154 return modelTypes; 155 } 156 } 157 158 /** 159 * Converts a set of sync types {@link String} to a set of {@link ObjectId}. 160 * 161 * This strips out any {@link ModelType} that is not an invalidation type. 162 */ 163 public static Set<ObjectId> syncTypesToObjectIds(Collection<String> syncTypes) { 164 return modelTypesToObjectIds(syncTypesToModelTypes(syncTypes)); 165 } 166 167 /** 168 * Converts a set of {@link ModelType} to a set of {@link ObjectId}. 169 * 170 * This strips out any {@link ModelType} that is not an invalidation type. 171 */ 172 public static Set<ObjectId> modelTypesToObjectIds(Set<ModelType> modelTypes) { 173 Set<ModelType> filteredModelTypes = filterOutNonInvalidationTypes(modelTypes); 174 Set<ObjectId> objectIds = new HashSet<ObjectId>(filteredModelTypes.size()); 175 for (ModelType modelType : filteredModelTypes) { 176 objectIds.add(modelType.toObjectId()); 177 } 178 return objectIds; 179 } 180 181 /** Converts a set of {@link ModelType} to a set of string names. */ 182 public static Set<String> modelTypesToSyncTypesForTest(Set<ModelType> modelTypes) { 183 Set<String> objectIds = new HashSet<String>(modelTypes.size()); 184 for (ModelType modelType : modelTypes) { 185 objectIds.add(modelType.toString()); 186 } 187 return objectIds; 188 } 189 190 /** Filters out non-invalidation types from a set of {@link ModelType}. */ 191 @VisibleForTesting 192 public static Set<ModelType> filterOutNonInvalidationTypes(Set<ModelType> modelTypes) { 193 Set<ModelType> filteredTypes = new HashSet<ModelType>(modelTypes.size()); 194 for (ModelType modelType : modelTypes) { 195 if (!modelType.isNonInvalidationType()) { 196 filteredTypes.add(modelType); 197 } 198 } 199 return filteredTypes; 200 } 201 202 } 203