summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2013-10-28 09:14:37 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2013-10-28 09:14:37 -0700
commit99dcb2eb3578c3d14658b3850cb3e32608e173b1 (patch)
treea1f3af9303c0e972526599a23e698d37d083b47f
parent2534c16b44922e19e040a999cd99b412674e63a1 (diff)
parent10e509dcc20da34b79bc4616cc795a3720ddad49 (diff)
downloadframeworks_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.java5
-rw-r--r--packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java93
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);
+ }
+ }
}