Roll cacheinvalidation DEPS to r341
[chromium-blink-merge.git] / sync / android / java / src / org / chromium / sync / notifier / InvalidationPreferences.java
blob0a128492ebf32a27d68ff03e37b0036dc0e6f211
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.
5 package org.chromium.sync.notifier;
7 import android.accounts.Account;
8 import android.content.Context;
9 import android.content.SharedPreferences;
10 import android.preference.PreferenceManager;
11 import android.util.Base64;
12 import android.util.Log;
14 import com.google.ipc.invalidation.external.client.types.ObjectId;
16 import org.chromium.base.VisibleForTesting;
18 import java.util.Collection;
19 import java.util.HashSet;
20 import java.util.Set;
22 import javax.annotation.Nullable;
24 /**
25 * Class to manage the preferences used by the invalidation client.
26 * <p>
27 * This class provides methods to read and write the preferences used by the invalidation client.
28 * <p>
29 * To read a preference, call the appropriate {@code get...} method.
30 * <p>
31 * To write a preference, first call {@link #edit} to obtain a {@link EditContext}. Then, make
32 * one or more calls to a {@code set...} method, providing the same edit context to each call.
33 * Finally, call {@link #commit(EditContext)} to save the changes to stable storage.
35 * @author dsmyers@google.com (Daniel Myers)
37 public class InvalidationPreferences {
38 /**
39 * Wrapper around a {@link android.content.SharedPreferences.Editor} for the preferences.
40 * Used to avoid exposing raw preference objects to users of this class.
42 public class EditContext {
43 private final SharedPreferences.Editor mEditor;
45 EditContext() {
46 mEditor = PreferenceManager.getDefaultSharedPreferences(mContext).edit();
50 @VisibleForTesting
51 public static class PrefKeys {
52 /**
53 * Shared preference key to store the invalidation types that we want to register
54 * for.
56 @VisibleForTesting
57 public static final String SYNC_TANGO_TYPES = "sync_tango_types";
59 /**
60 * Shared preference key to store tango object ids for additional objects that we want to
61 * register for.
63 @VisibleForTesting
64 public static final String TANGO_OBJECT_IDS = "tango_object_ids";
66 /** Shared preference key to store the name of the account in use. */
67 @VisibleForTesting
68 public static final String SYNC_ACCT_NAME = "sync_acct_name";
70 /** Shared preference key to store the type of account in use. */
71 static final String SYNC_ACCT_TYPE = "sync_acct_type";
73 /** Shared preference key to store internal notification client library state. */
74 static final String SYNC_TANGO_INTERNAL_STATE = "sync_tango_internal_state";
77 private static final String TAG = "InvalidationPreferences";
79 private final Context mContext;
81 public InvalidationPreferences(Context context) {
82 Context appContext = context.getApplicationContext();
83 if (appContext == null) throw new NullPointerException("Unable to get application context");
84 mContext = appContext;
87 /** Returns a new {@link EditContext} to modify the preferences managed by this class. */
88 public EditContext edit() {
89 return new EditContext();
92 /**
93 * Applies the changes accumulated in {@code editContext}. Returns whether they were
94 * successfully written.
95 * <p>
96 * NOTE: this method performs blocking I/O and must not be called from the UI thread.
98 public boolean commit(EditContext editContext) {
99 if (!editContext.mEditor.commit()) {
100 Log.w(TAG, "Failed to commit invalidation preferences");
101 return false;
103 return true;
106 /** Returns the saved sync types, or {@code null} if none exist. */
107 @Nullable public Set<String> getSavedSyncedTypes() {
108 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
109 return preferences.getStringSet(PrefKeys.SYNC_TANGO_TYPES, null);
112 /** Sets the saved sync types to {@code syncTypes} in {@code editContext}. */
113 public void setSyncTypes(EditContext editContext, Collection<String> syncTypes) {
114 if (syncTypes == null) throw new NullPointerException("syncTypes is null.");
115 Set<String> selectedTypesSet = new HashSet<String>(syncTypes);
116 editContext.mEditor.putStringSet(PrefKeys.SYNC_TANGO_TYPES, selectedTypesSet);
119 /** Returns the saved non-sync object ids, or {@code null} if none exist. */
120 @Nullable
121 public Set<ObjectId> getSavedObjectIds() {
122 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
123 Set<String> objectIdStrings = preferences.getStringSet(PrefKeys.TANGO_OBJECT_IDS, null);
124 if (objectIdStrings == null) {
125 return null;
127 Set<ObjectId> objectIds = new HashSet<ObjectId>(objectIdStrings.size());
128 for (String objectIdString : objectIdStrings) {
129 ObjectId objectId = getObjectId(objectIdString);
130 if (objectId != null) {
131 objectIds.add(objectId);
134 return objectIds;
137 /** Sets the saved non-sync object ids */
138 public void setObjectIds(EditContext editContext, Collection<ObjectId> objectIds) {
139 if (objectIds == null) throw new NullPointerException("objectIds is null.");
140 Set<String> objectIdStrings = new HashSet<String>(objectIds.size());
141 for (ObjectId objectId : objectIds) {
142 objectIdStrings.add(getObjectIdString(objectId));
144 editContext.mEditor.putStringSet(PrefKeys.TANGO_OBJECT_IDS, objectIdStrings);
147 /** Returns the saved account, or {@code null} if none exists. */
148 @Nullable public Account getSavedSyncedAccount() {
149 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
150 String accountName = preferences.getString(PrefKeys.SYNC_ACCT_NAME, null);
151 String accountType = preferences.getString(PrefKeys.SYNC_ACCT_TYPE, null);
152 if (accountName == null || accountType == null) {
153 return null;
155 return new Account(accountName, accountType);
158 /** Sets the saved account to {@code account} in {@code editContext}. */
159 public void setAccount(EditContext editContext, Account account) {
160 editContext.mEditor.putString(PrefKeys.SYNC_ACCT_NAME, account.name);
161 editContext.mEditor.putString(PrefKeys.SYNC_ACCT_TYPE, account.type);
164 /** Returns the notification client internal state. */
165 @Nullable public byte[] getInternalNotificationClientState() {
166 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
167 String base64State = preferences.getString(PrefKeys.SYNC_TANGO_INTERNAL_STATE, null);
168 if (base64State == null) {
169 return null;
171 return Base64.decode(base64State, Base64.DEFAULT);
174 /** Sets the notification client internal state to {@code state}. */
175 public void setInternalNotificationClientState(EditContext editContext, byte[] state) {
176 editContext.mEditor.putString(PrefKeys.SYNC_TANGO_INTERNAL_STATE,
177 Base64.encodeToString(state, Base64.DEFAULT));
180 /** Converts the given object id to a string for storage in preferences. */
181 private String getObjectIdString(ObjectId objectId) {
182 return objectId.getSource() + ":" + new String(objectId.getName());
186 * Converts the given object id string stored in preferences to an object id.
187 * Returns null if the string does not represent a valid object id.
189 private ObjectId getObjectId(String objectIdString) {
190 int separatorPos = objectIdString.indexOf(':');
191 // Ensure that the separator is surrounded by at least one character on each side.
192 if (separatorPos < 1 || separatorPos == objectIdString.length() - 1) {
193 return null;
195 int objectSource;
196 try {
197 objectSource = Integer.parseInt(objectIdString.substring(0, separatorPos));
198 } catch (NumberFormatException e) {
199 return null;
201 byte[] objectName = objectIdString.substring(separatorPos + 1).getBytes();
202 return ObjectId.newInstance(objectSource, objectName);