blob: 3656f09c71c5fc2cd3e5ba0bdd2f148e800d80df [file] [log] [blame]
/*
* Copyright 2014, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.managedprovisioning;
import android.accounts.Account;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
/**
* Helper class to load/save resume information from Intents into a SharedPreferences.
*/
public class IntentStore {
private SharedPreferences mPrefs;
private String mPrefsName; // Name of the file where mPrefs is stored.
private Context mContext;
private ComponentName mIntentTarget;
// Key arrays should never be null.
private String[] mStringKeys = new String[0];
private String[] mLongKeys = new String[0];
private String[] mIntKeys = new String[0];
private String[] mBooleanKeys = new String[0];
private String[] mPersistableBundleKeys = new String[0];
private String[] mAccountKeys = new String[0];
private String[] mComponentNameKeys = new String[0];
private static final String TAG_PERSISTABLEBUNDLE = "persistable_bundle";
private static final String TAG_ACCOUNT = "account";
private static final String ATTRIBUTE_ACCOUNT_NAME = "name";
private static final String ATTRIBUTE_ACCOUNT_TYPE = "type";
private static final String IS_SET = "isSet";
public IntentStore(Context context, ComponentName intentTarget, String preferencesName) {
mContext = context;
mPrefsName = preferencesName;
mPrefs = context.getSharedPreferences(preferencesName, Context.MODE_PRIVATE);
mIntentTarget = intentTarget;
}
public IntentStore setStringKeys(String[] keys) {
mStringKeys = (keys == null) ? new String[0] : keys;
return this;
}
public IntentStore setLongKeys(String[] keys) {
mLongKeys = (keys == null) ? new String[0] : keys;
return this;
}
public IntentStore setIntKeys(String[] keys) {
mIntKeys = (keys == null) ? new String[0] : keys;
return this;
}
public IntentStore setBooleanKeys(String[] keys) {
mBooleanKeys = (keys == null) ? new String[0] : keys;
return this;
}
public IntentStore setAccountKeys(String[] keys) {
mAccountKeys = (keys == null) ? new String[0] : keys;
return this;
}
public IntentStore setPersistableBundleKeys(String[] keys) {
mPersistableBundleKeys = (keys == null) ? new String[0] : keys;
return this;
}
public IntentStore setComponentNameKeys(String[] keys) {
mComponentNameKeys = (keys == null) ? new String[0] : keys;
return this;
}
public void clear() {
mPrefs.edit().clear().commit();
}
public void save(Bundle data){
SharedPreferences.Editor editor = mPrefs.edit();
editor.clear();
for (String key : mStringKeys) {
editor.putString(key, data.getString(key));
}
for (String key : mLongKeys) {
editor.putLong(key, data.getLong(key));
}
for (String key : mIntKeys) {
editor.putInt(key, data.getInt(key));
}
for (String key : mBooleanKeys) {
editor.putBoolean(key, data.getBoolean(key));
}
for (String key : mAccountKeys) {
Account account = (Account) data.getParcelable(key);
String accountString = accountToString(account);
if (accountString != null) {
editor.putString(key, accountString);
}
}
for (String key : mPersistableBundleKeys) {
// Cast should be guaranteed to succeed by check in the provisioning activities.
String bundleString = persistableBundleToString((PersistableBundle) data
.getParcelable(key));
if (bundleString != null) {
editor.putString(key, bundleString);
}
}
for (String key : mComponentNameKeys) {
ComponentName cn = (ComponentName) data.getParcelable(key);
if (cn != null) {
editor.putString(key, cn.flattenToString());
}
}
editor.putBoolean(IS_SET, true);
editor.commit();
}
public Intent load() {
if (!mPrefs.getBoolean(IS_SET, false)) {
return null;
}
Intent result = new Intent();
result.setComponent(mIntentTarget);
for (String key : mStringKeys) {
String value = mPrefs.getString(key, null);
if (value != null) {
result.putExtra(key, value);
}
}
for (String key : mLongKeys) {
if (mPrefs.contains(key)) {
result.putExtra(key, mPrefs.getLong(key, 0));
}
}
for (String key : mIntKeys) {
if (mPrefs.contains(key)) {
result.putExtra(key, mPrefs.getInt(key, 0));
}
}
for (String key : mBooleanKeys) {
if (mPrefs.contains(key)) {
result.putExtra(key, mPrefs.getBoolean(key, false));
}
}
for (String key : mAccountKeys) {
if (mPrefs.contains(key)) {
Account account = stringToAccount(mPrefs.getString(key, null));
if (account != null) {
result.putExtra(key, account);
}
}
}
for (String key : mPersistableBundleKeys) {
if (mPrefs.contains(key)) {
PersistableBundle bundle = stringToPersistableBundle(mPrefs.getString(key, null));
if (bundle != null) {
result.putExtra(key, bundle);
}
}
}
for (String key : mComponentNameKeys) {
if (mPrefs.contains(key)) {
String st = mPrefs.getString(key, null);
if (st != null) {
result.putExtra(key, ComponentName.unflattenFromString(st));
}
}
}
return result;
}
private String accountToString(Account account) {
if (account == null) {
return null;
}
StringWriter writer = new StringWriter();
XmlSerializer serializer = Xml.newSerializer();
try {
serializer.setOutput(writer);
serializer.startDocument(null, true);
serializer.startTag(null, TAG_ACCOUNT);
serializer.attribute(null /* namespace */, ATTRIBUTE_ACCOUNT_NAME, account.name);
serializer.attribute(null /* namespace */, ATTRIBUTE_ACCOUNT_TYPE, account.type);
serializer.endTag(null, TAG_ACCOUNT);
serializer.endDocument();
} catch (IOException e) {
ProvisionLogger.loge("Account could not be stored as string.", e);
return null;
}
return writer.toString();
}
private Account stringToAccount(String string) {
if (string == null) {
return null;
}
XmlPullParserFactory factory;
XmlPullParser parser;
try {
factory = XmlPullParserFactory.newInstance();
parser = factory.newPullParser();
parser.setInput(new StringReader(string));
if ((parser.next() == XmlPullParser.START_TAG)
&& TAG_ACCOUNT.equals(parser.getName())) {
String name = parser.getAttributeValue(null /* namespace */,
ATTRIBUTE_ACCOUNT_NAME);
String type = parser.getAttributeValue(null /* namespace */,
ATTRIBUTE_ACCOUNT_TYPE);
if (name != null && type != null) {
return new Account(name, type);
}
}
} catch (IOException|XmlPullParserException e) {
ProvisionLogger.loge(e);
// Fall through.
}
ProvisionLogger.loge("Account could not be restored from string " + string);
return null;
}
private String persistableBundleToString(PersistableBundle bundle) {
if (bundle == null) {
return null;
}
StringWriter writer = new StringWriter();
XmlSerializer serializer = Xml.newSerializer();
try {
serializer.setOutput(writer);
serializer.startDocument(null, true);
serializer.startTag(null, TAG_PERSISTABLEBUNDLE);
bundle.saveToXml(serializer);
serializer.endTag(null, TAG_PERSISTABLEBUNDLE);
serializer.endDocument();
} catch (IOException|XmlPullParserException e) {
ProvisionLogger.loge("Persistable bundle could not be stored as string.", e);
return null;
}
return writer.toString();
}
private PersistableBundle stringToPersistableBundle(String string) {
if (string == null) {
return null;
}
XmlPullParserFactory factory;
XmlPullParser parser;
try {
factory = XmlPullParserFactory.newInstance();
parser = factory.newPullParser();
parser.setInput(new StringReader(string));
if (parser.next() == XmlPullParser.START_TAG) {
if (TAG_PERSISTABLEBUNDLE.equals(parser.getName())) {
return PersistableBundle.restoreFromXml(parser);
}
}
} catch (IOException|XmlPullParserException e) {
ProvisionLogger.loge(e);
// Fall through.
}
ProvisionLogger.loge("Persistable bundle could not be restored from string " + string);
return null;
}
}