From 97b1bba413cc015d464fc7ea5fb7268050e34d29 Mon Sep 17 00:00:00 2001 From: Holly Sun Date: Mon, 18 Dec 2023 16:02:44 -0800 Subject: [PATCH] Implement Install Apps button in Private Space. UX mock: https://www.figma.com/file/K6bIIcG882EiJNjxvSWsFT/V%E2%80%A2-Private-Space?node-id=7246%3A83750&mode=dev UX icon spec: https://www.figma.com/file/K6bIIcG882EiJNjxvSWsFT/V%E2%80%A2-Private-Space?type=design&node-id=19979-224329&mode=design&t=50SDFdomAtonNU4V-0 Video: https://drive.google.com/file/d/1VtTzxR46dLiaozOo6sOHADv1qTcBOwDP/view?usp=sharing Screenshot: https://screenshot.googleplex.com/3ShcUozVrkGMHbc https://screenshot.googleplex.com/3F4c3yzJ7RUpma7 Reason to use PrivateSpaceInstallAppButtonInfo: reuse `VIEW_TYPE_ICON`, which needs an AppInfo. Bug: 308064949 Test: manual Flag: ACONFIG com.android.launcher3.private_space_app_installer_button development Change-Id: I3fb27fae8324d4b276816b17f9b0a2d9b6f33ed2 --- .../private_space_install_app_icon.xml | 31 +++++++++++++ res/values/strings.xml | 4 ++ .../allapps/AlphabeticalAppsList.java | 2 + .../allapps/PrivateProfileManager.java | 44 +++++++++++++++++++ .../android/launcher3/model/data/AppInfo.java | 3 +- 5 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 res/drawable/private_space_install_app_icon.xml diff --git a/res/drawable/private_space_install_app_icon.xml b/res/drawable/private_space_install_app_icon.xml new file mode 100644 index 0000000000..4c167ba841 --- /dev/null +++ b/res/drawable/private_space_install_app_icon.xml @@ -0,0 +1,31 @@ + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 6a4a9a4e49..956d24daa2 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -461,6 +461,10 @@ Lock/Unlock Private Space Private Space Transitioning + + Install apps + + Install apps to Private Space diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java index 3e55f610a1..35c07c3e77 100644 --- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java +++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java @@ -322,6 +322,8 @@ public class AlphabeticalAppsList implement break; case PrivateProfileManager.STATE_ENABLED: // Add PS Apps only in Enabled State. + mPrivateProviderManager.addPrivateSpaceInstallAppButton(mAdapterItems); + position++; addAppsWithSections(mPrivateApps, position); if (mActivityContext.getAppsView() != null) { mActivityContext.getAppsView().getActiveRecyclerView() diff --git a/src/com/android/launcher3/allapps/PrivateProfileManager.java b/src/com/android/launcher3/allapps/PrivateProfileManager.java index 693681bd1d..c99b69fce2 100644 --- a/src/com/android/launcher3/allapps/PrivateProfileManager.java +++ b/src/com/android/launcher3/allapps/PrivateProfileManager.java @@ -17,11 +17,14 @@ 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.SectionDecorationInfo.ROUND_NOTHING; import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.launcher3.util.SettingsCache.PRIVATE_SPACE_HIDE_WHEN_LOCKED_URI; +import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; @@ -30,13 +33,21 @@ import android.os.UserManager; import androidx.annotation.VisibleForTesting; +import com.android.launcher3.BuildConfig; import com.android.launcher3.Flags; +import com.android.launcher3.R; +import com.android.launcher3.icons.BitmapInfo; +import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.logging.StatsLogManager; +import com.android.launcher3.model.data.AppInfo; 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.List; import java.util.function.Predicate; /** @@ -71,6 +82,39 @@ public class PrivateProfileManager extends UserProfileManager { return adapterItems.size(); } + /** Adds Private Space install app button to the layout. */ + public void addPrivateSpaceInstallAppButton(List 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); + BitmapInfo bitmapInfo = LauncherIcons.obtain(context).createIconBitmap(shortcut); + + AppInfo itemInfo = new AppInfo(); + itemInfo.title = context.getResources().getString(R.string.ps_add_button_label); + itemInfo.intent = intent; + itemInfo.bitmap = bitmapInfo; + itemInfo.contentDescription = context.getResources().getString( + com.android.launcher3.R.string.ps_add_button_content_description); + + BaseAllAppsAdapter.AdapterItem item = new BaseAllAppsAdapter.AdapterItem(VIEW_TYPE_ICON); + item.itemInfo = itemInfo; + item.decorationInfo = new SectionDecorationInfo(context, ROUND_NOTHING, + /* decorateTogether */ true); + + adapterItems.add(item); + mAllApps.mAH.get(MAIN).mAdapter.notifyItemInserted(adapterItems.size() - 1); + } + /** Disables quiet mode for Private Space User Profile. */ public void unlockPrivateProfile() { enableQuietMode(false); diff --git a/src/com/android/launcher3/model/data/AppInfo.java b/src/com/android/launcher3/model/data/AppInfo.java index 872ce4bdba..ea8a7a11bc 100644 --- a/src/com/android/launcher3/model/data/AppInfo.java +++ b/src/com/android/launcher3/model/data/AppInfo.java @@ -55,7 +55,8 @@ public class AppInfo extends ItemInfoWithIcon implements WorkspaceItemFactory { */ public Intent intent; - @NonNull + // componentName for the Private Space Install App button can be null + @Nullable public ComponentName componentName; // Section name used for indexing.