Loading src/com/android/settings/search2/SearchFragment.java +38 −5 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.LinearLayout.LayoutParams; import android.widget.SearchView; Loading @@ -48,6 +49,9 @@ public class SearchFragment extends InstrumentedFragment implements { private static final String TAG = "SearchFragment"; @VisibleForTesting static final int SEARCH_TAG = "SearchViewTag".hashCode(); // State values private static final String STATE_QUERY = "state_query"; private static final String STATE_NEVER_ENTERED_QUERY = "state_never_entered_query"; Loading Loading @@ -80,12 +84,23 @@ public class SearchFragment extends InstrumentedFragment implements @VisibleForTesting (otherwise = VisibleForTesting.PRIVATE) SearchFeatureProvider mSearchFeatureProvider; @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) SearchResultsAdapter mSearchAdapter; private SearchResultsAdapter mSearchAdapter; private RecyclerView mResultsRecyclerView; @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) RecyclerView mResultsRecyclerView; private SearchView mSearchView; @VisibleForTesting final RecyclerView.OnScrollListener mScrollListener = new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { if (dy != 0) { hideKeyboard(); } } }; @Override public int getMetricsCategory() { return MetricsProto.MetricsEvent.DASHBOARD_SEARCH_RESULTS; Loading Loading @@ -122,6 +137,7 @@ public class SearchFragment extends InstrumentedFragment implements actionBar.setCustomView(mSearchView); actionBar.setDisplayShowCustomEnabled(true); actionBar.setDisplayShowTitleEnabled(false); mSearchView.requestFocus(); // Run the Index update only if we have some space if (!Utils.isLowStorage(activity)) { Loading @@ -138,6 +154,7 @@ public class SearchFragment extends InstrumentedFragment implements mResultsRecyclerView = (RecyclerView) view.findViewById(R.id.list_results); mResultsRecyclerView.setAdapter(mSearchAdapter); mResultsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); mResultsRecyclerView.addOnScrollListener(mScrollListener); return view; } Loading Loading @@ -189,7 +206,7 @@ public class SearchFragment extends InstrumentedFragment implements // Save submitted query. getLoaderManager().restartLoader(SaveQueryRecorderCallback.LOADER_ID_SAVE_QUERY_TASK, null, mSaveQueryRecorderCallback); hideKeyboard(); return true; } Loading Loading @@ -240,17 +257,33 @@ public class SearchFragment extends InstrumentedFragment implements loaderManager.restartLoader(LOADER_ID_INSTALLED_APPS, null /* args */, this /* callback */); } private SearchView makeSearchView(ActionBar actionBar, String query) { @VisibleForTesting (otherwise = VisibleForTesting.PRIVATE) SearchView makeSearchView(ActionBar actionBar, String query) { final SearchView searchView = new SearchView(actionBar.getThemedContext()); searchView.setIconifiedByDefault(false); searchView.setQuery(query, false /* submitQuery */); searchView.setOnQueryTextListener(this); searchView.setTag(SEARCH_TAG, searchView); final LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); searchView.setLayoutParams(lp); return searchView; } private void hideKeyboard() { final Activity activity = getActivity(); if (activity != null) { View view = activity.getCurrentFocus(); InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(view.getWindowToken(), 0); } if (mResultsRecyclerView != null) { mResultsRecyclerView.requestFocus(); } } private class SaveQueryRecorderCallback implements LoaderManager.LoaderCallbacks<Void> { // TODO: make a generic background task manager to handle one-off tasks like this one. Loading tests/app/src/com/android/settings/search2/SearchFragmentEspressoTest.java 0 → 100644 +49 −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.support.test.filters.SmallTest; import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; import android.widget.SearchView; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.matcher.ViewMatchers.hasFocus; import static android.support.test.espresso.matcher.ViewMatchers.withClassName; import static android.support.test.espresso.matcher.ViewMatchers.withTagKey; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.core.AllOf.allOf; @RunWith(AndroidJUnit4.class) @SmallTest public class SearchFragmentEspressoTest { @Rule public ActivityTestRule<SearchActivity> mActivityRule = new ActivityTestRule<>(SearchActivity.class, true, true); @Test public void test_OpenKeyboardOnSearchLaunch() { onView(allOf(hasFocus(), withTagKey(SearchFragment.SEARCH_TAG))) .check(matches(withClassName(containsString(SearchView.class.getName())))); } } tests/robotests/src/com/android/settings/search2/SearchFragmentTest.java +0 −8 Original line number Diff line number Diff line Loading @@ -20,16 +20,12 @@ import android.content.Context; import android.content.Loader; import android.os.Bundle; import android.os.UserManager; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.dashboard.SiteMapManager; import com.android.settings.testutils.DatabaseTestUtils; import com.android.settings.testutils.FakeFeatureFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -41,14 +37,11 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.util.ActivityController; import java.util.ArrayList; import java.util.List; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; Loading Loading @@ -248,5 +241,4 @@ public class SearchFragmentTest { verify(fragment, times(2)).onLoadFinished(any(Loader.class), any(List.class)); } } Loading
src/com/android/settings/search2/SearchFragment.java +38 −5 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.LinearLayout.LayoutParams; import android.widget.SearchView; Loading @@ -48,6 +49,9 @@ public class SearchFragment extends InstrumentedFragment implements { private static final String TAG = "SearchFragment"; @VisibleForTesting static final int SEARCH_TAG = "SearchViewTag".hashCode(); // State values private static final String STATE_QUERY = "state_query"; private static final String STATE_NEVER_ENTERED_QUERY = "state_never_entered_query"; Loading Loading @@ -80,12 +84,23 @@ public class SearchFragment extends InstrumentedFragment implements @VisibleForTesting (otherwise = VisibleForTesting.PRIVATE) SearchFeatureProvider mSearchFeatureProvider; @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) SearchResultsAdapter mSearchAdapter; private SearchResultsAdapter mSearchAdapter; private RecyclerView mResultsRecyclerView; @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) RecyclerView mResultsRecyclerView; private SearchView mSearchView; @VisibleForTesting final RecyclerView.OnScrollListener mScrollListener = new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { if (dy != 0) { hideKeyboard(); } } }; @Override public int getMetricsCategory() { return MetricsProto.MetricsEvent.DASHBOARD_SEARCH_RESULTS; Loading Loading @@ -122,6 +137,7 @@ public class SearchFragment extends InstrumentedFragment implements actionBar.setCustomView(mSearchView); actionBar.setDisplayShowCustomEnabled(true); actionBar.setDisplayShowTitleEnabled(false); mSearchView.requestFocus(); // Run the Index update only if we have some space if (!Utils.isLowStorage(activity)) { Loading @@ -138,6 +154,7 @@ public class SearchFragment extends InstrumentedFragment implements mResultsRecyclerView = (RecyclerView) view.findViewById(R.id.list_results); mResultsRecyclerView.setAdapter(mSearchAdapter); mResultsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); mResultsRecyclerView.addOnScrollListener(mScrollListener); return view; } Loading Loading @@ -189,7 +206,7 @@ public class SearchFragment extends InstrumentedFragment implements // Save submitted query. getLoaderManager().restartLoader(SaveQueryRecorderCallback.LOADER_ID_SAVE_QUERY_TASK, null, mSaveQueryRecorderCallback); hideKeyboard(); return true; } Loading Loading @@ -240,17 +257,33 @@ public class SearchFragment extends InstrumentedFragment implements loaderManager.restartLoader(LOADER_ID_INSTALLED_APPS, null /* args */, this /* callback */); } private SearchView makeSearchView(ActionBar actionBar, String query) { @VisibleForTesting (otherwise = VisibleForTesting.PRIVATE) SearchView makeSearchView(ActionBar actionBar, String query) { final SearchView searchView = new SearchView(actionBar.getThemedContext()); searchView.setIconifiedByDefault(false); searchView.setQuery(query, false /* submitQuery */); searchView.setOnQueryTextListener(this); searchView.setTag(SEARCH_TAG, searchView); final LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); searchView.setLayoutParams(lp); return searchView; } private void hideKeyboard() { final Activity activity = getActivity(); if (activity != null) { View view = activity.getCurrentFocus(); InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(view.getWindowToken(), 0); } if (mResultsRecyclerView != null) { mResultsRecyclerView.requestFocus(); } } private class SaveQueryRecorderCallback implements LoaderManager.LoaderCallbacks<Void> { // TODO: make a generic background task manager to handle one-off tasks like this one. Loading
tests/app/src/com/android/settings/search2/SearchFragmentEspressoTest.java 0 → 100644 +49 −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.support.test.filters.SmallTest; import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; import android.widget.SearchView; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.matcher.ViewMatchers.hasFocus; import static android.support.test.espresso.matcher.ViewMatchers.withClassName; import static android.support.test.espresso.matcher.ViewMatchers.withTagKey; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.core.AllOf.allOf; @RunWith(AndroidJUnit4.class) @SmallTest public class SearchFragmentEspressoTest { @Rule public ActivityTestRule<SearchActivity> mActivityRule = new ActivityTestRule<>(SearchActivity.class, true, true); @Test public void test_OpenKeyboardOnSearchLaunch() { onView(allOf(hasFocus(), withTagKey(SearchFragment.SEARCH_TAG))) .check(matches(withClassName(containsString(SearchView.class.getName())))); } }
tests/robotests/src/com/android/settings/search2/SearchFragmentTest.java +0 −8 Original line number Diff line number Diff line Loading @@ -20,16 +20,12 @@ import android.content.Context; import android.content.Loader; import android.os.Bundle; import android.os.UserManager; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.dashboard.SiteMapManager; import com.android.settings.testutils.DatabaseTestUtils; import com.android.settings.testutils.FakeFeatureFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -41,14 +37,11 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.util.ActivityController; import java.util.ArrayList; import java.util.List; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; Loading Loading @@ -248,5 +241,4 @@ public class SearchFragmentTest { verify(fragment, times(2)).onLoadFinished(any(Loader.class), any(List.class)); } }