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

Commit be0e3f37 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Display recents when search fragment open."

parents e9b0bc65 199b0fd6
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