• 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     private String[] mComponentNameKeys = new String[0];
53 
54     private static final String TAG_PERSISTABLEBUNDLE = "persistable_bundle";
55     private static final String TAG_ACCOUNT = "account";
56     private static final String ATTRIBUTE_ACCOUNT_NAME = "name";
57     private static final String ATTRIBUTE_ACCOUNT_TYPE = "type";
58 
59     private static final String IS_SET = "isSet";
60 
IntentStore(Context context, ComponentName intentTarget, String preferencesName)61     public IntentStore(Context context, ComponentName intentTarget, String preferencesName) {
62         mContext = context;
63         mPrefsName = preferencesName;
64         mPrefs = context.getSharedPreferences(preferencesName, Context.MODE_PRIVATE);
65         mIntentTarget = intentTarget;
66     }
67 
setStringKeys(String[] keys)68     public IntentStore setStringKeys(String[] keys) {
69         mStringKeys = (keys == null) ? new String[0] : keys;
70         return this;
71     }
72 
setLongKeys(String[] keys)73     public IntentStore setLongKeys(String[] keys) {
74         mLongKeys = (keys == null) ? new String[0] : keys;
75         return this;
76     }
77 
setIntKeys(String[] keys)78     public IntentStore setIntKeys(String[] keys) {
79         mIntKeys = (keys == null) ? new String[0] : keys;
80         return this;
81     }
82 
setBooleanKeys(String[] keys)83     public IntentStore setBooleanKeys(String[] keys) {
84         mBooleanKeys = (keys == null) ? new String[0] : keys;
85         return this;
86     }
87 
setAccountKeys(String[] keys)88     public IntentStore setAccountKeys(String[] keys) {
89         mAccountKeys = (keys == null) ? new String[0] : keys;
90         return this;
91     }
92 
setPersistableBundleKeys(String[] keys)93     public IntentStore setPersistableBundleKeys(String[] keys) {
94         mPersistableBundleKeys = (keys == null) ? new String[0] : keys;
95         return this;
96     }
97 
setComponentNameKeys(String[] keys)98     public IntentStore setComponentNameKeys(String[] keys) {
99         mComponentNameKeys = (keys == null) ? new String[0] : keys;
100         return this;
101     }
102 
clear()103     public void clear() {
104         mPrefs.edit().clear().commit();
105     }
106 
save(Bundle data)107     public void save(Bundle data){
108         SharedPreferences.Editor editor = mPrefs.edit();
109 
110         editor.clear();
111         for (String key : mStringKeys) {
112             editor.putString(key, data.getString(key));
113         }
114         for (String key : mLongKeys) {
115             editor.putLong(key, data.getLong(key));
116         }
117         for (String key : mIntKeys) {
118             editor.putInt(key, data.getInt(key));
119         }
120         for (String key : mBooleanKeys) {
121             editor.putBoolean(key, data.getBoolean(key));
122         }
123         for (String key : mAccountKeys) {
124             Account account = (Account) data.getParcelable(key);
125             String accountString = accountToString(account);
126             if (accountString != null) {
127                 editor.putString(key, accountString);
128             }
129         }
130         for (String key : mPersistableBundleKeys) {
131 
132             // Cast should be guaranteed to succeed by check in the provisioning activities.
133             String bundleString = persistableBundleToString((PersistableBundle) data
134                     .getParcelable(key));
135             if (bundleString != null) {
136                 editor.putString(key, bundleString);
137             }
138         }
139         for (String key : mComponentNameKeys) {
140             ComponentName cn = (ComponentName) data.getParcelable(key);
141             if (cn != null) {
142                 editor.putString(key, cn.flattenToString());
143             }
144         }
145         editor.putBoolean(IS_SET, true);
146         editor.commit();
147     }
148 
load()149     public Intent load() {
150         if (!mPrefs.getBoolean(IS_SET, false)) {
151             return null;
152         }
153 
154         Intent result = new Intent();
155         result.setComponent(mIntentTarget);
156 
157         for (String key : mStringKeys) {
158             String value = mPrefs.getString(key, null);
159             if (value != null) {
160                 result.putExtra(key, value);
161             }
162         }
163         for (String key : mLongKeys) {
164             if (mPrefs.contains(key)) {
165                 result.putExtra(key, mPrefs.getLong(key, 0));
166             }
167         }
168         for (String key : mIntKeys) {
169             if (mPrefs.contains(key)) {
170                 result.putExtra(key, mPrefs.getInt(key, 0));
171             }
172         }
173         for (String key : mBooleanKeys) {
174             if (mPrefs.contains(key)) {
175                 result.putExtra(key, mPrefs.getBoolean(key, false));
176             }
177         }
178         for (String key : mAccountKeys) {
179             if (mPrefs.contains(key)) {
180                 Account account = stringToAccount(mPrefs.getString(key, null));
181                 if (account != null) {
182                     result.putExtra(key, account);
183                 }
184             }
185         }
186         for (String key : mPersistableBundleKeys) {
187             if (mPrefs.contains(key)) {
188                 PersistableBundle bundle = stringToPersistableBundle(mPrefs.getString(key, null));
189                 if (bundle != null) {
190                     result.putExtra(key, bundle);
191                 }
192             }
193         }
194         for (String key : mComponentNameKeys) {
195             if (mPrefs.contains(key)) {
196                 String st = mPrefs.getString(key, null);
197                 if (st != null) {
198                     result.putExtra(key, ComponentName.unflattenFromString(st));
199                 }
200             }
201         }
202 
203         return result;
204     }
205 
accountToString(Account account)206     private String accountToString(Account account) {
207         if (account == null) {
208             return null;
209         }
210         StringWriter writer = new StringWriter();
211         XmlSerializer serializer = Xml.newSerializer();
212         try {
213             serializer.setOutput(writer);
214             serializer.startDocument(null, true);
215             serializer.startTag(null, TAG_ACCOUNT);
216             serializer.attribute(null /* namespace */, ATTRIBUTE_ACCOUNT_NAME, account.name);
217             serializer.attribute(null /* namespace */, ATTRIBUTE_ACCOUNT_TYPE, account.type);
218             serializer.endTag(null, TAG_ACCOUNT);
219             serializer.endDocument();
220         } catch (IOException e) {
221             ProvisionLogger.loge("Account could not be stored as string.", e);
222             return null;
223         }
224 
225         return writer.toString();
226     }
227 
stringToAccount(String string)228     private Account stringToAccount(String string) {
229         if (string == null) {
230             return null;
231         }
232         XmlPullParserFactory factory;
233         XmlPullParser parser;
234         try {
235             factory = XmlPullParserFactory.newInstance();
236 
237             parser = factory.newPullParser();
238             parser.setInput(new StringReader(string));
239 
240             if ((parser.next() == XmlPullParser.START_TAG)
241                     && TAG_ACCOUNT.equals(parser.getName())) {
242                 String name = parser.getAttributeValue(null /* namespace */,
243                         ATTRIBUTE_ACCOUNT_NAME);
244                 String type = parser.getAttributeValue(null /* namespace */,
245                         ATTRIBUTE_ACCOUNT_TYPE);
246                 if (name != null && type != null) {
247                     return new Account(name, type);
248                 }
249             }
250         } catch (IOException|XmlPullParserException e) {
251             ProvisionLogger.loge(e);
252             // Fall through.
253         }
254         ProvisionLogger.loge("Account could not be restored from string " + string);
255         return null;
256     }
257 
persistableBundleToString(PersistableBundle bundle)258     private String persistableBundleToString(PersistableBundle bundle) {
259         if (bundle == null) {
260             return null;
261         }
262 
263         StringWriter writer = new StringWriter();
264         XmlSerializer serializer = Xml.newSerializer();
265         try {
266             serializer.setOutput(writer);
267             serializer.startDocument(null, true);
268             serializer.startTag(null, TAG_PERSISTABLEBUNDLE);
269             bundle.saveToXml(serializer);
270             serializer.endTag(null, TAG_PERSISTABLEBUNDLE);
271             serializer.endDocument();
272         } catch (IOException|XmlPullParserException e) {
273             ProvisionLogger.loge("Persistable bundle could not be stored as string.", e);
274             return null;
275         }
276 
277         return writer.toString();
278     }
279 
stringToPersistableBundle(String string)280     private PersistableBundle stringToPersistableBundle(String string) {
281         if (string == null) {
282             return null;
283         }
284 
285         XmlPullParserFactory factory;
286         XmlPullParser parser;
287         try {
288             factory = XmlPullParserFactory.newInstance();
289 
290             parser = factory.newPullParser();
291             parser.setInput(new StringReader(string));
292 
293             if (parser.next() == XmlPullParser.START_TAG) {
294                 if (TAG_PERSISTABLEBUNDLE.equals(parser.getName())) {
295                     return PersistableBundle.restoreFromXml(parser);
296                 }
297             }
298         } catch (IOException|XmlPullParserException e) {
299             ProvisionLogger.loge(e);
300             // Fall through.
301         }
302         ProvisionLogger.loge("Persistable bundle could not be restored from string " + string);
303         return null;
304     }
305 }
306