diff options
author | Jeff Sharkey <jsharkey@android.com> | 2013-10-28 09:14:37 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-10-28 09:14:37 -0700 |
commit | 99dcb2eb3578c3d14658b3850cb3e32608e173b1 (patch) | |
tree | a1f3af9303c0e972526599a23e698d37d083b47f | |
parent | 2534c16b44922e19e040a999cd99b412674e63a1 (diff) | |
parent | 10e509dcc20da34b79bc4616cc795a3720ddad49 (diff) | |
download | frameworks_base-99dcb2eb3578c3d14658b3850cb3e32608e173b1.zip frameworks_base-99dcb2eb3578c3d14658b3850cb3e32608e173b1.tar.gz frameworks_base-99dcb2eb3578c3d14658b3850cb3e32608e173b1.tar.bz2 |
am 10e509dc: Merge "Use inotify to update DocumentsUI." into klp-dev
* commit '10e509dcc20da34b79bc4616cc795a3720ddad49':
Use inotify to update DocumentsUI.
-rw-r--r-- | packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java | 5 | ||||
-rw-r--r-- | packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java | 93 |
2 files changed, 93 insertions, 5 deletions
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java index fa8bc9d..775720e 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java @@ -84,7 +84,6 @@ import com.google.android.collect.Lists; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; /** * Display the documents inside a single directory. @@ -127,9 +126,7 @@ public class DirectoryFragment extends Fragment { private static final String EXTRA_QUERY = "query"; private static final String EXTRA_IGNORE_STATE = "ignoreState"; - private static AtomicInteger sLoaderId = new AtomicInteger(4000); - - private final int mLoaderId = sLoaderId.incrementAndGet(); + private final int mLoaderId = 42; public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) { show(fm, TYPE_NORMAL, root, doc, null, anim); diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java index 65e3eee..559e052 100644 --- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java @@ -16,14 +16,17 @@ package com.android.externalstorage; +import android.content.ContentResolver; import android.content.Context; import android.content.res.AssetFileDescriptor; import android.database.Cursor; import android.database.MatrixCursor; import android.database.MatrixCursor.RowBuilder; import android.graphics.Point; +import android.net.Uri; import android.os.CancellationSignal; import android.os.Environment; +import android.os.FileObserver; import android.os.ParcelFileDescriptor; import android.os.storage.StorageManager; import android.os.storage.StorageVolume; @@ -49,6 +52,8 @@ import java.util.Map; public class ExternalStorageProvider extends DocumentsProvider { private static final String TAG = "ExternalStorage"; + private static final boolean LOG_INOTIFY = false; + public static final String AUTHORITY = "com.android.externalstorage.documents"; // docId format: root:path/to/file @@ -83,6 +88,9 @@ public class ExternalStorageProvider extends DocumentsProvider { @GuardedBy("mRootsLock") private HashMap<String, File> mIdToPath; + @GuardedBy("mObservers") + private Map<File, DirectoryObserver> mObservers = Maps.newHashMap(); + @Override public boolean onCreate() { mStorageManager = (StorageManager) getContext().getSystemService(Context.STORAGE_SERVICE); @@ -327,8 +335,9 @@ public class ExternalStorageProvider extends DocumentsProvider { public Cursor queryChildDocuments( String parentDocumentId, String[] projection, String sortOrder) throws FileNotFoundException { - final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection)); final File parent = getFileForDocId(parentDocumentId); + final MatrixCursor result = new DirectoryCursor( + resolveDocumentProjection(projection), parentDocumentId, parent); for (File file : parent.listFiles()) { includeFile(result, null, file); } @@ -431,4 +440,86 @@ public class ExternalStorageProvider extends DocumentsProvider { } return name; } + + private void startObserving(File file, Uri notifyUri) { + synchronized (mObservers) { + DirectoryObserver observer = mObservers.get(file); + if (observer == null) { + observer = new DirectoryObserver( + file, getContext().getContentResolver(), notifyUri); + observer.startWatching(); + mObservers.put(file, observer); + } + observer.mRefCount++; + + if (LOG_INOTIFY) Log.d(TAG, "after start: " + observer); + } + } + + private void stopObserving(File file) { + synchronized (mObservers) { + DirectoryObserver observer = mObservers.get(file); + if (observer == null) return; + + observer.mRefCount--; + if (observer.mRefCount == 0) { + mObservers.remove(file); + observer.stopWatching(); + } + + if (LOG_INOTIFY) Log.d(TAG, "after stop: " + observer); + } + } + + private static class DirectoryObserver extends FileObserver { + private static final int NOTIFY_EVENTS = ATTRIB | CLOSE_WRITE | MOVED_FROM | MOVED_TO + | CREATE | DELETE | DELETE_SELF | MOVE_SELF; + + private final File mFile; + private final ContentResolver mResolver; + private final Uri mNotifyUri; + + private int mRefCount = 0; + + public DirectoryObserver(File file, ContentResolver resolver, Uri notifyUri) { + super(file.getAbsolutePath(), NOTIFY_EVENTS); + mFile = file; + mResolver = resolver; + mNotifyUri = notifyUri; + } + + @Override + public void onEvent(int event, String path) { + if ((event & NOTIFY_EVENTS) != 0) { + if (LOG_INOTIFY) Log.d(TAG, "onEvent() " + event + " at " + path); + mResolver.notifyChange(mNotifyUri, null, false); + } + } + + @Override + public String toString() { + return "DirectoryObserver{file=" + mFile.getAbsolutePath() + ", ref=" + mRefCount + "}"; + } + } + + private class DirectoryCursor extends MatrixCursor { + private final File mFile; + + public DirectoryCursor(String[] columnNames, String docId, File file) { + super(columnNames); + + final Uri notifyUri = DocumentsContract.buildChildDocumentsUri( + AUTHORITY, docId); + setNotificationUri(getContext().getContentResolver(), notifyUri); + + mFile = file; + startObserving(mFile, notifyUri); + } + + @Override + public void close() { + super.close(); + stopObserving(mFile); + } + } } |