Add search to app info list.
- add a search option menu to the manage applications page. - add a search filter to the app list adapter to remove any app whose app name does not contain the search query. Change-Id: Ie749daeef2cdc4a22fade45422ae90f44d00ceb2 Fixes: 119598311 Test: make RunSettingsRoboTests
This commit is contained in:
27
res/drawable/ic_find_in_page_24px.xml
Normal file
27
res/drawable/ic_find_in_page_24px.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2018 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?android:attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M6,2C4.9,2 4.01,2.9 4.01,4L4,20c0,1.1 0.89,2 1.99,2H18c1.1,0 2,-0.9 2,-2V8l-6,-6H6zM18,17.59l-2.2,-2.2c0.44,-0.69 0.7,-1.51 0.7,-2.39c0,-2.48 -2.02,-4.5 -4.5,-4.5S7.5,10.52 7.5,13s2.02,4.5 4.5,4.5c0.88,0 1.69,-0.26 2.39,-0.7l3.2,3.2L6,20V4h7.17L18,8.83V17.59zM12,15.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5S13.38,15.5 12,15.5z"/>
|
||||||
|
</vector>
|
@@ -15,6 +15,13 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:id="@+id/search_app_list_menu"
|
||||||
|
android:title="@string/search_settings"
|
||||||
|
android:icon="@drawable/ic_find_in_page_24px"
|
||||||
|
android:showAsAction="always|collapseActionView"
|
||||||
|
android:actionViewClass="android.widget.SearchView" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/advanced"
|
android:id="@+id/advanced"
|
||||||
android:title="@string/advanced_apps"
|
android:title="@string/advanced_apps"
|
||||||
|
@@ -67,11 +67,14 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.AdapterView.OnItemSelectedListener;
|
import android.widget.AdapterView.OnItemSelectedListener;
|
||||||
|
import android.widget.Filter;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.SearchView;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
import androidx.annotation.WorkerThread;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
@@ -140,7 +143,7 @@ import java.util.Set;
|
|||||||
* intent.
|
* intent.
|
||||||
*/
|
*/
|
||||||
public class ManageApplications extends InstrumentedFragment
|
public class ManageApplications extends InstrumentedFragment
|
||||||
implements View.OnClickListener, OnItemSelectedListener {
|
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 = true;
|
||||||
@@ -196,6 +199,7 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
|
|
||||||
private View mListContainer;
|
private View mListContainer;
|
||||||
private RecyclerView mRecyclerView;
|
private RecyclerView mRecyclerView;
|
||||||
|
private SearchView mSearchView;
|
||||||
|
|
||||||
// Size resource used for packages whose size computation failed for some reason
|
// Size resource used for packages whose size computation failed for some reason
|
||||||
CharSequence mInvalidSizeStr;
|
CharSequence mInvalidSizeStr;
|
||||||
@@ -599,6 +603,13 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
mOptionsMenu = menu;
|
mOptionsMenu = menu;
|
||||||
inflater.inflate(R.menu.manage_apps, menu);
|
inflater.inflate(R.menu.manage_apps, menu);
|
||||||
|
|
||||||
|
final MenuItem searchMenuItem = menu.findItem(R.id.search_app_list_menu);
|
||||||
|
if (searchMenuItem != null) {
|
||||||
|
mSearchView = (SearchView) searchMenuItem.getActionView();
|
||||||
|
mSearchView.setQueryHint(getText(R.string.search_settings));
|
||||||
|
mSearchView.setOnQueryTextListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
updateOptionsMenu();
|
updateOptionsMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -724,6 +735,17 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
public void onNothingSelected(AdapterView<?> parent) {
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onQueryTextSubmit(String query) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onQueryTextChange(String newText) {
|
||||||
|
mApplications.filterSearch(newText);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void updateView() {
|
public void updateView() {
|
||||||
updateOptionsMenu();
|
updateOptionsMenu();
|
||||||
final Activity host = getActivity();
|
final Activity host = getActivity();
|
||||||
@@ -859,6 +881,7 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
|
|
||||||
private AppFilterItem mAppFilter;
|
private AppFilterItem mAppFilter;
|
||||||
private ArrayList<ApplicationsState.AppEntry> mEntries;
|
private ArrayList<ApplicationsState.AppEntry> mEntries;
|
||||||
|
private ArrayList<ApplicationsState.AppEntry> mOriginalEntries;
|
||||||
private boolean mResumed;
|
private boolean mResumed;
|
||||||
private int mLastSortMode = -1;
|
private int mLastSortMode = -1;
|
||||||
private int mWhichSize = SIZE_TOTAL;
|
private int mWhichSize = SIZE_TOTAL;
|
||||||
@@ -866,6 +889,7 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
private boolean mHasReceivedLoadEntries;
|
private boolean mHasReceivedLoadEntries;
|
||||||
private boolean mHasReceivedBridgeCallback;
|
private boolean mHasReceivedBridgeCallback;
|
||||||
private FileViewHolderController mExtraViewController;
|
private FileViewHolderController mExtraViewController;
|
||||||
|
private SearchFilter mSearchFilter;
|
||||||
|
|
||||||
// This is to remember and restore the last scroll position when this
|
// This is to remember and restore the last scroll position when this
|
||||||
// fragment is paused. We need this special handling because app entries are added gradually
|
// fragment is paused. We need this special handling because app entries are added gradually
|
||||||
@@ -1100,6 +1124,13 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void filterSearch(String query) {
|
||||||
|
if (mSearchFilter == null) {
|
||||||
|
mSearchFilter = new SearchFilter();
|
||||||
|
}
|
||||||
|
mSearchFilter.filter(query);
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static boolean shouldUseStableItemHeight(int listType) {
|
static boolean shouldUseStableItemHeight(int listType) {
|
||||||
return true;
|
return true;
|
||||||
@@ -1146,6 +1177,7 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
entries = removeDuplicateIgnoringUser(entries);
|
entries = removeDuplicateIgnoringUser(entries);
|
||||||
}
|
}
|
||||||
mEntries = entries;
|
mEntries = entries;
|
||||||
|
mOriginalEntries = entries;
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
if (getItemCount() == 0) {
|
if (getItemCount() == 0) {
|
||||||
mManageApplications.mRecyclerView.setVisibility(View.GONE);
|
mManageApplications.mRecyclerView.setVisibility(View.GONE);
|
||||||
@@ -1153,6 +1185,14 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
} else {
|
} else {
|
||||||
mManageApplications.mEmptyView.setVisibility(View.GONE);
|
mManageApplications.mEmptyView.setVisibility(View.GONE);
|
||||||
mManageApplications.mRecyclerView.setVisibility(View.VISIBLE);
|
mManageApplications.mRecyclerView.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
if (mManageApplications.mSearchView != null
|
||||||
|
&& mManageApplications.mSearchView.isVisibleToUser()) {
|
||||||
|
final CharSequence query = mManageApplications.mSearchView.getQuery();
|
||||||
|
if (!TextUtils.isEmpty(query)) {
|
||||||
|
filterSearch(query.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Restore the last scroll position if the number of entries added so far is bigger than
|
// Restore the last scroll position if the number of entries added so far is bigger than
|
||||||
// it.
|
// it.
|
||||||
@@ -1405,6 +1445,38 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array filter that constrains the content of the array adapter with a substring.
|
||||||
|
* Item that does not contains the specified substring will be removed from the list.</p>
|
||||||
|
*/
|
||||||
|
private class SearchFilter extends Filter {
|
||||||
|
@WorkerThread
|
||||||
|
@Override
|
||||||
|
protected FilterResults performFiltering(CharSequence query) {
|
||||||
|
final ArrayList<ApplicationsState.AppEntry> matchedEntries;
|
||||||
|
if (TextUtils.isEmpty(query)) {
|
||||||
|
matchedEntries = mOriginalEntries;
|
||||||
|
} else {
|
||||||
|
matchedEntries = new ArrayList<>();
|
||||||
|
for (ApplicationsState.AppEntry entry : mOriginalEntries) {
|
||||||
|
if (entry.label.toLowerCase().contains(query.toString().toLowerCase())) {
|
||||||
|
matchedEntries.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final FilterResults results = new FilterResults();
|
||||||
|
results.values = matchedEntries;
|
||||||
|
results.count = matchedEntries.size();
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||||
|
mEntries = (ArrayList<ApplicationsState.AppEntry>) results.values;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SummaryProvider implements SummaryLoader.SummaryProvider {
|
private static class SummaryProvider implements SummaryLoader.SummaryProvider {
|
||||||
|
@@ -28,11 +28,12 @@ import static com.android.settings.applications.manageapplications.ManageApplica
|
|||||||
|
|
||||||
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.Matchers.anyBoolean;
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Matchers.anyInt;
|
import static org.mockito.Matchers.anyInt;
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
@@ -48,9 +49,11 @@ import android.os.Looper;
|
|||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.SearchView;
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
@@ -158,6 +161,35 @@ public class ManageApplicationsTest {
|
|||||||
verify(loadingContainer, never()).setVisibility(View.VISIBLE);
|
verify(loadingContainer, never()).setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onCreateOptionsMenu_shouldSetSearchQueryListener() {
|
||||||
|
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.onCreateOptionsMenu(mMenu, mock(MenuInflater.class));
|
||||||
|
|
||||||
|
verify(searchView).setOnQueryTextListener(mFragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onQueryTextChange_shouldFilterSearchInApplicationsAdapter() {
|
||||||
|
final ManageApplications.ApplicationsAdapter adapter =
|
||||||
|
mock(ManageApplications.ApplicationsAdapter.class);
|
||||||
|
final String query = "Test App";
|
||||||
|
ReflectionHelpers.setField(mFragment, "mApplications", adapter);
|
||||||
|
|
||||||
|
mFragment.onQueryTextChange(query);
|
||||||
|
|
||||||
|
verify(adapter).filterSearch(query);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void updateLoading_appLoaded_shouldNotDelayCallToHandleLoadingContainer() {
|
public void updateLoading_appLoaded_shouldNotDelayCallToHandleLoadingContainer() {
|
||||||
ReflectionHelpers.setField(mFragment, "mLoadingContainer", mock(View.class));
|
ReflectionHelpers.setField(mFragment, "mLoadingContainer", mock(View.class));
|
||||||
@@ -249,6 +281,34 @@ public class ManageApplicationsTest {
|
|||||||
verify(loadingViewController).showContent(true /* animate */);
|
verify(loadingViewController).showContent(true /* animate */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onRebuildComplete_hasSearchQuery_shouldFilterSearch() {
|
||||||
|
final String query = "Test";
|
||||||
|
final RecyclerView recyclerView = mock(RecyclerView.class);
|
||||||
|
final View emptyView = mock(View.class);
|
||||||
|
ReflectionHelpers.setField(mFragment, "mRecyclerView", recyclerView);
|
||||||
|
ReflectionHelpers.setField(mFragment, "mEmptyView", emptyView);
|
||||||
|
final SearchView searchView = mock(SearchView.class);
|
||||||
|
ReflectionHelpers.setField(mFragment, "mSearchView", searchView);
|
||||||
|
when(searchView.isVisibleToUser()).thenReturn(true);
|
||||||
|
when(searchView.getQuery()).thenReturn(query);
|
||||||
|
final View listContainer = mock(View.class);
|
||||||
|
when(listContainer.getVisibility()).thenReturn(View.VISIBLE);
|
||||||
|
ReflectionHelpers.setField(mFragment, "mListContainer", listContainer);
|
||||||
|
ReflectionHelpers.setField(
|
||||||
|
mFragment, "mFilterAdapter", mock(ManageApplications.FilterSpinnerAdapter.class));
|
||||||
|
final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
|
||||||
|
appList.add(mock(ApplicationsState.AppEntry.class));
|
||||||
|
final ManageApplications.ApplicationsAdapter adapter =
|
||||||
|
spy(new ManageApplications.ApplicationsAdapter(mState, mFragment,
|
||||||
|
AppFilterRegistry.getInstance().get(FILTER_APPS_ALL),
|
||||||
|
null /* savedInstanceState */));
|
||||||
|
|
||||||
|
adapter.onRebuildComplete(appList);
|
||||||
|
|
||||||
|
verify(adapter).filterSearch(query);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void notifyItemChange_recyclerViewIdle_shouldNotify() {
|
public void notifyItemChange_recyclerViewIdle_shouldNotify() {
|
||||||
final RecyclerView recyclerView = mock(RecyclerView.class);
|
final RecyclerView recyclerView = mock(RecyclerView.class);
|
||||||
@@ -343,6 +403,48 @@ public class ManageApplicationsTest {
|
|||||||
verify(holder, never()).updateSwitch(any(), anyBoolean(), anyBoolean());
|
verify(holder, never()).updateSwitch(any(), anyBoolean(), anyBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void applicationsAdapter_filterSearch_emptyQuery_shouldShowFullList() {
|
||||||
|
final ManageApplications.ApplicationsAdapter adapter =
|
||||||
|
new ManageApplications.ApplicationsAdapter(
|
||||||
|
mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
|
||||||
|
final String[] appNames = {"Apricot", "Banana", "Cantaloupe", "Fig", "Mango"};
|
||||||
|
ReflectionHelpers.setField(adapter, "mOriginalEntries", getTestAppList(appNames));
|
||||||
|
|
||||||
|
adapter.filterSearch("");
|
||||||
|
|
||||||
|
assertThat(adapter.getItemCount()).isEqualTo(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void applicationsAdapter_filterSearch_noMatch_shouldShowEmptyList() {
|
||||||
|
final ManageApplications.ApplicationsAdapter adapter =
|
||||||
|
new ManageApplications.ApplicationsAdapter(
|
||||||
|
mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
|
||||||
|
final String[] appNames = {"Apricot", "Banana", "Cantaloupe", "Fig", "Mango"};
|
||||||
|
ReflectionHelpers.setField(adapter, "mOriginalEntries", getTestAppList(appNames));
|
||||||
|
|
||||||
|
adapter.filterSearch("orange");
|
||||||
|
|
||||||
|
assertThat(adapter.getItemCount()).isEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void applicationsAdapter_filterSearch_shouldShowMatchedItemsOnly() {
|
||||||
|
final ManageApplications.ApplicationsAdapter adapter =
|
||||||
|
new ManageApplications.ApplicationsAdapter(
|
||||||
|
mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
|
||||||
|
final String[] appNames = {"Apricot", "Banana", "Cantaloupe", "Fig", "Mango"};
|
||||||
|
ReflectionHelpers.setField(adapter, "mOriginalEntries", getTestAppList(appNames));
|
||||||
|
|
||||||
|
adapter.filterSearch("an");
|
||||||
|
|
||||||
|
assertThat(adapter.getItemCount()).isEqualTo(3);
|
||||||
|
assertThat(adapter.getAppEntry(0).label).isEqualTo("Banana");
|
||||||
|
assertThat(adapter.getAppEntry(1).label).isEqualTo("Cantaloupe");
|
||||||
|
assertThat(adapter.getAppEntry(2).label).isEqualTo("Mango");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void sortOrderSavedOnRebuild() {
|
public void sortOrderSavedOnRebuild() {
|
||||||
when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
|
when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
|
||||||
@@ -375,4 +477,14 @@ public class ManageApplicationsTest {
|
|||||||
return new RoboMenuItem(id);
|
return new RoboMenuItem(id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ArrayList<ApplicationsState.AppEntry> getTestAppList(String[] appNames) {
|
||||||
|
final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
|
||||||
|
for (String name : appNames) {
|
||||||
|
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
||||||
|
appEntry.label = name;
|
||||||
|
appList.add(appEntry);
|
||||||
|
}
|
||||||
|
return appList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user