• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.managedprovisioning;
17 
18 import android.accounts.Account;
19 import android.content.ComponentName;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.SharedPreferences;
23 import android.os.Bundle;
24 import android.os.PersistableBundle;
25 import android.util.Xml;
26 
27 import org.xmlpull.v1.XmlPullParser;
28 import org.xmlpull.v1.XmlPullParserException;
29 import org.xmlpull.v1.XmlPullParserFactory;
30 import org.xmlpull.v1.XmlSerializer;
31 
32 import java.io.IOException;
33 import java.io.StringReader;
34 import java.io.StringWriter;
35 
36 /**
37  * Helper class to load/save resume information from Intents into a SharedPreferences.
38  */
39 public class IntentStore {
40     private SharedPreferences mPrefs;
41     private String mPrefsName; // Name of the file where mPrefs is stored.
42     private Context mContext;
43     private ComponentName mIntentTarget;
44 
45     // Key arrays should never be null.
46     private String[] mStringKeys = new String[0];
47     private String[] mLongKeys = new String[0];
48     private String[] mIntKeys = new String[0];
49     private String[] mBooleanKeys = new String[0];
50     private String[] mPersistableBundleKeys = new String[0];
51     private String[] mAccountKeys = new String[0];
52 
53     private static final String TAG_PERSISTABLEBUNDLE = "persistable_bundle";
54     private static final String TAG_ACCOUNT = "account";
55     private static final String ATTRIBUTE_ACCOUNT_NAME = "name";
56     private static final String ATTRIBUTE_ACCOUNT_TYPE = "type";
57 
58     private static final String IS_SET = "isSet";
59 
IntentStore(Context context, ComponentName intentTarget, String preferencesName)60     public IntentStore(Context context, ComponentName intentTarget, String preferencesName) {
61         mContext = context;
62         mPrefsName = preferencesName;
63         mPrefs = context.getSharedPreferences(preferencesName, Context.MODE_PRIVATE);
64         mIntentTarget = intentTarget;
65     }
66 
setStringKeys(String[] keys)67     public IntentStore setStringKeys(String[] keys) {
68         mStringKeys = (keys == null) ? new String[0] : keys;
69         return this;
70     }
71 
setLongKeys(String[] keys)72     public IntentStore setLongKeys(String[] keys) {
73         mLongKeys = (keys == null) ? new String[0] : keys;
74         return this;
75     }
76 
setIntKeys(String[] keys)77     public IntentStore setIntKeys(String[] keys) {
78         mIntKeys = (keys == null) ? new String[0] : keys;
79         return this;
80     }
81 
setBooleanKeys(String[] keys)82     public IntentStore setBooleanKeys(String[] keys) {
83         mBooleanKeys = (keys == null) ? new String[0] : keys;
84         return this;
85     }
86 
setAccountKeys(String[] keys)87     public IntentStore setAccountKeys(String[] keys) {
88         mAccountKeys = (keys == null) ? new String[0] : keys;
89         return this;
90     }
91 
setPersistableBundleKeys(String[] keys)92     public IntentStore setPersistableBundleKeys(String[] keys) {
93         mPersistableBundleKeys = (keys == null) ? new String[0] : keys;
94         return this;
95     }
96 
clear()97     public void clear() {
98         mPrefs.edit().clear().commit();
99     }
100 
save(Bundle data)101     public void save(Bundle data){
102         SharedPreferences.Editor editor = mPrefs.edit();
103 
104         editor.clear();
105         for (String key : mStringKeys) {
106             editor.putString(key, data.getString(key));
107         }
108         for (String key : mLongKeys) {
109             editor.putLong(key, data.getLong(key));
110         }
111         for (String key : mIntKeys) {
112             editor.putInt(key, data.getInt(key));
113         }
114         for (String key : mBooleanKeys) {
115             editor.putBoolean(key, data.getBoolean(key));
116         }
117         for (String key : mAccountKeys) {
118             Account account = (Account) data.getParcelable(key);
119             String accountString = accountToString(account);
120             if (accountString != null) {
121                 editor.putString(key, accountString);
122             }
123         }
124         for (String key : mPersistableBundleKeys) {
125 
126             // Cast should be guaranteed to succeed by check in the provisioning activities.
127             String bundleString = persistableBundleToString((PersistableBundle) data
128                     .getParcelable(key));
129             if (bundleString != null) {
130                 editor.putString(key, bundleString);
131             }
132         }
133         editor.putBoolean(IS_SET, true);
134         editor.commit();
135     }
136 
load()137     public Intent load() {
138         if (!mPrefs.getBoolean(IS_SET, false)) {
139             return null;
140         }
141 
142         Intent result = new Intent();
143         result.setComponent(mIntentTarget);
144 
145         for (String key : mStringKeys) {
146             String value = mPrefs.getString(key, null);
147             if (value != null) {
148                 result.putExtra(key, value);
149             }
150         }
151         for (String key : mLongKeys) {
152             if (mPrefs.contains(key)) {
153                 result.putExtra(key, mPrefs.getLong(key, 0));
154             }
155         }
156         for (String key : mIntKeys) {
157             if (mPrefs.contains(key)) {
158                 result.putExtra(key, mPrefs.getInt(key, 0));
159             }
160         }
161         for (String key : mBooleanKeys) {
162             if (mPrefs.contains(key)) {
163                 result.putExtra(key, mPrefs.getBoolean(key, false));
164             }
165         }
166         for (String key : mAccountKeys) {
167             if (mPrefs.contains(key)) {
168                 Account account = stringToAccount(mPrefs.getString(key, null));
169                 if (account != null) {
170                     result.putExtra(key, account);
171                 }
172             }
173         }
174         for (String key : mPersistableBundleKeys) {
175             if (mPrefs.contains(key)) {
176                 PersistableBundle bundle = stringToPersistableBundle(mPrefs.getString(key, null));
177                 if (bundle != null) {
178                     result.putExtra(key, bundle);
179                 }
180             }
181         }
182 
183         return result;
184     }
185 
accountToString(Account account)186     private String accountToString(Account account) {
187         if (account == null) {
188             return null;
189         }
190         StringWriter writer = new StringWriter();
191         XmlSerializer serializer = Xml.newSerializer();
192         try {
193             serializer.setOutput(writer);
194             serializer.startDocument(null, true);
195             serializer.startTag(null, TAG_ACCOUNT);
196             serializer.attribute(null /* namespace */, ATTRIBUTE_ACCOUNT_NAME, account.name);
197             serializer.attribute(null /* namespace */, ATTRIBUTE_ACCOUNT_TYPE, account.type);
198             serializer.endTag(null, TAG_ACCOUNT);
199             serializer.endDocument();
200         } catch (IOException e) {
201             ProvisionLogger.loge("Account could not be stored as string.", e);
202             return null;
203         }
204 
205         return writer.toString();
206     }
207 
stringToAccount(String string)208     private Account stringToAccount(String string) {
209         if (string == null) {
210             return null;
211         }
212         XmlPullParserFactory factory;
213         XmlPullParser parser;
214         try {
215             factory = XmlPullParserFactory.newInstance();
216 
217             parser = factory.newPullParser();
218             parser.setInput(new StringReader(string));
219 
220             if ((parser.next() == XmlPullParser.START_TAG)
221                     && TAG_ACCOUNT.equals(parser.getName())) {
222                 String name = parser.getAttributeValue(null /* namespace */,
223                         ATTRIBUTE_ACCOUNT_NAME);
224                 String type = parser.getAttributeValue(null /* namespace */,
225                         ATTRIBUTE_ACCOUNT_TYPE);
226                 if (name != null && type != null) {
227                     return new Account(name, type);
228                 }
229             }
230         } catch (IOException|XmlPullParserException e) {
231             ProvisionLogger.loge(e);
232             // Fall through.
233         }
234         ProvisionLogger.loge("Account could not be restored from string " + string);
235         return null;
236     }
237 
persistableBundleToString(PersistableBundle bundle)238     private String persistableBundleToString(PersistableBundle bundle) {
239         if (bundle == null) {
240             return null;
241         }
242 
243         StringWriter writer = new StringWriter();
244         XmlSerializer serializer = Xml.newSerializer();
245         try {
246             serializer.setOutput(writer);
247             serializer.startDocument(null, true);
248             serializer.startTag(null, TAG_PERSISTABLEBUNDLE);
249             bundle.saveToXml(serializer);
250             serializer.endTag(null, TAG_PERSISTABLEBUNDLE);
251             serializer.endDocument();
252         } catch (IOException|XmlPullParserException e) {
253             ProvisionLogger.loge("Persistable bundle could not be stored as string.", e);
254             return null;
255         }
256 
257         return writer.toString();
258     }
259 
stringToPersistableBundle(String string)260     private PersistableBundle stringToPersistableBundle(String string) {
261         if (string == null) {
262             return null;
263         }
264 
265         XmlPullParserFactory factory;
266         XmlPullParser parser;
267         try {
268             factory = XmlPullParserFactory.newInstance();
269 
270             parser = factory.newPullParser();
271             parser.setInput(new StringReader(string));
272 
273             if (parser.next() == XmlPullParser.START_TAG) {
274                 if (TAG_PERSISTABLEBUNDLE.equals(parser.getName())) {
275                     return PersistableBundle.restoreFromXml(parser);
276                 }
277             }
278         } catch (IOException|XmlPullParserException e) {
279             ProvisionLogger.loge(e);
280             // Fall through.
281         }
282         ProvisionLogger.loge("Persistable bundle could not be restored from string " + string);
283         return null;
284     }
285 }
286