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

Commit 199b0fd6 authored by Fan Zhang's avatar Fan Zhang
Browse files

Display recents when search fragment open.

Bug: 27391895
Test: make RunSettingsRoboTests
Change-Id: I62cfa35af96babf85a795910aa76dc774e2b80f2
parent ae4d32e2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ public class SavedQueryViewHolder extends SearchViewHolder {

    public SavedQueryViewHolder(View view) {
        super(view);
        titleView = (TextView) view.findViewById(android.R.id.title);
        titleView = view.findViewById(android.R.id.title);
    }

    @Override
+24 −20
Original line number Diff line number Diff line
@@ -45,9 +45,8 @@ import com.android.settings.overlay.FeatureFactory;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class SearchFragment extends InstrumentedFragment implements
        SearchView.OnQueryTextListener, LoaderManager.LoaderCallbacks<List<? extends SearchResult>>
{
public class SearchFragment extends InstrumentedFragment implements SearchView.OnQueryTextListener,
        LoaderManager.LoaderCallbacks<List<? extends SearchResult>> {
    private static final String TAG = "SearchFragment";

    @VisibleForTesting
@@ -66,7 +65,7 @@ public class SearchFragment extends InstrumentedFragment implements
    private static final int NUM_QUERY_LOADERS = 2;

    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    AtomicInteger mUnfinishedLoadersCount = new AtomicInteger(NUM_QUERY_LOADERS);;
    AtomicInteger mUnfinishedLoadersCount = new AtomicInteger(NUM_QUERY_LOADERS);

    // Logging
    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
@@ -93,8 +92,7 @@ public class SearchFragment extends InstrumentedFragment implements
    private LinearLayout mNoResultsView;

    @VisibleForTesting
    final RecyclerView.OnScrollListener mScrollListener =
            new RecyclerView.OnScrollListener() {
    final RecyclerView.OnScrollListener mScrollListener = new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            if (dy != 0) {
@@ -155,12 +153,12 @@ public class SearchFragment extends InstrumentedFragment implements
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        final View view = inflater.inflate(R.layout.search_panel_2, container, false);
        mResultsRecyclerView = (RecyclerView) view.findViewById(R.id.list_results);
        mResultsRecyclerView = view.findViewById(R.id.list_results);
        mResultsRecyclerView.setAdapter(mSearchAdapter);
        mResultsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        mResultsRecyclerView.addOnScrollListener(mScrollListener);

        mNoResultsView = (LinearLayout) view.findViewById(R.id.no_results_layout);
        mNoResultsView = view.findViewById(R.id.no_results_layout);
        return view;
    }

@@ -245,16 +243,20 @@ public class SearchFragment extends InstrumentedFragment implements
    @Override
    public void onLoadFinished(Loader<List<? extends SearchResult>> loader,
            List<? extends SearchResult> data) {
        mSearchAdapter.addResultsToMap(data, loader.getClass().getName());

        if (mUnfinishedLoadersCount.decrementAndGet() == 0) {
            final int resultCount = mSearchAdapter.mergeResults();
            mSearchFeatureProvider.showFeedbackButton(this, getView());

            if (resultCount == 0) {
                mNoResultsView.setVisibility(View.VISIBLE);
        final int resultCount;
        switch (loader.getId()) {
            case LOADER_ID_RECENTS:
                resultCount = mSearchAdapter.displaySavedQuery(data);
                break;
            default:
                mSearchAdapter.addSearchResults(data, loader.getClass().getName());
                if (mUnfinishedLoadersCount.decrementAndGet() != 0) {
                    return;
                }
                resultCount = mSearchAdapter.displaySearchResults();
        }
        mNoResultsView.setVisibility(resultCount == 0 ? View.VISIBLE : View.GONE);
        mSearchFeatureProvider.showFeedbackButton(this, getView());
    }

    @Override
@@ -267,6 +269,8 @@ public class SearchFragment extends InstrumentedFragment implements

    public void onSavedQueryClicked(CharSequence query) {
        final String queryString = query.toString();
        mMetricsFeatureProvider.action(getContext(),
                MetricsProto.MetricsEvent.ACTION_CLICK_SETTINGS_SEARCH_SAVED_QUERY);
        mSearchView.setQuery(queryString, false /* submit */);
        onQueryTextChange(queryString);
    }
+22 −10
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ package com.android.settings.search2;
import android.content.Context;
import android.support.annotation.MainThread;
import android.support.annotation.VisibleForTesting;
import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.RecyclerView;
import android.util.ArrayMap;
import android.view.LayoutInflater;
import android.view.View;
@@ -32,10 +32,10 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.android.settings.search2.SearchResult.TOP_RANK;
import static com.android.settings.search2.SearchResult.BOTTOM_RANK;
import static com.android.settings.search2.SearchResult.TOP_RANK;

public class SearchResultsAdapter extends Adapter<SearchViewHolder> {
public class SearchResultsAdapter extends RecyclerView.Adapter<SearchViewHolder> {

    private final List<SearchResult> mSearchResults;
    private final SearchFragment mFragment;
@@ -91,16 +91,28 @@ public class SearchResultsAdapter extends Adapter<SearchViewHolder> {

    /**
     * Store the results from each of the loaders to be merged when all loaders are finished.
     * @param freshResults are the results from the loader.
     *
     * @param results         the results from the loader.
     * @param loaderClassName class name of the loader.
     */
    @MainThread
    public void addResultsToMap(List<? extends SearchResult> freshResults,
            String loaderClassName) {
        if (freshResults == null) {
    public void addSearchResults(List<? extends SearchResult> results, String loaderClassName) {
        if (results == null) {
            return;
        }
        mResultsMap.put(loaderClassName, freshResults);
        mResultsMap.put(loaderClassName, results);
    }

    /**
     * Displays recent searched queries.
     *
     * @return The number of saved queries to display
     */
    public int displaySavedQuery(List<? extends SearchResult> data) {
        clearResults();
        mSearchResults.addAll(data);
        notifyDataSetChanged();
        return mSearchResults.size();
    }

    /**
@@ -109,7 +121,7 @@ public class SearchResultsAdapter extends Adapter<SearchViewHolder> {
     *
     * @return Number of matched results
     */
    public int mergeResults() {
    public int displaySearchResults() {
        final List<? extends SearchResult> databaseResults = mResultsMap
                .get(DatabaseResultLoader.class.getName());
        final List<? extends SearchResult> installedAppResults = mResultsMap
+9 −14
Original line number Diff line number Diff line
@@ -21,9 +21,9 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;

import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
@@ -34,13 +34,12 @@ import com.android.settings.search2.InstalledAppResultLoader;
import com.android.settings.search2.IntentPayload;
import com.android.settings.search2.IntentSearchViewHolder;
import com.android.settings.search2.ResultPayload;
import com.android.settings.search2.SearchActivity;
import com.android.settings.search2.SearchFragment;
import com.android.settings.search2.SearchResult;
import com.android.settings.search2.SearchResult.Builder;
import com.android.settings.search2.SearchResultsAdapter;

import com.android.settings.search2.SearchViewHolder;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -48,15 +47,11 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowViewGroup;
import org.robolectric.util.ActivityController;

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

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;

@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -85,15 +80,15 @@ public class SearchResultsAdapterTest {
    @Test
    public void testSingleSourceMerge_ExactCopyReturned() {
        ArrayList<SearchResult> intentResults = getIntentSampleResults();
        mAdapter.addResultsToMap(intentResults, mLoaderClassName);
        mAdapter.mergeResults();
        mAdapter.addSearchResults(intentResults, mLoaderClassName);
        mAdapter.displaySearchResults();

        List<SearchResult> updatedResults = mAdapter.getSearchResults();
        assertThat(updatedResults).containsAllIn(intentResults);
    }

    @Test
    public void testCreatViewHolder_ReturnsIntentResult() {
    public void testCreateViewHolder_ReturnsIntentResult() {
        ViewGroup group = new FrameLayout(mContext);
        SearchViewHolder view = mAdapter.onCreateViewHolder(group,
                ResultPayload.PayloadType.INTENT);
@@ -101,7 +96,7 @@ public class SearchResultsAdapterTest {
    }

    @Test
    public void testCreatViewHolder_ReturnsInlineSwitchResult() {
    public void testCreateViewHolder_ReturnsInlineSwitchResult() {
        ViewGroup group = new FrameLayout(mContext);
        SearchViewHolder view = mAdapter.onCreateViewHolder(group,
                ResultPayload.PayloadType.INLINE_SWITCH);
@@ -110,11 +105,11 @@ public class SearchResultsAdapterTest {

    @Test
    public void testEndToEndSearch_ProperResultsMerged() {
        mAdapter.addResultsToMap(getDummyAppResults(),
        mAdapter.addSearchResults(getDummyAppResults(),
                InstalledAppResultLoader.class.getName());
        mAdapter.addResultsToMap(getDummyDbResults(),
        mAdapter.addSearchResults(getDummyDbResults(),
                DatabaseResultLoader.class.getName());
        int count = mAdapter.mergeResults();
        int count = mAdapter.displaySearchResults();

        List<SearchResult> results = mAdapter.getSearchResults();
        assertThat(results.get(0).title).isEqualTo("alpha");
+67 −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.settings.search2;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;

import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;

import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SavedQueryViewHolderTest {

    @Mock
    private SearchFragment mSearchFragment;
    private Context mContext;
    private SavedQueryViewHolder mHolder;
    private View mView;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mContext = RuntimeEnvironment.application;
        mView = LayoutInflater.from(mContext)
                .inflate(R.layout.search_saved_query_item, null);
        mHolder = new SavedQueryViewHolder(mView);
    }

    @Test
    public void onBind_shouldBindClickCallback() {
        final SearchResult result = mock(SearchResult.class);
        mHolder.onBind(mSearchFragment, result);

        mView.performClick();

        verify(mSearchFragment).onSavedQueryClicked(any(CharSequence.class));
    }
}
Loading