OSDN Git Service

Don't update conditions on background threads
authorJason Monk <jmonk@google.com>
Wed, 25 May 2016 16:53:34 +0000 (12:53 -0400)
committerJason Monk <jmonk@google.com>
Wed, 25 May 2016 16:53:34 +0000 (12:53 -0400)
Instead build a list and set it on the main thread to avoid
concurrent modification crashes.

Change-Id: I936fbeb70359583e55ae8ddcb0ea46b5753cb3b0
Fixes: 28794277

src/com/android/settings/dashboard/conditional/ConditionManager.java

index 128ac27..f38bb2a 100644 (file)
@@ -56,7 +56,7 @@ public class ConditionManager {
 
     private ConditionManager(Context context) {
         mContext = context;
-        mConditions = new ArrayList<Condition>();
+        mConditions = new ArrayList<>();
         new ConditionLoader().execute();
     }
 
@@ -67,11 +67,11 @@ public class ConditionManager {
         }
     }
 
-    private void readFromXml() {
-        if (DEBUG) Log.d(TAG, "Reading from " + mXmlFile.toString());
+    private void readFromXml(File xmlFile, ArrayList<Condition> conditions) {
+        if (DEBUG) Log.d(TAG, "Reading from " + xmlFile.toString());
         try {
             XmlPullParser parser = Xml.newPullParser();
-            FileReader in = new FileReader(mXmlFile);
+            FileReader in = new FileReader(xmlFile);
             parser.setInput(in);
             int state = parser.getEventType();
 
@@ -86,7 +86,7 @@ public class ConditionManager {
                     PersistableBundle bundle = PersistableBundle.restoreFromXml(parser);
                     if (DEBUG) Log.d(TAG, "Reading " + clz + " -- " + bundle);
                     condition.restoreState(bundle);
-                    mConditions.add(condition);
+                    conditions.add(condition);
                     while (parser.getDepth() > depth) {
                         parser.next();
                     }
@@ -129,21 +129,21 @@ public class ConditionManager {
         }
     }
 
-    private void addMissingConditions() {
-        addIfMissing(AirplaneModeCondition.class);
-        addIfMissing(HotspotCondition.class);
-        addIfMissing(DndCondition.class);
-        addIfMissing(BatterySaverCondition.class);
-        addIfMissing(CellularDataCondition.class);
-        addIfMissing(BackgroundDataCondition.class);
-        addIfMissing(WorkModeCondition.class);
-        Collections.sort(mConditions, CONDITION_COMPARATOR);
+    private void addMissingConditions(ArrayList<Condition> conditions) {
+        addIfMissing(AirplaneModeCondition.class, conditions);
+        addIfMissing(HotspotCondition.class, conditions);
+        addIfMissing(DndCondition.class, conditions);
+        addIfMissing(BatterySaverCondition.class, conditions);
+        addIfMissing(CellularDataCondition.class, conditions);
+        addIfMissing(BackgroundDataCondition.class, conditions);
+        addIfMissing(WorkModeCondition.class, conditions);
+        Collections.sort(conditions, CONDITION_COMPARATOR);
     }
 
-    private void addIfMissing(Class<? extends Condition> clz) {
-        if (getCondition(clz) == null) {
+    private void addIfMissing(Class<? extends Condition> clz, ArrayList<Condition> conditions) {
+        if (getCondition(clz, conditions) == null) {
             if (DEBUG) Log.d(TAG, "Adding missing " + clz.getName());
-            mConditions.add(createCondition(clz));
+            conditions.add(createCondition(clz));
         }
     }
 
@@ -171,10 +171,14 @@ public class ConditionManager {
     }
 
     public <T extends Condition> T getCondition(Class<T> clz) {
-        final int N = mConditions.size();
+        return getCondition(clz, mConditions);
+    }
+
+    private <T extends Condition> T getCondition(Class<T> clz, List<Condition> conditions) {
+        final int N = conditions.size();
         for (int i = 0; i < N; i++) {
-            if (clz.equals(mConditions.get(i).getClass())) {
-                return (T) mConditions.get(i);
+            if (clz.equals(conditions.get(i).getClass())) {
+                return (T) conditions.get(i);
             }
         }
         return null;
@@ -213,19 +217,22 @@ public class ConditionManager {
         mListeners.remove(listener);
     }
 
-    private class ConditionLoader extends AsyncTask<Void, Void, Void> {
+    private class ConditionLoader extends AsyncTask<Void, Void, ArrayList<Condition>> {
         @Override
-        protected Void doInBackground(Void... params) {
+        protected ArrayList<Condition> doInBackground(Void... params) {
+            ArrayList<Condition> conditions = new ArrayList<>();
             mXmlFile = new File(mContext.getFilesDir(), FILE_NAME);
             if (mXmlFile.exists()) {
-                readFromXml();
+                readFromXml(mXmlFile, conditions);
             }
-            addMissingConditions();
-            return null;
+            addMissingConditions(conditions);
+            return conditions;
         }
 
         @Override
-        protected void onPostExecute(Void aVoid) {
+        protected void onPostExecute(ArrayList<Condition> conditions) {
+            mConditions.clear();
+            mConditions.addAll(conditions);
             final int N = mListeners.size();
             for (int i = 0; i < N; i++) {
                 mListeners.get(i).onConditionsChanged();