Loading core/java/android/database/AbstractCursor.java +20 −10 Original line number Diff line number Diff line Loading @@ -419,18 +419,27 @@ public abstract class AbstractCursor implements CrossProcessCursor { Preconditions.checkNotNull(cr); Preconditions.checkNotNull(notifyUris); setNotificationUris(cr, notifyUris, cr.getUserId()); setNotificationUris(cr, notifyUris, cr.getUserId(), true); } /** @hide - set the notification uri but with an observer for a particular user's view */ public void setNotificationUris(ContentResolver cr, List<Uri> notifyUris, int userHandle) { /** * Set the notification uri but with an observer for a particular user's view. Also allows * disabling the use of a self observer, which is sensible if either * a) the cursor's owner calls {@link #onChange(boolean)} whenever the content changes, or * b) the cursor is known not to have any content observers. * @hide */ public void setNotificationUris(ContentResolver cr, List<Uri> notifyUris, int userHandle, boolean registerSelfObserver) { synchronized (mSelfObserverLock) { mNotifyUris = notifyUris; mNotifyUri = mNotifyUris.get(0); mContentResolver = cr; if (mSelfObserver != null) { mContentResolver.unregisterContentObserver(mSelfObserver); mSelfObserverRegistered = false; } if (registerSelfObserver) { mSelfObserver = new SelfContentObserver(this); final int size = mNotifyUris.size(); for (int i = 0; i < size; ++i) { Loading @@ -441,6 +450,7 @@ public abstract class AbstractCursor implements CrossProcessCursor { mSelfObserverRegistered = true; } } } @Override public Uri getNotificationUri() { Loading core/java/com/android/internal/content/FileSystemProvider.java +26 −14 Original line number Diff line number Diff line Loading @@ -60,9 +60,11 @@ import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; /** * A helper class for {@link android.provider.DocumentsProvider} to perform file operations on local Loading Loading @@ -613,28 +615,28 @@ public abstract class FileSystemProvider extends DocumentsProvider { return projection == null ? mDefaultProjection : projection; } private void startObserving(File file, Uri notifyUri) { private void startObserving(File file, Uri notifyUri, DirectoryCursor cursor) { synchronized (mObservers) { DirectoryObserver observer = mObservers.get(file); if (observer == null) { observer = new DirectoryObserver( file, getContext().getContentResolver(), notifyUri); observer = new DirectoryObserver(file, getContext().getContentResolver(), notifyUri); observer.startWatching(); mObservers.put(file, observer); } observer.mRefCount++; observer.mCursors.add(cursor); if (LOG_INOTIFY) Log.d(TAG, "after start: " + observer); } } private void stopObserving(File file) { private void stopObserving(File file, DirectoryCursor cursor) { synchronized (mObservers) { DirectoryObserver observer = mObservers.get(file); if (observer == null) return; observer.mRefCount--; if (observer.mRefCount == 0) { observer.mCursors.remove(cursor); if (observer.mCursors.size() == 0) { mObservers.remove(file); observer.stopWatching(); } Loading @@ -650,27 +652,31 @@ public abstract class FileSystemProvider extends DocumentsProvider { private final File mFile; private final ContentResolver mResolver; private final Uri mNotifyUri; private final CopyOnWriteArrayList<DirectoryCursor> mCursors; private int mRefCount = 0; public DirectoryObserver(File file, ContentResolver resolver, Uri notifyUri) { DirectoryObserver(File file, ContentResolver resolver, Uri notifyUri) { super(file.getAbsolutePath(), NOTIFY_EVENTS); mFile = file; mResolver = resolver; mNotifyUri = notifyUri; mCursors = new CopyOnWriteArrayList<>(); } @Override public void onEvent(int event, String path) { if ((event & NOTIFY_EVENTS) != 0) { if (LOG_INOTIFY) Log.d(TAG, "onEvent() " + event + " at " + path); for (DirectoryCursor cursor : mCursors) { cursor.notifyChanged(); } mResolver.notifyChange(mNotifyUri, null, false); } } @Override public String toString() { return "DirectoryObserver{file=" + mFile.getAbsolutePath() + ", ref=" + mRefCount + "}"; String filePath = mFile.getAbsolutePath(); return "DirectoryObserver{file=" + filePath + ", ref=" + mCursors.size() + "}"; } } Loading @@ -681,16 +687,22 @@ public abstract class FileSystemProvider extends DocumentsProvider { super(columnNames); final Uri notifyUri = buildNotificationUri(docId); setNotificationUri(getContext().getContentResolver(), notifyUri); boolean registerSelfObserver = false; // Our FileObserver sees all relevant changes. setNotificationUris(getContext().getContentResolver(), Arrays.asList(notifyUri), getContext().getContentResolver().getUserId(), registerSelfObserver); mFile = file; startObserving(mFile, notifyUri); startObserving(mFile, notifyUri, this); } public void notifyChanged() { onChange(false); } @Override public void close() { super.close(); stopObserving(mFile); stopObserving(mFile, this); } } } Loading
core/java/android/database/AbstractCursor.java +20 −10 Original line number Diff line number Diff line Loading @@ -419,18 +419,27 @@ public abstract class AbstractCursor implements CrossProcessCursor { Preconditions.checkNotNull(cr); Preconditions.checkNotNull(notifyUris); setNotificationUris(cr, notifyUris, cr.getUserId()); setNotificationUris(cr, notifyUris, cr.getUserId(), true); } /** @hide - set the notification uri but with an observer for a particular user's view */ public void setNotificationUris(ContentResolver cr, List<Uri> notifyUris, int userHandle) { /** * Set the notification uri but with an observer for a particular user's view. Also allows * disabling the use of a self observer, which is sensible if either * a) the cursor's owner calls {@link #onChange(boolean)} whenever the content changes, or * b) the cursor is known not to have any content observers. * @hide */ public void setNotificationUris(ContentResolver cr, List<Uri> notifyUris, int userHandle, boolean registerSelfObserver) { synchronized (mSelfObserverLock) { mNotifyUris = notifyUris; mNotifyUri = mNotifyUris.get(0); mContentResolver = cr; if (mSelfObserver != null) { mContentResolver.unregisterContentObserver(mSelfObserver); mSelfObserverRegistered = false; } if (registerSelfObserver) { mSelfObserver = new SelfContentObserver(this); final int size = mNotifyUris.size(); for (int i = 0; i < size; ++i) { Loading @@ -441,6 +450,7 @@ public abstract class AbstractCursor implements CrossProcessCursor { mSelfObserverRegistered = true; } } } @Override public Uri getNotificationUri() { Loading
core/java/com/android/internal/content/FileSystemProvider.java +26 −14 Original line number Diff line number Diff line Loading @@ -60,9 +60,11 @@ import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; /** * A helper class for {@link android.provider.DocumentsProvider} to perform file operations on local Loading Loading @@ -613,28 +615,28 @@ public abstract class FileSystemProvider extends DocumentsProvider { return projection == null ? mDefaultProjection : projection; } private void startObserving(File file, Uri notifyUri) { private void startObserving(File file, Uri notifyUri, DirectoryCursor cursor) { synchronized (mObservers) { DirectoryObserver observer = mObservers.get(file); if (observer == null) { observer = new DirectoryObserver( file, getContext().getContentResolver(), notifyUri); observer = new DirectoryObserver(file, getContext().getContentResolver(), notifyUri); observer.startWatching(); mObservers.put(file, observer); } observer.mRefCount++; observer.mCursors.add(cursor); if (LOG_INOTIFY) Log.d(TAG, "after start: " + observer); } } private void stopObserving(File file) { private void stopObserving(File file, DirectoryCursor cursor) { synchronized (mObservers) { DirectoryObserver observer = mObservers.get(file); if (observer == null) return; observer.mRefCount--; if (observer.mRefCount == 0) { observer.mCursors.remove(cursor); if (observer.mCursors.size() == 0) { mObservers.remove(file); observer.stopWatching(); } Loading @@ -650,27 +652,31 @@ public abstract class FileSystemProvider extends DocumentsProvider { private final File mFile; private final ContentResolver mResolver; private final Uri mNotifyUri; private final CopyOnWriteArrayList<DirectoryCursor> mCursors; private int mRefCount = 0; public DirectoryObserver(File file, ContentResolver resolver, Uri notifyUri) { DirectoryObserver(File file, ContentResolver resolver, Uri notifyUri) { super(file.getAbsolutePath(), NOTIFY_EVENTS); mFile = file; mResolver = resolver; mNotifyUri = notifyUri; mCursors = new CopyOnWriteArrayList<>(); } @Override public void onEvent(int event, String path) { if ((event & NOTIFY_EVENTS) != 0) { if (LOG_INOTIFY) Log.d(TAG, "onEvent() " + event + " at " + path); for (DirectoryCursor cursor : mCursors) { cursor.notifyChanged(); } mResolver.notifyChange(mNotifyUri, null, false); } } @Override public String toString() { return "DirectoryObserver{file=" + mFile.getAbsolutePath() + ", ref=" + mRefCount + "}"; String filePath = mFile.getAbsolutePath(); return "DirectoryObserver{file=" + filePath + ", ref=" + mCursors.size() + "}"; } } Loading @@ -681,16 +687,22 @@ public abstract class FileSystemProvider extends DocumentsProvider { super(columnNames); final Uri notifyUri = buildNotificationUri(docId); setNotificationUri(getContext().getContentResolver(), notifyUri); boolean registerSelfObserver = false; // Our FileObserver sees all relevant changes. setNotificationUris(getContext().getContentResolver(), Arrays.asList(notifyUri), getContext().getContentResolver().getUserId(), registerSelfObserver); mFile = file; startObserving(mFile, notifyUri); startObserving(mFile, notifyUri, this); } public void notifyChanged() { onChange(false); } @Override public void close() { super.close(); stopObserving(mFile); stopObserving(mFile, this); } } }