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

Commit 23ea3e60 authored by Kelvin Kwan's avatar Kelvin Kwan Committed by Android (Google) Code Review
Browse files

Merge "Uses correct uris for QUICK_VIEW, VIEW, and MANAGE_DOCUMENT" into rvc-dev

parents 96f1b367 cb7fa36b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -497,7 +497,7 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA
            // First try managing the document; we expect manager to filter
            // based on authority, so we don't grant.
            Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT);
            manage.setData(doc.derivedUri);
            manage.setData(doc.getDocumentUri());
            try {
                doc.userId.startActivityAsUser(mActivity, manage);
                return true;
@@ -542,7 +542,7 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA

    protected Intent buildViewIntent(DocumentInfo doc) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(doc.derivedUri, doc.mimeType);
        intent.setDataAndType(doc.getDocumentUri(), doc.mimeType);

        // Downloads has traditionally added the WRITE permission
        // in the TrampolineActivity. Since this behavior is long
+38 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.documentsui.files;

import static com.android.documentsui.base.DocumentInfo.getCursorInt;
import static com.android.documentsui.base.DocumentInfo.getCursorString;
import static com.android.documentsui.base.Shared.MAX_DOCS_IN_INTENT;
import static com.android.documentsui.base.SharedMinimal.DEBUG;
@@ -41,6 +42,7 @@ import com.android.documentsui.Model;
import com.android.documentsui.R;
import com.android.documentsui.base.DebugFlags;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.UserId;
import com.android.documentsui.roots.RootCursorWrapper;

import java.util.ArrayList;
@@ -184,7 +186,9 @@ public final class QuickViewIntentBuilder {
        String mimeType;
        String id;
        String authority;
        UserId userId;
        Uri uri;
        boolean hasNonMatchingDocumentUser = false;

        // Cursor's are not guaranteed to be immutable. Hence, traverse it only once.
        for (int i = 0; i < siblingIds.length; i++) {
@@ -209,18 +213,49 @@ public final class QuickViewIntentBuilder {
                continue;
            }

            userId = UserId.of(getCursorInt(cursor, RootCursorWrapper.COLUMN_USER_ID));
            if (!userId.equals(mDocument.userId)) {
                // If there is any document in the model does not have the same user as
                // mDocument, we will not add any siblings and the user for security reason.
                // Although the quick view package is trusted, the trusted quick view package may
                // not notice it is a cross-profile uri and may allow other app to handle this uri.
                if (DEBUG) {
                    Log.d(TAG,
                            "Skipping document from the other user. modelId: "
                                    + siblingIds[i]);
                }
                hasNonMatchingDocumentUser = true;
                continue;
            }

            id = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
            authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
            if (UserId.CURRENT_USER.equals(userId)) {
                uri = DocumentsContract.buildDocumentUri(authority, id);

            uris.add(uri);
            } else {
                uri = userId.buildDocumentUriAsUser(authority, id);
            }

            if (id.equals(mDocument.documentId)) {
                uris.add(uri);
                documentLocation = uris.size() - 1;  // Position in "uris", not in the model.
                if (DEBUG) {
                    Log.d(TAG, "Found starting point for QV. " + documentLocation);
                }
            } else if (!hasNonMatchingDocumentUser) {
                uris.add(uri);
            }
        }

        if (!uris.isEmpty() && hasNonMatchingDocumentUser) {
            if (DEBUG) {
                Log.d(TAG,
                        "Remove all other uris except the document uri");
            }
            Uri documentUri = uris.get(documentLocation);
            uris.clear();
            uris.add(documentUri);
            return 0; // index of the item in a singleton list is 0.
        }

        return documentLocation;
+9 −2
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ public class TestModel extends Model {

    static final String[] COLUMNS = new String[]{
        RootCursorWrapper.COLUMN_AUTHORITY,
        RootCursorWrapper.COLUMN_USER_ID,
        Document.COLUMN_DOCUMENT_ID,
        Document.COLUMN_FLAGS,
        Document.COLUMN_DISPLAY_NAME,
@@ -103,9 +104,10 @@ public class TestModel extends Model {
                flags);
    }

    public DocumentInfo createDocument(String name, String mimeType, int flags) {
    public DocumentInfo createDocumentForUser(String name, String mimeType, int flags,
            UserId userId) {
        DocumentInfo doc = new DocumentInfo();
        doc.userId = mUserId;
        doc.userId = userId;
        doc.authority = mAuthority;
        doc.documentId = Integer.toString(++mLastId);
        doc.derivedUri = DocumentsContract.buildDocumentUri(doc.authority, doc.documentId);
@@ -119,10 +121,15 @@ public class TestModel extends Model {
        return doc;
    }

    public DocumentInfo createDocument(String name, String mimeType, int flags) {
        return createDocumentForUser(name, mimeType, flags, mUserId);
    }

    private void addToCursor(DocumentInfo doc) {
        MatrixCursor.RowBuilder row = mCursor.newRow();
        row.add(Document.COLUMN_DOCUMENT_ID, doc.documentId);
        row.add(RootCursorWrapper.COLUMN_AUTHORITY, doc.authority);
        row.add(RootCursorWrapper.COLUMN_USER_ID, doc.userId);
        row.add(Document.COLUMN_DISPLAY_NAME, doc.displayName);
        row.add(Document.COLUMN_MIME_TYPE, doc.mimeType);
        row.add(Document.COLUMN_FLAGS, doc.flags);
+62 −0
Original line number Diff line number Diff line
package com.android.documentsui.files;

import static com.google.common.truth.Truth.assertThat;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.QuickViewConstants;
@@ -15,8 +18,10 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.testing.TestEnv;
import com.android.documentsui.testing.TestPackageManager;
import com.android.documentsui.testing.TestProvidersAccess;
import com.android.documentsui.testing.TestResources;

import org.junit.Before;
@@ -94,4 +99,61 @@ public class QuickViewIntentBuilderTest {
        assertEquals("Unexpected features set: " + features, 1, features.size());
        assertTrue(features.contains(QuickViewConstants.FEATURE_VIEW));
    }

    @Test
    public void testBuild() {
        mEnv.model.reset();
        DocumentInfo previewDoc = mEnv.model.createFile("a.png", 0);
        mEnv.model.createFile("b.png", 0);
        mEnv.model.createFile("c.png", 0);
        mEnv.model.update();

        QuickViewIntentBuilder builder =
                new QuickViewIntentBuilder(mContext, mRes, previewDoc, mEnv.model, true);

        Intent intent = builder.build();
        ClipData clip = intent.getClipData();
        assertThat(clip.getItemAt(intent.getIntExtra(Intent.EXTRA_INDEX, -1)).getUri())
                .isEqualTo(previewDoc.getDocumentUri());
        assertThat(clip.getItemCount()).isEqualTo(3);
    }

    @Test
    public void testBuild_excludeFolder() {
        mEnv.model.reset();
        mEnv.model.createFolder("folder");
        mEnv.model.createFolder("does not count");
        mEnv.model.createFile("a.png", 0);
        DocumentInfo previewDoc = mEnv.model.createFile("b.png", 0);
        mEnv.model.createFile("c.png", 0);
        mEnv.model.update();

        QuickViewIntentBuilder builder =
                new QuickViewIntentBuilder(mContext, mRes, previewDoc, mEnv.model, true);

        Intent intent = builder.build();
        ClipData clip = intent.getClipData();
        assertThat(clip.getItemAt(intent.getIntExtra(Intent.EXTRA_INDEX, -1)).getUri())
                .isEqualTo(previewDoc.getDocumentUri());
        assertThat(clip.getItemCount()).isEqualTo(3);
    }

    @Test
    public void testBuild_twoProfiles_containsOnlyPreviewDocument() {
        mEnv.model.reset();
        mEnv.model.createDocumentForUser("a.txt", "text/plain", 0,
                TestProvidersAccess.OtherUser.USER_ID);
        DocumentInfo previewDoc = mEnv.model.createFile("b.png", 0);
        mEnv.model.createFile("c.png", 0);
        mEnv.model.update();

        QuickViewIntentBuilder builder =
                new QuickViewIntentBuilder(mContext, mRes, previewDoc, mEnv.model, true);

        Intent intent = builder.build();
        ClipData clip = intent.getClipData();
        assertThat(clip.getItemAt(intent.getIntExtra(Intent.EXTRA_INDEX, -1)).getUri())
                .isEqualTo(previewDoc.getDocumentUri());
        assertThat(clip.getItemCount()).isEqualTo(1);
    }
}
+8 −4
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import com.android.documentsui.Injector;
import com.android.documentsui.R;
import com.android.documentsui.TestUserIdManager;
import com.android.documentsui.UserIdManager;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.DocumentStack;
import com.android.documentsui.base.Lookup;
import com.android.documentsui.base.RootInfo;
@@ -683,11 +684,14 @@ public class ActionHandlerTest {
    @Test
    public void testPreviewItem_onOtherUser() throws Exception {
        if (VersionUtils.isAtLeastR()) {

            mActivity.resources.setQuickViewerPackage("corptropolis.viewer");
            mActivity.currentRoot = TestProvidersAccess.OtherUser.DOWNLOADS;
            mEnv.model.reset();
            DocumentInfo otherUserDoc = mEnv.model.createDocumentForUser("a.png",
                    "image/png", /* flags= */ 0, TestProvidersAccess.OtherUser.USER_ID);
            mEnv.model.update();

            mHandler.onDocumentOpened(TestEnv.OtherUser.FILE_PNG, ActionHandler.VIEW_TYPE_PREVIEW,
            mHandler.onDocumentOpened(otherUserDoc, ActionHandler.VIEW_TYPE_PREVIEW,
                    ActionHandler.VIEW_TYPE_REGULAR, true);
            mActivity.assertActivityAsUserStarted(Intent.ACTION_QUICK_VIEW,
                    TestProvidersAccess.OtherUser.USER_HANDLE);