summaryrefslogtreecommitdiffstats
path: root/core/java/android/widget/ActivityChooserModel.java
diff options
context:
space:
mode:
authorSvetoslav Ganov <svetoslavganov@google.com>2012-05-07 18:23:44 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-05-07 18:23:44 -0700
commitb1ae25cb37e92a30d196290b75a159e5382c5b34 (patch)
tree2fa20cf2a87868d09cbd7f630874f4177d0e34f7 /core/java/android/widget/ActivityChooserModel.java
parentb2ee0d57672faf42ca88fa878dc7e688046c915e (diff)
parentca858797816be82e2b1e2b88dea17b20e52d8429 (diff)
downloadframeworks_base-b1ae25cb37e92a30d196290b75a159e5382c5b34.zip
frameworks_base-b1ae25cb37e92a30d196290b75a159e5382c5b34.tar.gz
frameworks_base-b1ae25cb37e92a30d196290b75a159e5382c5b34.tar.bz2
Merge "ActivityChooserModel does not handle package changes on the thread that created it." into jb-dev
Diffstat (limited to 'core/java/android/widget/ActivityChooserModel.java')
-rw-r--r--core/java/android/widget/ActivityChooserModel.java547
1 files changed, 244 insertions, 303 deletions
diff --git a/core/java/android/widget/ActivityChooserModel.java b/core/java/android/widget/ActivityChooserModel.java
index fba8d3a..1578154 100644
--- a/core/java/android/widget/ActivityChooserModel.java
+++ b/core/java/android/widget/ActivityChooserModel.java
@@ -21,9 +21,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.database.DataSetObservable;
-import android.database.DataSetObserver;
import android.os.AsyncTask;
-import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.util.Xml;
@@ -42,10 +40,8 @@ import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
-import java.util.Set;
/**
* <p>
@@ -239,7 +235,7 @@ public class ActivityChooserModel extends DataSetObservable {
/**
* List of activities that can handle the current intent.
*/
- private final List<ActivityResolveInfo> mActivites = new ArrayList<ActivityResolveInfo>();
+ private final List<ActivityResolveInfo> mActivities = new ArrayList<ActivityResolveInfo>();
/**
* List with historical choice records.
@@ -278,18 +274,18 @@ public class ActivityChooserModel extends DataSetObservable {
/**
* Flag whether choice history can be read. In general many clients can
- * share the same data model and {@link #readHistoricalData()} may be called
+ * share the same data model and {@link #readHistoricalDataIfNeeded()} may be called
* by arbitrary of them any number of times. Therefore, this class guarantees
* that the very first read succeeds and subsequent reads can be performed
- * only after a call to {@link #persistHistoricalData()} followed by change
+ * only after a call to {@link #persistHistoricalDataIfNeeded()} followed by change
* of the share records.
*/
private boolean mCanReadHistoricalData = true;
/**
* Flag whether the choice history was read. This is used to enforce that
- * before calling {@link #persistHistoricalData()} a call to
- * {@link #persistHistoricalData()} has been made. This aims to avoid a
+ * before calling {@link #persistHistoricalDataIfNeeded()} a call to
+ * {@link #persistHistoricalDataIfNeeded()} has been made. This aims to avoid a
* scenario in which a choice history file exits, it is not read yet and
* it is overwritten. Note that always all historical records are read in
* full and the file is rewritten. This is necessary since we need to
@@ -299,16 +295,16 @@ public class ActivityChooserModel extends DataSetObservable {
/**
* Flag whether the choice records have changed. In general many clients can
- * share the same data model and {@link #persistHistoricalData()} may be called
+ * share the same data model and {@link #persistHistoricalDataIfNeeded()} may be called
* by arbitrary of them any number of times. Therefore, this class guarantees
* that choice history will be persisted only if it has changed.
*/
private boolean mHistoricalRecordsChanged = true;
/**
- * Hander for scheduling work on client tread.
+ * Flag whether to reload the activities for the current intent.
*/
- private final Handler mHandler = new Handler();
+ private boolean mReloadActivities = false;
/**
* Policy for controlling how the model handles chosen activities.
@@ -346,7 +342,6 @@ public class ActivityChooserModel extends DataSetObservable {
dataModel = new ActivityChooserModel(context, historyFileName);
sDataModelRegistry.put(historyFileName, dataModel);
}
- dataModel.readHistoricalData();
return dataModel;
}
}
@@ -383,7 +378,8 @@ public class ActivityChooserModel extends DataSetObservable {
return;
}
mIntent = intent;
- loadActivitiesLocked();
+ mReloadActivities = true;
+ ensureConsistentState();
}
}
@@ -407,7 +403,8 @@ public class ActivityChooserModel extends DataSetObservable {
*/
public int getActivityCount() {
synchronized (mInstanceLock) {
- return mActivites.size();
+ ensureConsistentState();
+ return mActivities.size();
}
}
@@ -421,7 +418,8 @@ public class ActivityChooserModel extends DataSetObservable {
*/
public ResolveInfo getActivity(int index) {
synchronized (mInstanceLock) {
- return mActivites.get(index).resolveInfo;
+ ensureConsistentState();
+ return mActivities.get(index).resolveInfo;
}
}
@@ -433,15 +431,18 @@ public class ActivityChooserModel extends DataSetObservable {
* @return The index if found, -1 otherwise.
*/
public int getActivityIndex(ResolveInfo activity) {
- List<ActivityResolveInfo> activities = mActivites;
- final int activityCount = activities.size();
- for (int i = 0; i < activityCount; i++) {
- ActivityResolveInfo currentActivity = activities.get(i);
- if (currentActivity.resolveInfo == activity) {
- return i;
+ synchronized (mInstanceLock) {
+ ensureConsistentState();
+ List<ActivityResolveInfo> activities = mActivities;
+ final int activityCount = activities.size();
+ for (int i = 0; i < activityCount; i++) {
+ ActivityResolveInfo currentActivity = activities.get(i);
+ if (currentActivity.resolveInfo == activity) {
+ return i;
+ }
}
+ return INVALID_INDEX;
}
- return INVALID_INDEX;
}
/**
@@ -462,30 +463,34 @@ public class ActivityChooserModel extends DataSetObservable {
* @see OnChooseActivityListener
*/
public Intent chooseActivity(int index) {
- ActivityResolveInfo chosenActivity = mActivites.get(index);
+ synchronized (mInstanceLock) {
+ ensureConsistentState();
- ComponentName chosenName = new ComponentName(
- chosenActivity.resolveInfo.activityInfo.packageName,
- chosenActivity.resolveInfo.activityInfo.name);
+ ActivityResolveInfo chosenActivity = mActivities.get(index);
- Intent choiceIntent = new Intent(mIntent);
- choiceIntent.setComponent(chosenName);
+ ComponentName chosenName = new ComponentName(
+ chosenActivity.resolveInfo.activityInfo.packageName,
+ chosenActivity.resolveInfo.activityInfo.name);
- if (mActivityChoserModelPolicy != null) {
- // Do not allow the policy to change the intent.
- Intent choiceIntentCopy = new Intent(choiceIntent);
- final boolean handled = mActivityChoserModelPolicy.onChooseActivity(this,
- choiceIntentCopy);
- if (handled) {
- return null;
+ Intent choiceIntent = new Intent(mIntent);
+ choiceIntent.setComponent(chosenName);
+
+ if (mActivityChoserModelPolicy != null) {
+ // Do not allow the policy to change the intent.
+ Intent choiceIntentCopy = new Intent(choiceIntent);
+ final boolean handled = mActivityChoserModelPolicy.onChooseActivity(this,
+ choiceIntentCopy);
+ if (handled) {
+ return null;
+ }
}
- }
- HistoricalRecord historicalRecord = new HistoricalRecord(chosenName,
- System.currentTimeMillis(), DEFAULT_HISTORICAL_RECORD_WEIGHT);
- addHisoricalRecord(historicalRecord);
+ HistoricalRecord historicalRecord = new HistoricalRecord(chosenName,
+ System.currentTimeMillis(), DEFAULT_HISTORICAL_RECORD_WEIGHT);
+ addHisoricalRecord(historicalRecord);
- return choiceIntent;
+ return choiceIntent;
+ }
}
/**
@@ -494,7 +499,9 @@ public class ActivityChooserModel extends DataSetObservable {
* @param listener The listener.
*/
public void setOnChooseActivityListener(OnChooseActivityListener listener) {
- mActivityChoserModelPolicy = listener;
+ synchronized (mInstanceLock) {
+ mActivityChoserModelPolicy = listener;
+ }
}
/**
@@ -508,8 +515,9 @@ public class ActivityChooserModel extends DataSetObservable {
*/
public ResolveInfo getDefaultActivity() {
synchronized (mInstanceLock) {
- if (!mActivites.isEmpty()) {
- return mActivites.get(0).resolveInfo;
+ ensureConsistentState();
+ if (!mActivities.isEmpty()) {
+ return mActivities.get(0).resolveInfo;
}
}
return null;
@@ -526,72 +534,50 @@ public class ActivityChooserModel extends DataSetObservable {
* @param index The index of the activity to set as default.
*/
public void setDefaultActivity(int index) {
- ActivityResolveInfo newDefaultActivity = mActivites.get(index);
- ActivityResolveInfo oldDefaultActivity = mActivites.get(0);
-
- final float weight;
- if (oldDefaultActivity != null) {
- // Add a record with weight enough to boost the chosen at the top.
- weight = oldDefaultActivity.weight - newDefaultActivity.weight
- + DEFAULT_ACTIVITY_INFLATION;
- } else {
- weight = DEFAULT_HISTORICAL_RECORD_WEIGHT;
- }
-
- ComponentName defaultName = new ComponentName(
- newDefaultActivity.resolveInfo.activityInfo.packageName,
- newDefaultActivity.resolveInfo.activityInfo.name);
- HistoricalRecord historicalRecord = new HistoricalRecord(defaultName,
- System.currentTimeMillis(), weight);
- addHisoricalRecord(historicalRecord);
- }
-
- /**
- * Reads the history data from the backing file if the latter
- * was provided. Calling this method more than once before a call
- * to {@link #persistHistoricalData()} has been made has no effect.
- * <p>
- * <strong>Note:</strong> Historical data is read asynchronously and
- * as soon as the reading is completed any registered
- * {@link DataSetObserver}s will be notified. Also no historical
- * data is read until this method is invoked.
- * <p>
- */
- private void readHistoricalData() {
synchronized (mInstanceLock) {
- if (!mCanReadHistoricalData || !mHistoricalRecordsChanged) {
- return;
- }
- mCanReadHistoricalData = false;
- mReadShareHistoryCalled = true;
- if (!TextUtils.isEmpty(mHistoryFileName)) {
- AsyncTask.SERIAL_EXECUTOR.execute(new HistoryLoader());
+ ensureConsistentState();
+
+ ActivityResolveInfo newDefaultActivity = mActivities.get(index);
+ ActivityResolveInfo oldDefaultActivity = mActivities.get(0);
+
+ final float weight;
+ if (oldDefaultActivity != null) {
+ // Add a record with weight enough to boost the chosen at the top.
+ weight = oldDefaultActivity.weight - newDefaultActivity.weight
+ + DEFAULT_ACTIVITY_INFLATION;
+ } else {
+ weight = DEFAULT_HISTORICAL_RECORD_WEIGHT;
}
+
+ ComponentName defaultName = new ComponentName(
+ newDefaultActivity.resolveInfo.activityInfo.packageName,
+ newDefaultActivity.resolveInfo.activityInfo.name);
+ HistoricalRecord historicalRecord = new HistoricalRecord(defaultName,
+ System.currentTimeMillis(), weight);
+ addHisoricalRecord(historicalRecord);
}
}
/**
* Persists the history data to the backing file if the latter
- * was provided. Calling this method before a call to {@link #readHistoricalData()}
+ * was provided. Calling this method before a call to {@link #readHistoricalDataIfNeeded()}
* throws an exception. Calling this method more than one without choosing an
* activity has not effect.
*
* @throws IllegalStateException If this method is called before a call to
- * {@link #readHistoricalData()}.
+ * {@link #readHistoricalDataIfNeeded()}.
*/
- private void persistHistoricalData() {
- synchronized (mInstanceLock) {
- if (!mReadShareHistoryCalled) {
- throw new IllegalStateException("No preceding call to #readHistoricalData");
- }
- if (!mHistoricalRecordsChanged) {
- return;
- }
- mHistoricalRecordsChanged = false;
- mCanReadHistoricalData = true;
- if (!TextUtils.isEmpty(mHistoryFileName)) {
- AsyncTask.SERIAL_EXECUTOR.execute(new HistoryPersister());
- }
+ private void persistHistoricalDataIfNeeded() {
+ if (!mReadShareHistoryCalled) {
+ throw new IllegalStateException("No preceding call to #readHistoricalData");
+ }
+ if (!mHistoricalRecordsChanged) {
+ return;
+ }
+ mHistoricalRecordsChanged = false;
+ if (!TextUtils.isEmpty(mHistoryFileName)) {
+ new PersistHistoryAsyncTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR,
+ new ArrayList<HistoricalRecord>(mHistoricalRecords), mHistoryFileName);
}
}
@@ -608,21 +594,7 @@ public class ActivityChooserModel extends DataSetObservable {
return;
}
mActivitySorter = activitySorter;
- sortActivities();
- }
- }
-
- /**
- * Sorts the activities based on history and an intent. If
- * a sorter is not specified this a default implementation is used.
- *
- * @see #setActivitySorter(ActivitySorter)
- */
- private void sortActivities() {
- synchronized (mInstanceLock) {
- if (mActivitySorter != null && !mActivites.isEmpty()) {
- mActivitySorter.sort(mIntent, mActivites,
- Collections.unmodifiableList(mHistoricalRecords));
+ if (sortActivitiesIfNeeded()) {
notifyChanged();
}
}
@@ -647,8 +619,10 @@ public class ActivityChooserModel extends DataSetObservable {
return;
}
mHistoryMaxSize = historyMaxSize;
- pruneExcessiveHistoricalRecordsLocked();
- sortActivities();
+ pruneExcessiveHistoricalRecordsIfNeeded();
+ if (sortActivitiesIfNeeded()) {
+ notifyChanged();
+ }
}
}
@@ -670,6 +644,7 @@ public class ActivityChooserModel extends DataSetObservable {
*/
public int getHistorySize() {
synchronized (mInstanceLock) {
+ ensureConsistentState();
return mHistoricalRecords.size();
}
}
@@ -681,82 +656,110 @@ public class ActivityChooserModel extends DataSetObservable {
}
/**
- * Adds a historical record.
- *
- * @param historicalRecord The record to add.
- * @return True if the record was added.
+ * Ensures the model is in a consistent state which is the
+ * activities for the current intent have been loaded, the
+ * most recent history has been read, and the activities
+ * are sorted.
*/
- private boolean addHisoricalRecord(HistoricalRecord historicalRecord) {
- synchronized (mInstanceLock) {
- final boolean added = mHistoricalRecords.add(historicalRecord);
- if (added) {
- mHistoricalRecordsChanged = true;
- pruneExcessiveHistoricalRecordsLocked();
- persistHistoricalData();
- sortActivities();
- }
- return added;
+ private void ensureConsistentState() {
+ boolean stateChanged = loadActivitiesIfNeeded();
+ stateChanged |= readHistoricalDataIfNeeded();
+ pruneExcessiveHistoricalRecordsIfNeeded();
+ if (stateChanged) {
+ sortActivitiesIfNeeded();
+ notifyChanged();
}
}
/**
- * Prunes older excessive records to guarantee {@link #mHistoryMaxSize}.
+ * Sorts the activities if necessary which is if there is a
+ * sorter, there are some activities to sort, and there is some
+ * historical data.
+ *
+ * @return Whether sorting was performed.
*/
- private void pruneExcessiveHistoricalRecordsLocked() {
- List<HistoricalRecord> choiceRecords = mHistoricalRecords;
- final int pruneCount = choiceRecords.size() - mHistoryMaxSize;
- if (pruneCount <= 0) {
- return;
- }
- mHistoricalRecordsChanged = true;
- for (int i = 0; i < pruneCount; i++) {
- HistoricalRecord prunedRecord = choiceRecords.remove(0);
- if (DEBUG) {
- Log.i(LOG_TAG, "Pruned: " + prunedRecord);
- }
+ private boolean sortActivitiesIfNeeded() {
+ if (mActivitySorter != null && mIntent != null
+ && !mActivities.isEmpty() && !mHistoricalRecords.isEmpty()) {
+ mActivitySorter.sort(mIntent, mActivities,
+ Collections.unmodifiableList(mHistoricalRecords));
+ return true;
}
+ return false;
}
/**
- * Loads the activities.
+ * Loads the activities for the current intent if needed which is
+ * if they are not already loaded for the current intent.
+ *
+ * @return Whether loading was performed.
*/
- private void loadActivitiesLocked() {
- mActivites.clear();
- if (mIntent != null) {
- List<ResolveInfo> resolveInfos =
- mContext.getPackageManager().queryIntentActivities(mIntent, 0);
+ private boolean loadActivitiesIfNeeded() {
+ if (mReloadActivities && mIntent != null) {
+ mReloadActivities = false;
+ mActivities.clear();
+ List<ResolveInfo> resolveInfos = mContext.getPackageManager()
+ .queryIntentActivities(mIntent, 0);
final int resolveInfoCount = resolveInfos.size();
for (int i = 0; i < resolveInfoCount; i++) {
ResolveInfo resolveInfo = resolveInfos.get(i);
- mActivites.add(new ActivityResolveInfo(resolveInfo));
+ mActivities.add(new ActivityResolveInfo(resolveInfo));
}
- sortActivities();
- } else {
- notifyChanged();
+ return true;
}
+ return false;
}
/**
- * Prunes historical records for a package that goes away.
+ * Reads the historical data if necessary which is it has
+ * changed, there is a history file, and there is not persist
+ * in progress.
*
- * @param packageName The name of the package that goes away.
+ * @return Whether reading was performed.
*/
- private void pruneHistoricalRecordsForPackageLocked(String packageName) {
- boolean recordsRemoved = false;
-
- List<HistoricalRecord> historicalRecords = mHistoricalRecords;
- for (int i = 0; i < historicalRecords.size(); i++) {
- HistoricalRecord historicalRecord = historicalRecords.get(i);
- String recordPackageName = historicalRecord.activity.getPackageName();
- if (recordPackageName.equals(packageName)) {
- historicalRecords.remove(historicalRecord);
- recordsRemoved = true;
- }
+ private boolean readHistoricalDataIfNeeded() {
+ if (mCanReadHistoricalData && mHistoricalRecordsChanged &&
+ !TextUtils.isEmpty(mHistoryFileName)) {
+ mCanReadHistoricalData = false;
+ mReadShareHistoryCalled = true;
+ readHistoricalDataImpl();
+ return true;
}
+ return false;
+ }
- if (recordsRemoved) {
+ /**
+ * Adds a historical record.
+ *
+ * @param historicalRecord The record to add.
+ * @return True if the record was added.
+ */
+ private boolean addHisoricalRecord(HistoricalRecord historicalRecord) {
+ final boolean added = mHistoricalRecords.add(historicalRecord);
+ if (added) {
mHistoricalRecordsChanged = true;
- sortActivities();
+ pruneExcessiveHistoricalRecordsIfNeeded();
+ persistHistoricalDataIfNeeded();
+ sortActivitiesIfNeeded();
+ notifyChanged();
+ }
+ return added;
+ }
+
+ /**
+ * Prunes older excessive records to guarantee maxHistorySize.
+ */
+ private void pruneExcessiveHistoricalRecordsIfNeeded() {
+ final int pruneCount = mHistoricalRecords.size() - mHistoryMaxSize;
+ if (pruneCount <= 0) {
+ return;
+ }
+ mHistoricalRecordsChanged = true;
+ for (int i = 0; i < pruneCount; i++) {
+ HistoricalRecord prunedRecord = mHistoricalRecords.remove(0);
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Pruned: " + prunedRecord);
+ }
}
}
@@ -974,112 +977,72 @@ public class ActivityChooserModel extends DataSetObservable {
/**
* Command for reading the historical records from a file off the UI thread.
*/
- private final class HistoryLoader implements Runnable {
-
- public void run() {
- FileInputStream fis = null;
- try {
- fis = mContext.openFileInput(mHistoryFileName);
- } catch (FileNotFoundException fnfe) {
- if (DEBUG) {
- Log.i(LOG_TAG, "Could not open historical records file: " + mHistoryFileName);
- }
- return;
+ private void readHistoricalDataImpl() {
+ FileInputStream fis = null;
+ try {
+ fis = mContext.openFileInput(mHistoryFileName);
+ } catch (FileNotFoundException fnfe) {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Could not open historical records file: " + mHistoryFileName);
}
- try {
- XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
-
- int type = XmlPullParser.START_DOCUMENT;
- while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {
- type = parser.next();
- }
-
- if (!TAG_HISTORICAL_RECORDS.equals(parser.getName())) {
- throw new XmlPullParserException("Share records file does not start with "
- + TAG_HISTORICAL_RECORDS + " tag.");
- }
-
- List<HistoricalRecord> readRecords = new ArrayList<HistoricalRecord>();
+ return;
+ }
+ try {
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(fis, null);
- while (true) {
- type = parser.next();
- if (type == XmlPullParser.END_DOCUMENT) {
- break;
- }
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
- String nodeName = parser.getName();
- if (!TAG_HISTORICAL_RECORD.equals(nodeName)) {
- throw new XmlPullParserException("Share records file not well-formed.");
- }
+ int type = XmlPullParser.START_DOCUMENT;
+ while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {
+ type = parser.next();
+ }
- String activity = parser.getAttributeValue(null, ATTRIBUTE_ACTIVITY);
- final long time =
- Long.parseLong(parser.getAttributeValue(null, ATTRIBUTE_TIME));
- final float weight =
- Float.parseFloat(parser.getAttributeValue(null, ATTRIBUTE_WEIGHT));
+ if (!TAG_HISTORICAL_RECORDS.equals(parser.getName())) {
+ throw new XmlPullParserException("Share records file does not start with "
+ + TAG_HISTORICAL_RECORDS + " tag.");
+ }
- HistoricalRecord readRecord = new HistoricalRecord(activity, time,
- weight);
- readRecords.add(readRecord);
+ List<HistoricalRecord> historicalRecords = mHistoricalRecords;
+ historicalRecords.clear();
- if (DEBUG) {
- Log.i(LOG_TAG, "Read " + readRecord.toString());
- }
+ while (true) {
+ type = parser.next();
+ if (type == XmlPullParser.END_DOCUMENT) {
+ break;
}
-
- if (DEBUG) {
- Log.i(LOG_TAG, "Read " + readRecords.size() + " historical records.");
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+ String nodeName = parser.getName();
+ if (!TAG_HISTORICAL_RECORD.equals(nodeName)) {
+ throw new XmlPullParserException("Share records file not well-formed.");
}
- synchronized (mInstanceLock) {
- Set<HistoricalRecord> uniqueShareRecords =
- new LinkedHashSet<HistoricalRecord>(readRecords);
-
- // Make sure no duplicates. Example: Read a file with
- // one record, add one record, persist the two records,
- // add a record, read the persisted records - the
- // read two records should not be added again.
- List<HistoricalRecord> historicalRecords = mHistoricalRecords;
- final int historicalRecordsCount = historicalRecords.size();
- for (int i = historicalRecordsCount - 1; i >= 0; i--) {
- HistoricalRecord historicalRecord = historicalRecords.get(i);
- uniqueShareRecords.add(historicalRecord);
- }
-
- if (historicalRecords.size() == uniqueShareRecords.size()) {
- return;
- }
+ String activity = parser.getAttributeValue(null, ATTRIBUTE_ACTIVITY);
+ final long time =
+ Long.parseLong(parser.getAttributeValue(null, ATTRIBUTE_TIME));
+ final float weight =
+ Float.parseFloat(parser.getAttributeValue(null, ATTRIBUTE_WEIGHT));
+ HistoricalRecord readRecord = new HistoricalRecord(activity, time, weight);
+ historicalRecords.add(readRecord);
- // Make sure the oldest records go to the end.
- historicalRecords.clear();
- historicalRecords.addAll(uniqueShareRecords);
-
- mHistoricalRecordsChanged = true;
-
- // Do this on the client thread since the client may be on the UI
- // thread, wait for data changes which happen during sorting, and
- // perform UI modification based on the data change.
- mHandler.post(new Runnable() {
- public void run() {
- pruneExcessiveHistoricalRecordsLocked();
- sortActivities();
- }
- });
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Read " + readRecord.toString());
}
- } catch (XmlPullParserException xppe) {
- Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, xppe);
- } catch (IOException ioe) {
- Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, ioe);
- } finally {
- if (fis != null) {
- try {
- fis.close();
- } catch (IOException ioe) {
- /* ignore */
- }
+ }
+
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Read " + historicalRecords.size() + " historical records.");
+ }
+ } catch (XmlPullParserException xppe) {
+ Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, xppe);
+ } catch (IOException ioe) {
+ Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, ioe);
+ } finally {
+ if (fis != null) {
+ try {
+ fis.close();
+ } catch (IOException ioe) {
+ /* ignore */
}
}
}
@@ -1088,21 +1051,21 @@ public class ActivityChooserModel extends DataSetObservable {
/**
* Command for persisting the historical records to a file off the UI thread.
*/
- private final class HistoryPersister implements Runnable {
+ private final class PersistHistoryAsyncTask extends AsyncTask<Object, Void, Void> {
- public void run() {
- FileOutputStream fos = null;
- List<HistoricalRecord> records = null;
+ @Override
+ @SuppressWarnings("unchecked")
+ public Void doInBackground(Object... args) {
+ List<HistoricalRecord> historicalRecords = (List<HistoricalRecord>) args[0];
+ String hostoryFileName = (String) args[1];
- synchronized (mInstanceLock) {
- records = new ArrayList<HistoricalRecord>(mHistoricalRecords);
- }
+ FileOutputStream fos = null;
try {
- fos = mContext.openFileOutput(mHistoryFileName, Context.MODE_PRIVATE);
+ fos = mContext.openFileOutput(hostoryFileName, Context.MODE_PRIVATE);
} catch (FileNotFoundException fnfe) {
- Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, fnfe);
- return;
+ Log.e(LOG_TAG, "Error writing historical recrod file: " + hostoryFileName, fnfe);
+ return null;
}
XmlSerializer serializer = Xml.newSerializer();
@@ -1112,11 +1075,12 @@ public class ActivityChooserModel extends DataSetObservable {
serializer.startDocument("UTF-8", true);
serializer.startTag(null, TAG_HISTORICAL_RECORDS);
- final int recordCount = records.size();
+ final int recordCount = historicalRecords.size();
for (int i = 0; i < recordCount; i++) {
- HistoricalRecord record = records.remove(0);
+ HistoricalRecord record = historicalRecords.remove(0);
serializer.startTag(null, TAG_HISTORICAL_RECORD);
- serializer.attribute(null, ATTRIBUTE_ACTIVITY, record.activity.flattenToString());
+ serializer.attribute(null, ATTRIBUTE_ACTIVITY,
+ record.activity.flattenToString());
serializer.attribute(null, ATTRIBUTE_TIME, String.valueOf(record.time));
serializer.attribute(null, ATTRIBUTE_WEIGHT, String.valueOf(record.weight));
serializer.endTag(null, TAG_HISTORICAL_RECORD);
@@ -1138,6 +1102,7 @@ public class ActivityChooserModel extends DataSetObservable {
} catch (IOException ioe) {
Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, ioe);
} finally {
+ mCanReadHistoricalData = true;
if (fos != null) {
try {
fos.close();
@@ -1146,6 +1111,7 @@ public class ActivityChooserModel extends DataSetObservable {
}
}
}
+ return null;
}
}
@@ -1155,33 +1121,8 @@ public class ActivityChooserModel extends DataSetObservable {
private final class DataModelPackageMonitor extends PackageMonitor {
@Override
- public void onPackageAdded(String packageName, int uid) {
- synchronized (mInstanceLock) {
- loadActivitiesLocked();
- }
- }
-
- @Override
- public void onPackageAppeared(String packageName, int reason) {
- synchronized (mInstanceLock) {
- loadActivitiesLocked();
- }
- }
-
- @Override
- public void onPackageRemoved(String packageName, int uid) {
- synchronized (mInstanceLock) {
- pruneHistoricalRecordsForPackageLocked(packageName);
- loadActivitiesLocked();
- }
- }
-
- @Override
- public void onPackageDisappeared(String packageName, int reason) {
- synchronized (mInstanceLock) {
- pruneHistoricalRecordsForPackageLocked(packageName);
- loadActivitiesLocked();
- }
+ public void onSomePackagesChanged() {
+ mReloadActivities = true;
}
}
}