Add personal / work tabs for work profile widgets
Video: https://drive.google.com/file/d/1TORRNcvVM7fIvNd_WZaajLbI7D9z4VFA/view?usp=sharing Test: Main profile only: run AddConfigWidgetTest. With work profile: manually launch the full widgets sheet. Go to the personal tab: only personal widgets are shown. Go to the work tab: only work widgets are shown Successfully add personal / work widgets from the full widgets sheet. Bug: 179797520 Change-Id: Iad8b90c2af35e0580319d7a05510ec88e4f8b86c
This commit is contained in:
parent
dfdeddc66a
commit
391404fcb7
|
@ -27,12 +27,6 @@
|
|||
android:background="?android:attr/colorPrimary"
|
||||
android:elevation="4dp">
|
||||
|
||||
<com.android.launcher3.widget.picker.WidgetsRecyclerView
|
||||
android:id="@+id/widgets_list_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false" />
|
||||
|
||||
<!-- Fast scroller popup -->
|
||||
<TextView
|
||||
android:id="@+id/fast_scroller_popup"
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:launcher="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<include layout="@layout/personal_work_tabs" />
|
||||
|
||||
<com.android.launcher3.workprofile.PersonalWorkPagedView
|
||||
android:id="@+id/widgets_view_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/tabs"
|
||||
android:clipToPadding="false"
|
||||
android:descendantFocusability="afterDescendants"
|
||||
launcher:pageIndicator="@+id/tabs">
|
||||
|
||||
<com.android.launcher3.widget.picker.WidgetsRecyclerView
|
||||
android:id="@+id/primary_widgets_list_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false" />
|
||||
|
||||
<com.android.launcher3.widget.picker.WidgetsRecyclerView
|
||||
android:id="@+id/work_widgets_list_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false" />
|
||||
|
||||
</com.android.launcher3.workprofile.PersonalWorkPagedView>
|
||||
|
||||
</merge>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
<com.android.launcher3.widget.picker.WidgetsRecyclerView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/primary_widgets_list_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false" />
|
|
@ -96,6 +96,8 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
|
|||
private static final int MIN_FLING_VELOCITY = 250;
|
||||
|
||||
private boolean mFreeScroll = false;
|
||||
/** If {@code false}, disable swipe gesture to switch between pages. */
|
||||
private boolean mSwipeGestureEnabled = true;
|
||||
|
||||
protected final int mFlingThresholdVelocity;
|
||||
protected final int mEasyFlingThresholdVelocity;
|
||||
|
@ -857,6 +859,14 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If {@code enableSwipeGesture} is {@code true}, enables swipe gesture to navigate between
|
||||
* pages. Otherwise, disables the navigation gesture.
|
||||
*/
|
||||
public void setSwipeGestureEnabled(boolean swipeGestureEnabled) {
|
||||
mSwipeGestureEnabled = swipeGestureEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -879,6 +889,8 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
|
|||
* scrolling there.
|
||||
*/
|
||||
|
||||
if (!mSwipeGestureEnabled) return false;
|
||||
|
||||
// Skip touch handling if there are no pages to swipe
|
||||
if (getChildCount() <= 0) return false;
|
||||
|
||||
|
|
|
@ -60,6 +60,6 @@ public class PackageItemInfo extends ItemInfoWithIcon {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(packageName);
|
||||
return Objects.hash(packageName, user);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,16 +22,22 @@ import android.animation.Animator;
|
|||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.content.Context;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Pair;
|
||||
import android.util.SparseArray;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.launcher3.Insettable;
|
||||
import com.android.launcher3.Launcher;
|
||||
|
@ -43,30 +49,39 @@ import com.android.launcher3.compat.AccessibilityManagerCompat;
|
|||
import com.android.launcher3.views.RecyclerViewFastScroller;
|
||||
import com.android.launcher3.views.TopRoundedCornerView;
|
||||
import com.android.launcher3.widget.BaseWidgetSheet;
|
||||
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
|
||||
import com.android.launcher3.workprofile.PersonalWorkPagedView;
|
||||
import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePageChangedListener;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Popup for showing the full list of available widgets
|
||||
*/
|
||||
public class WidgetsFullSheet extends BaseWidgetSheet
|
||||
implements Insettable, ProviderChangedListener {
|
||||
implements Insettable, ProviderChangedListener, OnActivePageChangedListener {
|
||||
|
||||
private static final long DEFAULT_OPEN_DURATION = 267;
|
||||
private static final long FADE_IN_DURATION = 150;
|
||||
private static final float VERTICAL_START_POSITION = 0.3f;
|
||||
|
||||
private final Rect mInsets = new Rect();
|
||||
private final boolean mHasWorkProfile;
|
||||
private final SparseArray<AdapterHolder> mAdapters = new SparseArray();
|
||||
private final UserHandle mCurrentUser = Process.myUserHandle();
|
||||
private final Predicate<WidgetsListBaseEntry> mPrimaryWidgetsFilter = entry ->
|
||||
mCurrentUser.equals(entry.mPkgItem.user);
|
||||
private final Predicate<WidgetsListBaseEntry> mWorkWidgetsFilter =
|
||||
mPrimaryWidgetsFilter.negate();
|
||||
|
||||
private final WidgetsListAdapter mAdapter;
|
||||
|
||||
private WidgetsRecyclerView mRecyclerView;
|
||||
@Nullable private PersonalWorkPagedView mViewPager;
|
||||
|
||||
public WidgetsFullSheet(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
LauncherAppState apps = LauncherAppState.getInstance(context);
|
||||
mAdapter = new WidgetsListAdapter(context,
|
||||
LayoutInflater.from(context), apps.getWidgetCache(), apps.getIconCache(),
|
||||
this, this);
|
||||
|
||||
mHasWorkProfile = context.getSystemService(LauncherApps.class).getProfiles().size() > 1;
|
||||
mAdapters.put(AdapterHolder.PRIMARY, new AdapterHolder(AdapterHolder.PRIMARY));
|
||||
mAdapters.put(AdapterHolder.WORK, new AdapterHolder(AdapterHolder.WORK));
|
||||
}
|
||||
|
||||
public WidgetsFullSheet(Context context, AttributeSet attrs) {
|
||||
|
@ -77,25 +92,51 @@ public class WidgetsFullSheet extends BaseWidgetSheet
|
|||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mContent = findViewById(R.id.container);
|
||||
|
||||
mRecyclerView = findViewById(R.id.widgets_list_view);
|
||||
mRecyclerView.setAdapter(mAdapter);
|
||||
mAdapter.setApplyBitmapDeferred(true, mRecyclerView);
|
||||
|
||||
TopRoundedCornerView springLayout = (TopRoundedCornerView) mContent;
|
||||
springLayout.addSpringView(R.id.widgets_list_view);
|
||||
mRecyclerView.setEdgeEffectFactory(springLayout.createEdgeEffectFactory());
|
||||
|
||||
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
|
||||
int contentLayoutRes = mHasWorkProfile ? R.layout.widgets_full_sheet_paged_view
|
||||
: R.layout.widgets_full_sheet_recyclerview;
|
||||
layoutInflater.inflate(contentLayoutRes, springLayout, true);
|
||||
|
||||
if (mHasWorkProfile) {
|
||||
mViewPager = findViewById(R.id.widgets_view_pager);
|
||||
// Temporarily disable swipe gesture until widgets list horizontal scrollviews per
|
||||
// app are replaced by gird views.
|
||||
mViewPager.setSwipeGestureEnabled(false);
|
||||
mViewPager.initParentViews(this);
|
||||
mViewPager.getPageIndicator().setOnActivePageChangedListener(this);
|
||||
mViewPager.getPageIndicator().setActiveMarker(AdapterHolder.PRIMARY);
|
||||
findViewById(R.id.tab_personal)
|
||||
.setOnClickListener((View view) -> mViewPager.snapToPage(0));
|
||||
findViewById(R.id.tab_work)
|
||||
.setOnClickListener((View view) -> mViewPager.snapToPage(1));
|
||||
springLayout.addSpringView(R.id.primary_widgets_list_view);
|
||||
springLayout.addSpringView(R.id.work_widgets_list_view);
|
||||
} else {
|
||||
mViewPager = null;
|
||||
springLayout.addSpringView(R.id.primary_widgets_list_view);
|
||||
}
|
||||
|
||||
onWidgetsBound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivePageChanged(int currentActivePage) {
|
||||
mAdapters.get(currentActivePage).mWidgetsRecyclerView.bindFastScrollbar();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public WidgetsRecyclerView getRecyclerView() {
|
||||
return mRecyclerView;
|
||||
if (!mHasWorkProfile || mViewPager.getCurrentPage() == AdapterHolder.PRIMARY) {
|
||||
return mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView;
|
||||
}
|
||||
return mAdapters.get(AdapterHolder.WORK).mWidgetsRecyclerView;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Pair<View, String> getAccessibilityTarget() {
|
||||
return Pair.create(mRecyclerView, getContext().getString(
|
||||
return Pair.create(getRecyclerView(), getContext().getString(
|
||||
mIsOpen ? R.string.widgets_list : R.string.widgets_list_closed));
|
||||
}
|
||||
|
||||
|
@ -116,9 +157,10 @@ public class WidgetsFullSheet extends BaseWidgetSheet
|
|||
public void setInsets(Rect insets) {
|
||||
mInsets.set(insets);
|
||||
|
||||
mRecyclerView.setPadding(
|
||||
mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(),
|
||||
mRecyclerView.getPaddingRight(), insets.bottom);
|
||||
setBottomPadding(mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView, insets.bottom);
|
||||
if (mHasWorkProfile) {
|
||||
setBottomPadding(mAdapters.get(AdapterHolder.WORK).mWidgetsRecyclerView, insets.bottom);
|
||||
}
|
||||
if (insets.bottom > 0) {
|
||||
setupNavBarColor();
|
||||
} else {
|
||||
|
@ -129,6 +171,14 @@ public class WidgetsFullSheet extends BaseWidgetSheet
|
|||
requestLayout();
|
||||
}
|
||||
|
||||
private void setBottomPadding(RecyclerView recyclerView, int bottomPadding) {
|
||||
recyclerView.setPadding(
|
||||
recyclerView.getPaddingLeft(),
|
||||
recyclerView.getPaddingTop(),
|
||||
recyclerView.getPaddingRight(),
|
||||
bottomPadding);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int widthUsed;
|
||||
|
@ -168,7 +218,17 @@ public class WidgetsFullSheet extends BaseWidgetSheet
|
|||
|
||||
@Override
|
||||
public void onWidgetsBound() {
|
||||
mAdapter.setWidgets(mLauncher.getPopupDataProvider().getAllWidgets());
|
||||
List<WidgetsListBaseEntry> allWidgets = mLauncher.getPopupDataProvider().getAllWidgets();
|
||||
|
||||
AdapterHolder primaryUserAdapterHolder = mAdapters.get(AdapterHolder.PRIMARY);
|
||||
primaryUserAdapterHolder.setup(findViewById(R.id.primary_widgets_list_view));
|
||||
primaryUserAdapterHolder.mWidgetsListAdapter.setWidgets(allWidgets);
|
||||
if (mHasWorkProfile) {
|
||||
AdapterHolder workUserAdapterHolder = mAdapters.get(AdapterHolder.WORK);
|
||||
workUserAdapterHolder.setup(findViewById(R.id.work_widgets_list_view));
|
||||
workUserAdapterHolder.mWidgetsListAdapter.setWidgets(allWidgets);
|
||||
onActivePageChanged(mViewPager.getCurrentPage());
|
||||
}
|
||||
}
|
||||
|
||||
private void open(boolean animate) {
|
||||
|
@ -183,12 +243,9 @@ public class WidgetsFullSheet extends BaseWidgetSheet
|
|||
.setDuration(DEFAULT_OPEN_DURATION)
|
||||
.setInterpolator(AnimationUtils.loadInterpolator(
|
||||
getContext(), android.R.interpolator.linear_out_slow_in));
|
||||
mRecyclerView.setLayoutFrozen(true);
|
||||
mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mRecyclerView.setLayoutFrozen(false);
|
||||
mAdapter.setApplyBitmapDeferred(false, mRecyclerView);
|
||||
mOpenCloseAnimator.removeListener(this);
|
||||
}
|
||||
});
|
||||
|
@ -198,7 +255,6 @@ public class WidgetsFullSheet extends BaseWidgetSheet
|
|||
});
|
||||
} else {
|
||||
setTranslationShift(TRANSLATION_SHIFT_OPENED);
|
||||
mAdapter.setApplyBitmapDeferred(false, mRecyclerView);
|
||||
post(this::announceAccessibilityChanges);
|
||||
}
|
||||
}
|
||||
|
@ -218,12 +274,12 @@ public class WidgetsFullSheet extends BaseWidgetSheet
|
|||
// Disable swipe down when recycler view is scrolling
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
mNoIntercept = false;
|
||||
RecyclerViewFastScroller scroller = mRecyclerView.getScrollbar();
|
||||
RecyclerViewFastScroller scroller = getRecyclerView().getScrollbar();
|
||||
if (scroller.getThumbOffsetY() >= 0
|
||||
&& getPopupContainer().isEventOverView(scroller, ev)) {
|
||||
mNoIntercept = true;
|
||||
} else if (getPopupContainer().isEventOverView(mContent, ev)) {
|
||||
mNoIntercept = !mRecyclerView.shouldContainerScroll(ev, getPopupContainer());
|
||||
mNoIntercept = !getRecyclerView().shouldContainerScroll(ev, getPopupContainer());
|
||||
}
|
||||
}
|
||||
return super.onControllerInterceptTouchEvent(ev);
|
||||
|
@ -242,14 +298,14 @@ public class WidgetsFullSheet extends BaseWidgetSheet
|
|||
/** Gets the {@link WidgetsRecyclerView} which shows all widgets in {@link WidgetsFullSheet}. */
|
||||
@VisibleForTesting
|
||||
public static WidgetsRecyclerView getWidgetsView(Launcher launcher) {
|
||||
return launcher.findViewById(R.id.widgets_list_view);
|
||||
return launcher.findViewById(R.id.primary_widgets_list_view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHintCloseAnim(
|
||||
float distanceToMove, Interpolator interpolator, PendingAnimation target) {
|
||||
target.setFloat(mRecyclerView, VIEW_TRANSLATE_Y, -distanceToMove, interpolator);
|
||||
target.setViewAlpha(mRecyclerView, 0.5f, interpolator);
|
||||
target.setFloat(getRecyclerView(), VIEW_TRANSLATE_Y, -distanceToMove, interpolator);
|
||||
target.setViewAlpha(getRecyclerView(), 0.5f, interpolator);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -257,4 +313,39 @@ public class WidgetsFullSheet extends BaseWidgetSheet
|
|||
super.onCloseComplete();
|
||||
AccessibilityManagerCompat.sendStateEventToTest(getContext(), NORMAL_STATE_ORDINAL);
|
||||
}
|
||||
|
||||
/** A holder class for holding adapters & their corresponding recycler view. */
|
||||
private final class AdapterHolder {
|
||||
static final int PRIMARY = 0;
|
||||
static final int WORK = 1;
|
||||
|
||||
private final int mAdapterType;
|
||||
private final WidgetsListAdapter mWidgetsListAdapter;
|
||||
|
||||
private WidgetsRecyclerView mWidgetsRecyclerView;
|
||||
|
||||
AdapterHolder(int adapterType) {
|
||||
mAdapterType = adapterType;
|
||||
|
||||
Context context = getContext();
|
||||
LauncherAppState apps = LauncherAppState.getInstance(context);
|
||||
mWidgetsListAdapter = new WidgetsListAdapter(
|
||||
context,
|
||||
LayoutInflater.from(context),
|
||||
apps.getWidgetCache(),
|
||||
apps.getIconCache(),
|
||||
/* iconClickListener= */ WidgetsFullSheet.this,
|
||||
/* iconLongClickListener= */ WidgetsFullSheet.this);
|
||||
mWidgetsListAdapter.setFilter(
|
||||
mAdapterType == PRIMARY ? mPrimaryWidgetsFilter : mWorkWidgetsFilter);
|
||||
}
|
||||
|
||||
void setup(WidgetsRecyclerView recyclerView) {
|
||||
mWidgetsRecyclerView = recyclerView;
|
||||
mWidgetsRecyclerView.setAdapter(mWidgetsListAdapter);
|
||||
mWidgetsRecyclerView.setEdgeEffectFactory(
|
||||
((TopRoundedCornerView) mContent).createEdgeEffectFactory());
|
||||
mWidgetsListAdapter.setApplyBitmapDeferred(false, mWidgetsRecyclerView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ import com.android.launcher3.widget.picker.WidgetsListHeaderViewHolderBinder.OnH
|
|||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
@ -74,6 +75,11 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
|
|||
private ArrayList<WidgetsListBaseEntry> mVisibleEntries = new ArrayList<>();
|
||||
@Nullable private String mWidgetsContentVisiblePackage = null;
|
||||
|
||||
private Predicate<WidgetsListBaseEntry> mHeaderAndSelectedContentFilter = entry ->
|
||||
entry instanceof WidgetsListHeaderEntry
|
||||
|| entry.mPkgItem.packageName.equals(mWidgetsContentVisiblePackage);
|
||||
@Nullable private Predicate<WidgetsListBaseEntry> mFilter = null;
|
||||
|
||||
public WidgetsListAdapter(Context context, LayoutInflater layoutInflater,
|
||||
WidgetPreviewLoader widgetPreviewLoader, IconCache iconCache,
|
||||
OnClickListener iconClickListener, OnLongClickListener iconLongClickListener) {
|
||||
|
@ -85,6 +91,10 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
|
|||
new WidgetsListHeaderViewHolderBinder(layoutInflater, this::onHeaderClicked));
|
||||
}
|
||||
|
||||
public void setFilter(Predicate<WidgetsListBaseEntry> filter) {
|
||||
mFilter = filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defers applying bitmap on all the {@link WidgetCell} in the {@param rv}.
|
||||
*
|
||||
|
@ -132,8 +142,8 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
|
|||
}
|
||||
});
|
||||
List<WidgetsListBaseEntry> newVisibleEntries = mAllEntries.stream()
|
||||
.filter(entry -> entry instanceof WidgetsListHeaderEntry
|
||||
|| entry.mPkgItem.packageName.equals(mWidgetsContentVisiblePackage))
|
||||
.filter(entry -> (mFilter == null || mFilter.test(entry))
|
||||
&& mHeaderAndSelectedContentFilter.test(entry))
|
||||
.collect(Collectors.toList());
|
||||
mDiffReporter.process(mVisibleEntries, newVisibleEntries, mRowComparator);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import android.appwidget.AppWidgetProviderInfo;
|
|||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
|
@ -115,7 +114,7 @@ public class WidgetsModel {
|
|||
widgetsAndShortcuts.add(new WidgetItem(info, app.getIconCache(), pm));
|
||||
updatedItems.add(info);
|
||||
}
|
||||
setWidgetsAndShortcuts(widgetsAndShortcuts, app, packageUser);
|
||||
setWidgetsAndShortcuts(widgetsAndShortcuts, app);
|
||||
} catch (Exception e) {
|
||||
if (!FeatureFlags.IS_STUDIO_BUILD && Utilities.isBinderSizeError(e)) {
|
||||
// the returned value may be incomplete and will not be refreshed until the next
|
||||
|
@ -132,52 +131,28 @@ public class WidgetsModel {
|
|||
}
|
||||
|
||||
private synchronized void setWidgetsAndShortcuts(ArrayList<WidgetItem> rawWidgetsShortcuts,
|
||||
LauncherAppState app, @Nullable PackageUserKey packageUser) {
|
||||
LauncherAppState app) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "addWidgetsAndShortcuts, widgetsShortcuts#=" + rawWidgetsShortcuts.size());
|
||||
}
|
||||
|
||||
// Temporary list for {@link PackageItemInfos} to avoid having to go through
|
||||
// {@link mPackageItemInfos} to locate the key to be used for {@link #mWidgetsList}
|
||||
HashMap<String, PackageItemInfo> tmpPackageItemInfos = new HashMap<>();
|
||||
HashMap<PackageUserKey, PackageItemInfo> tmpPackageItemInfos = new HashMap<>();
|
||||
|
||||
// clear the lists.
|
||||
if (packageUser == null) {
|
||||
mWidgetsList.clear();
|
||||
} else {
|
||||
PackageItemInfo packageItem = mWidgetsList.keySet()
|
||||
.stream()
|
||||
.filter(item -> item.packageName.equals(packageUser.mPackageName))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (packageItem != null) {
|
||||
// We want to preserve the user that was on the packageItem previously,
|
||||
// so add it to tmpPackageItemInfos here to avoid creating a new entry.
|
||||
tmpPackageItemInfos.put(packageItem.packageName, packageItem);
|
||||
|
||||
// Add the widgets for other users in the rawList as it only contains widgets for
|
||||
// packageUser
|
||||
List<WidgetItem> otherUserItems = mWidgetsList.remove(packageItem);
|
||||
otherUserItems.removeIf(w -> w.user.equals(packageUser.mUser));
|
||||
rawWidgetsShortcuts.addAll(otherUserItems);
|
||||
}
|
||||
}
|
||||
|
||||
UserHandle myUser = Process.myUserHandle();
|
||||
|
||||
mWidgetsList.clear();
|
||||
// add and update.
|
||||
mWidgetsList.putAll(rawWidgetsShortcuts.stream()
|
||||
.filter(new WidgetValidityCheck(app))
|
||||
.collect(Collectors.groupingBy(item -> {
|
||||
String packageName = item.componentName.getPackageName();
|
||||
PackageItemInfo pInfo = tmpPackageItemInfos.get(packageName);
|
||||
PackageUserKey packageUserKey = new PackageUserKey(
|
||||
item.componentName.getPackageName(), item.user);
|
||||
PackageItemInfo pInfo = tmpPackageItemInfos.get(packageUserKey);
|
||||
if (pInfo == null) {
|
||||
pInfo = new PackageItemInfo(packageName);
|
||||
pInfo.user = item.user;
|
||||
tmpPackageItemInfos.put(packageName, pInfo);
|
||||
} else if (!myUser.equals(pInfo.user)) {
|
||||
// Keep updating the user, until we get the primary user.
|
||||
pInfo = new PackageItemInfo(packageUserKey.mPackageName);
|
||||
pInfo.user = item.user;
|
||||
tmpPackageItemInfos.put(packageUserKey, pInfo);
|
||||
}
|
||||
return pInfo;
|
||||
})));
|
||||
|
|
|
@ -153,7 +153,7 @@ public final class LauncherInstrumentation {
|
|||
private static final String WORKSPACE_RES_ID = "workspace";
|
||||
private static final String APPS_RES_ID = "apps_view";
|
||||
private static final String OVERVIEW_RES_ID = "overview_panel";
|
||||
private static final String WIDGETS_RES_ID = "widgets_list_view";
|
||||
private static final String WIDGETS_RES_ID = "primary_widgets_list_view";
|
||||
private static final String CONTEXT_MENU_RES_ID = "deep_shortcuts_container";
|
||||
public static final int WAIT_TIME_MS = 10000;
|
||||
public static final int LONG_WAIT_TIME_MS = 60000;
|
||||
|
|
Loading…
Reference in New Issue