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

Commit 351a7497 authored by Steve McKay's avatar Steve McKay
Browse files

Populate quick view intent w/ file uris.

Change-Id: Ie4f15b11be1939f8b71752505caa9d74ab9f9680
parent 32e51915
Loading
Loading
Loading
Loading
+29 −2
Original line number Diff line number Diff line
@@ -16,10 +16,13 @@

package com.android.documentsui;

import static com.android.documentsui.DirectoryFragment.ANIM_DOWN;
import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
import static com.android.documentsui.DirectoryFragment.ANIM_SIDE;
import static com.android.documentsui.DirectoryFragment.ANIM_UP;
import static com.android.internal.util.Preconditions.checkArgument;

import android.annotation.Nullable;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
@@ -79,8 +82,9 @@ abstract class BaseActivity extends Activity {
    private final String mTag;

    public abstract State getDisplayState();
    public abstract void onDocumentPicked(DocumentInfo doc);
    public abstract void onDocumentPicked(DocumentInfo doc, @Nullable DocumentContext siblings);
    public abstract void onDocumentsPicked(List<DocumentInfo> docs);

    abstract void onTaskFinished(Uri... uris);
    abstract void onDirectoryChanged(int anim);
    abstract void updateActionBar();
@@ -258,6 +262,17 @@ abstract class BaseActivity extends Activity {
                && !root.isDownloads();
    }

    void onDirectoryCreated(DocumentInfo doc) {
        checkArgument(doc.isDirectory());
        openDirectory(doc);
    }

    void openDirectory(DocumentInfo doc) {
        getDisplayState().stack.push(doc);
        getDisplayState().stackTouched = true;
        onCurrentDirectoryChanged(ANIM_DOWN);
    }

    /**
     * Call this when directory changes. Prior to root fragment update
     * the (abstract) directoryChanged method will be called.
@@ -605,7 +620,6 @@ abstract class BaseActivity extends Activity {
            if (isDestroyed()) return;
            getDisplayState().restored = true;
            onCurrentDirectoryChanged(ANIM_NONE);

            onStackRestored(mRestoredStack, mExternal);
        }
    }
@@ -843,4 +857,17 @@ abstract class BaseActivity extends Activity {
            updateActionBar();
        }
    }

    /**
     * Interface providing access to current view of documents
     * even when all documents are not homed to the same parent.
     */
    interface DocumentContext {
        /**
         * Returns the cursor for the selected document. The cursor can be used to retrieve
         * details about a document and its siblings.
         * @return
         */
        Cursor getCursor();
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -146,7 +146,7 @@ public class CreateDirectoryFragment extends DialogFragment {
        protected void onPostExecute(DocumentInfo result) {
            if (result != null) {
                // Navigate into newly created child
                mActivity.onDocumentPicked(result);
                mActivity.onDirectoryCreated(result);
            } else {
                Toast.makeText(mActivity, R.string.create_error, Toast.LENGTH_SHORT).show();
            }
+12 −2
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.android.documentsui.BaseActivity.DocumentContext;
import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.MultiSelectManager.Selection;
import com.android.documentsui.ProviderExecutor.Preemptable;
@@ -457,7 +458,7 @@ public class DirectoryFragment extends Fragment {
        final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
        if (isDocumentEnabled(docMimeType, docFlags)) {
            final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
            ((BaseActivity) getActivity()).onDocumentPicked(doc);
            ((BaseActivity) getActivity()).onDocumentPicked(doc, mAdapter);
            mSelectionManager.clearSelection();
            return true;
        }
@@ -949,7 +950,8 @@ public class DirectoryFragment extends Fragment {
        }
    }

    private final class DocumentsAdapter extends RecyclerView.Adapter<DocumentHolder> {
    private final class DocumentsAdapter extends RecyclerView.Adapter<DocumentHolder>
            implements DocumentContext {

        private final Context mContext;
        private final LayoutInflater mInflater;
@@ -1213,6 +1215,14 @@ public class DirectoryFragment extends Fragment {
            }
        }

        @Override
        public Cursor getCursor() {
            if (Looper.myLooper() != Looper.getMainLooper()) {
                throw new IllegalStateException("Can't call getCursor from non-main thread.");
            }
            return mCursor;
        }

        private Cursor getItem(int position) {
            if (position < mCursorCount) {
                mCursor.moveToPosition(position);
+3 −9
Original line number Diff line number Diff line
@@ -26,12 +26,8 @@ import static com.android.documentsui.BaseActivity.State.ACTION_OPEN_TREE;
import static com.android.documentsui.DirectoryFragment.ANIM_DOWN;
import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
import static com.android.documentsui.DirectoryFragment.ANIM_UP;
import static com.android.internal.util.Preconditions.checkArgument;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
@@ -608,12 +604,10 @@ public class DocumentsActivity extends BaseActivity {
    }

    @Override
    public void onDocumentPicked(DocumentInfo doc) {
    public void onDocumentPicked(DocumentInfo doc, DocumentContext context) {
        final FragmentManager fm = getFragmentManager();
        if (doc.isDirectory()) {
            mState.stack.push(doc);
            mState.stackTouched = true;
            onCurrentDirectoryChanged(ANIM_DOWN);
            openDirectory(doc);
        } else if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
            // Explicit file picked, return
            new ExistingFinishTask(doc.derivedUri).executeOnExecutor(getCurrentExecutor());
+112 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 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.model.DocumentInfo.getCursorString;

import android.annotation.Nullable;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.util.Log;

import com.android.documentsui.BaseActivity.DocumentContext;
import com.android.documentsui.model.DocumentInfo;

/**
 * Provides support for gather a list of quick-viewable files into a quick view intent.
 */
final class QuickViewIntentBuilder {

    private static final String TAG = "QvIntentBuilder";
    private static final boolean DEBUG = false;

    private final DocumentInfo mDocument;
    private final DocumentContext mContext;

    public ClipData mClipData;
    public int mDocumentLocation;
    private PackageManager mPkgManager;

    public QuickViewIntentBuilder(
            PackageManager pkgManager, DocumentInfo doc, DocumentContext context) {
        mPkgManager = pkgManager;
        mDocument = doc;
        mContext = context;
    }

    /**
     * Builds the intent for quick viewing. Short circuits building if a handler cannot
     * be resolved; in this case {@code null} is returned.
     */
    @Nullable Intent build() {
        if (DEBUG) Log.d(TAG, "Preparing intent for doc:" + mDocument.documentId);

        Intent intent = new Intent(Intent.ACTION_QUICK_VIEW);
        intent.setDataAndType(mDocument.derivedUri, mDocument.mimeType);

        // Try to resolve the intent. If a matching app isn't installed, it won't resolve.
        ComponentName handler = intent.resolveActivity(mPkgManager);
        if (handler == null) {
            return null;
        }

        Cursor cursor = mContext.getCursor();
        for (int i = 0; i < cursor.getCount(); i++) {
            onNextItem(i, cursor);
        }

        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.putExtra(Intent.EXTRA_INDEX, mDocumentLocation);
        intent.setClipData(mClipData);

        return intent;
    }

    private void onNextItem(int index, Cursor cursor) {
        cursor.moveToPosition(index);

        String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
            return;
        }

        String id = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
        String authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
        Uri uri = DocumentsContract.buildDocumentUri(authority, id);
        if (DEBUG) Log.d(TAG, "Including file[" + id + "] @ " + uri);

        if (id.equals(mDocument.documentId)) {
            if (DEBUG) Log.d(TAG, "Found starting point for QV. " + index);
            mDocumentLocation = index;
        }

        ClipData.Item item = new ClipData.Item(uri);
        if (mClipData == null) {
            mClipData = new ClipData(
                    "URIs", new String[]{ClipDescription.MIMETYPE_TEXT_URILIST}, item);
        } else {
            mClipData.addItem(item);
        }
    }
}
Loading