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

Commit 9e7dc7d9 authored by Steve McKay's avatar Steve McKay
Browse files

Load metadtata in background.

Bug: 63925015
Test: manual
Change-Id: I95d32587258f5bd7639d5b2bd58d36860c5ca38f
parent 961f1ec8
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ import java.util.function.Consumer;
 */
public final class InspectorController {

    private final Loader mLoader;
    private final DataSupplier mLoader;
    private final HeaderDisplay mHeader;
    private final DetailsDisplay mDetails;
    private final TableDisplay mMetadata;
@@ -68,7 +68,7 @@ public final class InspectorController {
    @VisibleForTesting
    public InspectorController(
            Context context,
            Loader loader,
            DataSupplier loader,
            PackageManager pm,
            ProvidersAccess providers,
            HeaderDisplay header,
@@ -116,7 +116,7 @@ public final class InspectorController {
     *     can include extras that enable debug mode ({@link Shared#EXTRA_SHOW_DEBUG}
     *     and override the file title (@link {@link Intent#EXTRA_TITLE}).
     */
    public InspectorController(Activity activity, Loader loader, View layout, Bundle args) {
    public InspectorController(Activity activity, DataSupplier loader, View layout, Bundle args) {
        this(activity,
            loader,
            activity.getPackageManager(),
@@ -343,9 +343,9 @@ public final class InspectorController {
    }

    /**
     * Interface for loading document metadata.
     * Interface for loading all the various forms of document datal
     */
    public interface Loader {
    public interface DataSupplier {

        /**
         * Starts the Asynchronous process of loading file data.
+2 −2
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ import android.widget.ScrollView;

import com.android.documentsui.R;
import com.android.documentsui.base.Shared;
import com.android.documentsui.inspector.InspectorController.Loader;
import com.android.documentsui.inspector.InspectorController.DataSupplier;

/**
 * Displays the Properties view in Files.
@@ -47,7 +47,7 @@ public class InspectorFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        final Loader loader = new DocumentLoader(getActivity(), getLoaderManager());
        final DataSupplier loader = new RuntimeDataSupplier(getActivity(), getLoaderManager());

        mView = (ScrollView) inflater.inflate(R.layout.inspector_fragment,
                container, false);
+99 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.inspector;

import android.content.AsyncTaskLoader;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.support.annotation.Nullable;
import android.util.Log;

import java.io.FileNotFoundException;

/**
 * Loads metadata from {@link DocumentsContract#getDocumentMetadata(android.content.ContentProviderClient, Uri, String[])}
 */
final class MetadataLoader extends AsyncTaskLoader<Bundle> {

    private static final String TAG = "MetadataLoader";

    private final Context mContext;
    private final Uri mUri;

    private @Nullable Bundle mMetadata;

    MetadataLoader(Context context, Uri uri) {
        super(context);
        mContext = context;
        mUri = uri;
    }

    @Override
    public Bundle loadInBackground() {
        try {
            return DocumentsContract.getDocumentMetadata(
                    mContext.getContentResolver(),
                    mUri,
                    null);
        } catch (FileNotFoundException e) {
            Log.e(TAG, "Failed to load metadata for doc: " + mUri, e);
        }

        return null;
    }

    @Override
    protected void onStartLoading() {
        if (mMetadata != null) {
            deliverResult(mMetadata);
        }
        if (takeContentChanged() || mMetadata == null) {
            forceLoad();
        }
    }

    @Override
    public void deliverResult(Bundle metadata) {
        if (isReset()) {
            return;
        }
        mMetadata = metadata;
        if (isStarted()) {
            super.deliverResult(metadata);
        }
    }

    /**
     * Must be called from the UI thread
     */
    @Override
    protected void onStopLoading() {
        // Attempt to cancel the current load task if possible.
        cancelLoad();
    }

    @Override
    protected void onReset() {
        super.onReset();

        // Ensure the loader is stopped
        onStopLoading();

        mMetadata = null;
    }
}
+7 −41
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ import static com.android.internal.util.Preconditions.checkArgument;

import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.AsyncTaskLoader;
import android.content.Context;
import android.content.CursorLoader;
import android.database.ContentObserver;
@@ -30,22 +29,20 @@ import android.os.Handler;
import android.os.Looper;
import android.provider.DocumentsContract;
import android.support.annotation.Nullable;
import android.util.Log;

import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.inspector.InspectorController.Loader;
import com.android.documentsui.inspector.InspectorController.DataSupplier;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
 * Asynchronously loads a document data for the inspector.
 *
 * <p>This loader is not a Loader! Its our own funky loader.
 */
public class DocumentLoader implements Loader {

    private static final String TAG = "DocumentLoader";
public class RuntimeDataSupplier implements DataSupplier {

    private final Context mContext;
    private final LoaderManager mLoaderMgr;
@@ -54,7 +51,7 @@ public class DocumentLoader implements Loader {
    private @Nullable Callbacks mDirCallbacks;
    private @Nullable LoaderCallbacks<Bundle> mMetadataCallbacks;

    public DocumentLoader(Context context, LoaderManager loaderMgr) {
    public RuntimeDataSupplier(Context context, LoaderManager loaderMgr) {
        checkArgument(context != null);
        checkArgument(loaderMgr != null);
        mContext = context;
@@ -72,6 +69,7 @@ public class DocumentLoader implements Loader {
        Consumer<Cursor> callback = new Consumer<Cursor>() {
            @Override
            public void accept(Cursor cursor) {

                if (cursor == null || !cursor.moveToFirst()) {
                    updateView.accept(null);
                } else {
@@ -109,51 +107,19 @@ public class DocumentLoader implements Loader {

    @Override
    public void getDocumentMetadata(Uri uri, Consumer<Bundle> callback) {

        // TODO: For some reason the async loading of metadata isn't working.
        // This is a hackaround. Tracking bug @ b/63925015
        try {
            Bundle syncData = DocumentsContract.getDocumentMetadata(
                    mContext.getContentResolver(),
                    uri,
                    null);
            callback.accept(syncData);
        } catch (FileNotFoundException e) {
            callback.accept(Bundle.EMPTY);
        }

        Log.d(TAG, "Loading document metadata.");

        mMetadataCallbacks = new LoaderCallbacks<Bundle>() {
            @Override
            public android.content.Loader<Bundle> onCreateLoader(int id, Bundle unused) {
                Log.d(TAG, "Creating loader for metadata.");
                return new AsyncTaskLoader<Bundle>(mContext) {
                    @Override
                    public Bundle loadInBackground() {
                        try {
                            Log.d(TAG, "Executing call to load metadata.");
                            return DocumentsContract.getDocumentMetadata(
                                    mContext.getContentResolver(),
                                    uri, null);
                        } catch (FileNotFoundException e) {
                            Log.e(TAG, "Failed to load metadata for doc: " + uri, e);
                        }

                        return null;
                    }
                };
                return new MetadataLoader(mContext, uri);
            }

            @Override
            public void onLoadFinished(android.content.Loader<Bundle> loader, Bundle data) {
                Log.d(TAG, "Received document metadata. Relaying to callback.");
                callback.accept(data);
            }

            @Override
            public void onLoaderReset(android.content.Loader<Bundle> loader) {
                Log.d(TAG, "Document metadata reset. Yerp!");
            }
        };

+3 −3
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ import android.support.test.InstrumentationRegistry;
import com.android.documentsui.InspectorProvider;
import android.test.suitebuilder.annotation.MediumTest;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.inspector.InspectorController.Loader;
import com.android.documentsui.inspector.InspectorController.DataSupplier;
import com.android.documentsui.testing.TestLoaderManager;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -46,7 +46,7 @@ public class DocumentLoaderTest extends TestCase {

    private Context mContext;
    private TestLoaderManager mLoaderManager;
    private Loader mLoader;
    private DataSupplier mLoader;
    private ContentResolver mResolver;

    @Before
@@ -55,7 +55,7 @@ public class DocumentLoaderTest extends TestCase {
        mContext = InstrumentationRegistry.getTargetContext();
        mResolver = mContext.getContentResolver();
        mLoaderManager = new TestLoaderManager();
        mLoader = new DocumentLoader(mContext, mLoaderManager);
        mLoader = new RuntimeDataSupplier(mContext, mLoaderManager);

        if (Looper.myLooper() == null) {
            Looper.prepare();
Loading