Merge "Fix a bug where we could lose a loader content change." into jb-mr2-dev
diff --git a/api/current.txt b/api/current.txt
index 1668170..f4407b5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6159,6 +6159,7 @@
ctor public Loader(android.content.Context);
method public void abandon();
method public boolean cancelLoad();
+ method public void commitContentChanged();
method public java.lang.String dataToString(D);
method public void deliverCancellation();
method public void deliverResult(D);
@@ -6179,6 +6180,7 @@
method public void registerListener(int, android.content.Loader.OnLoadCompleteListener<D>);
method public void registerOnLoadCanceledListener(android.content.Loader.OnLoadCanceledListener<D>);
method public void reset();
+ method public void rollbackContentChanged();
method public final void startLoading();
method public void stopLoading();
method public boolean takeContentChanged();
diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java
index 188c786..612c67f 100644
--- a/core/java/android/content/AsyncTaskLoader.java
+++ b/core/java/android/content/AsyncTaskLoader.java
@@ -231,6 +231,7 @@
onCanceled(data);
if (mCancellingTask == task) {
if (DEBUG) Slog.v(TAG, "Cancelled task is now canceled!");
+ rollbackContentChanged();
mLastLoadCompleteTime = SystemClock.uptimeMillis();
mCancellingTask = null;
if (DEBUG) Slog.v(TAG, "Delivering cancellation");
@@ -248,6 +249,7 @@
// This cursor has been abandoned; just cancel the new data.
onCanceled(data);
} else {
+ commitContentChanged();
mLastLoadCompleteTime = SystemClock.uptimeMillis();
mTask = null;
if (DEBUG) Slog.v(TAG, "Delivering result");
diff --git a/core/java/android/content/Loader.java b/core/java/android/content/Loader.java
index 3052414..911e49c 100644
--- a/core/java/android/content/Loader.java
+++ b/core/java/android/content/Loader.java
@@ -58,6 +58,7 @@
boolean mAbandoned = false;
boolean mReset = true;
boolean mContentChanged = false;
+ boolean mProcessingChange = false;
/**
* An implementation of a ContentObserver that takes care of connecting
@@ -439,6 +440,7 @@
mStarted = false;
mAbandoned = false;
mContentChanged = false;
+ mProcessingChange = false;
}
/**
@@ -458,9 +460,34 @@
public boolean takeContentChanged() {
boolean res = mContentChanged;
mContentChanged = false;
+ mProcessingChange |= res;
return res;
}
-
+
+ /**
+ * Commit that you have actually fully processed a content change that
+ * was returned by {@link #takeContentChanged}. This is for use with
+ * {@link #rollbackContentChanged()} to handle situations where a load
+ * is cancelled. Call this when you have completely processed a load
+ * without it being cancelled.
+ */
+ public void commitContentChanged() {
+ mProcessingChange = false;
+ }
+
+ /**
+ * Report that you have abandoned the processing of a content change that
+ * was returned by {@link #takeContentChanged()} and would like to rollback
+ * to the state where there is again a pending content change. This is
+ * to handle the case where a data load due to a content change has been
+ * canceled before its data was delivered back to the loader.
+ */
+ public void rollbackContentChanged() {
+ if (mProcessingChange) {
+ mContentChanged = true;
+ }
+ }
+
/**
* Called when {@link ForceLoadContentObserver} detects a change. The
* default implementation checks to see if the loader is currently started;
@@ -512,9 +539,14 @@
public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
writer.print(prefix); writer.print("mId="); writer.print(mId);
writer.print(" mListener="); writer.println(mListener);
- writer.print(prefix); writer.print("mStarted="); writer.print(mStarted);
- writer.print(" mContentChanged="); writer.print(mContentChanged);
- writer.print(" mAbandoned="); writer.print(mAbandoned);
- writer.print(" mReset="); writer.println(mReset);
+ if (mStarted || mContentChanged || mProcessingChange) {
+ writer.print(prefix); writer.print("mStarted="); writer.print(mStarted);
+ writer.print(" mContentChanged="); writer.print(mContentChanged);
+ writer.print(" mProcessingChange="); writer.println(mProcessingChange);
+ }
+ if (mAbandoned || mReset) {
+ writer.print(prefix); writer.print("mAbandoned="); writer.print(mAbandoned);
+ writer.print(" mReset="); writer.println(mReset);
+ }
}
}
\ No newline at end of file