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

Commit a350a769 authored by Tony Huang's avatar Tony Huang Committed by Android (Google) Code Review
Browse files

Merge "Make Recent root know contents changed" into qt-qpr1-dev

parents f7e53bbc 4d179b7a
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -576,11 +576,15 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA
            Context context = mActivity;

            if (mState.stack.isRecents()) {
                final LockingContentObserver observer = new LockingContentObserver(
                        mContentLock, AbstractActionHandler.this::loadDocumentsForCurrentStack);
                MultiRootDocumentsLoader loader;

                if (mSearchMgr.isSearching()) {
                    if (DEBUG) {
                        Log.d(TAG, "Creating new GlobalSearchLoader.");
                    }
                    return new GlobalSearchLoader(
                    loader = new GlobalSearchLoader(
                            context,
                            mProviders,
                            mState,
@@ -591,13 +595,15 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA
                    if (DEBUG) {
                        Log.d(TAG, "Creating new loader recents.");
                    }
                    return new RecentsLoader(
                    loader =  new RecentsLoader(
                            context,
                            mProviders,
                            mState,
                            mExecutors,
                            mInjector.fileTypeLookup);
                }
                loader.setObserver(observer);
                return loader;
            } else {
                Uri contentsUri = mSearchMgr.isSearching()
                        ? DocumentsContract.buildSearchDocumentsUri(
+0 −28
Original line number Diff line number Diff line
@@ -16,20 +16,16 @@

package com.android.documentsui;

import static com.android.documentsui.base.SharedMinimal.DEBUG;
import static com.android.documentsui.base.SharedMinimal.VERBOSE;

import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.FileUtils;
import android.os.Handler;
import android.os.Looper;
import android.os.OperationCanceledException;
import android.os.RemoteException;
import android.provider.DocumentsContract.Document;
@@ -241,28 +237,4 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {

        getContext().getContentResolver().unregisterContentObserver(mObserver);
    }

    private static final class LockingContentObserver extends ContentObserver {
        private final ContentLock mLock;
        private final Runnable mContentChangedCallback;

        public LockingContentObserver(ContentLock lock, Runnable contentChangedCallback) {
            super(new Handler(Looper.getMainLooper()));
            mLock = lock;
            mContentChangedCallback = contentChangedCallback;
        }

        @Override
        public boolean deliverSelfNotifications() {
            return true;
        }

        @Override
        public void onChange(boolean selfChange) {
            if (DEBUG) {
                Log.d(TAG, "Directory content updated.");
            }
            mLock.runWhenUnlocked(mContentChangedCallback);
        }
    }
}
+53 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.documentsui;

import static com.android.documentsui.base.SharedMinimal.DEBUG;
import static com.android.documentsui.base.SharedMinimal.TAG;

import android.database.ContentObserver;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

/**
 * A custom {@link ContentObserver} which constructed by a {@link ContentLock}
 * and a {@link Runnable} callback. It will callback when it's onChange and ContentLock is unlock.
 */
public final class LockingContentObserver extends ContentObserver {
    private final ContentLock mLock;
    private final Runnable mContentChangedCallback;

    public LockingContentObserver(ContentLock lock, Runnable contentChangedCallback) {
        super(new Handler(Looper.getMainLooper()));
        mLock = lock;
        mContentChangedCallback = contentChangedCallback;
    }

    @Override
    public boolean deliverSelfNotifications() {
        return true;
    }

    @Override
    public void onChange(boolean selfChange) {
        if (DEBUG) {
            Log.d(TAG, "Content updated.");
        }
        mLock.runWhenUnlocked(mContentChangedCallback);
    }
}
+17 −1
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.documentsui;

import static com.android.documentsui.base.SharedMinimal.DEBUG;
import static com.android.documentsui.base.SharedMinimal.TAG;

import android.app.ActivityManager;
import android.content.ContentProviderClient;
@@ -65,6 +64,9 @@ import java.util.concurrent.TimeUnit;
 * and return the combined result.
 */
public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<DirectoryResult> {

    private static final String TAG = "MultiRootDocsLoader";

    // TODO: clean up cursor ownership so background thread doesn't traverse
    // previously returned cursors for filtering/sorting; this currently races
    // with the UI thread.
@@ -83,6 +85,7 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory
    private final ProvidersAccess mProviders;
    private final Lookup<String, Executor> mExecutors;
    private final Lookup<String, String> mFileTypeMap;
    private LockingContentObserver mObserver;

    @GuardedBy("mTasks")
    /** A authority -> QueryTask map */
@@ -101,6 +104,8 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory
     * @param state current state
     * @param executors the executors of authorities
     * @param fileTypeMap the map of mime types and file types.
     * @param lock the selection lock
     * @param contentChangedCallback callback when content changed
     */
    public MultiRootDocumentsLoader(Context context, ProvidersAccess providers, State state,
            Lookup<String, Executor> executors, Lookup<String, String> fileTypeMap) {
@@ -126,6 +131,10 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory
        }
    }

    public void setObserver(LockingContentObserver observer) {
        mObserver = observer;
    }

    private DirectoryResult loadInBackgroundLocked() {
        if (mFirstPassLatch == null) {
            // First time through we kick off all the recent tasks, and wait
@@ -322,6 +331,10 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory

        FileUtils.closeQuietly(mResult);
        mResult = null;

        if (mObserver != null) {
            getContext().getContentResolver().unregisterContentObserver(mObserver);
        }
    }

    // TODO: create better transfer of ownership around cursor to ensure its
@@ -406,6 +419,9 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory
                        mState.sortModel.addQuerySortArgs(queryArgs);
                        addQueryArgs(queryArgs);
                        res[i] = client.query(uri, null, queryArgs, null);
                        if (mObserver != null) {
                            res[i].registerContentObserver(mObserver);
                        }
                        mCursors[i] = generateResultCursor(rootInfos.get(i), res[i]);
                    } catch (Exception e) {
                        Log.w(TAG, "Failed to load " + authority + ", " + rootInfos.get(i).rootId,
+30 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.documentsui.testing;

import android.database.MatrixCursor;

public class TestCursor extends MatrixCursor {

    public TestCursor(String[] columnNames) {
        super(columnNames);
    }

    public void mockOnChange() {
        onChange(false);
    }
}
Loading