diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java index 330e496c56..26d8f303e8 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java @@ -23,7 +23,6 @@ import android.content.Context; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.R; -import com.android.launcher3.allapps.AllAppsContainerView; import com.android.launcher3.util.Themes; /** @@ -44,8 +43,7 @@ public class AllAppsState extends LauncherState { @Override public String getDescription(Launcher launcher) { - AllAppsContainerView appsView = launcher.getAppsView(); - return appsView.getDescription(); + return launcher.getAppsView().getDescription(); } @Override diff --git a/res/layout/secondary_launcher.xml b/res/layout/secondary_launcher.xml index b15a320bba..3ccd4f25e2 100644 --- a/res/layout/secondary_launcher.xml +++ b/res/layout/secondary_launcher.xml @@ -41,7 +41,8 @@ android:contentDescription="@string/all_apps_button_label" android:onClick="onAppsButtonClicked" /> - - + \ No newline at end of file diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java index 80c2d9e48b..b47554f744 100644 --- a/src/com/android/launcher3/BaseDraggingActivity.java +++ b/src/com/android/launcher3/BaseDraggingActivity.java @@ -49,7 +49,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.LauncherSettings.Favorites; -import com.android.launcher3.allapps.AllAppsContainerView; +import com.android.launcher3.allapps.ActivityAllAppsContainerView; import com.android.launcher3.allapps.search.DefaultSearchAdapterProvider; import com.android.launcher3.allapps.search.SearchAdapterProvider; import com.android.launcher3.logging.InstanceId; @@ -340,7 +340,8 @@ public abstract class BaseDraggingActivity extends BaseActivity * Creates and returns {@link SearchAdapterProvider} for build variant specific search result * views */ - public SearchAdapterProvider createSearchAdapterProvider(AllAppsContainerView allapps) { - return new DefaultSearchAdapterProvider(this, allapps); + public SearchAdapterProvider createSearchAdapterProvider( + ActivityAllAppsContainerView allApps) { + return new DefaultSearchAdapterProvider(this); } } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 8e83c1209f..b90a8758b9 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -122,7 +122,7 @@ import androidx.annotation.VisibleForTesting; import com.android.launcher3.DropTarget.DragObject; import com.android.launcher3.accessibility.BaseAccessibilityDelegate.LauncherAction; import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; -import com.android.launcher3.allapps.AllAppsContainerView; +import com.android.launcher3.allapps.ActivityAllAppsContainerView; import com.android.launcher3.allapps.AllAppsStore; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.allapps.DiscoveryBounce; @@ -315,7 +315,7 @@ public class Launcher extends StatefulActivity implements Launche // Main container view for the all apps screen. @Thunk - AllAppsContainerView mAppsView; + ActivityAllAppsContainerView mAppsView; AllAppsTransitionController mAllAppsController; // Scrim view for the all apps and overview state. @@ -1490,7 +1490,8 @@ public class Launcher extends StatefulActivity implements Launche return mDragLayer; } - public AllAppsContainerView getAppsView() { + @Override + public ActivityAllAppsContainerView getAppsView() { return mAppsView; } diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java new file mode 100644 index 0000000000..070b98ed75 --- /dev/null +++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2022 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.launcher3.allapps; + +import android.content.Context; +import android.content.Intent; +import android.util.AttributeSet; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.View; + +import androidx.core.graphics.ColorUtils; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.R; +import com.android.launcher3.Utilities; +import com.android.launcher3.allapps.search.SearchAdapterProvider; +import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.util.PackageManagerHelper; + +import java.util.Objects; + +/** + * All apps container view with search support for use in a dragging activity. + * + * @param Type of context inflating all apps. + */ +public class ActivityAllAppsContainerView extends + BaseAllAppsContainerView { + + protected SearchUiManager mSearchUiManager; + /** + * View that defines the search box. Result is rendered inside the recycler view defined in the + * base class. + */ + private View mSearchContainer; + /** {@code true} when rendered view is in search state instead of the scroll state. */ + private boolean mIsSearching; + + public ActivityAllAppsContainerView(Context context) { + this(context, null); + } + + public ActivityAllAppsContainerView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public ActivityAllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + mActivityContext.addOnDeviceProfileChangeListener(this); + } + + public SearchUiManager getSearchUiManager() { + return mSearchUiManager; + } + + public View getSearchView() { + return mSearchContainer; + } + + /** Updates all apps container with the latest search query. */ + public void setLastSearchQuery(String query) { + Intent marketSearchIntent = PackageManagerHelper.getMarketSearchIntent( + mActivityContext, query); + OnClickListener marketSearchClickListener = (v) -> mActivityContext.startActivitySafely(v, + marketSearchIntent, null); + for (int i = 0; i < mAH.size(); i++) { + mAH.get(i).adapter.setLastSearchQuery(query, marketSearchClickListener); + } + mIsSearching = true; + rebindAdapters(); + mHeader.setCollapsed(true); + } + + /** Invoke when the current search session is finished. */ + public void onClearSearchResult() { + mIsSearching = false; + mHeader.setCollapsed(false); + rebindAdapters(); + 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(); + } + } + } + + /** Handles selection on focused view and returns {@code true} on success. */ + public boolean launchHighlightedItem() { + return getMainAdapterProvider().launchHighlightedItem(); + } + + @Override + protected SearchAdapterProvider createMainAdapterProvider() { + return mActivityContext.createSearchAdapterProvider(this); + } + + @Override + public boolean shouldContainerScroll(MotionEvent ev) { + // IF the MotionEvent is inside the search box, and the container keeps on receiving + // touch input, container should move down. + if (mActivityContext.getDragLayer().isEventOverView(mSearchContainer, ev)) { + return true; + } + return super.shouldContainerScroll(ev); + } + + @Override + public void reset(boolean animate) { + super.reset(animate); + // Reset the search bar after transitioning home. + mSearchUiManager.resetSearch(); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mSearchContainer = findViewById(R.id.search_container_all_apps); + mSearchUiManager = (SearchUiManager) mSearchContainer; + mSearchUiManager.initializeSearch(this); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + mSearchUiManager.preDispatchKeyEvent(event); + return super.dispatchKeyEvent(event); + } + + @Override + public String getDescription() { + if (!mUsingTabs && mIsSearching) { + return getContext().getString(R.string.all_apps_search_results); + } else { + return super.getDescription(); + } + } + + @Override + protected boolean showTabs() { + return super.showTabs() && !mIsSearching; + } + + @Override + protected void rebindAdapters(boolean force) { + super.rebindAdapters(force); + if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get() + || getMainAdapterProvider().getDecorator() == null) { + return; + } + + RecyclerView.ItemDecoration decoration = getMainAdapterProvider().getDecorator(); + mAH.stream() + .map(adapterHolder -> adapterHolder.mRecyclerView) + .filter(Objects::nonNull) + .forEach(v -> { + v.removeItemDecoration(decoration); // Remove in case it is already added. + v.addItemDecoration(decoration); + }); + } + + @Override + protected void updateHeaderScroll(int scrolledOffset) { + super.updateHeaderScroll(scrolledOffset); + if (mSearchUiManager.getEditText() == null) { + return; + } + + float prog = Utilities.boundToRange((float) scrolledOffset / mHeaderThreshold, 0f, 1f); + boolean bgVisible = mSearchUiManager.getBackgroundVisibility(); + if (scrolledOffset == 0 && !mIsSearching) { + bgVisible = true; + } else if (scrolledOffset > mHeaderThreshold) { + bgVisible = false; + } + mSearchUiManager.setBackgroundVisibility(bgVisible, 1 - prog); + } + + @Override + protected int getHeaderColor(float blendRatio) { + return ColorUtils.setAlphaComponent( + super.getHeaderColor(blendRatio), + (int) (mSearchContainer.getAlpha() * 255)); + } + + @Override + protected int getHeaderBottom() { + return super.getHeaderBottom() + mSearchContainer.getBottom(); + } +} diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java index d5c9a53f12..f1ca9c0c99 100644 --- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java +++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java @@ -18,7 +18,6 @@ package com.android.launcher3.allapps; import static com.android.launcher3.touch.ItemLongClickListener.INSTANCE_ALL_APPS; import android.content.Context; -import android.content.Intent; import android.content.res.Resources; import android.view.Gravity; import android.view.LayoutInflater; @@ -38,21 +37,22 @@ import androidx.core.view.accessibility.AccessibilityRecordCompat; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.BubbleTextView; import com.android.launcher3.R; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.ItemInfoWithIcon; -import com.android.launcher3.util.PackageManagerHelper; +import com.android.launcher3.views.ActivityContext; import java.util.Arrays; import java.util.List; /** * The grid view adapter of all the apps. + * + * @param Type of context inflating all apps. */ -public class AllAppsGridAdapter extends +public class AllAppsGridAdapter extends RecyclerView.Adapter { public static final String TAG = "AppsGridAdapter"; @@ -256,9 +256,9 @@ public class AllAppsGridAdapter extends } } - private final BaseDraggingActivity mLauncher; + private final T mActivityContext; private final LayoutInflater mLayoutInflater; - private final AlphabeticalAppsList mApps; + private final AlphabeticalAppsList mApps; private final GridLayoutManager mGridLayoutMgr; private final GridSpanSizer mGridSizer; @@ -271,27 +271,28 @@ public class AllAppsGridAdapter extends // The text to show when there are no search results and no market search handler. protected String mEmptySearchMessage; - // The intent to send off to the market app, updated each time the search query changes. - private Intent mMarketSearchIntent; + // The click listener to send off to the market app, updated each time the search query changes. + private OnClickListener mMarketSearchClickListener; private final int mExtraHeight; - public AllAppsGridAdapter(BaseDraggingActivity launcher, LayoutInflater inflater, - AlphabeticalAppsList apps, BaseAdapterProvider[] adapterProviders) { - Resources res = launcher.getResources(); - mLauncher = launcher; + public AllAppsGridAdapter(T activityContext, LayoutInflater inflater, + AlphabeticalAppsList apps, BaseAdapterProvider[] adapterProviders) { + Resources res = activityContext.getResources(); + mActivityContext = activityContext; mApps = apps; mEmptySearchMessage = res.getString(R.string.all_apps_loading_message); mGridSizer = new GridSpanSizer(); - mGridLayoutMgr = new AppsGridLayoutManager(launcher); + mGridLayoutMgr = new AppsGridLayoutManager(mActivityContext); mGridLayoutMgr.setSpanSizeLookup(mGridSizer); mLayoutInflater = inflater; - mOnIconClickListener = launcher.getItemOnClickListener(); + mOnIconClickListener = mActivityContext.getItemOnClickListener(); mAdapterProviders = adapterProviders; - setAppsPerRow(mLauncher.getDeviceProfile().numShownAllAppsColumns); - mExtraHeight = launcher.getResources().getDimensionPixelSize(R.dimen.all_apps_height_extra); + setAppsPerRow(mActivityContext.getDeviceProfile().numShownAllAppsColumns); + mExtraHeight = mActivityContext.getResources().getDimensionPixelSize( + R.dimen.all_apps_height_extra); } public void setAppsPerRow(int appsPerRow) { @@ -334,10 +335,10 @@ public class AllAppsGridAdapter extends * Sets the last search query that was made, used to show when there are no results and to also * seed the intent for searching the market. */ - public void setLastSearchQuery(String query) { - Resources res = mLauncher.getResources(); + public void setLastSearchQuery(String query, OnClickListener marketSearchClickListener) { + Resources res = mActivityContext.getResources(); mEmptySearchMessage = res.getString(R.string.all_apps_no_search_results, query); - mMarketSearchIntent = PackageManagerHelper.getMarketSearchIntent(mLauncher, query); + mMarketSearchClickListener = marketSearchClickListener; } /** @@ -360,7 +361,8 @@ public class AllAppsGridAdapter extends icon.setOnClickListener(mOnIconClickListener); icon.setOnLongClickListener(mOnIconLongClickListener); // Ensure the all apps icon height matches the workspace icons in portrait mode. - icon.getLayoutParams().height = mLauncher.getDeviceProfile().allAppsCellHeightPx; + icon.getLayoutParams().height = + mActivityContext.getDeviceProfile().allAppsCellHeightPx; if (FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get()) { icon.getLayoutParams().height += mExtraHeight; } @@ -371,8 +373,7 @@ public class AllAppsGridAdapter extends case VIEW_TYPE_SEARCH_MARKET: View searchMarketView = mLayoutInflater.inflate(R.layout.all_apps_search_market, parent, false); - searchMarketView.setOnClickListener(v -> mLauncher.startActivitySafely( - v, mMarketSearchIntent, null)); + searchMarketView.setOnClickListener(mMarketSearchClickListener); return new ViewHolder(searchMarketView); case VIEW_TYPE_ALL_APPS_DIVIDER: return new ViewHolder(mLayoutInflater.inflate( @@ -407,7 +408,7 @@ public class AllAppsGridAdapter extends break; case VIEW_TYPE_SEARCH_MARKET: TextView searchView = (TextView) holder.itemView; - if (mMarketSearchIntent != null) { + if (mMarketSearchClickListener != null) { searchView.setVisibility(View.VISIBLE); } else { searchView.setVisibility(View.GONE); diff --git a/src/com/android/launcher3/allapps/AllAppsPagedView.java b/src/com/android/launcher3/allapps/AllAppsPagedView.java index 3cc9ce6806..872503ae1c 100644 --- a/src/com/android/launcher3/allapps/AllAppsPagedView.java +++ b/src/com/android/launcher3/allapps/AllAppsPagedView.java @@ -21,13 +21,13 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import android.content.Context; import android.util.AttributeSet; -import com.android.launcher3.Launcher; import com.android.launcher3.PagedView; +import com.android.launcher3.views.ActivityContext; import com.android.launcher3.workprofile.PersonalWorkPagedView; /** - * A {@link PagedView} for showing different views for the personal and work profile respectively - * in the {@link AllAppsContainerView}. + * A {@link PagedView} for showing different views for the personal and work profile respectively + * in the {@link BaseAllAppsContainerView}. */ public class AllAppsPagedView extends PersonalWorkPagedView { @@ -47,7 +47,7 @@ public class AllAppsPagedView extends PersonalWorkPagedView { protected boolean snapToPageWithVelocity(int whichPage, int velocity) { boolean resp = super.snapToPageWithVelocity(whichPage, velocity); if (resp && whichPage != mCurrentPage) { - Launcher.getLauncher(getContext()).getStatsLogManager().logger() + ActivityContext.lookupContext(getContext()).getStatsLogManager().logger() .log(mCurrentPage < whichPage ? LAUNCHER_ALLAPPS_SWIPE_TO_WORK_TAB : LAUNCHER_ALLAPPS_SWIPE_TO_PERSONAL_TAB); diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index bccd9b41a0..c2cb845f0d 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -36,7 +36,6 @@ import android.view.View; import androidx.recyclerview.widget.RecyclerView; -import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.BaseRecyclerView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.LauncherAppState; @@ -58,7 +57,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView { private static final boolean DEBUG = false; private static final boolean DEBUG_LATENCY = Utilities.isPropertyEnabled(SEARCH_LOGGING); - private AlphabeticalAppsList mApps; + private AlphabeticalAppsList mApps; private final int mNumAppsPerRow; // The specific view heights that we use to calculate scroll @@ -104,16 +103,16 @@ public class AllAppsRecyclerView extends BaseRecyclerView { /** * Sets the list of apps in this view, used to determine the fastscroll position. */ - public void setApps(AlphabeticalAppsList apps) { + public void setApps(AlphabeticalAppsList apps) { mApps = apps; } - public AlphabeticalAppsList getApps() { + public AlphabeticalAppsList getApps() { return mApps; } private void updatePoolSize() { - DeviceProfile grid = BaseDraggingActivity.fromContext(getContext()).getDeviceProfile(); + DeviceProfile grid = ActivityContext.lookupContext(getContext()).getDeviceProfile(); RecyclerView.RecycledViewPool pool = getRecycledViewPool(); int approxRows = (int) Math.ceil(grid.availableHeightPx / grid.allAppsIconSizePx); pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH, 1); @@ -201,7 +200,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView { public void onScrollStateChanged(int state) { super.onScrollStateChanged(state); - StatsLogManager mgr = BaseDraggingActivity.fromContext(getContext()).getStatsLogManager(); + StatsLogManager mgr = ActivityContext.lookupContext(getContext()).getStatsLogManager(); switch (state) { case SCROLL_STATE_DRAGGING: requestFocus(); @@ -470,7 +469,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView { * Returns distance between left and right app icons */ public int getTabWidth() { - DeviceProfile grid = BaseDraggingActivity.fromContext(getContext()).getDeviceProfile(); + DeviceProfile grid = ActivityContext.lookupContext(getContext()).getDeviceProfile(); int totalWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight(); int iconPadding = totalWidth / grid.numShownAllAppsColumns - grid.allAppsIconSizePx; return totalWidth - iconPadding - grid.allAppsIconDrawablePaddingPx; diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index fc78beae58..b6a2459c2c 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -75,7 +75,7 @@ public class AllAppsTransitionController } }; - private AllAppsContainerView mAppsView; + private ActivityAllAppsContainerView mAppsView; private final Launcher mLauncher; private boolean mIsVerticalLayout; @@ -201,7 +201,7 @@ public class AllAppsTransitionController /** * see Launcher#setupViews */ - public void setupViews(ScrimView scrimView, AllAppsContainerView appsView) { + public void setupViews(ScrimView scrimView, ActivityAllAppsContainerView appsView) { mScrimView = scrimView; mAppsView = appsView; if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && Utilities.ATLEAST_R) { diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java index ce5c5890ea..1a1d5211c2 100644 --- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java +++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java @@ -18,12 +18,12 @@ package com.android.launcher3.allapps; import android.content.Context; -import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.LabelComparator; +import com.android.launcher3.views.ActivityContext; import java.util.ArrayList; import java.util.Collections; @@ -35,8 +35,11 @@ import java.util.TreeMap; /** * The alphabetically sorted list of applications. + * + * @param Type of context inflating this view. */ -public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener { +public class AlphabeticalAppsList implements + AllAppsStore.OnUpdateListener { public static final String TAG = "AlphabeticalAppsList"; @@ -64,7 +67,7 @@ public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener { } - private final BaseDraggingActivity mLauncher; + private final T mActivityContext; // The set of apps from the system private final List mApps = new ArrayList<>(); @@ -79,7 +82,7 @@ public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener { // The of ordered component names as a result of a search query private ArrayList mSearchResults; - private AllAppsGridAdapter mAdapter; + private AllAppsGridAdapter mAdapter; private AppInfoComparator mAppNameComparator; private final int mNumAppsPerRow; private int mNumAppRowsInAdapter; @@ -88,10 +91,10 @@ public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener { public AlphabeticalAppsList(Context context, AllAppsStore appsStore, WorkAdapterProvider adapterProvider) { mAllAppsStore = appsStore; - mLauncher = BaseDraggingActivity.fromContext(context); + mActivityContext = ActivityContext.lookupContext(context); mAppNameComparator = new AppInfoComparator(context); mWorkAdapterProvider = adapterProvider; - mNumAppsPerRow = mLauncher.getDeviceProfile().inv.numColumns; + mNumAppsPerRow = mActivityContext.getDeviceProfile().inv.numColumns; mAllAppsStore.addUpdateListener(this); } @@ -103,7 +106,7 @@ public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener { /** * Sets the adapter to notify when this dataset changes. */ - public void setAdapter(AllAppsGridAdapter adapter) { + public void setAdapter(AllAppsGridAdapter adapter) { mAdapter = adapter; } @@ -229,7 +232,7 @@ public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener { // As a special case for some languages (currently only Simplified Chinese), we may need to // coalesce sections - Locale curLocale = mLauncher.getResources().getConfiguration().locale; + Locale curLocale = mActivityContext.getResources().getConfiguration().locale; boolean localeRequiresSectionSorting = curLocale.equals(Locale.SIMPLIFIED_CHINESE); if (localeRequiresSectionSorting) { // Compute the section headers. We use a TreeMap with the section name comparator to diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java similarity index 67% rename from src/com/android/launcher3/allapps/AllAppsContainerView.java rename to src/com/android/launcher3/allapps/BaseAllAppsContainerView.java index f06ec4f3a7..c1f0e068eb 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java @@ -31,15 +31,12 @@ import android.os.Bundle; import android.os.Parcelable; import android.os.Process; import android.os.UserManager; -import android.text.SpannableStringBuilder; import android.util.AttributeSet; import android.util.Log; import android.util.SparseArray; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; -import android.view.ViewGroup; import android.view.WindowInsets; import androidx.annotation.NonNull; @@ -50,7 +47,6 @@ import androidx.core.graphics.ColorUtils; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener; import com.android.launcher3.DragSource; @@ -60,22 +56,27 @@ import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.allapps.search.SearchAdapterProvider; -import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.keyboard.FocusedItemDecorator; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.Themes; +import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.RecyclerViewFastScroller; import com.android.launcher3.views.ScrimView; import com.android.launcher3.views.SpringRelativeLayout; import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePageChangedListener; +import java.util.Arrays; +import java.util.List; + /** - * The all apps view container. + * Base all apps view container. + * + * @param Type of context inflating all apps. */ -public class AllAppsContainerView extends SpringRelativeLayout implements DragSource, - Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener, - ScrimView.ScrimDrawingController { +public abstract class BaseAllAppsContainerView extends + SpringRelativeLayout implements DragSource, Insettable, OnDeviceProfileChangeListener, + OnActivePageChangedListener, ScrimView.ScrimDrawingController { private static final String BUNDLE_KEY_CURRENT_PAGE = "launcher.allapps.current_page"; @@ -85,10 +86,12 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo private final Paint mHeaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Rect mInsets = new Rect(); - protected final BaseDraggingActivity mLauncher; - protected final AdapterHolder[] mAH; + /** Context of an activity or window that is inflating this container. */ + protected final T mActivityContext; + protected final List mAH; protected final ItemInfoMatcher mPersonalMatcher = ItemInfoMatcher.ofUser( Process.myUserHandle()); + private final SearchAdapterProvider mMainAdapterProvider; private final AllAppsStore mAllAppsStore = new AllAppsStore(); private final RecyclerView.OnScrollListener mScrollListener = @@ -100,69 +103,58 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo }; private final WorkProfileManager mWorkManager; - private final Paint mNavBarScrimPaint; private int mNavBarScrimHeight = 0; - protected SearchUiManager mSearchUiManager; - private View mSearchContainer; private AllAppsPagedView mViewPager; protected FloatingHeaderView mHeader; - - private SpannableStringBuilder mSearchQueryBuilder = null; - protected boolean mUsingTabs; - private boolean mIsSearching; private boolean mHasWorkApps; protected RecyclerViewFastScroller mTouchHandler; protected final Point mFastScrollerOffset = new Point(); - private SearchAdapterProvider mSearchAdapterProvider; private final int mScrimColor; private final int mHeaderProtectionColor; - private final float mHeaderThreshold; + protected final float mHeaderThreshold; private ScrimView mScrimView; private int mHeaderColor; private int mTabsProtectionAlpha; - public AllAppsContainerView(Context context) { - this(context, null); - } - - public AllAppsContainerView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public AllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) { + protected BaseAllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - - mLauncher = BaseDraggingActivity.fromContext(context); + mActivityContext = ActivityContext.lookupContext(context); + mMainAdapterProvider = createMainAdapterProvider(); mScrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor); mHeaderThreshold = getResources().getDimensionPixelSize( R.dimen.dynamic_grid_cell_border_spacing); mHeaderProtectionColor = Themes.getAttrColor(context, R.attr.allappsHeaderProtectionColor); - mLauncher.addOnDeviceProfileChangeListener(this); - - mSearchAdapterProvider = mLauncher.createSearchAdapterProvider(this); - - mAH = new AdapterHolder[2]; - - mWorkManager = new WorkProfileManager(mLauncher.getSystemService(UserManager.class), this, - Utilities.getPrefs(mLauncher)); - mAH[AdapterHolder.MAIN] = new AdapterHolder(false /* isWork */); - mAH[AdapterHolder.WORK] = new AdapterHolder(true /* isWork */); + mWorkManager = new WorkProfileManager( + mActivityContext.getSystemService(UserManager.class), + this, + Utilities.getPrefs(mActivityContext)); + mAH = Arrays.asList(null, null); + mAH.set(AdapterHolder.MAIN, new AdapterHolder(false /* isWork */)); + mAH.set(AdapterHolder.WORK, new AdapterHolder(true /* isWork */)); mNavBarScrimPaint = new Paint(); mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor)); mAllAppsStore.addUpdateListener(this::onAppsUpdated); - updateBackground(mLauncher.getDeviceProfile()); + updateBackground(mActivityContext.getDeviceProfile()); + } + + /** Creates the adapter provider for the main section. */ + protected abstract SearchAdapterProvider createMainAdapterProvider(); + + /** The adapter provider for the main section. */ + public final SearchAdapterProvider getMainAdapterProvider() { + return mMainAdapterProvider; } @Override @@ -219,11 +211,11 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo public void onDeviceProfileChanged(DeviceProfile dp) { for (AdapterHolder holder : mAH) { holder.adapter.setAppsPerRow(dp.numShownAllAppsColumns); - if (holder.recyclerView != null) { + if (holder.mRecyclerView != null) { // Remove all views and clear the pool, while keeping the data same. After this // call, all the viewHolders will be recreated. - holder.recyclerView.swapAdapter(holder.recyclerView.getAdapter(), true); - holder.recyclerView.getRecycledViewPool().clear(); + holder.mRecyclerView.swapAdapter(holder.mRecyclerView.getAdapter(), true); + holder.mRecyclerView.getRecycledViewPool().clear(); } } updateBackground(dp); @@ -244,7 +236,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo } } mHasWorkApps = hasWorkApps; - if (!mAH[AdapterHolder.MAIN].appsList.hasFilter()) { + if (!mAH.get(AdapterHolder.MAIN).mAppsList.hasFilter()) { rebindAdapters(); if (hasWorkApps) { mWorkManager.reset(); @@ -256,28 +248,24 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo * Returns whether the view itself will handle the touch event or not. */ public boolean shouldContainerScroll(MotionEvent ev) { - // IF the MotionEvent is inside the search box, and the container keeps on receiving - // touch input, container should move down. - if (mLauncher.getDragLayer().isEventOverView(mSearchContainer, ev)) { - return true; - } + // TODO(b/216203409) Support dragging down from bottom sheet divider, if present. AllAppsRecyclerView rv = getActiveRecyclerView(); if (rv == null) { return true; } - if (rv.getScrollbar().getThumbOffsetY() >= 0 && - mLauncher.getDragLayer().isEventOverView(rv.getScrollbar(), ev)) { + if (rv.getScrollbar().getThumbOffsetY() >= 0 + && mActivityContext.getDragLayer().isEventOverView(rv.getScrollbar(), ev)) { return false; } - return rv.shouldContainerScroll(ev, mLauncher.getDragLayer()); + return rv.shouldContainerScroll(ev, mActivityContext.getDragLayer()); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { AllAppsRecyclerView rv = getActiveRecyclerView(); - if (rv != null && - rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(), mFastScrollerOffset)) { + if (rv != null && rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(), + mFastScrollerOffset)) { mTouchHandler = rv.getScrollbar(); } else { mTouchHandler = null; @@ -308,6 +296,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo return false; } + /** Description of the container view based on its current state. */ public String getDescription() { @StringRes int descriptionRes; if (mUsingTabs) { @@ -315,19 +304,18 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo mViewPager.getNextPage() == 0 ? R.string.all_apps_button_personal_label : R.string.all_apps_button_work_label; - } else if (mIsSearching) { - descriptionRes = R.string.all_apps_search_results; } else { descriptionRes = R.string.all_apps_button_label; } return getContext().getString(descriptionRes); } + /** The current recycler view visible in the container. */ public AllAppsRecyclerView getActiveRecyclerView() { if (!mUsingTabs || mViewPager.getNextPage() == 0) { - return mAH[AdapterHolder.MAIN].recyclerView; + return mAH.get(AdapterHolder.MAIN).mRecyclerView; } else { - return mAH[AdapterHolder.WORK].recyclerView; + return mAH.get(AdapterHolder.WORK).mRecyclerView; } } @@ -339,16 +327,15 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo * Resets the state of AllApps. */ public void reset(boolean animate) { - for (int i = 0; i < mAH.length; i++) { - if (mAH[i].recyclerView != null) { - mAH[i].recyclerView.scrollToTop(); + for (int i = 0; i < mAH.size(); i++) { + if (mAH.get(i).mRecyclerView != null) { + mAH.get(i).mRecyclerView.scrollToTop(); } } if (isHeaderVisible()) { mHeader.reset(animate); } - // Reset the search bar and base recycler view after transitioning home - mSearchUiManager.resetSearch(); + // Reset the base recycler view after transitioning home. updateHeaderScroll(0); } @@ -366,20 +353,6 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo mHeader = findViewById(R.id.all_apps_header); rebindAdapters(true /* force */); - - mSearchContainer = findViewById(R.id.search_container_all_apps); - mSearchUiManager = (SearchUiManager) mSearchContainer; - mSearchUiManager.initializeSearch(this); - } - - public SearchUiManager getSearchUiManager() { - return mSearchUiManager; - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - mSearchUiManager.preDispatchKeyEvent(event); - return super.dispatchKeyEvent(event); } @Override @@ -389,15 +362,15 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo @Override public void setInsets(Rect insets) { mInsets.set(insets); - DeviceProfile grid = mLauncher.getDeviceProfile(); + DeviceProfile grid = mActivityContext.getDeviceProfile(); - for (int i = 0; i < mAH.length; i++) { - mAH[i].padding.bottom = insets.bottom; - mAH[i].padding.left = mAH[i].padding.right = grid.allAppsLeftRightPadding; - mAH[i].applyPadding(); + for (int i = 0; i < mAH.size(); i++) { + mAH.get(i).mPadding.bottom = insets.bottom; + mAH.get(i).mPadding.left = mAH.get(i).mPadding.right = grid.allAppsLeftRightPadding; + mAH.get(i).applyPadding(); } - ViewGroup.MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams(); + MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams(); mlp.topMargin = grid.isTablet ? insets.top : 0; int leftRightMargin = grid.allAppsLeftRightMargin; mlp.leftMargin = insets.left + leftRightMargin; @@ -433,57 +406,60 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo } } - private void rebindAdapters() { + protected void rebindAdapters() { rebindAdapters(false /* force */); } protected void rebindAdapters(boolean force) { - boolean showTabs = mHasWorkApps && !mIsSearching; + boolean showTabs = showTabs(); if (showTabs == mUsingTabs && !force) { return; } replaceRVContainer(showTabs); mUsingTabs = showTabs; - mAllAppsStore.unregisterIconContainer(mAH[AdapterHolder.MAIN].recyclerView); - mAllAppsStore.unregisterIconContainer(mAH[AdapterHolder.WORK].recyclerView); + mAllAppsStore.unregisterIconContainer(mAH.get(AdapterHolder.MAIN).mRecyclerView); + mAllAppsStore.unregisterIconContainer(mAH.get(AdapterHolder.WORK).mRecyclerView); if (mUsingTabs) { - mAH[AdapterHolder.MAIN].setup(mViewPager.getChildAt(0), mPersonalMatcher); - mAH[AdapterHolder.WORK].setup(mViewPager.getChildAt(1), mWorkManager.getMatcher()); - mAH[AdapterHolder.WORK].recyclerView.setId(R.id.apps_list_view_work); + mAH.get(AdapterHolder.MAIN).setup(mViewPager.getChildAt(0), mPersonalMatcher); + mAH.get(AdapterHolder.WORK).setup(mViewPager.getChildAt(1), mWorkManager.getMatcher()); + mAH.get(AdapterHolder.WORK).mRecyclerView.setId(R.id.apps_list_view_work); mViewPager.getPageIndicator().setActiveMarker(AdapterHolder.MAIN); findViewById(R.id.tab_personal) .setOnClickListener((View view) -> { if (mViewPager.snapToPage(AdapterHolder.MAIN)) { - mLauncher.getStatsLogManager().logger() + mActivityContext.getStatsLogManager().logger() .log(LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB); } }); findViewById(R.id.tab_work) .setOnClickListener((View view) -> { if (mViewPager.snapToPage(AdapterHolder.WORK)) { - mLauncher.getStatsLogManager().logger() + mActivityContext.getStatsLogManager().logger() .log(LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB); } }); onActivePageChanged(mViewPager.getNextPage()); } else { - mAH[AdapterHolder.MAIN].setup(findViewById(R.id.apps_list_view), null); - mAH[AdapterHolder.WORK].recyclerView = null; + mAH.get(AdapterHolder.MAIN).setup(findViewById(R.id.apps_list_view), null); + mAH.get(AdapterHolder.WORK).mRecyclerView = null; } setupHeader(); - mAllAppsStore.registerIconContainer(mAH[AdapterHolder.MAIN].recyclerView); - mAllAppsStore.registerIconContainer(mAH[AdapterHolder.WORK].recyclerView); + mAllAppsStore.registerIconContainer(mAH.get(AdapterHolder.MAIN).mRecyclerView); + mAllAppsStore.registerIconContainer(mAH.get(AdapterHolder.WORK).mRecyclerView); } + protected boolean showTabs() { + return mHasWorkApps; + } private void replaceRVContainer(boolean showTabs) { for (AdapterHolder adapterHolder : mAH) { - if (adapterHolder.recyclerView != null) { - adapterHolder.recyclerView.setLayoutManager(null); - adapterHolder.recyclerView.setAdapter(null); + if (adapterHolder.mRecyclerView != null) { + adapterHolder.mRecyclerView.setLayoutManager(null); + adapterHolder.mRecyclerView.setAdapter(null); } } View oldView = getRecyclerViewContainer(); @@ -497,7 +473,8 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo mViewPager.initParentViews(this); mViewPager.getPageIndicator().setOnActivePageChangedListener(this); if (mWorkManager.attachWorkModeSwitch()) { - mWorkManager.getWorkModeSwitch().post(() -> mAH[AdapterHolder.WORK].applyPadding()); + mWorkManager.getWorkModeSwitch().post( + () -> mAH.get(AdapterHolder.WORK).applyPadding()); } } else { mWorkManager.detachWorkModeSwitch(); @@ -512,8 +489,8 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo @Override public void onActivePageChanged(int currentActivePage) { mHeader.setMainActive(currentActivePage == AdapterHolder.MAIN); - if (mAH[currentActivePage].recyclerView != null) { - mAH[currentActivePage].recyclerView.bindFastScrollbar(); + if (mAH.get(currentActivePage).mRecyclerView != null) { + mAH.get(currentActivePage).mRecyclerView.bindFastScrollbar(); } reset(true /* animate */); @@ -535,95 +512,53 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo return isDescendantViewVisible(R.id.tab_personal); } - // Used by tests only + @VisibleForTesting public boolean isWorkTabVisible() { return isDescendantViewVisible(R.id.tab_work); } - public AlphabeticalAppsList getApps() { - return mAH[AdapterHolder.MAIN].appsList; + public AlphabeticalAppsList getApps() { + return mAH.get(AdapterHolder.MAIN).mAppsList; } public FloatingHeaderView getFloatingHeaderView() { return mHeader; } - public View getSearchView() { - return mSearchContainer; - } - + @VisibleForTesting public View getContentView() { return mViewPager == null ? getActiveRecyclerView() : mViewPager; } + /** The current page visible in all apps. */ public int getCurrentPage() { return mViewPager != null ? mViewPager.getCurrentPage() : AdapterHolder.MAIN; } - /** - * Handles selection on focused view and returns success - */ - public boolean launchHighlightedItem() { - if (mSearchAdapterProvider == null) return false; - return mSearchAdapterProvider.launchHighlightedItem(); - } - - public SearchAdapterProvider getSearchAdapterProvider() { - return mSearchAdapterProvider; - } - + /** The scroll bar for the active recycler view. */ public RecyclerViewFastScroller getScrollBar() { AllAppsRecyclerView rv = getActiveRecyclerView(); return rv == null ? null : rv.getScrollbar(); } - public void setupHeader() { + void setupHeader() { mHeader.setVisibility(View.VISIBLE); - mHeader.setup(mAH, mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView == null); + mHeader.setup(mAH, mAH.get(AdapterHolder.WORK).mRecyclerView == null); int padding = mHeader.getMaxTranslation(); - for (int i = 0; i < mAH.length; i++) { - mAH[i].padding.top = padding; - mAH[i].applyPadding(); - if (mAH[i].recyclerView != null) { - mAH[i].recyclerView.scrollToTop(); - } - } - } - - public void setLastSearchQuery(String query) { - for (int i = 0; i < mAH.length; i++) { - mAH[i].adapter.setLastSearchQuery(query); - } - mIsSearching = true; - rebindAdapters(); - mHeader.setCollapsed(true); - } - - public void onClearSearchResult() { - mIsSearching = false; - mHeader.setCollapsed(false); - rebindAdapters(); - mHeader.reset(false); - } - - public void onSearchResultsChanged() { - for (int i = 0; i < mAH.length; i++) { - if (mAH[i].recyclerView != null) { - mAH[i].recyclerView.onSearchResultsChanged(); + for (int i = 0; i < mAH.size(); i++) { + mAH.get(i).mPadding.top = padding; + mAH.get(i).applyPadding(); + if (mAH.get(i).mRecyclerView != null) { + mAH.get(i).mRecyclerView.scrollToTop(); } } } + /** @see View#setVerticalFadingEdgeEnabled(boolean). */ public void setRecyclerViewVerticalFadingEdgeEnabled(boolean enabled) { - for (int i = 0; i < mAH.length; i++) { - mAH[i].applyVerticalFadingEdgeEnabled(enabled); - } - } - - public void addElevationController(RecyclerView.OnScrollListener scrollListener) { - if (!mUsingTabs) { - mAH[AdapterHolder.MAIN].recyclerView.addOnScrollListener(scrollListener); + for (int i = 0; i < mAH.size(); i++) { + mAH.get(i).applyVerticalFadingEdgeEnabled(enabled); } } @@ -632,7 +567,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo } /** - * Adds an update listener to {@param animator} that adds springs to the animation. + * Adds an update listener to animator that adds springs to the animation. */ public void addSpringFromFlingUpdateListener(ValueAnimator animator, float velocity /* release velocity */, @@ -650,6 +585,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo }); } + /** Invoked when the container is pulled. */ public void onPull(float deltaDistance, float displacement) { absorbPullDeltaDistance(PULL_MULTIPLIER * deltaDistance, PULL_MULTIPLIER * displacement); // Current motion spec is to actually push and not pull @@ -679,7 +615,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo mHeaderPaint.setColor(mHeaderColor); mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor))); if (mHeaderPaint.getColor() != mScrimColor && mHeaderPaint.getColor() != 0) { - int bottom = (int) (mSearchContainer.getBottom() + getTranslationY()); + int bottom = getHeaderBottom(); canvas.drawRect(0, 0, canvas.getWidth(), bottom, mHeaderPaint); int tabsHeight = getFloatingHeaderView().getPeripheralProtectionHeight(); if (mTabsProtectionAlpha > 0 && tabsHeight != 0) { @@ -689,101 +625,6 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo } } - public class AdapterHolder { - public static final int MAIN = 0; - public static final int WORK = 1; - - private final boolean mIsWork; - public final AllAppsGridAdapter adapter; - final LinearLayoutManager layoutManager; - final AlphabeticalAppsList appsList; - final Rect padding = new Rect(); - AllAppsRecyclerView recyclerView; - boolean verticalFadingEdge; - - - AdapterHolder(boolean isWork) { - mIsWork = isWork; - appsList = new AlphabeticalAppsList(mLauncher, mAllAppsStore, - isWork ? mWorkManager.getAdapterProvider() : null); - - BaseAdapterProvider[] adapterProviders = - isWork ? new BaseAdapterProvider[]{mSearchAdapterProvider, - mWorkManager.getAdapterProvider()} - : new BaseAdapterProvider[]{mSearchAdapterProvider}; - - adapter = new AllAppsGridAdapter(mLauncher, getLayoutInflater(), appsList, - adapterProviders); - appsList.setAdapter(adapter); - layoutManager = adapter.getLayoutManager(); - } - - void setup(@NonNull View rv, @Nullable ItemInfoMatcher matcher) { - appsList.updateItemFilter(matcher); - recyclerView = (AllAppsRecyclerView) rv; - recyclerView.setEdgeEffectFactory(createEdgeEffectFactory()); - recyclerView.setApps(appsList); - recyclerView.setLayoutManager(layoutManager); - recyclerView.setAdapter(adapter); - recyclerView.setHasFixedSize(true); - // No animations will occur when changes occur to the items in this RecyclerView. - recyclerView.setItemAnimator(null); - recyclerView.addOnScrollListener(mScrollListener); - FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(recyclerView); - recyclerView.addItemDecoration(focusedItemDecorator); - adapter.setIconFocusListener(focusedItemDecorator.getFocusListener()); - applyVerticalFadingEdgeEnabled(verticalFadingEdge); - applyPadding(); - if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()) { - recyclerView.addItemDecoration(mSearchAdapterProvider.getDecorator()); - } - } - - void applyPadding() { - if (recyclerView != null) { - int bottomOffset = 0; - if (mIsWork && mWorkManager.getWorkModeSwitch() != null) { - bottomOffset = mInsets.bottom + mWorkManager.getWorkModeSwitch().getHeight(); - } - recyclerView.setPadding(padding.left, padding.top, padding.right, - padding.bottom + bottomOffset); - } - } - - public void applyVerticalFadingEdgeEnabled(boolean enabled) { - verticalFadingEdge = enabled; - mAH[AdapterHolder.MAIN].recyclerView.setVerticalFadingEdgeEnabled(!mUsingTabs - && verticalFadingEdge); - } - } - - - protected void updateHeaderScroll(int scrolledOffset) { - - float prog = Utilities.boundToRange((float) scrolledOffset / mHeaderThreshold, 0f, 1f); - int viewBG = ColorUtils.blendARGB(mScrimColor, mHeaderProtectionColor, prog); - int headerColor = ColorUtils.setAlphaComponent(viewBG, - (int) (getSearchView().getAlpha() * 255)); - int tabsAlpha = mHeader.getPeripheralProtectionHeight() == 0 ? 0 - : (int) (Utilities.boundToRange( - (scrolledOffset + mHeader.mSnappedScrolledY) / mHeaderThreshold, 0f, 1f) - * 255); - if (headerColor != mHeaderColor || mTabsProtectionAlpha != tabsAlpha) { - mHeaderColor = headerColor; - mTabsProtectionAlpha = tabsAlpha; - invalidateHeader(); - } - if (mSearchUiManager.getEditText() != null) { - boolean bgVisible = mSearchUiManager.getBackgroundVisibility(); - if (scrolledOffset == 0 && !mIsSearching) { - bgVisible = true; - } else if (scrolledOffset > mHeaderThreshold) { - bgVisible = false; - } - mSearchUiManager.setBackgroundVisibility(bgVisible, 1 - prog); - } - } - /** * redraws header protection */ @@ -792,4 +633,91 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo mScrimView.invalidate(); } } + + protected void updateHeaderScroll(int scrolledOffset) { + float prog = Utilities.boundToRange((float) scrolledOffset / mHeaderThreshold, 0f, 1f); + int headerColor = getHeaderColor(prog); + int tabsAlpha = mHeader.getPeripheralProtectionHeight() == 0 ? 0 + : (int) (Utilities.boundToRange( + (scrolledOffset + mHeader.mSnappedScrolledY) / mHeaderThreshold, 0f, 1f) + * 255); + if (headerColor != mHeaderColor || mTabsProtectionAlpha != tabsAlpha) { + mHeaderColor = headerColor; + mTabsProtectionAlpha = tabsAlpha; + invalidateHeader(); + } + } + + protected int getHeaderColor(float blendRatio) { + return ColorUtils.blendARGB(mScrimColor, mHeaderProtectionColor, blendRatio); + } + + protected int getHeaderBottom() { + return (int) getTranslationY(); + } + + /** Holds a {@link AllAppsGridAdapter} and related fields. */ + public class AdapterHolder { + public static final int MAIN = 0; + public static final int WORK = 1; + + private final boolean mIsWork; + public final AllAppsGridAdapter adapter; + final LinearLayoutManager mLayoutManager; + final AlphabeticalAppsList mAppsList; + final Rect mPadding = new Rect(); + AllAppsRecyclerView mRecyclerView; + boolean mVerticalFadingEdge; + + AdapterHolder(boolean isWork) { + mIsWork = isWork; + mAppsList = new AlphabeticalAppsList<>(mActivityContext, mAllAppsStore, + isWork ? mWorkManager.getAdapterProvider() : null); + + BaseAdapterProvider[] adapterProviders = + isWork ? new BaseAdapterProvider[]{mMainAdapterProvider, + mWorkManager.getAdapterProvider()} + : new BaseAdapterProvider[]{mMainAdapterProvider}; + + adapter = new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), mAppsList, + adapterProviders); + mAppsList.setAdapter(adapter); + mLayoutManager = adapter.getLayoutManager(); + } + + void setup(@NonNull View rv, @Nullable ItemInfoMatcher matcher) { + mAppsList.updateItemFilter(matcher); + mRecyclerView = (AllAppsRecyclerView) rv; + mRecyclerView.setEdgeEffectFactory(createEdgeEffectFactory()); + mRecyclerView.setApps(mAppsList); + mRecyclerView.setLayoutManager(mLayoutManager); + mRecyclerView.setAdapter(adapter); + mRecyclerView.setHasFixedSize(true); + // No animations will occur when changes occur to the items in this RecyclerView. + mRecyclerView.setItemAnimator(null); + mRecyclerView.addOnScrollListener(mScrollListener); + FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(mRecyclerView); + mRecyclerView.addItemDecoration(focusedItemDecorator); + adapter.setIconFocusListener(focusedItemDecorator.getFocusListener()); + applyVerticalFadingEdgeEnabled(mVerticalFadingEdge); + applyPadding(); + } + + void applyPadding() { + if (mRecyclerView != null) { + int bottomOffset = 0; + if (mIsWork && mWorkManager.getWorkModeSwitch() != null) { + bottomOffset = mInsets.bottom + mWorkManager.getWorkModeSwitch().getHeight(); + } + mRecyclerView.setPadding(mPadding.left, mPadding.top, mPadding.right, + mPadding.bottom + bottomOffset); + } + } + + private void applyVerticalFadingEdgeEnabled(boolean enabled) { + mVerticalFadingEdge = enabled; + mAH.get(AdapterHolder.MAIN).mRecyclerView.setVerticalFadingEdgeEnabled(!mUsingTabs + && mVerticalFadingEdge); + } + } } diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java index 1f7822deef..059d4b8991 100644 --- a/src/com/android/launcher3/allapps/FloatingHeaderView.java +++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java @@ -41,6 +41,7 @@ import com.android.systemui.plugins.AllAppsRow.OnHeightUpdatedListener; import com.android.systemui.plugins.PluginListener; import java.util.ArrayList; +import java.util.List; import java.util.Map; public class FloatingHeaderView extends LinearLayout implements @@ -72,7 +73,8 @@ public class FloatingHeaderView extends LinearLayout implements moved(current); applyVerticalMove(); if (headerCollapsed != mHeaderCollapsed) { - AllAppsContainerView parent = (AllAppsContainerView) getParent(); + BaseAllAppsContainerView parent = + (BaseAllAppsContainerView) getParent(); parent.invalidateHeader(); } } @@ -195,7 +197,7 @@ public class FloatingHeaderView extends LinearLayout implements updateExpectedHeight(); if (mMaxTranslation != oldMaxHeight) { - AllAppsContainerView parent = (AllAppsContainerView) getParent(); + BaseAllAppsContainerView parent = (BaseAllAppsContainerView) getParent(); if (parent != null) { parent.setupHeader(); } @@ -224,7 +226,8 @@ public class FloatingHeaderView extends LinearLayout implements return super.getFocusedChild(); } - public void setup(AllAppsContainerView.AdapterHolder[] mAH, boolean tabsHidden) { + void setup( + List.AdapterHolder> mAH, boolean tabsHidden) { for (FloatingHeaderRow row : mAllRows) { row.setup(this, mAllRows, tabsHidden); } @@ -232,8 +235,10 @@ public class FloatingHeaderView extends LinearLayout implements mTabsHidden = tabsHidden; mTabLayout.setVisibility(tabsHidden ? View.GONE : View.VISIBLE); - mMainRV = setupRV(mMainRV, mAH[AllAppsContainerView.AdapterHolder.MAIN].recyclerView); - mWorkRV = setupRV(mWorkRV, mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView); + mMainRV = setupRV(mMainRV, + mAH.get(BaseAllAppsContainerView.AdapterHolder.MAIN).mRecyclerView); + mWorkRV = setupRV(mWorkRV, + mAH.get(BaseAllAppsContainerView.AdapterHolder.WORK).mRecyclerView); mParent = (ViewGroup) mMainRV.getParent(); setMainActive(mMainRVActive || mWorkRV == null); reset(false); diff --git a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java index b6dcec679b..30d33f95ee 100644 --- a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java @@ -26,9 +26,7 @@ import com.android.launcher3.LauncherState; /** * AllAppsContainerView with launcher specific callbacks */ -public class LauncherAllAppsContainerView extends AllAppsContainerView { - - private final Launcher mLauncher; +public class LauncherAllAppsContainerView extends ActivityAllAppsContainerView { public LauncherAllAppsContainerView(Context context) { this(context, null); @@ -40,14 +38,13 @@ public class LauncherAllAppsContainerView extends AllAppsContainerView { public LauncherAllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - mLauncher = Launcher.getLauncher(context); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // The AllAppsContainerView houses the QSB and is hence visible from the Workspace // Overview states. We shouldn't intercept for the scrubber in these cases. - if (!mLauncher.isInState(LauncherState.ALL_APPS)) { + if (!mActivityContext.isInState(LauncherState.ALL_APPS)) { mTouchHandler = null; return false; } @@ -57,7 +54,7 @@ public class LauncherAllAppsContainerView extends AllAppsContainerView { @Override public boolean onTouchEvent(MotionEvent ev) { - if (!mLauncher.isInState(LauncherState.ALL_APPS)) { + if (!mActivityContext.isInState(LauncherState.ALL_APPS)) { return false; } return super.onTouchEvent(ev); @@ -66,13 +63,8 @@ public class LauncherAllAppsContainerView extends AllAppsContainerView { @Override public void setInsets(Rect insets) { super.setInsets(insets); - int allAppsStartingPositionY = mLauncher.getDeviceProfile().availableHeightPx - - mLauncher.getDeviceProfile().allAppsOpenVerticalTranslate; - mLauncher.getAllAppsController().setScrollRangeDelta(allAppsStartingPositionY); - } - - @Override - public void onActivePageChanged(int currentActivePage) { - super.onActivePageChanged(currentActivePage); + int allAppsStartingPositionY = mActivityContext.getDeviceProfile().availableHeightPx + - mActivityContext.getDeviceProfile().allAppsOpenVerticalTranslate; + mActivityContext.getAllAppsController().setScrollRangeDelta(allAppsStartingPositionY); } } diff --git a/src/com/android/launcher3/allapps/SearchUiManager.java b/src/com/android/launcher3/allapps/SearchUiManager.java index 7478b53d55..f9055ee09a 100644 --- a/src/com/android/launcher3/allapps/SearchUiManager.java +++ b/src/com/android/launcher3/allapps/SearchUiManager.java @@ -29,7 +29,7 @@ public interface SearchUiManager { /** * Initializes the search manager. */ - void initializeSearch(AllAppsContainerView containerView); + void initializeSearch(ActivityAllAppsContainerView containerView); /** * Notifies the search manager to close any active search session. diff --git a/src/com/android/launcher3/allapps/WorkEduCard.java b/src/com/android/launcher3/allapps/WorkEduCard.java index 9db7bf01ac..c3364962ef 100644 --- a/src/com/android/launcher3/allapps/WorkEduCard.java +++ b/src/com/android/launcher3/allapps/WorkEduCard.java @@ -23,16 +23,18 @@ import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.FrameLayout; -import com.android.launcher3.Launcher; import com.android.launcher3.R; +import com.android.launcher3.Utilities; +import com.android.launcher3.views.ActivityContext; /** * Work profile toggle switch shown at the bottom of AllApps work tab */ -public class WorkEduCard extends FrameLayout implements View.OnClickListener, +public class WorkEduCard extends FrameLayout implements + View.OnClickListener, Animation.AnimationListener { - private final Launcher mLauncher; + private final ActivityContext mActivityContext; Animation mDismissAnim; private int mPosition = -1; @@ -46,7 +48,7 @@ public class WorkEduCard extends FrameLayout implements View.OnClickListener, public WorkEduCard(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - mLauncher = Launcher.getLauncher(getContext()); + mActivityContext = ActivityContext.lookupContext(getContext()); mDismissAnim = AnimationUtils.loadAnimation(context, android.R.anim.fade_out); mDismissAnim.setDuration(500); mDismissAnim.setAnimationListener(this); @@ -69,13 +71,14 @@ public class WorkEduCard extends FrameLayout implements View.OnClickListener, super.onFinishInflate(); findViewById(R.id.action_btn).setOnClickListener(this); MarginLayoutParams lp = ((MarginLayoutParams) findViewById(R.id.wrapper).getLayoutParams()); - lp.width = mLauncher.getAppsView().getActiveRecyclerView().getTabWidth(); + lp.width = mActivityContext.getAppsView().getActiveRecyclerView().getTabWidth(); } @Override public void onClick(View view) { startAnimation(mDismissAnim); - mLauncher.getSharedPrefs().edit().putInt(WorkAdapterProvider.KEY_WORK_EDU_STEP, 1).apply(); + Utilities.getPrefs(getContext()).edit().putInt(WorkAdapterProvider.KEY_WORK_EDU_STEP, + 1).apply(); } @Override @@ -97,8 +100,8 @@ public class WorkEduCard extends FrameLayout implements View.OnClickListener, if (mPosition == -1) { if (getParent() != null) ((ViewGroup) getParent()).removeView(WorkEduCard.this); } else { - AllAppsRecyclerView rv = mLauncher.getAppsView() - .mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView; + AllAppsRecyclerView rv = mActivityContext.getAppsView().mAH.get( + ActivityAllAppsContainerView.AdapterHolder.WORK).mRecyclerView; rv.getApps().getAdapterItems().remove(mPosition); rv.getAdapter().notifyItemRemoved(mPosition); } diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java index be015817d0..4598690087 100644 --- a/src/com/android/launcher3/allapps/WorkModeSwitch.java +++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java @@ -26,12 +26,11 @@ import android.view.ViewGroup; import android.view.WindowInsets; import android.widget.Button; -import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; -import com.android.launcher3.Launcher; import com.android.launcher3.Utilities; import com.android.launcher3.anim.KeyboardInsetAnimationCallback; +import com.android.launcher3.views.ActivityContext; import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip; /** @@ -73,7 +72,7 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi new KeyboardInsetAnimationCallback(this); setWindowInsetsAnimationCallback(keyboardInsetAnimationCallback); } - DeviceProfile grid = BaseDraggingActivity.fromContext(getContext()).getDeviceProfile(); + DeviceProfile grid = ActivityContext.lookupContext(getContext()).getDeviceProfile(); setInsets(grid.getInsets()); } @@ -91,7 +90,7 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi @Override public void onActivePageChanged(int page) { - mOnWorkTab = page == AllAppsContainerView.AdapterHolder.WORK; + mOnWorkTab = page == ActivityAllAppsContainerView.AdapterHolder.WORK; updateVisibility(); } @@ -99,9 +98,9 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi public void onClick(View view) { if (Utilities.ATLEAST_P && isEnabled()) { setFlag(FLAG_PROFILE_TOGGLE_ONGOING); - Launcher launcher = Launcher.getLauncher(getContext()); - launcher.getStatsLogManager().logger().log(LAUNCHER_TURN_OFF_WORK_APPS_TAP); - launcher.getAppsView().getWorkManager().setWorkProfileEnabled(false); + ActivityContext activityContext = ActivityContext.lookupContext(getContext()); + activityContext.getStatsLogManager().logger().log(LAUNCHER_TURN_OFF_WORK_APPS_TAP); + activityContext.getAppsView().getWorkManager().setWorkProfileEnabled(false); } } diff --git a/src/com/android/launcher3/allapps/WorkPausedCard.java b/src/com/android/launcher3/allapps/WorkPausedCard.java index 7593ca7427..729622f519 100644 --- a/src/com/android/launcher3/allapps/WorkPausedCard.java +++ b/src/com/android/launcher3/allapps/WorkPausedCard.java @@ -24,16 +24,16 @@ import android.view.View; import android.widget.Button; import android.widget.LinearLayout; -import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.views.ActivityContext; /** * Work profile toggle switch shown at the bottom of AllApps work tab */ public class WorkPausedCard extends LinearLayout implements View.OnClickListener { - private final Launcher mLauncher; + private final ActivityContext mActivityContext; private Button mBtn; public WorkPausedCard(Context context) { @@ -46,7 +46,7 @@ public class WorkPausedCard extends LinearLayout implements View.OnClickListener public WorkPausedCard(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - mLauncher = Launcher.getLauncher(getContext()); + mActivityContext = ActivityContext.lookupContext(getContext()); } @@ -61,8 +61,8 @@ public class WorkPausedCard extends LinearLayout implements View.OnClickListener public void onClick(View view) { if (Utilities.ATLEAST_P) { setEnabled(false); - mLauncher.getAppsView().getWorkManager().setWorkProfileEnabled(true); - mLauncher.getStatsLogManager().logger().log(LAUNCHER_TURN_ON_WORK_APPS_TAP); + mActivityContext.getAppsView().getWorkManager().setWorkProfileEnabled(true); + mActivityContext.getStatsLogManager().logger().log(LAUNCHER_TURN_ON_WORK_APPS_TAP); } } diff --git a/src/com/android/launcher3/allapps/WorkProfileManager.java b/src/com/android/launcher3/allapps/WorkProfileManager.java index e223248866..bcaf1f4b21 100644 --- a/src/com/android/launcher3/allapps/WorkProfileManager.java +++ b/src/com/android/launcher3/allapps/WorkProfileManager.java @@ -39,7 +39,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * Companion class for {@link AllAppsContainerView} to manage work tab and personal tab related + * Companion class for {@link BaseAllAppsContainerView} to manage work tab and personal tab + * related * logic based on {@link WorkProfileState}? */ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActivePageChangedListener { @@ -50,7 +51,6 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP public static final int STATE_DISABLED = 2; public static final int STATE_TRANSITION = 3; - private final UserManager mUserManager; /** @@ -65,7 +65,7 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP public @interface WorkProfileState { } - private final AllAppsContainerView mAllApps; + private final BaseAllAppsContainerView mAllApps; private final WorkAdapterProvider mAdapterProvider; private final ItemInfoMatcher mMatcher; @@ -75,7 +75,7 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP private int mCurrentState; - public WorkProfileManager(UserManager userManager, AllAppsContainerView allApps, + public WorkProfileManager(UserManager userManager, BaseAllAppsContainerView allApps, SharedPreferences preferences) { mUserManager = userManager; mAllApps = allApps; @@ -118,7 +118,7 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP mCurrentState = currentState; mAdapterProvider.updateCurrentState(currentState); if (getAH() != null) { - getAH().appsList.updateAdapterItems(); + getAH().mAppsList.updateAdapterItems(); } if (mWorkModeSwitch != null) { mWorkModeSwitch.updateCurrentState(currentState == STATE_ENABLED); @@ -126,7 +126,7 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP } /** - * Creates and attaches for profile toggle button to {@link AllAppsContainerView} + * Creates and attaches for profile toggle button to {@link BaseAllAppsContainerView} */ public boolean attachWorkModeSwitch() { if (!mAllApps.getAppsStore().hasModelFlag( @@ -149,7 +149,7 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP } /** - * Removes work profile toggle button from {@link AllAppsContainerView} + * Removes work profile toggle button from {@link BaseAllAppsContainerView} */ public void detachWorkModeSwitch() { if (mWorkModeSwitch != null && mWorkModeSwitch.getParent() == mAllApps) { @@ -172,8 +172,8 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP return mWorkModeSwitch; } - private AllAppsContainerView.AdapterHolder getAH() { - return mAllApps.mAH[AllAppsContainerView.AdapterHolder.WORK]; + private BaseAllAppsContainerView.AdapterHolder getAH() { + return mAllApps.mAH.get(BaseAllAppsContainerView.AdapterHolder.WORK); } public int getCurrentState() { diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java index 4c5a9e64c9..ffc049b6e8 100644 --- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java +++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java @@ -37,7 +37,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.ExtendedEditText; import com.android.launcher3.Insettable; import com.android.launcher3.R; -import com.android.launcher3.allapps.AllAppsContainerView; +import com.android.launcher3.allapps.ActivityAllAppsContainerView; import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem; import com.android.launcher3.allapps.AllAppsStore; import com.android.launcher3.allapps.AlphabeticalAppsList; @@ -57,8 +57,8 @@ public class AppsSearchContainerLayout extends ExtendedEditText private final AllAppsSearchBarController mSearchBarController; private final SpannableStringBuilder mSearchQueryBuilder; - private AlphabeticalAppsList mApps; - private AllAppsContainerView mAppsView; + private AlphabeticalAppsList mApps; + private ActivityAllAppsContainerView mAppsView; // The amount of pixels to shift down and overlap with the rest of the content. private final int mContentOverlap; @@ -130,7 +130,7 @@ public class AppsSearchContainerLayout extends ExtendedEditText } @Override - public void initializeSearch(AllAppsContainerView appsView) { + public void initializeSearch(ActivityAllAppsContainerView appsView) { mApps = appsView.getApps(); mAppsView = appsView; mSearchBarController.initialize( diff --git a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java index 7abd555b9d..2fe4915e2f 100644 --- a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java +++ b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java @@ -25,21 +25,19 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.BubbleTextView; -import com.android.launcher3.allapps.AllAppsContainerView; import com.android.launcher3.allapps.AllAppsGridAdapter; import com.android.launcher3.model.data.ItemInfo; /** * Provides views for local search results */ -public class DefaultSearchAdapterProvider extends SearchAdapterProvider { +public class DefaultSearchAdapterProvider extends SearchAdapterProvider { private final RecyclerView.ItemDecoration mDecoration; private View mHighlightedView; - public DefaultSearchAdapterProvider(BaseDraggingActivity launcher, - AllAppsContainerView appsContainerView) { - super(launcher, appsContainerView); + public DefaultSearchAdapterProvider(BaseDraggingActivity launcher) { + super(launcher); mDecoration = new RecyclerView.ItemDecoration() { @Override public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, diff --git a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java index 7af0406e30..bc52784caf 100644 --- a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java +++ b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java @@ -21,18 +21,19 @@ import android.view.View; import androidx.recyclerview.widget.RecyclerView; -import com.android.launcher3.BaseDraggingActivity; -import com.android.launcher3.allapps.AllAppsContainerView; import com.android.launcher3.allapps.BaseAdapterProvider; +import com.android.launcher3.views.ActivityContext; /** * A UI expansion wrapper providing for search results + * + * @param Context for this adapter provider. */ -public abstract class SearchAdapterProvider extends BaseAdapterProvider { +public abstract class SearchAdapterProvider extends BaseAdapterProvider { - protected final BaseDraggingActivity mLauncher; + protected final T mLauncher; - public SearchAdapterProvider(BaseDraggingActivity launcher, AllAppsContainerView appsView) { + public SearchAdapterProvider(T launcher) { mLauncher = launcher; } diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index 98be72a6b9..7c665c6d87 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -55,7 +55,7 @@ import com.android.launcher3.R; import com.android.launcher3.Reorderable; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; -import com.android.launcher3.allapps.AllAppsContainerView; +import com.android.launcher3.allapps.ActivityAllAppsContainerView; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dot.FolderDotInfo; @@ -397,7 +397,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel float finalScale = scale * scaleRelativeToDragLayer; // Account for potentially different icon sizes with non-default grid settings - if (d.dragSource instanceof AllAppsContainerView) { + if (d.dragSource instanceof ActivityAllAppsContainerView) { DeviceProfile grid = mActivity.getDeviceProfile(); float containerScale = (1f * grid.iconSizePx / grid.allAppsIconSizePx); finalScale *= containerScale; diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java index 1a96c2311c..cba0655b24 100644 --- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java @@ -30,7 +30,7 @@ import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherModel; import com.android.launcher3.R; -import com.android.launcher3.allapps.AllAppsContainerView; +import com.android.launcher3.allapps.ActivityAllAppsContainerView; import com.android.launcher3.model.BgDataModel; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.ItemInfo; @@ -52,7 +52,8 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity private LauncherModel mModel; private BaseDragLayer mDragLayer; - private AllAppsContainerView mAppsView; + // TODO(b/216191717): Verify all apps works on secondary display. + private ActivityAllAppsContainerView mAppsView; private View mAppsButton; private PopupDataProvider mPopupDataProvider; @@ -143,7 +144,8 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity return mAppDrawerShown; } - public AllAppsContainerView getAppsView() { + @Override + public ActivityAllAppsContainerView getAppsView() { return mAppsView; } diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java index 0d8602fa3e..967f2c8400 100644 --- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java @@ -30,7 +30,7 @@ import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BubbleTextView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; -import com.android.launcher3.allapps.AllAppsContainerView; +import com.android.launcher3.allapps.ActivityAllAppsContainerView; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.popup.PopupContainerWithArrow; import com.android.launcher3.popup.PopupDataProvider; @@ -47,7 +47,7 @@ import java.util.Collections; public class SecondaryDragLayer extends BaseDragLayer { private View mAllAppsButton; - private AllAppsContainerView mAppsView; + private ActivityAllAppsContainerView mAppsView; private GridView mWorkspace; private PinnedAppsAdapter mPinnedAppsAdapter; diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java index c0f6316b95..8b48baeab7 100644 --- a/src/com/android/launcher3/views/ActivityContext.java +++ b/src/com/android/launcher3/views/ActivityContext.java @@ -25,6 +25,7 @@ import android.view.View.AccessibilityDelegate; import androidx.annotation.Nullable; import com.android.launcher3.DeviceProfile; +import com.android.launcher3.allapps.BaseAllAppsContainerView; import com.android.launcher3.dot.DotInfo; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.folder.FolderIcon; @@ -93,6 +94,13 @@ public interface ActivityContext { */ BaseDragLayer getDragLayer(); + /** + * The all apps container, if it exists in this context. + */ + default BaseAllAppsContainerView getAppsView() { + return null; + } + DeviceProfile getDeviceProfile(); default ViewCache getViewCache() { diff --git a/tests/src/com/android/launcher3/ui/WorkProfileTest.java b/tests/src/com/android/launcher3/ui/WorkProfileTest.java index 939cfe1ae6..f31e4f315c 100644 --- a/tests/src/com/android/launcher3/ui/WorkProfileTest.java +++ b/tests/src/com/android/launcher3/ui/WorkProfileTest.java @@ -26,7 +26,7 @@ import android.util.Log; import android.view.View; import com.android.launcher3.R; -import com.android.launcher3.allapps.AllAppsContainerView; +import com.android.launcher3.allapps.ActivityAllAppsContainerView; import com.android.launcher3.allapps.AllAppsPagedView; import com.android.launcher3.allapps.WorkAdapterProvider; import com.android.launcher3.allapps.WorkEduCard; @@ -41,7 +41,7 @@ import java.util.Objects; public class WorkProfileTest extends AbstractLauncherUiTest { - private static final int WORK_PAGE = AllAppsContainerView.AdapterHolder.WORK; + private static final int WORK_PAGE = ActivityAllAppsContainerView.AdapterHolder.WORK; private int mProfileUserId; @@ -132,7 +132,7 @@ public class WorkProfileTest extends AbstractLauncherUiTest { // start work profile toggle ON test executeOnLauncher(l -> { - AllAppsContainerView allApps = l.getAppsView(); + ActivityAllAppsContainerView allApps = l.getAppsView(); assertEquals("Work tab is not focused", allApps.getCurrentPage(), WORK_PAGE); View workPausedCard = allApps.getActiveRecyclerView().findViewHolderForAdapterPosition( 0).itemView;