Misc bug fixes around search bar in app list UI.
- Turn off DEBUG log flag, it's spammy and is a potential PII risk. - Save search bar expand state so it stays open during screen rotation. - Introduce a intent extra so callers can deep link into this UI with search bar pre-expanded. Fixes: 130422388 Test: robotest Change-Id: Ib81080733707306de516c49340571c543e70874e
This commit is contained in:
@@ -135,7 +135,7 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
implements View.OnClickListener, OnItemSelectedListener, SearchView.OnQueryTextListener {
|
implements View.OnClickListener, OnItemSelectedListener, SearchView.OnQueryTextListener {
|
||||||
|
|
||||||
static final String TAG = "ManageApplications";
|
static final String TAG = "ManageApplications";
|
||||||
static final boolean DEBUG = true;
|
static final boolean DEBUG = false;
|
||||||
|
|
||||||
// Intent extras.
|
// Intent extras.
|
||||||
public static final String EXTRA_CLASSNAME = "classname";
|
public static final String EXTRA_CLASSNAME = "classname";
|
||||||
@@ -151,6 +151,7 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
private static final String EXTRA_HAS_ENTRIES = "hasEntries";
|
private static final String EXTRA_HAS_ENTRIES = "hasEntries";
|
||||||
private static final String EXTRA_HAS_BRIDGE = "hasBridge";
|
private static final String EXTRA_HAS_BRIDGE = "hasBridge";
|
||||||
private static final String EXTRA_FILTER_TYPE = "filterType";
|
private static final String EXTRA_FILTER_TYPE = "filterType";
|
||||||
|
private static final String EXTRA_EXPAND_SEARCH_VIEW = "expand_search_view";
|
||||||
|
|
||||||
// attributes used as keys when passing values to AppInfoDashboardFragment activity
|
// attributes used as keys when passing values to AppInfoDashboardFragment activity
|
||||||
public static final String APP_CHG = "chg";
|
public static final String APP_CHG = "chg";
|
||||||
@@ -220,6 +221,9 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
FilterSpinnerAdapter mFilterAdapter;
|
FilterSpinnerAdapter mFilterAdapter;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
RecyclerView mRecyclerView;
|
RecyclerView mRecyclerView;
|
||||||
|
// Whether or not search view is expanded.
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean mExpandSearch;
|
||||||
|
|
||||||
private View mRootView;
|
private View mRootView;
|
||||||
private Spinner mFilterSpinner;
|
private Spinner mFilterSpinner;
|
||||||
@@ -307,12 +311,14 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
mFilter = appFilterRegistry.get(appFilterRegistry.getDefaultFilterType(mListType));
|
mFilter = appFilterRegistry.get(appFilterRegistry.getDefaultFilterType(mListType));
|
||||||
mIsWorkOnly = args != null ? args.getBoolean(EXTRA_WORK_ONLY) : false;
|
mIsWorkOnly = args != null ? args.getBoolean(EXTRA_WORK_ONLY) : false;
|
||||||
mWorkUserId = args != null ? args.getInt(EXTRA_WORK_ID) : NO_USER_SPECIFIED;
|
mWorkUserId = args != null ? args.getInt(EXTRA_WORK_ID) : NO_USER_SPECIFIED;
|
||||||
|
mExpandSearch = activity.getIntent().getBooleanExtra(EXTRA_EXPAND_SEARCH_VIEW, false);
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
mSortOrder = savedInstanceState.getInt(EXTRA_SORT_ORDER, mSortOrder);
|
mSortOrder = savedInstanceState.getInt(EXTRA_SORT_ORDER, mSortOrder);
|
||||||
mShowSystem = savedInstanceState.getBoolean(EXTRA_SHOW_SYSTEM, mShowSystem);
|
mShowSystem = savedInstanceState.getBoolean(EXTRA_SHOW_SYSTEM, mShowSystem);
|
||||||
mFilterType =
|
mFilterType =
|
||||||
savedInstanceState.getInt(EXTRA_FILTER_TYPE, AppFilterRegistry.FILTER_APPS_ALL);
|
savedInstanceState.getInt(EXTRA_FILTER_TYPE, AppFilterRegistry.FILTER_APPS_ALL);
|
||||||
|
mExpandSearch = savedInstanceState.getBoolean(EXTRA_EXPAND_SEARCH_VIEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
mInvalidSizeStr = activity.getText(R.string.invalid_size_value);
|
mInvalidSizeStr = activity.getText(R.string.invalid_size_value);
|
||||||
@@ -501,6 +507,7 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
outState.putBoolean(EXTRA_SHOW_SYSTEM, mShowSystem);
|
outState.putBoolean(EXTRA_SHOW_SYSTEM, mShowSystem);
|
||||||
outState.putBoolean(EXTRA_HAS_ENTRIES, mApplications.mHasReceivedLoadEntries);
|
outState.putBoolean(EXTRA_HAS_ENTRIES, mApplications.mHasReceivedLoadEntries);
|
||||||
outState.putBoolean(EXTRA_HAS_BRIDGE, mApplications.mHasReceivedBridgeCallback);
|
outState.putBoolean(EXTRA_HAS_BRIDGE, mApplications.mHasReceivedBridgeCallback);
|
||||||
|
outState.putBoolean(EXTRA_EXPAND_SEARCH_VIEW, !mSearchView.isIconified());
|
||||||
outState.putInt(EXTRA_FILTER_TYPE, mFilter.getFilterType());
|
outState.putInt(EXTRA_FILTER_TYPE, mFilter.getFilterType());
|
||||||
if (mApplications != null) {
|
if (mApplications != null) {
|
||||||
mApplications.onSaveInstanceState(outState);
|
mApplications.onSaveInstanceState(outState);
|
||||||
@@ -607,6 +614,9 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
mSearchView = (SearchView) searchMenuItem.getActionView();
|
mSearchView = (SearchView) searchMenuItem.getActionView();
|
||||||
mSearchView.setQueryHint(getText(R.string.search_settings));
|
mSearchView.setQueryHint(getText(R.string.search_settings));
|
||||||
mSearchView.setOnQueryTextListener(this);
|
mSearchView.setOnQueryTextListener(this);
|
||||||
|
if (mExpandSearch) {
|
||||||
|
searchMenuItem.expandActionView();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateOptionsMenu();
|
updateOptionsMenu();
|
||||||
|
@@ -19,17 +19,14 @@ package com.android.settings.applications.manageapplications;
|
|||||||
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING;
|
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING;
|
||||||
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
|
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
|
||||||
|
|
||||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry
|
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_ALL;
|
||||||
.FILTER_APPS_ALL;
|
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_MAIN;
|
||||||
import static com.android.settings.applications.manageapplications.ManageApplications
|
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_NOTIFICATION;
|
||||||
.LIST_TYPE_MAIN;
|
|
||||||
import static com.android.settings.applications.manageapplications.ManageApplications
|
|
||||||
.LIST_TYPE_NOTIFICATION;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.doNothing;
|
||||||
@@ -172,7 +169,7 @@ public class ManageApplicationsTest {
|
|||||||
when(searchMenu.getActionView()).thenReturn(searchView);
|
when(searchMenu.getActionView()).thenReturn(searchView);
|
||||||
when(mMenu.findItem(R.id.search_app_list_menu)).thenReturn(searchMenu);
|
when(mMenu.findItem(R.id.search_app_list_menu)).thenReturn(searchMenu);
|
||||||
when(mMenu.add(anyInt() /* groupId */, anyInt() /* itemId */, anyInt() /* order */,
|
when(mMenu.add(anyInt() /* groupId */, anyInt() /* itemId */, anyInt() /* order */,
|
||||||
anyInt() /* titleRes */)).thenReturn(helpMenu);
|
anyInt() /* titleRes */)).thenReturn(helpMenu);
|
||||||
doReturn("Test").when(mFragment).getText(anyInt() /* resId */);
|
doReturn("Test").when(mFragment).getText(anyInt() /* resId */);
|
||||||
doNothing().when(mFragment).updateOptionsMenu();
|
doNothing().when(mFragment).updateOptionsMenu();
|
||||||
|
|
||||||
@@ -181,10 +178,28 @@ public class ManageApplicationsTest {
|
|||||||
verify(searchView).setOnQueryTextListener(mFragment);
|
verify(searchView).setOnQueryTextListener(mFragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onCreateOptionsMenu_hasExpandSearchFlag_shouldExpandSearchView() {
|
||||||
|
final SearchView searchView = mock(SearchView.class);
|
||||||
|
final MenuItem searchMenu = mock(MenuItem.class);
|
||||||
|
final MenuItem helpMenu = mock(MenuItem.class);
|
||||||
|
when(searchMenu.getActionView()).thenReturn(searchView);
|
||||||
|
when(mMenu.findItem(R.id.search_app_list_menu)).thenReturn(searchMenu);
|
||||||
|
when(mMenu.add(anyInt() /* groupId */, anyInt() /* itemId */, anyInt() /* order */,
|
||||||
|
anyInt() /* titleRes */)).thenReturn(helpMenu);
|
||||||
|
doReturn("Test").when(mFragment).getText(anyInt() /* resId */);
|
||||||
|
doNothing().when(mFragment).updateOptionsMenu();
|
||||||
|
|
||||||
|
mFragment.mExpandSearch = true;
|
||||||
|
mFragment.onCreateOptionsMenu(mMenu, mock(MenuInflater.class));
|
||||||
|
|
||||||
|
verify(searchMenu).expandActionView();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onQueryTextChange_shouldFilterSearchInApplicationsAdapter() {
|
public void onQueryTextChange_shouldFilterSearchInApplicationsAdapter() {
|
||||||
final ManageApplications.ApplicationsAdapter adapter =
|
final ManageApplications.ApplicationsAdapter adapter =
|
||||||
mock(ManageApplications.ApplicationsAdapter.class);
|
mock(ManageApplications.ApplicationsAdapter.class);
|
||||||
final String query = "Test App";
|
final String query = "Test App";
|
||||||
ReflectionHelpers.setField(mFragment, "mApplications", adapter);
|
ReflectionHelpers.setField(mFragment, "mApplications", adapter);
|
||||||
|
|
||||||
@@ -289,13 +304,13 @@ public class ManageApplicationsTest {
|
|||||||
when(listContainer.getVisibility()).thenReturn(View.VISIBLE);
|
when(listContainer.getVisibility()).thenReturn(View.VISIBLE);
|
||||||
ReflectionHelpers.setField(mFragment, "mListContainer", listContainer);
|
ReflectionHelpers.setField(mFragment, "mListContainer", listContainer);
|
||||||
ReflectionHelpers.setField(
|
ReflectionHelpers.setField(
|
||||||
mFragment, "mFilterAdapter", mock(ManageApplications.FilterSpinnerAdapter.class));
|
mFragment, "mFilterAdapter", mock(ManageApplications.FilterSpinnerAdapter.class));
|
||||||
final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
|
final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
|
||||||
appList.add(mock(ApplicationsState.AppEntry.class));
|
appList.add(mock(ApplicationsState.AppEntry.class));
|
||||||
final ManageApplications.ApplicationsAdapter adapter =
|
final ManageApplications.ApplicationsAdapter adapter =
|
||||||
spy(new ManageApplications.ApplicationsAdapter(mState, mFragment,
|
spy(new ManageApplications.ApplicationsAdapter(mState, mFragment,
|
||||||
AppFilterRegistry.getInstance().get(FILTER_APPS_ALL),
|
AppFilterRegistry.getInstance().get(FILTER_APPS_ALL),
|
||||||
null /* savedInstanceState */));
|
null /* savedInstanceState */));
|
||||||
|
|
||||||
adapter.onRebuildComplete(appList);
|
adapter.onRebuildComplete(appList);
|
||||||
|
|
||||||
@@ -365,7 +380,7 @@ public class ManageApplicationsTest {
|
|||||||
ReflectionHelpers.setField(holder, "itemView", mock(View.class));
|
ReflectionHelpers.setField(holder, "itemView", mock(View.class));
|
||||||
ManageApplications.ApplicationsAdapter adapter =
|
ManageApplications.ApplicationsAdapter adapter =
|
||||||
new ManageApplications.ApplicationsAdapter(mState,
|
new ManageApplications.ApplicationsAdapter(mState,
|
||||||
mFragment, mock(AppFilterItem.class),
|
mFragment, mock(AppFilterItem.class),
|
||||||
mock(Bundle.class));
|
mock(Bundle.class));
|
||||||
final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
|
final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
|
||||||
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
||||||
@@ -399,8 +414,8 @@ public class ManageApplicationsTest {
|
|||||||
@Test
|
@Test
|
||||||
public void applicationsAdapter_filterSearch_emptyQuery_shouldShowFullList() {
|
public void applicationsAdapter_filterSearch_emptyQuery_shouldShowFullList() {
|
||||||
final ManageApplications.ApplicationsAdapter adapter =
|
final ManageApplications.ApplicationsAdapter adapter =
|
||||||
new ManageApplications.ApplicationsAdapter(
|
new ManageApplications.ApplicationsAdapter(
|
||||||
mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
|
mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
|
||||||
final String[] appNames = {"Apricot", "Banana", "Cantaloupe", "Fig", "Mango"};
|
final String[] appNames = {"Apricot", "Banana", "Cantaloupe", "Fig", "Mango"};
|
||||||
ReflectionHelpers.setField(adapter, "mOriginalEntries", getTestAppList(appNames));
|
ReflectionHelpers.setField(adapter, "mOriginalEntries", getTestAppList(appNames));
|
||||||
|
|
||||||
@@ -412,8 +427,8 @@ public class ManageApplicationsTest {
|
|||||||
@Test
|
@Test
|
||||||
public void applicationsAdapter_filterSearch_noMatch_shouldShowEmptyList() {
|
public void applicationsAdapter_filterSearch_noMatch_shouldShowEmptyList() {
|
||||||
final ManageApplications.ApplicationsAdapter adapter =
|
final ManageApplications.ApplicationsAdapter adapter =
|
||||||
new ManageApplications.ApplicationsAdapter(
|
new ManageApplications.ApplicationsAdapter(
|
||||||
mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
|
mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
|
||||||
final String[] appNames = {"Apricot", "Banana", "Cantaloupe", "Fig", "Mango"};
|
final String[] appNames = {"Apricot", "Banana", "Cantaloupe", "Fig", "Mango"};
|
||||||
ReflectionHelpers.setField(adapter, "mOriginalEntries", getTestAppList(appNames));
|
ReflectionHelpers.setField(adapter, "mOriginalEntries", getTestAppList(appNames));
|
||||||
|
|
||||||
@@ -425,8 +440,8 @@ public class ManageApplicationsTest {
|
|||||||
@Test
|
@Test
|
||||||
public void applicationsAdapter_filterSearch_shouldShowMatchedItemsOnly() {
|
public void applicationsAdapter_filterSearch_shouldShowMatchedItemsOnly() {
|
||||||
final ManageApplications.ApplicationsAdapter adapter =
|
final ManageApplications.ApplicationsAdapter adapter =
|
||||||
new ManageApplications.ApplicationsAdapter(
|
new ManageApplications.ApplicationsAdapter(
|
||||||
mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
|
mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
|
||||||
final String[] appNames = {"Apricot", "Banana", "Cantaloupe", "Fig", "Mango"};
|
final String[] appNames = {"Apricot", "Banana", "Cantaloupe", "Fig", "Mango"};
|
||||||
ReflectionHelpers.setField(adapter, "mOriginalEntries", getTestAppList(appNames));
|
ReflectionHelpers.setField(adapter, "mOriginalEntries", getTestAppList(appNames));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user