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

Commit 79b8982b authored by Ivan Chiang's avatar Ivan Chiang
Browse files

Add the check to decide whether to show the chip row

- Get the supported query args from new column Root#COLUMN_QUERY_ARGS
- If the root doesn't support mime type search, hide the chip row

Change-Id: I1c9aa5cdc3a122cde3a2d626d87b94e29f0b777b
Fix: 121234248
Test: atest SearchViewManagerTest
parent 8f12b3b8
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.documentsui.base;

import static android.provider.DocumentsContract.QUERY_ARG_MIME_TYPES;

import static com.android.documentsui.base.DocumentInfo.getCursorInt;
import static com.android.documentsui.base.DocumentInfo.getCursorLong;
import static com.android.documentsui.base.DocumentInfo.getCursorString;
@@ -55,6 +57,7 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
    private static final int LOAD_FROM_CONTENT_RESOLVER = -1;
    // private static final int VERSION_INIT = 1; // Not used anymore
    private static final int VERSION_DROP_TYPE = 2;
    private static final int VERSION_SEARCH_TYPE = 3;

    // The values of these constants determine the sort order of various roots in the RootsFragment.
    @IntDef(flag = false, value = {
@@ -91,6 +94,7 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
    public String documentId;
    public long availableBytes;
    public String mimeTypes;
    public String queryArgs;

    /** Derived fields that aren't persisted */
    public String[] derivedMimeTypes;
@@ -116,6 +120,7 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
        availableBytes = -1;
        mimeTypes = null;
        ejecting = false;
        queryArgs = null;

        derivedMimeTypes = null;
        derivedIcon = 0;
@@ -126,6 +131,8 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
    public void read(DataInputStream in) throws IOException {
        final int version = in.readInt();
        switch (version) {
            case VERSION_SEARCH_TYPE:
                queryArgs = DurableUtils.readNullableString(in);
            case VERSION_DROP_TYPE:
                authority = DurableUtils.readNullableString(in);
                rootId = DurableUtils.readNullableString(in);
@@ -145,7 +152,8 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {

    @Override
    public void write(DataOutputStream out) throws IOException {
        out.writeInt(VERSION_DROP_TYPE);
        out.writeInt(VERSION_SEARCH_TYPE);
        DurableUtils.writeNullableString(out, queryArgs);
        DurableUtils.writeNullableString(out, authority);
        DurableUtils.writeNullableString(out, rootId);
        out.writeInt(flags);
@@ -192,6 +200,7 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
        root.documentId = getCursorString(cursor, Root.COLUMN_DOCUMENT_ID);
        root.availableBytes = getCursorLong(cursor, Root.COLUMN_AVAILABLE_BYTES);
        root.mimeTypes = getCursorString(cursor, Root.COLUMN_MIME_TYPES);
        root.queryArgs = getCursorString(cursor, Root.COLUMN_QUERY_ARGS);
        root.deriveFields();
        return root;
    }
@@ -320,6 +329,10 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
        return (flags & Root.FLAG_SUPPORTS_SEARCH) != 0;
    }

    public boolean supportsMimeTypesSearch() {
        return queryArgs != null && queryArgs.contains(QUERY_ARG_MIME_TYPES);
    }

    public boolean supportsEject() {
        return (flags & Root.FLAG_SUPPORTS_EJECT) != 0;
    }
+2 −10
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
@@ -244,7 +243,7 @@ public class SearchViewManager implements
        }

        final RootInfo root = stack != null ? stack.getRoot() : null;
        if (root == null || (root.flags & Root.FLAG_SUPPORTS_SEARCH) == 0) {
        if (root == null || !root.supportsSearch()) {
            supportsSearch = false;
        }

@@ -260,14 +259,7 @@ public class SearchViewManager implements
        // Recent root show open search bar, do not show duplicate search icon.
        mMenuItem.setVisible(supportsSearch && !stack.isRecents());

        // Only Storage roots, Downloads root, media roots and recent root
        // support mime type query now.
        // TODO: b/121234248 add check for whether the root supports new search method.
        if (supportsSearch && !root.isDownloads() && !root.isStorage() && !root.isLibrary()) {
            supportsSearch = false;
        }

        mChipViewManager.setChipsRowVisible(supportsSearch);
        mChipViewManager.setChipsRowVisible(supportsSearch && root.supportsMimeTypesSearch());
    }

    /**
+3 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.documentsui.roots;

import static android.provider.DocumentsContract.QUERY_ARG_MIME_TYPES;

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

@@ -111,6 +113,7 @@ public class ProvidersCache implements ProvidersAccess {
            derivedIcon = R.drawable.ic_root_recent;
            derivedType = RootInfo.TYPE_RECENTS;
            flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_SEARCH;
            queryArgs = QUERY_ARG_MIME_TYPES;
            title = mContext.getString(R.string.root_recent);
            availableBytes = -1;
        }};
+77 −4
Original line number Diff line number Diff line
@@ -16,6 +16,12 @@

package com.android.documentsui.queries;

import static android.provider.DocumentsContract.QUERY_ARG_DISPLAY_NAME;
import static android.provider.DocumentsContract.QUERY_ARG_FILE_SIZE_OVER;
import static android.provider.DocumentsContract.QUERY_ARG_LAST_MODIFIED_AFTER;
import static android.provider.DocumentsContract.QUERY_ARG_MIME_TYPES;
import static android.provider.DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;

import static com.android.documentsui.base.State.ACTION_GET_CONTENT;

import static junit.framework.Assert.assertEquals;
@@ -23,22 +29,32 @@ import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.provider.DocumentsContract;
import android.text.TextUtils;
import android.view.ViewGroup;

import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.documentsui.R;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.DocumentStack;
import com.android.documentsui.base.EventHandler;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.queries.SearchViewManager.SearchManagerListener;
import com.android.documentsui.testing.TestEventHandler;
import com.android.documentsui.testing.TestHandler;
import com.android.documentsui.testing.TestMenu;
import com.android.documentsui.testing.TestMenuItem;
import com.android.documentsui.testing.TestTimer;

import org.junit.Before;
@@ -57,6 +73,8 @@ public final class SearchViewManagerTest {
    private TestEventHandler<String> mTestEventHandler;
    private TestTimer mTestTimer;
    private TestHandler mTestHandler;
    private TestMenu mTestMenu;
    private TestMenuItem mSearchMenuItem;
    private SearchViewManager mSearchViewManager;
    private SearchChipViewManager mSearchChipViewManager;

@@ -84,12 +102,13 @@ public final class SearchViewManagerTest {
        };

        ViewGroup chipGroup = mock(ViewGroup.class);
        mSearchChipViewManager = new SearchChipViewManager(chipGroup);
        mSearchChipViewManager = spy(new SearchChipViewManager(chipGroup));
        mSearchViewManager = new TestableSearchViewManager(searchListener, mTestEventHandler,
                mSearchChipViewManager, null /* savedState */, mTestTimer, mTestHandler);

        final TestMenu testMenu = TestMenu.create();
        mSearchViewManager.install(testMenu, true);
        mTestMenu = TestMenu.create();
        mSearchMenuItem = mTestMenu.findItem(R.id.option_menu_search);
        mSearchViewManager.install(mTestMenu, true);
    }

    private static class TestableSearchViewManager extends SearchViewManager {
@@ -290,11 +309,65 @@ public final class SearchViewManagerTest {
        final Bundle queryArgs = mSearchViewManager.buildQueryArgs();
        assertFalse(queryArgs.isEmpty());

        final String[] mimeTypes = queryArgs.getStringArray(DocumentsContract.QUERY_ARG_MIME_TYPES);
        final String[] mimeTypes = queryArgs.getStringArray(QUERY_ARG_MIME_TYPES);
        assertTrue(mimeTypes.length > 0);
        assertEquals("image/*", mimeTypes[0]);
    }

    @Test
    public void testSupportsMimeTypesSearch_showChips() throws Exception {
        RootInfo root = spy(new RootInfo());
        when(root.isRecents()).thenReturn(false);
        root.flags = FLAG_SUPPORTS_SEARCH;
        root.queryArgs = QUERY_ARG_MIME_TYPES;
        DocumentStack stack = new DocumentStack(root, new DocumentInfo());

        mSearchViewManager.showMenu(stack);

        verify(mSearchChipViewManager, times(1)).setChipsRowVisible(true);
    }

    @Test
    public void testNotSupportsMimeTypesSearch_notShowChips() throws Exception {
        RootInfo root = spy(new RootInfo());
        when(root.isRecents()).thenReturn(false);
        root.flags = FLAG_SUPPORTS_SEARCH;
        root.queryArgs = TextUtils.join("\n",
                new String[]{QUERY_ARG_DISPLAY_NAME, QUERY_ARG_FILE_SIZE_OVER,
                        QUERY_ARG_LAST_MODIFIED_AFTER});
        DocumentStack stack = new DocumentStack(root, new DocumentInfo());

        mSearchViewManager.showMenu(stack);

        verify(mSearchChipViewManager, times(1)).setChipsRowVisible(false);
    }

    @Test
    public void testSupportsSearch_showMenu() throws Exception {
        RootInfo root = spy(new RootInfo());
        when(root.isRecents()).thenReturn(false);
        root.flags = FLAG_SUPPORTS_SEARCH;
        DocumentStack stack = new DocumentStack(root, new DocumentInfo());

        mSearchViewManager.showMenu(stack);

        assertTrue(mSearchMenuItem.isVisible());
    }

    @Test
    public void testNotSupportsSearch_notShowMenuAndChips() throws Exception {
        RootInfo root = spy(new RootInfo());
        when(root.isRecents()).thenReturn(false);
        root.queryArgs = QUERY_ARG_MIME_TYPES;
        DocumentStack stack = new DocumentStack(root, new DocumentInfo());

        mSearchViewManager.install(mTestMenu, true);
        mSearchViewManager.showMenu(stack);

        assertFalse(mSearchMenuItem.isVisible());
        verify(mSearchChipViewManager, times(1)).setChipsRowVisible(false);
    }

    private static Set<SearchChipData> getFakeSearchChipDataList() {
        final Set<SearchChipData> chipDataList = new HashSet<>();
        chipDataList.add(new SearchChipData(0 /* chipType */, 0, new String[]{"image/*"}));