Merge "Implementing support for item diffing instead of creating out the complete UI on every update" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4bd36a37a7
@@ -23,7 +23,6 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||
@@ -197,13 +196,6 @@ public abstract class BaseRecyclerView extends RecyclerView {
|
||||
if (mScrollbar != null) {
|
||||
mScrollbar.reattachThumbToScroll();
|
||||
}
|
||||
if (getLayoutManager() instanceof LinearLayoutManager) {
|
||||
LinearLayoutManager layoutManager = (LinearLayoutManager) getLayoutManager();
|
||||
if (layoutManager.findFirstCompletelyVisibleItemPosition() == 0) {
|
||||
// We are at the top, so don't scrollToPosition (would cause unnecessary relayout).
|
||||
return;
|
||||
}
|
||||
}
|
||||
scrollToPosition(0);
|
||||
}
|
||||
}
|
||||
@@ -29,11 +29,13 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
|
||||
import com.android.launcher3.allapps.search.SearchAdapterProvider;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
import com.android.launcher3.views.AppLauncher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -95,11 +97,15 @@ public class ActivityAllAppsContainerView<T extends Context & AppLauncher
|
||||
mHeader.reset(false);
|
||||
}
|
||||
|
||||
/** Invoke when the search results change. */
|
||||
public void onSearchResultsChanged() {
|
||||
for (int i = 0; i < mAH.size(); i++) {
|
||||
if (mAH.get(i).mRecyclerView != null) {
|
||||
mAH.get(i).mRecyclerView.onSearchResultsChanged();
|
||||
/**
|
||||
* Sets results list for search
|
||||
*/
|
||||
public void setSearchResults(ArrayList<AdapterItem> results) {
|
||||
if (getApps().setSearchResults(results)) {
|
||||
for (int i = 0; i < mAH.size(); i++) {
|
||||
if (mAH.get(i).mRecyclerView != null) {
|
||||
mAH.get(i).mRecyclerView.onSearchResultsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,10 +37,10 @@ public class AllAppsFastScrollHelper {
|
||||
* Smooth scrolls the recycler view to the given section.
|
||||
*/
|
||||
public void smoothScrollToSection(FastScrollSectionInfo info) {
|
||||
if (mTargetFastScrollPosition == info.fastScrollToItem.position) {
|
||||
if (mTargetFastScrollPosition == info.position) {
|
||||
return;
|
||||
}
|
||||
mTargetFastScrollPosition = info.fastScrollToItem.position;
|
||||
mTargetFastScrollPosition = info.position;
|
||||
mRv.getLayoutManager().startSmoothScroll(new MyScroller(mTargetFastScrollPosition));
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,26 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
|
||||
public void onChanged() {
|
||||
mCachedScrollPositions.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeChanged(int positionStart, int itemCount) {
|
||||
onChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeInserted(int positionStart, int itemCount) {
|
||||
onChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeRemoved(int positionStart, int itemCount) {
|
||||
onChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
|
||||
onChanged();
|
||||
}
|
||||
};
|
||||
|
||||
// The empty-search result background
|
||||
@@ -241,17 +261,14 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
|
||||
// Find the fastscroll section that maps to this touch fraction
|
||||
List<AlphabeticalAppsList.FastScrollSectionInfo> fastScrollSections =
|
||||
mApps.getFastScrollerSections();
|
||||
AlphabeticalAppsList.FastScrollSectionInfo lastInfo = fastScrollSections.get(0);
|
||||
for (int i = 1; i < fastScrollSections.size(); i++) {
|
||||
AlphabeticalAppsList.FastScrollSectionInfo info = fastScrollSections.get(i);
|
||||
if (info.touchFraction > touchFraction) {
|
||||
break;
|
||||
}
|
||||
lastInfo = info;
|
||||
int count = fastScrollSections.size();
|
||||
if (count == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
mFastScrollHelper.smoothScrollToSection(lastInfo);
|
||||
return lastInfo.sectionName;
|
||||
int index = Utilities.boundToRange((int) (touchFraction * count), 0, count - 1);
|
||||
AlphabeticalAppsList.FastScrollSectionInfo section = fastScrollSections.get(index);
|
||||
mFastScrollHelper.smoothScrollToSection(section);
|
||||
return section.sectionName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,9 +15,14 @@
|
||||
*/
|
||||
package com.android.launcher3.allapps;
|
||||
|
||||
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_ALL_APPS_DIVIDER;
|
||||
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_EMPTY_SEARCH;
|
||||
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_SEARCH_MARKET;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
|
||||
import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
@@ -52,14 +57,13 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
|
||||
*/
|
||||
public static class FastScrollSectionInfo {
|
||||
// The section name
|
||||
public String sectionName;
|
||||
// The AdapterItem to scroll to for this section
|
||||
public AdapterItem fastScrollToItem;
|
||||
// The touch fraction that should map to this fast scroll section info
|
||||
public float touchFraction;
|
||||
public final String sectionName;
|
||||
// The item position
|
||||
public final int position;
|
||||
|
||||
public FastScrollSectionInfo(String sectionName) {
|
||||
public FastScrollSectionInfo(String sectionName, int position) {
|
||||
this.sectionName = sectionName;
|
||||
this.position = position;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,13 +111,6 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
|
||||
mAdapter = adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the apps.
|
||||
*/
|
||||
public List<AppInfo> getApps() {
|
||||
return mApps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns fast scroller sections of all the current filtered applications.
|
||||
*/
|
||||
@@ -235,77 +232,49 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
|
||||
* mCachedSectionNames to have been calculated for the set of all apps in mApps.
|
||||
*/
|
||||
public void updateAdapterItems() {
|
||||
refillAdapterItems();
|
||||
refreshRecyclerView();
|
||||
}
|
||||
|
||||
private void refreshRecyclerView() {
|
||||
if (mAdapter != null) {
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void refillAdapterItems() {
|
||||
String lastSectionName = null;
|
||||
FastScrollSectionInfo lastFastScrollerSectionInfo = null;
|
||||
int position = 0;
|
||||
|
||||
List<AdapterItem> oldItems = new ArrayList<>(mAdapterItems);
|
||||
// Prepare to update the list of sections, filtered apps, etc.
|
||||
mAccessibilityResultsCount = 0;
|
||||
mFastScrollerSections.clear();
|
||||
mAdapterItems.clear();
|
||||
mAccessibilityResultsCount = 0;
|
||||
|
||||
// Recreate the filtered and sectioned apps (for convenience for the grid layout) from the
|
||||
// ordered set of sections
|
||||
|
||||
if (!hasFilter()) {
|
||||
mAccessibilityResultsCount = mApps.size();
|
||||
int position = 0;
|
||||
if (mWorkAdapterProvider != null) {
|
||||
position += mWorkAdapterProvider.addWorkItems(mAdapterItems);
|
||||
if (!mWorkAdapterProvider.shouldShowWorkApps()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
String lastSectionName = null;
|
||||
for (AppInfo info : mApps) {
|
||||
String sectionName = info.sectionName;
|
||||
mAdapterItems.add(AdapterItem.asApp(info));
|
||||
|
||||
String sectionName = info.sectionName;
|
||||
// Create a new section if the section names do not match
|
||||
if (!sectionName.equals(lastSectionName)) {
|
||||
lastSectionName = sectionName;
|
||||
lastFastScrollerSectionInfo = new FastScrollSectionInfo(sectionName);
|
||||
mFastScrollerSections.add(lastFastScrollerSectionInfo);
|
||||
mFastScrollerSections.add(new FastScrollSectionInfo(sectionName, position));
|
||||
}
|
||||
|
||||
// Create an app item
|
||||
AdapterItem appItem = AdapterItem.asApp(position++, info);
|
||||
if (lastFastScrollerSectionInfo.fastScrollToItem == null) {
|
||||
lastFastScrollerSectionInfo.fastScrollToItem = appItem;
|
||||
}
|
||||
|
||||
mAdapterItems.add(appItem);
|
||||
position++;
|
||||
}
|
||||
} else {
|
||||
int count = mSearchResults.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
AdapterItem adapterItem = mSearchResults.get(i);
|
||||
adapterItem.position = i;
|
||||
mAdapterItems.add(adapterItem);
|
||||
|
||||
if (adapterItem.isCountedForAccessibility()) {
|
||||
mAccessibilityResultsCount++;
|
||||
}
|
||||
}
|
||||
mAdapterItems.addAll(mSearchResults);
|
||||
if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
|
||||
// Append the search market item
|
||||
if (hasNoFilteredResults()) {
|
||||
mAdapterItems.add(AdapterItem.asEmptySearch(position++));
|
||||
mAdapterItems.add(new AdapterItem(VIEW_TYPE_EMPTY_SEARCH));
|
||||
} else {
|
||||
mAdapterItems.add(AdapterItem.asAllAppsDivider(position++));
|
||||
mAdapterItems.add(new AdapterItem(VIEW_TYPE_ALL_APPS_DIVIDER));
|
||||
}
|
||||
mAdapterItems.add(AdapterItem.asMarketSearch(position++));
|
||||
|
||||
mAdapterItems.add(new AdapterItem(VIEW_TYPE_SEARCH_MARKET));
|
||||
}
|
||||
}
|
||||
mAccessibilityResultsCount = (int) mAdapterItems.stream()
|
||||
.filter(AdapterItem::isCountedForAccessibility).count();
|
||||
|
||||
if (mNumAppsPerRowAllApps != 0) {
|
||||
// Update the number of rows in the adapter after we do all the merging (otherwise, we
|
||||
// would have to shift the values again)
|
||||
@@ -328,19 +297,43 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
|
||||
}
|
||||
}
|
||||
mNumAppRowsInAdapter = rowIndex + 1;
|
||||
}
|
||||
|
||||
// Pre-calculate all the fast scroller fractions
|
||||
float perSectionTouchFraction = 1f / mFastScrollerSections.size();
|
||||
float cumulativeTouchFraction = 0f;
|
||||
for (FastScrollSectionInfo info : mFastScrollerSections) {
|
||||
AdapterItem item = info.fastScrollToItem;
|
||||
if (!BaseAllAppsAdapter.isIconViewType(item.viewType)) {
|
||||
info.touchFraction = 0f;
|
||||
continue;
|
||||
}
|
||||
info.touchFraction = cumulativeTouchFraction;
|
||||
cumulativeTouchFraction += perSectionTouchFraction;
|
||||
}
|
||||
if (mAdapter != null) {
|
||||
DiffUtil.calculateDiff(new MyDiffCallback(oldItems, mAdapterItems), false)
|
||||
.dispatchUpdatesTo(mAdapter);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyDiffCallback extends DiffUtil.Callback {
|
||||
|
||||
private final List<AdapterItem> mOldList;
|
||||
private final List<AdapterItem> mNewList;
|
||||
|
||||
MyDiffCallback(List<AdapterItem> oldList, List<AdapterItem> newList) {
|
||||
mOldList = oldList;
|
||||
mNewList = newList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOldListSize() {
|
||||
return mOldList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNewListSize() {
|
||||
return mNewList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
|
||||
return mOldList.get(oldItemPosition).isSameAs(mNewList.get(newItemPosition));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
|
||||
return mOldList.get(oldItemPosition).isContentSame(mNewList.get(newItemPosition));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -88,10 +88,8 @@ public abstract class BaseAllAppsAdapter<T extends Context & ActivityContext> ex
|
||||
*/
|
||||
public static class AdapterItem {
|
||||
/** Common properties */
|
||||
// The index of this adapter item in the list
|
||||
public int position;
|
||||
// The type of this item
|
||||
public int viewType;
|
||||
public final int viewType;
|
||||
|
||||
// The row that this item shows up on
|
||||
public int rowIndex;
|
||||
@@ -100,50 +98,37 @@ public abstract class BaseAllAppsAdapter<T extends Context & ActivityContext> ex
|
||||
// The associated ItemInfoWithIcon for the item
|
||||
public AppInfo itemInfo = null;
|
||||
|
||||
public AdapterItem(int viewType) {
|
||||
this.viewType = viewType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for AppIcon AdapterItem
|
||||
*/
|
||||
public static AdapterItem asApp(int pos, AppInfo appInfo) {
|
||||
AdapterItem item = new AdapterItem();
|
||||
item.viewType = VIEW_TYPE_ICON;
|
||||
item.position = pos;
|
||||
public static AdapterItem asApp(AppInfo appInfo) {
|
||||
AdapterItem item = new AdapterItem(VIEW_TYPE_ICON);
|
||||
item.itemInfo = appInfo;
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for empty search results view
|
||||
*/
|
||||
public static AdapterItem asEmptySearch(int pos) {
|
||||
AdapterItem item = new AdapterItem();
|
||||
item.viewType = VIEW_TYPE_EMPTY_SEARCH;
|
||||
item.position = pos;
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for a dividerView in AllAppsSearch
|
||||
*/
|
||||
public static AdapterItem asAllAppsDivider(int pos) {
|
||||
AdapterItem item = new AdapterItem();
|
||||
item.viewType = VIEW_TYPE_ALL_APPS_DIVIDER;
|
||||
item.position = pos;
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for a market search button
|
||||
*/
|
||||
public static AdapterItem asMarketSearch(int pos) {
|
||||
AdapterItem item = new AdapterItem();
|
||||
item.viewType = VIEW_TYPE_SEARCH_MARKET;
|
||||
item.position = pos;
|
||||
return item;
|
||||
}
|
||||
|
||||
protected boolean isCountedForAccessibility() {
|
||||
return viewType == VIEW_TYPE_ICON || viewType == VIEW_TYPE_SEARCH_MARKET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the items represent the same object
|
||||
*/
|
||||
public boolean isSameAs(AdapterItem other) {
|
||||
return (other.viewType != viewType) && (other.getClass() == getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called only if {@link #isSameAs} returns true to check if the contents are same
|
||||
* as well. Returning true will prevent redrawing of thee item.
|
||||
*/
|
||||
public boolean isContentSame(AdapterItem other) {
|
||||
return itemInfo == null && other.itemInfo == null;
|
||||
}
|
||||
}
|
||||
|
||||
protected final T mActivityContext;
|
||||
|
||||
@@ -19,10 +19,10 @@ import android.content.SharedPreferences;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
|
||||
import com.android.launcher3.model.StringCache;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
|
||||
@@ -107,13 +107,9 @@ public class WorkAdapterProvider extends BaseAdapterProvider {
|
||||
public int addWorkItems(ArrayList<AllAppsGridAdapter.AdapterItem> adapterItems) {
|
||||
if (mState == WorkProfileManager.STATE_DISABLED) {
|
||||
//add disabled card here.
|
||||
AllAppsGridAdapter.AdapterItem disabledCard = new AllAppsGridAdapter.AdapterItem();
|
||||
disabledCard.viewType = VIEW_TYPE_WORK_DISABLED_CARD;
|
||||
adapterItems.add(disabledCard);
|
||||
adapterItems.add(new AdapterItem(VIEW_TYPE_WORK_DISABLED_CARD));
|
||||
} else if (mState == WorkProfileManager.STATE_ENABLED && !isEduSeen()) {
|
||||
AllAppsGridAdapter.AdapterItem eduCard = new AllAppsGridAdapter.AdapterItem();
|
||||
eduCard.viewType = VIEW_TYPE_WORK_EDU_CARD;
|
||||
adapterItems.add(eduCard);
|
||||
adapterItems.add(new AdapterItem(VIEW_TYPE_WORK_EDU_CARD));
|
||||
}
|
||||
|
||||
return adapterItems.size();
|
||||
|
||||
@@ -38,7 +38,6 @@ import com.android.launcher3.Insettable;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
|
||||
import com.android.launcher3.allapps.AllAppsStore;
|
||||
import com.android.launcher3.allapps.AlphabeticalAppsList;
|
||||
import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
|
||||
import com.android.launcher3.allapps.SearchUiManager;
|
||||
import com.android.launcher3.search.SearchCallback;
|
||||
@@ -57,7 +56,6 @@ public class AppsSearchContainerLayout extends ExtendedEditText
|
||||
private final AllAppsSearchBarController mSearchBarController;
|
||||
private final SpannableStringBuilder mSearchQueryBuilder;
|
||||
|
||||
private AlphabeticalAppsList<?> mApps;
|
||||
private ActivityAllAppsContainerView<?> mAppsView;
|
||||
|
||||
// The amount of pixels to shift down and overlap with the rest of the content.
|
||||
@@ -131,7 +129,6 @@ public class AppsSearchContainerLayout extends ExtendedEditText
|
||||
|
||||
@Override
|
||||
public void initializeSearch(ActivityAllAppsContainerView<?> appsView) {
|
||||
mApps = appsView.getApps();
|
||||
mAppsView = appsView;
|
||||
mSearchBarController.initialize(
|
||||
new DefaultAppSearchAlgorithm(getContext()),
|
||||
@@ -170,17 +167,14 @@ public class AppsSearchContainerLayout extends ExtendedEditText
|
||||
@Override
|
||||
public void onSearchResult(String query, ArrayList<AdapterItem> items) {
|
||||
if (items != null) {
|
||||
mApps.setSearchResults(items);
|
||||
notifyResultChanged();
|
||||
mAppsView.setSearchResults(items);
|
||||
mAppsView.setLastSearchQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearSearchResult() {
|
||||
if (mApps.setSearchResults(null)) {
|
||||
notifyResultChanged();
|
||||
}
|
||||
mAppsView.setSearchResults(null);
|
||||
|
||||
// Clear the search query
|
||||
mSearchQueryBuilder.clear();
|
||||
@@ -189,10 +183,6 @@ public class AppsSearchContainerLayout extends ExtendedEditText
|
||||
mAppsView.onClearSearchResult();
|
||||
}
|
||||
|
||||
private void notifyResultChanged() {
|
||||
mAppsView.onSearchResultsChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInsets(Rect insets) {
|
||||
MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
|
||||
|
||||
@@ -85,8 +85,7 @@ public class DefaultAppSearchAlgorithm implements SearchAlgorithm<AdapterItem> {
|
||||
for (int i = 0; i < total && resultCount < MAX_RESULTS_COUNT; i++) {
|
||||
AppInfo info = apps.get(i);
|
||||
if (StringMatcherUtility.matches(queryTextLower, info.title.toString(), matcher)) {
|
||||
AdapterItem appItem = AdapterItem.asApp(resultCount, info);
|
||||
result.add(appItem);
|
||||
result.add(AdapterItem.asApp(info));
|
||||
resultCount++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,21 +239,6 @@ public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouch
|
||||
mHeaderViewDimensionsProvider = headerViewDimensionsProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scrollToTop() {
|
||||
if (mScrollbar != null) {
|
||||
mScrollbar.reattachThumbToScroll();
|
||||
}
|
||||
|
||||
if (getLayoutManager() instanceof LinearLayoutManager) {
|
||||
if (getCurrentScrollY() == 0) {
|
||||
// We are at the top, so don't scrollToPosition (would cause unnecessary relayout).
|
||||
return;
|
||||
}
|
||||
}
|
||||
scrollToPosition(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of the height, in pixels, of this list adapter's items from index 0 until
|
||||
* {@code untilIndex}.
|
||||
|
||||
@@ -25,11 +25,14 @@ import static org.junit.Assert.assertTrue;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
|
||||
import com.android.launcher3.allapps.AllAppsPagedView;
|
||||
import com.android.launcher3.allapps.WorkAdapterProvider;
|
||||
import com.android.launcher3.allapps.WorkEduCard;
|
||||
import com.android.launcher3.allapps.WorkPausedCard;
|
||||
import com.android.launcher3.allapps.WorkProfileManager;
|
||||
import com.android.launcher3.tapl.LauncherInstrumentation;
|
||||
|
||||
@@ -38,6 +41,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class WorkProfileTest extends AbstractLauncherUiTest {
|
||||
|
||||
@@ -130,6 +134,8 @@ public class WorkProfileTest extends AbstractLauncherUiTest {
|
||||
return manager.getCurrentState() == WorkProfileManager.STATE_DISABLED;
|
||||
}, LauncherInstrumentation.WAIT_TIME_MS);
|
||||
|
||||
waitForWorkCard("Work paused card not shown", view -> view instanceof WorkPausedCard);
|
||||
|
||||
// start work profile toggle ON test
|
||||
executeOnLauncher(l -> {
|
||||
ActivityAllAppsContainerView<?> allApps = l.getAppsView();
|
||||
@@ -154,9 +160,19 @@ public class WorkProfileTest extends AbstractLauncherUiTest {
|
||||
l.getAppsView().getWorkManager().reset();
|
||||
});
|
||||
|
||||
waitForLauncherCondition("Work profile education not shown",
|
||||
l -> l.getAppsView().getActiveRecyclerView()
|
||||
.findViewHolderForAdapterPosition(0).itemView instanceof WorkEduCard,
|
||||
LauncherInstrumentation.WAIT_TIME_MS);
|
||||
waitForWorkCard("Work profile education not shown", view -> view instanceof WorkEduCard);
|
||||
}
|
||||
|
||||
private void waitForWorkCard(String message, Predicate<View> workCardCheck) {
|
||||
waitForLauncherCondition(message, l -> {
|
||||
l.getAppsView().getAppsStore().disableDeferUpdates(DEFER_UPDATES_TEST);
|
||||
ViewHolder holder = l.getAppsView().getActiveRecyclerView()
|
||||
.findViewHolderForAdapterPosition(0);
|
||||
try {
|
||||
return holder != null && workCardCheck.test(holder.itemView);
|
||||
} finally {
|
||||
l.getAppsView().getAppsStore().enableDeferUpdates(DEFER_UPDATES_TEST);
|
||||
}
|
||||
}, LauncherInstrumentation.WAIT_TIME_MS);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user