diff options
author | Jeff Sharkey <jsharkey@android.com> | 2013-10-23 11:18:35 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-10-23 11:18:35 -0700 |
commit | ae25a1a89b777c444df5d34a2537aff3f5c2249b (patch) | |
tree | 196ca065842d421f715a61cbd407fe8372382678 /packages/DocumentsUI | |
parent | 3efe70999173eb6ee9335142b80f42277bc695fa (diff) | |
parent | 05f92b7c5810dfc4e96cd5dddff1f7f380739136 (diff) | |
download | frameworks_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')
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); } } |