Add conditionals to Settings
Also add Airplane Mode and Hotspot conditionals (more to come soon) Change-Id: I11f206db59f7c715f416fb5852b8f0fcb857a247
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.settings.dashboard.conditional;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.PersistableBundle;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class ConditionManager {
|
||||
|
||||
private static final String TAG = "ConditionManager";
|
||||
|
||||
private static final boolean DEBUG = true;
|
||||
|
||||
private static final String FILE_NAME = "condition_state.xml";
|
||||
private static final String TAG_CONDITIONS = "conditions";
|
||||
private static final String TAG_CONDITION = "condition";
|
||||
private static final String ATTR_CLASS = "class";
|
||||
|
||||
private static ConditionManager sInstance;
|
||||
|
||||
private final Context mContext;
|
||||
private final ArrayList<Condition> mConditions;
|
||||
private final File mXmlFile;
|
||||
|
||||
private final ArrayList<ConditionListener> mListeners = new ArrayList<>();
|
||||
|
||||
private ConditionManager(Context context) {
|
||||
mContext = context;
|
||||
mConditions = new ArrayList<Condition>();
|
||||
mXmlFile = new File(context.getFilesDir(), FILE_NAME);
|
||||
if (mXmlFile.exists()) {
|
||||
readFromXml();
|
||||
}
|
||||
addMissingConditions();
|
||||
}
|
||||
|
||||
public void refreshAll() {
|
||||
final int N = mConditions.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
mConditions.get(i).refreshState();
|
||||
}
|
||||
}
|
||||
|
||||
private void readFromXml() {
|
||||
if (DEBUG) Log.d(TAG, "Reading from " + mXmlFile.toString());
|
||||
try {
|
||||
XmlPullParser parser = Xml.newPullParser();
|
||||
FileReader in = new FileReader(mXmlFile);
|
||||
parser.setInput(in);
|
||||
int state = parser.getEventType();
|
||||
|
||||
while (state != XmlPullParser.END_DOCUMENT) {
|
||||
if (TAG_CONDITION.equals(parser.getName())) {
|
||||
int depth = parser.getDepth();
|
||||
String clz = parser.getAttributeValue("", ATTR_CLASS);
|
||||
Condition condition = createCondition(Class.forName(clz));
|
||||
PersistableBundle bundle = PersistableBundle.restoreFromXml(parser);
|
||||
if (DEBUG) Log.d(TAG, "Reading " + clz + " -- " + bundle);
|
||||
condition.restoreState(bundle);
|
||||
mConditions.add(condition);
|
||||
while (parser.getDepth() > depth) {
|
||||
parser.next();
|
||||
}
|
||||
}
|
||||
state = parser.next();
|
||||
}
|
||||
in.close();
|
||||
} catch (XmlPullParserException | IOException | ClassNotFoundException e) {
|
||||
Log.w(TAG, "Problem reading " + FILE_NAME, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveToXml() {
|
||||
if (DEBUG) Log.d(TAG, "Writing to " + mXmlFile.toString());
|
||||
try {
|
||||
XmlSerializer serializer = Xml.newSerializer();
|
||||
FileWriter writer = new FileWriter(mXmlFile);
|
||||
serializer.setOutput(writer);
|
||||
|
||||
serializer.startDocument("UTF-8", true);
|
||||
serializer.startTag("", TAG_CONDITIONS);
|
||||
|
||||
final int N = mConditions.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
serializer.startTag("", TAG_CONDITION);
|
||||
serializer.attribute("", ATTR_CLASS, mConditions.get(i).getClass().getName());
|
||||
PersistableBundle bundle = new PersistableBundle();
|
||||
mConditions.get(i).saveState(bundle);
|
||||
bundle.saveToXml(serializer);
|
||||
serializer.endTag("", TAG_CONDITION);
|
||||
}
|
||||
|
||||
serializer.endTag("", TAG_CONDITIONS);
|
||||
serializer.flush();
|
||||
writer.close();
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
Log.w(TAG, "Problem writing " + FILE_NAME, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void addMissingConditions() {
|
||||
addIfMissing(AirplaneModeCondition.class);
|
||||
addIfMissing(HotspotCondition.class);
|
||||
}
|
||||
|
||||
private void addIfMissing(Class<? extends Condition> clz) {
|
||||
if (getCondition(clz) == null) {
|
||||
if (DEBUG) Log.d(TAG, "Adding missing " + clz.getName());
|
||||
mConditions.add(createCondition(clz));
|
||||
}
|
||||
}
|
||||
|
||||
private Condition createCondition(Class<?> clz) {
|
||||
if (AirplaneModeCondition.class == clz) {
|
||||
return new AirplaneModeCondition(this);
|
||||
} else if (HotspotCondition.class == clz) {
|
||||
return new HotspotCondition(this);
|
||||
}
|
||||
try {
|
||||
Constructor<?> constructor = clz.getConstructor(ConditionManager.class);
|
||||
return (Condition) constructor.newInstance(this);
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException
|
||||
| InvocationTargetException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
public <T extends Condition> T getCondition(Class<T> clz) {
|
||||
final int N = mConditions.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
if (clz.equals(mConditions.get(i).getClass())) {
|
||||
return (T) mConditions.get(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Condition> getConditions() {
|
||||
return mConditions;
|
||||
}
|
||||
|
||||
public List<Condition> getVisibleConditions() {
|
||||
List<Condition> conditions = new ArrayList<>();
|
||||
final int N = mConditions.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
if (mConditions.get(i).shouldShow()) {
|
||||
conditions.add(mConditions.get(i));
|
||||
}
|
||||
}
|
||||
Collections.sort(conditions, CONDITION_COMPARATOR);
|
||||
return conditions;
|
||||
}
|
||||
|
||||
public void notifyChanged(Condition condition) {
|
||||
saveToXml();
|
||||
final int N = mListeners.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
mListeners.get(i).onConditionsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void addListener(ConditionListener listener) {
|
||||
mListeners.add(listener);
|
||||
}
|
||||
|
||||
public void remListener(ConditionListener listener) {
|
||||
mListeners.remove(listener);
|
||||
}
|
||||
|
||||
public static ConditionManager get(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new ConditionManager(context);
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public interface ConditionListener {
|
||||
void onConditionsChanged();
|
||||
}
|
||||
|
||||
private static final Comparator<Condition> CONDITION_COMPARATOR = new Comparator<Condition>() {
|
||||
@Override
|
||||
public int compare(Condition lhs, Condition rhs) {
|
||||
return Long.compare(lhs.getLastChange(), rhs.getLastChange());
|
||||
}
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user