Merge "Separating system and user-installed apps in PS container." into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
eaeb666e43
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (C) 2023 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.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="?attr/materialColorOutlineVariant"/>
|
||||
<size android:height="1dp" />
|
||||
</shape>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (C) 2024 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.
|
||||
-->
|
||||
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/private_space_divider"
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="@dimen/ps_app_divider_padding"
|
||||
android:paddingRight="@dimen/ps_app_divider_padding"
|
||||
android:src="@drawable/private_space_app_divider"
|
||||
android:scaleType="fitXY"
|
||||
android:focusable="false" />
|
||||
@@ -487,4 +487,5 @@
|
||||
<dimen name="ps_button_height">36dp</dimen>
|
||||
<dimen name="ps_button_width">36dp</dimen>
|
||||
<dimen name="ps_lock_button_width">89dp</dimen>
|
||||
<dimen name="ps_app_divider_padding">16dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.android.launcher3.views.ActivityContext;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.TreeMap;
|
||||
import java.util.function.Predicate;
|
||||
@@ -269,10 +270,10 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
|
||||
addApps = mWorkProviderManager.shouldShowWorkApps();
|
||||
}
|
||||
if (addApps) {
|
||||
addAppsWithSections(mApps, position);
|
||||
position = addAppsWithSections(mApps, position);
|
||||
}
|
||||
if (Flags.enablePrivateSpace()) {
|
||||
addPrivateSpaceItems(position);
|
||||
position = addPrivateSpaceItems(position);
|
||||
}
|
||||
}
|
||||
mAccessibilityResultsCount = (int) mAdapterItems.stream()
|
||||
@@ -287,7 +288,8 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
|
||||
for (AdapterItem item : mAdapterItems) {
|
||||
item.rowIndex = 0;
|
||||
if (BaseAllAppsAdapter.isDividerViewType(item.viewType)
|
||||
|| BaseAllAppsAdapter.isPrivateSpaceHeaderView(item.viewType)) {
|
||||
|| BaseAllAppsAdapter.isPrivateSpaceHeaderView(item.viewType)
|
||||
|| BaseAllAppsAdapter.isPrivateSpaceSysAppsDividerView(item.viewType)) {
|
||||
numAppsInSection = 0;
|
||||
} else if (BaseAllAppsAdapter.isIconViewType(item.viewType)) {
|
||||
if (numAppsInSection % mNumAppsPerRowAllApps == 0) {
|
||||
@@ -309,12 +311,12 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
|
||||
}
|
||||
}
|
||||
|
||||
void addPrivateSpaceItems(int position) {
|
||||
int addPrivateSpaceItems(int position) {
|
||||
if (mPrivateProviderManager != null
|
||||
&& !mPrivateProviderManager.isPrivateSpaceHidden()
|
||||
&& !mPrivateApps.isEmpty()) {
|
||||
// Always add PS Header if Space is present and visible.
|
||||
position += mPrivateProviderManager.addPrivateSpaceHeader(mAdapterItems);
|
||||
position = mPrivateProviderManager.addPrivateSpaceHeader(mAdapterItems);
|
||||
int privateSpaceState = mPrivateProviderManager.getCurrentState();
|
||||
switch (privateSpaceState) {
|
||||
case PrivateProfileManager.STATE_DISABLED:
|
||||
@@ -322,15 +324,37 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
|
||||
break;
|
||||
case PrivateProfileManager.STATE_ENABLED:
|
||||
// Add PS Apps only in Enabled State.
|
||||
mPrivateProviderManager.addPrivateSpaceInstallAppButton(mAdapterItems);
|
||||
position++;
|
||||
addAppsWithSections(mPrivateApps, position);
|
||||
position = addPrivateSpaceApps(position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
private void addAppsWithSections(List<AppInfo> appList, int startPosition) {
|
||||
private int addPrivateSpaceApps(int position) {
|
||||
// Add Install Apps Button first.
|
||||
if (Flags.privateSpaceAppInstallerButton()) {
|
||||
mPrivateProviderManager.addPrivateSpaceInstallAppButton(mAdapterItems);
|
||||
position++;
|
||||
}
|
||||
|
||||
// Split of private space apps into user-installed and system apps.
|
||||
Map<Boolean, List<AppInfo>> split = mPrivateApps.stream()
|
||||
.collect(Collectors.partitioningBy(mPrivateProviderManager
|
||||
.splitIntoUserInstalledAndSystemApps()));
|
||||
// Add user installed apps
|
||||
position = addAppsWithSections(split.get(true), position);
|
||||
// Add system apps separator.
|
||||
if (Flags.privateSpaceSysAppsSeparation()) {
|
||||
position = mPrivateProviderManager.addSystemAppsDivider(mAdapterItems);
|
||||
}
|
||||
// Add system apps.
|
||||
position = addAppsWithSections(split.get(false), position);
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
private int addAppsWithSections(List<AppInfo> appList, int startPosition) {
|
||||
String lastSectionName = null;
|
||||
boolean hasPrivateApps = false;
|
||||
if (mPrivateProviderManager != null) {
|
||||
@@ -357,6 +381,7 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
|
||||
}
|
||||
startPosition++;
|
||||
}
|
||||
return startPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.android.launcher3.allapps;
|
||||
|
||||
import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_BOTTOM_LEFT;
|
||||
import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_BOTTOM_RIGHT;
|
||||
import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_NOTHING;
|
||||
import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_TOP_LEFT;
|
||||
import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_TOP_RIGHT;
|
||||
import static com.android.launcher3.allapps.UserProfileManager.STATE_DISABLED;
|
||||
@@ -61,7 +62,8 @@ public abstract class BaseAllAppsAdapter<T extends Context & ActivityContext> ex
|
||||
public static final int VIEW_TYPE_WORK_EDU_CARD = 1 << 4;
|
||||
public static final int VIEW_TYPE_WORK_DISABLED_CARD = 1 << 5;
|
||||
public static final int VIEW_TYPE_PRIVATE_SPACE_HEADER = 1 << 6;
|
||||
public static final int NEXT_ID = 7;
|
||||
public static final int VIEW_TYPE_PRIVATE_SPACE_SYS_APPS_DIVIDER = 1 << 7;
|
||||
public static final int NEXT_ID = 8;
|
||||
|
||||
// Common view type masks
|
||||
public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_ALL_APPS_DIVIDER;
|
||||
@@ -69,6 +71,8 @@ public abstract class BaseAllAppsAdapter<T extends Context & ActivityContext> ex
|
||||
|
||||
public static final int VIEW_TYPE_MASK_PRIVATE_SPACE_HEADER =
|
||||
VIEW_TYPE_PRIVATE_SPACE_HEADER;
|
||||
public static final int VIEW_TYPE_MASK_PRIVATE_SPACE_SYS_APPS_DIVIDER =
|
||||
VIEW_TYPE_PRIVATE_SPACE_SYS_APPS_DIVIDER;
|
||||
|
||||
protected final SearchAdapterProvider<?> mAdapterProvider;
|
||||
|
||||
@@ -199,6 +203,11 @@ public abstract class BaseAllAppsAdapter<T extends Context & ActivityContext> ex
|
||||
return isViewType(viewType, VIEW_TYPE_MASK_PRIVATE_SPACE_HEADER);
|
||||
}
|
||||
|
||||
/** Checks if the passed viewType represents private space system apps divider. */
|
||||
public static boolean isPrivateSpaceSysAppsDividerView(int viewType) {
|
||||
return isViewType(viewType, VIEW_TYPE_MASK_PRIVATE_SPACE_SYS_APPS_DIVIDER);
|
||||
}
|
||||
|
||||
public void setIconFocusListener(OnFocusChangeListener focusListener) {
|
||||
mIconFocusListener = focusListener;
|
||||
}
|
||||
@@ -227,9 +236,9 @@ public abstract class BaseAllAppsAdapter<T extends Context & ActivityContext> ex
|
||||
case VIEW_TYPE_EMPTY_SEARCH:
|
||||
return new ViewHolder(mLayoutInflater.inflate(R.layout.all_apps_empty_search,
|
||||
parent, false));
|
||||
case VIEW_TYPE_ALL_APPS_DIVIDER:
|
||||
case VIEW_TYPE_ALL_APPS_DIVIDER, VIEW_TYPE_PRIVATE_SPACE_SYS_APPS_DIVIDER:
|
||||
return new ViewHolder(mLayoutInflater.inflate(
|
||||
R.layout.all_apps_divider, parent, false));
|
||||
R.layout.private_space_divider, parent, false));
|
||||
case VIEW_TYPE_WORK_EDU_CARD:
|
||||
return new ViewHolder(mLayoutInflater.inflate(
|
||||
R.layout.work_apps_edu, parent, false));
|
||||
@@ -282,6 +291,11 @@ public abstract class BaseAllAppsAdapter<T extends Context & ActivityContext> ex
|
||||
new SectionDecorationInfo(mActivityContext, roundRegions,
|
||||
false /* decorateTogether */);
|
||||
break;
|
||||
case VIEW_TYPE_PRIVATE_SPACE_SYS_APPS_DIVIDER:
|
||||
adapterItem = mApps.getAdapterItems().get(position);
|
||||
adapterItem.decorationInfo = new SectionDecorationInfo(mActivityContext,
|
||||
ROUND_NOTHING, true /* decorateTogether */);
|
||||
break;
|
||||
case VIEW_TYPE_ALL_APPS_DIVIDER:
|
||||
case VIEW_TYPE_WORK_DISABLED_CARD:
|
||||
// nothing to do
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.launcher3.allapps;
|
||||
import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.MAIN;
|
||||
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_ICON;
|
||||
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_PRIVATE_SPACE_HEADER;
|
||||
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_PRIVATE_SPACE_SYS_APPS_DIVIDER;
|
||||
import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_NOTHING;
|
||||
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED;
|
||||
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_PRIVATE_SPACE_INSTALL_APP;
|
||||
@@ -45,10 +46,11 @@ import com.android.launcher3.pm.UserCache;
|
||||
import com.android.launcher3.uioverrides.ApiWrapper;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.launcher3.util.SettingsCache;
|
||||
import com.android.launcher3.util.UserIconInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
@@ -62,6 +64,8 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
private static final String PS_SETTINGS_FRAGMENT_VALUE = "AndroidPrivateSpace_personal";
|
||||
private final ActivityAllAppsContainerView<?> mAllApps;
|
||||
private final Predicate<UserHandle> mPrivateProfileMatcher;
|
||||
private Set<String> mPreInstalledSystemPackages = new HashSet<>();
|
||||
private Intent mAppInstallerIntent = new Intent();
|
||||
private PrivateAppsSectionDecorator mPrivateAppsSectionDecorator;
|
||||
private boolean mPrivateSpaceSettingsAvailable;
|
||||
private Runnable mUnlockRunnable;
|
||||
@@ -73,7 +77,7 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
super(userManager, statsLogManager, userCache);
|
||||
mAllApps = allApps;
|
||||
mPrivateProfileMatcher = (user) -> userCache.getUserInfo(user).isPrivate();
|
||||
UI_HELPER_EXECUTOR.post(this::setPrivateSpaceSettingsAvailable);
|
||||
UI_HELPER_EXECUTOR.post(this::initializeInBackgroundThread);
|
||||
}
|
||||
|
||||
/** Adds Private Space Header to the layout. */
|
||||
@@ -83,18 +87,17 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
return adapterItems.size();
|
||||
}
|
||||
|
||||
/** Adds Private Space System Apps Divider to the layout. */
|
||||
public int addSystemAppsDivider(List<BaseAllAppsAdapter.AdapterItem> adapterItems) {
|
||||
adapterItems.add(new BaseAllAppsAdapter
|
||||
.AdapterItem(VIEW_TYPE_PRIVATE_SPACE_SYS_APPS_DIVIDER));
|
||||
mAllApps.mAH.get(MAIN).mAdapter.notifyItemInserted(adapterItems.size() - 1);
|
||||
return adapterItems.size();
|
||||
}
|
||||
|
||||
/** Adds Private Space install app button to the layout. */
|
||||
public void addPrivateSpaceInstallAppButton(List<BaseAllAppsAdapter.AdapterItem> adapterItems) {
|
||||
Context context = mAllApps.getContext();
|
||||
// Prepare intent
|
||||
UserCache userCache = UserCache.getInstance(context);
|
||||
UserHandle userHandle = userCache.getUserProfiles().stream()
|
||||
.filter(user -> userCache.getUserInfo(user).type == UserIconInfo.TYPE_PRIVATE)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
Intent intent = ApiWrapper.getAppMarketActivityIntent(context,
|
||||
BuildConfig.APPLICATION_ID, userHandle);
|
||||
|
||||
// Prepare bitmapInfo
|
||||
Intent.ShortcutIconResource shortcut = Intent.ShortcutIconResource.fromContext(
|
||||
context, com.android.launcher3.R.drawable.private_space_install_app_icon);
|
||||
@@ -102,7 +105,7 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
|
||||
AppInfo itemInfo = new AppInfo();
|
||||
itemInfo.title = context.getResources().getString(R.string.ps_add_button_label);
|
||||
itemInfo.intent = intent;
|
||||
itemInfo.intent = mAppInstallerIntent;
|
||||
itemInfo.bitmap = bitmapInfo;
|
||||
itemInfo.contentDescription = context.getResources().getString(
|
||||
com.android.launcher3.R.string.ps_add_button_content_description);
|
||||
@@ -166,6 +169,22 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
return mPrivateSpaceSettingsAvailable;
|
||||
}
|
||||
|
||||
/** Initializes binder call based properties in non-main thread.
|
||||
* <p>
|
||||
* This can cause the Private Space container items to not load/respond correctly sometimes,
|
||||
* when the All Apps Container loads for the first time (device restarts, new profiles
|
||||
* added/removed, etc.), as the properties are being set in non-ui thread whereas the container
|
||||
* loads in the ui thread.
|
||||
* This case should still be ok, as locking the Private Space container and unlocking it,
|
||||
* reloads the values, fixing the incorrect UI.
|
||||
*/
|
||||
private void initializeInBackgroundThread() {
|
||||
Preconditions.assertNonUiThread();
|
||||
setPreInstalledSystemPackages();
|
||||
setAppInstallerIntent();
|
||||
setPrivateSpaceSettingsAvailable();
|
||||
}
|
||||
|
||||
private void setPrivateSpaceSettingsAvailable() {
|
||||
if (mPrivateSpaceSettingsAvailable) {
|
||||
return;
|
||||
@@ -178,6 +197,22 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
mPrivateSpaceSettingsAvailable = resolveInfo != null;
|
||||
}
|
||||
|
||||
private void setPreInstalledSystemPackages() {
|
||||
Preconditions.assertNonUiThread();
|
||||
if (getProfileUser() != null) {
|
||||
mPreInstalledSystemPackages = new HashSet<>(ApiWrapper
|
||||
.getPreInstalledSystemPackages(mAllApps.getContext(), getProfileUser()));
|
||||
}
|
||||
}
|
||||
|
||||
private void setAppInstallerIntent() {
|
||||
Preconditions.assertNonUiThread();
|
||||
if (getProfileUser() != null) {
|
||||
mAppInstallerIntent = ApiWrapper.getAppMarketActivityIntent(mAllApps.getContext(),
|
||||
BuildConfig.APPLICATION_ID, getProfileUser());
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void resetPrivateSpaceDecorator(int updatedState) {
|
||||
ActivityAllAppsContainerView<?>.AdapterHolder mainAdapterHolder = mAllApps.mAH.get(MAIN);
|
||||
@@ -225,4 +260,14 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
public Predicate<UserHandle> getUserMatcher() {
|
||||
return mPrivateProfileMatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits private apps into user installed and system apps.
|
||||
* When the list of system apps is empty, all apps are treated as system.
|
||||
*/
|
||||
public Predicate<AppInfo> splitIntoUserInstalledAndSystemApps() {
|
||||
return appInfo -> !mPreInstalledSystemPackages.isEmpty()
|
||||
&& (appInfo.componentName == null
|
||||
|| !(mPreInstalledSystemPackages.contains(appInfo.componentName.getPackageName())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.launcher3.allapps;
|
||||
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
|
||||
|
||||
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_PRIVATE_SPACE_HEADER;
|
||||
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_PRIVATE_SPACE_SYS_APPS_DIVIDER;
|
||||
import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_BOTTOM_LEFT;
|
||||
import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_BOTTOM_RIGHT;
|
||||
import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_NOTHING;
|
||||
@@ -63,9 +64,10 @@ public class AlphabeticalAppsListTest {
|
||||
|
||||
private static final int PRIVATE_SPACE_HEADER_ITEM_COUNT = 1;
|
||||
private static final int MAIN_USER_APP_COUNT = 2;
|
||||
private static final int PRIVATE_USER_APP_COUNT = 1;
|
||||
private static final int PRIVATE_USER_APP_COUNT = 2;
|
||||
private static final int NUM_APP_COLS = 4;
|
||||
private static final int NUM_APP_ROWS = 3;
|
||||
private static final int PRIVATE_SPACE_SYS_APP_SEPARATOR_ITEM_COUNT = 1;
|
||||
|
||||
private AlphabeticalAppsList<?> mAlphabeticalAppsList;
|
||||
@Mock
|
||||
@@ -96,6 +98,10 @@ public class AlphabeticalAppsListTest {
|
||||
when(mPrivateProfileManager.addPrivateSpaceHeader(any()))
|
||||
.thenAnswer(answer(this::addPrivateSpaceHeader));
|
||||
when(mPrivateProfileManager.getCurrentState()).thenReturn(STATE_ENABLED);
|
||||
when(mPrivateProfileManager.splitIntoUserInstalledAndSystemApps())
|
||||
.thenReturn(iteminfo -> iteminfo.componentName == null
|
||||
|| !iteminfo.componentName.getPackageName()
|
||||
.equals("com.android.launcher3.tests.camera"));
|
||||
|
||||
mAlphabeticalAppsList.updateItemFilter(info -> info != null
|
||||
&& info.user.equals(MAIN_HANDLE));
|
||||
@@ -111,6 +117,44 @@ public class AlphabeticalAppsListTest {
|
||||
&& item.itemInfo.user.equals(PRIVATE_HANDLE)).toList().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void privateProfileEnabled_privateProfileAppsShownWithSeparator() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_PRIVATE_SPACE);
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_PRIVATE_SPACE_SYS_APPS_SEPARATION);
|
||||
when(mAllAppsStore.getApps()).thenReturn(createAppInfoListForMainAndPrivateUser());
|
||||
when(mPrivateProfileManager.addPrivateSpaceHeader(any()))
|
||||
.thenAnswer(answer(this::addPrivateSpaceHeader));
|
||||
when(mPrivateProfileManager.addSystemAppsDivider(any()))
|
||||
.thenAnswer(answer(this::addSystemAppsDivider));
|
||||
when(mPrivateProfileManager.getCurrentState()).thenReturn(STATE_ENABLED);
|
||||
when(mPrivateProfileManager.splitIntoUserInstalledAndSystemApps())
|
||||
.thenReturn(iteminfo -> iteminfo.componentName == null
|
||||
|| !iteminfo.componentName.getPackageName()
|
||||
.equals("com.android.launcher3.tests.camera"));
|
||||
|
||||
mAlphabeticalAppsList.updateItemFilter(info -> info != null
|
||||
&& info.user.equals(MAIN_HANDLE));
|
||||
|
||||
assertEquals(MAIN_USER_APP_COUNT + PRIVATE_SPACE_HEADER_ITEM_COUNT
|
||||
+ PRIVATE_SPACE_SYS_APP_SEPARATOR_ITEM_COUNT
|
||||
+ PRIVATE_USER_APP_COUNT, mAlphabeticalAppsList.getAdapterItems().size());
|
||||
assertEquals(PRIVATE_SPACE_HEADER_ITEM_COUNT,
|
||||
mAlphabeticalAppsList.getAdapterItems().stream().filter(item ->
|
||||
item.viewType == VIEW_TYPE_PRIVATE_SPACE_HEADER).toList().size());
|
||||
assertEquals(PRIVATE_SPACE_SYS_APP_SEPARATOR_ITEM_COUNT,
|
||||
mAlphabeticalAppsList.getAdapterItems().stream().filter(item ->
|
||||
item.viewType == VIEW_TYPE_PRIVATE_SPACE_SYS_APPS_DIVIDER).toList().size());
|
||||
List<BaseAllAppsAdapter.AdapterItem> psApps = mAlphabeticalAppsList.getAdapterItems()
|
||||
.stream()
|
||||
.filter(item -> item.itemInfo != null && item.itemInfo.user.equals(PRIVATE_HANDLE))
|
||||
.toList();
|
||||
assertEquals(PRIVATE_USER_APP_COUNT, psApps.size());
|
||||
assert psApps.get(0).itemInfo.title != null;
|
||||
assertEquals("Private Messenger", psApps.get(0).itemInfo.title.toString());
|
||||
assert psApps.get(1).itemInfo.title != null;
|
||||
assertEquals("Private Camera", psApps.get(1).itemInfo.title.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void privateProfileDisabled_onlyPrivateProfileHeaderViewIsPresent() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_PRIVATE_SPACE);
|
||||
@@ -281,6 +325,12 @@ public class AlphabeticalAppsListTest {
|
||||
return adapterItemList.size();
|
||||
}
|
||||
|
||||
private int addSystemAppsDivider(List<BaseAllAppsAdapter.AdapterItem> adapterItemList) {
|
||||
adapterItemList.add(new BaseAllAppsAdapter
|
||||
.AdapterItem(VIEW_TYPE_PRIVATE_SPACE_SYS_APPS_DIVIDER));
|
||||
return adapterItemList.size();
|
||||
}
|
||||
|
||||
private AppInfo[] createAppInfoListForMainUser() {
|
||||
ComponentName gmailComponentName = new ComponentName(mContext,
|
||||
"com.android.launcher3.tests.Activity" + "Gmail");
|
||||
@@ -298,7 +348,11 @@ public class AlphabeticalAppsListTest {
|
||||
"com.android.launcher3.tests.Activity" + "PrivateMessenger");
|
||||
AppInfo privateMessengerAppInfo = new AppInfo(privateMessengercomponentName,
|
||||
"Private Messenger", PRIVATE_HANDLE, new Intent());
|
||||
return new AppInfo[]{privateMessengerAppInfo};
|
||||
ComponentName privateCameraComponentName = new ComponentName(
|
||||
"com.android.launcher3.tests.camera", "CameraActivity");
|
||||
AppInfo privateCameraAppInfo = new AppInfo(privateCameraComponentName,
|
||||
"Private Camera", PRIVATE_HANDLE, new Intent());
|
||||
return new AppInfo[]{privateMessengerAppInfo, privateCameraAppInfo};
|
||||
}
|
||||
|
||||
private AppInfo[] createAppInfoListForMainAndPrivateUser() {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.launcher3.allapps;
|
||||
|
||||
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
|
||||
|
||||
import static com.android.launcher3.allapps.UserProfileManager.STATE_DISABLED;
|
||||
import static com.android.launcher3.allapps.UserProfileManager.STATE_ENABLED;
|
||||
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED;
|
||||
@@ -31,8 +33,10 @@ import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Process;
|
||||
@@ -43,6 +47,7 @@ import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.pm.UserCache;
|
||||
import com.android.launcher3.util.ActivityContextWrapper;
|
||||
import com.android.launcher3.util.UserIconInfo;
|
||||
import com.android.launcher3.util.rule.TestStabilityRule;
|
||||
|
||||
@@ -56,6 +61,7 @@ import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@@ -89,6 +95,8 @@ public class PrivateProfileManagerTest {
|
||||
private AllAppsStore mAllAppsStore;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private LauncherApps mLauncherApps;
|
||||
|
||||
private boolean mRunnableCalled = false;
|
||||
|
||||
@@ -103,6 +111,13 @@ public class PrivateProfileManagerTest {
|
||||
when(mActivityAllAppsContainerView.getAppsStore()).thenReturn(mAllAppsStore);
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
when(mPackageManager.resolveActivity(any(), any())).thenReturn(new ResolveInfo());
|
||||
when(mContext.getSystemService(LauncherApps.class)).thenReturn(mLauncherApps);
|
||||
when(mLauncherApps.getAppMarketActivityIntent(any(), any())).thenReturn(PendingIntent
|
||||
.getActivity(new ActivityContextWrapper(getApplicationContext()), 0,
|
||||
new Intent(), PendingIntent.FLAG_IMMUTABLE).getIntentSender());
|
||||
when(mContext.getPackageName())
|
||||
.thenReturn("com.android.launcher3.tests.privateProfileManager");
|
||||
when(mLauncherApps.getPreInstalledSystemPackages(any())).thenReturn(new ArrayList<>());
|
||||
mPrivateProfileManager = new PrivateProfileManager(mUserManager,
|
||||
mActivityAllAppsContainerView, mStatsLogManager, mUserCache);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user