summaryrefslogtreecommitdiffstats
path: root/packages/DocumentsUI
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2013-10-23 11:18:35 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2013-10-23 11:18:35 -0700
commitae25a1a89b777c444df5d34a2537aff3f5c2249b (patch)
tree196ca065842d421f715a61cbd407fe8372382678 /packages/DocumentsUI
parent3efe70999173eb6ee9335142b80f42277bc695fa (diff)
parent05f92b7c5810dfc4e96cd5dddff1f7f380739136 (diff)
downloadframeworks_base-ae25a1a89b777c444df5d34a2537aff3f5c2249b.zip
frameworks_base-ae25a1a89b777c444df5d34a2537aff3f5c2249b.tar.gz
frameworks_base-ae25a1a89b777c444df5d34a2537aff3f5c2249b.tar.bz2
am 05f92b7c: am 6599c128: am 871cb5d5: Merge "Update roots when data cleared, refresh UI." into klp-dev
* commit '05f92b7c5810dfc4e96cd5dddff1f7f380739136': Update roots when data cleared, refresh UI. Treat document thumbnails as preemptable.
Diffstat (limited to 'packages/DocumentsUI')
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java13
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java1
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java51
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/RootsCache.java5
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/RootsLoader.java7
5 files changed, 69 insertions, 8 deletions
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index 1f3901c..fa8bc9d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -76,6 +76,7 @@ import android.widget.TextView;
import android.widget.Toast;
import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.ProviderExecutor.Preemptable;
import com.android.documentsui.RecentsProvider.StateColumns;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.RootInfo;
@@ -528,7 +529,7 @@ public class DirectoryFragment extends Fragment {
if (iconThumb != null) {
final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag();
if (oldTask != null) {
- oldTask.reallyCancel();
+ oldTask.preempt();
iconThumb.setTag(null);
}
}
@@ -794,7 +795,7 @@ public class DirectoryFragment extends Fragment {
final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag();
if (oldTask != null) {
- oldTask.reallyCancel();
+ oldTask.preempt();
iconThumb.setTag(null);
}
@@ -818,7 +819,7 @@ public class DirectoryFragment extends Fragment {
final ThumbnailAsyncTask task = new ThumbnailAsyncTask(
uri, iconMime, iconThumb, mThumbSize);
iconThumb.setTag(task);
- task.executeOnExecutor(ProviderExecutor.forAuthority(docAuthority));
+ ProviderExecutor.forAuthority(docAuthority).execute(task);
}
}
@@ -988,7 +989,8 @@ public class DirectoryFragment extends Fragment {
}
}
- private static class ThumbnailAsyncTask extends AsyncTask<Uri, Void, Bitmap> {
+ private static class ThumbnailAsyncTask extends AsyncTask<Uri, Void, Bitmap>
+ implements Preemptable {
private final Uri mUri;
private final ImageView mIconMime;
private final ImageView mIconThumb;
@@ -1004,7 +1006,8 @@ public class DirectoryFragment extends Fragment {
mSignal = new CancellationSignal();
}
- public void reallyCancel() {
+ @Override
+ public void preempt() {
cancel(false);
mSignal.cancel();
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java
index 6b46e3a..547e343 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java
@@ -75,6 +75,7 @@ public class DocumentsApplication extends Application {
packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ packageFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
packageFilter.addDataScheme("package");
registerReceiver(mCacheReceiver, packageFilter);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java b/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java
index 2105cb4..f94aebd 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java
@@ -16,10 +16,15 @@
package com.android.documentsui;
+import android.os.AsyncTask;
+
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
+import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
@@ -29,7 +34,7 @@ public class ProviderExecutor extends Thread implements Executor {
@GuardedBy("sExecutors")
private static HashMap<String, ProviderExecutor> sExecutors = Maps.newHashMap();
- public static Executor forAuthority(String authority) {
+ public static ProviderExecutor forAuthority(String authority) {
synchronized (sExecutors) {
ProviderExecutor executor = sExecutors.get(authority);
if (executor == null) {
@@ -42,10 +47,54 @@ public class ProviderExecutor extends Thread implements Executor {
}
}
+ public interface Preemptable {
+ void preempt();
+ }
+
private final LinkedBlockingQueue<Runnable> mQueue = new LinkedBlockingQueue<Runnable>();
+ private final ArrayList<WeakReference<Preemptable>> mPreemptable = Lists.newArrayList();
+
+ private void preempt() {
+ synchronized (mPreemptable) {
+ int count = 0;
+ for (WeakReference<Preemptable> ref : mPreemptable) {
+ final Preemptable p = ref.get();
+ if (p != null) {
+ count++;
+ p.preempt();
+ }
+ }
+ mPreemptable.clear();
+ }
+ }
+
+ /**
+ * Execute the given task. If given task is not {@link Preemptable}, it will
+ * preempt all outstanding preemptable tasks.
+ */
+ public <P> void execute(AsyncTask<P, ?, ?> task, P... params) {
+ if (task instanceof Preemptable) {
+ synchronized (mPreemptable) {
+ mPreemptable.add(new WeakReference<Preemptable>((Preemptable) task));
+ }
+ task.executeOnExecutor(mNonPreemptingExecutor, params);
+ } else {
+ task.executeOnExecutor(this, params);
+ }
+ }
+
+ private Executor mNonPreemptingExecutor = new Executor() {
+ @Override
+ public void execute(Runnable command) {
+ Preconditions.checkNotNull(command);
+ mQueue.add(command);
+ }
+ };
+
@Override
public void execute(Runnable command) {
+ preempt();
Preconditions.checkNotNull(command);
mQueue.add(command);
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index b98e1ee..f6b43c7 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -60,8 +60,8 @@ import java.util.concurrent.TimeUnit;
public class RootsCache {
private static final boolean LOGD = true;
- // TODO: cache roots in local provider to avoid spinning up backends
- // TODO: root updates should trigger UI refresh
+ public static final Uri sNotificationUri = Uri.parse(
+ "content://com.android.documentsui.roots/");
private final Context mContext;
private final ContentObserver mObserver;
@@ -201,6 +201,7 @@ public class RootsCache {
mStoppedAuthorities = mTaskStoppedAuthorities;
}
mFirstLoad.countDown();
+ resolver.notifyChange(sNotificationUri, null, false);
return null;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsLoader.java b/packages/DocumentsUI/src/com/android/documentsui/RootsLoader.java
index 7108971..8d37cdf 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsLoader.java
@@ -25,6 +25,8 @@ import com.android.documentsui.model.RootInfo;
import java.util.Collection;
public class RootsLoader extends AsyncTaskLoader<Collection<RootInfo>> {
+ private final ForceLoadContentObserver mObserver = new ForceLoadContentObserver();
+
private final RootsCache mRoots;
private final State mState;
@@ -34,6 +36,9 @@ public class RootsLoader extends AsyncTaskLoader<Collection<RootInfo>> {
super(context);
mRoots = roots;
mState = state;
+
+ getContext().getContentResolver()
+ .registerContentObserver(RootsCache.sNotificationUri, false, mObserver);
}
@Override
@@ -77,5 +82,7 @@ public class RootsLoader extends AsyncTaskLoader<Collection<RootInfo>> {
onStopLoading();
mResult = null;
+
+ getContext().getContentResolver().unregisterContentObserver(mObserver);
}
}