Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e05b677 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android Git Automerger
Browse files

am e643e337: am 99dcb2eb: am 10e509dc: Merge "Use inotify to update DocumentsUI." into klp-dev

* commit 'e643e337':
  Use inotify to update DocumentsUI.
parents c847c883 e643e337
Loading
Loading
Loading
Loading
+1 −4
Original line number Original line Diff line number Diff line
@@ -84,7 +84,6 @@ import com.google.android.collect.Lists;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.List;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;


/**
/**
 * Display the documents inside a single directory.
 * 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_QUERY = "query";
    private static final String EXTRA_IGNORE_STATE = "ignoreState";
    private static final String EXTRA_IGNORE_STATE = "ignoreState";


    private static AtomicInteger sLoaderId = new AtomicInteger(4000);
    private final int mLoaderId = 42;

    private final int mLoaderId = sLoaderId.incrementAndGet();


    public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) {
    public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) {
        show(fm, TYPE_NORMAL, root, doc, null, anim);
        show(fm, TYPE_NORMAL, root, doc, null, anim);
+92 −1
Original line number Original line Diff line number Diff line
@@ -16,14 +16,17 @@


package com.android.externalstorage;
package com.android.externalstorage;


import android.content.ContentResolver;
import android.content.Context;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.MatrixCursor;
import android.database.MatrixCursor.RowBuilder;
import android.database.MatrixCursor.RowBuilder;
import android.graphics.Point;
import android.graphics.Point;
import android.net.Uri;
import android.os.CancellationSignal;
import android.os.CancellationSignal;
import android.os.Environment;
import android.os.Environment;
import android.os.FileObserver;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor;
import android.os.storage.StorageManager;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.os.storage.StorageVolume;
@@ -49,6 +52,8 @@ import java.util.Map;
public class ExternalStorageProvider extends DocumentsProvider {
public class ExternalStorageProvider extends DocumentsProvider {
    private static final String TAG = "ExternalStorage";
    private static final String TAG = "ExternalStorage";


    private static final boolean LOG_INOTIFY = false;

    public static final String AUTHORITY = "com.android.externalstorage.documents";
    public static final String AUTHORITY = "com.android.externalstorage.documents";


    // docId format: root:path/to/file
    // docId format: root:path/to/file
@@ -83,6 +88,9 @@ public class ExternalStorageProvider extends DocumentsProvider {
    @GuardedBy("mRootsLock")
    @GuardedBy("mRootsLock")
    private HashMap<String, File> mIdToPath;
    private HashMap<String, File> mIdToPath;


    @GuardedBy("mObservers")
    private Map<File, DirectoryObserver> mObservers = Maps.newHashMap();

    @Override
    @Override
    public boolean onCreate() {
    public boolean onCreate() {
        mStorageManager = (StorageManager) getContext().getSystemService(Context.STORAGE_SERVICE);
        mStorageManager = (StorageManager) getContext().getSystemService(Context.STORAGE_SERVICE);
@@ -327,8 +335,9 @@ public class ExternalStorageProvider extends DocumentsProvider {
    public Cursor queryChildDocuments(
    public Cursor queryChildDocuments(
            String parentDocumentId, String[] projection, String sortOrder)
            String parentDocumentId, String[] projection, String sortOrder)
            throws FileNotFoundException {
            throws FileNotFoundException {
        final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
        final File parent = getFileForDocId(parentDocumentId);
        final File parent = getFileForDocId(parentDocumentId);
        final MatrixCursor result = new DirectoryCursor(
                resolveDocumentProjection(projection), parentDocumentId, parent);
        for (File file : parent.listFiles()) {
        for (File file : parent.listFiles()) {
            includeFile(result, null, file);
            includeFile(result, null, file);
        }
        }
@@ -431,4 +440,86 @@ public class ExternalStorageProvider extends DocumentsProvider {
        }
        }
        return name;
        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);
        }
    }
}
}