Enabling Private Space Container in Launcher.

This CL adds the following:
1. Adds filtering and addition of Private Profile apps in main user
all apps recycler view
2. Enables decoration of Private Profile apps
3. Enables hiding Private Space container based upon a settings entry.

Flag: ACONFIG com.android.launcher3.Flags.enable_private_space DEVELOPMENT
Bug: 289223923
Test: Ran Launcher3 tests
Change-Id: I33dc55a3a39e75d3fc336ca6a488b282e2dd322c
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 34bfdb7..9a19526 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -25,6 +25,7 @@
 import static com.android.launcher3.model.LoaderTask.SMARTSPACE_ON_HOME_SCREEN;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
+import static com.android.launcher3.util.SettingsCache.PRIVATE_SPACE_HIDE_WHEN_LOCKED_URI;
 
 import android.content.ComponentName;
 import android.content.Context;
@@ -166,6 +167,8 @@
         onNotificationSettingsChanged(settingsCache.getValue(NOTIFICATION_BADGING_URI));
         mOnTerminateCallback.add(() ->
                 settingsCache.unregister(NOTIFICATION_BADGING_URI, notificationLister));
+        // Register an observer to notify Launcher about Private Space settings toggle.
+        registerPrivateSpaceHideWhenLockListener(settingsCache);
     }
 
     public LauncherAppState(Context context, @Nullable String iconCacheFileName) {
@@ -188,6 +191,18 @@
         }
     }
 
+    private void registerPrivateSpaceHideWhenLockListener(SettingsCache settingsCache) {
+        SettingsCache.OnChangeListener psHideWhenLockChangedListener =
+                this::onPrivateSpaceHideWhenLockChanged;
+        settingsCache.register(PRIVATE_SPACE_HIDE_WHEN_LOCKED_URI, psHideWhenLockChangedListener);
+        mOnTerminateCallback.add(() -> settingsCache.unregister(PRIVATE_SPACE_HIDE_WHEN_LOCKED_URI,
+                psHideWhenLockChangedListener));
+    }
+
+    private void onPrivateSpaceHideWhenLockChanged(boolean isPrivateSpaceHideOnLockEnabled) {
+        mModel.forceReload();
+    }
+
     private void refreshAndReloadLauncher() {
         LauncherIcons.clearPool();
         mIconCache.updateIconParams(
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 7d52cbb..bd3740c 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -16,6 +16,7 @@
 package com.android.launcher3.allapps;
 
 import static com.android.launcher3.Flags.enableExpandingPauseWorkButton;
+import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.MAIN;
 import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.SEARCH;
 import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_DISABLED_CARD;
 import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_EDU_CARD;
@@ -69,6 +70,7 @@
 import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
 import com.android.launcher3.DragSource;
 import com.android.launcher3.DropTarget.DragObject;
+import com.android.launcher3.Flags;
 import com.android.launcher3.Insettable;
 import com.android.launcher3.InsettableFrameLayout;
 import com.android.launcher3.R;
@@ -95,6 +97,7 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 /**
  * All apps container view with search support for use in a dragging activity.
@@ -133,6 +136,7 @@
     protected final Predicate<ItemInfo> mPersonalMatcher = ItemInfoMatcher.ofUser(
             Process.myUserHandle());
     protected WorkProfileManager mWorkManager;
+    protected final PrivateProfileManager mPrivateProfileManager;
     protected final Point mFastScrollerOffset = new Point();
     protected final int mScrimColor;
     protected final float mHeaderThreshold;
@@ -175,6 +179,7 @@
     protected SearchAdapterProvider<?> mMainAdapterProvider;
     private View mBottomSheetHandleArea;
     private boolean mHasWorkApps;
+    private boolean mHasPrivateApps;
     private float[] mBottomSheetCornerRadii;
     private ScrimView mScrimView;
     private int mHeaderColor;
@@ -184,6 +189,8 @@
     private int mTabsProtectionAlpha;
     @Nullable private AllAppsTransitionController mAllAppsTransitionController;
 
+    private PrivateSpaceHeaderViewController mPrivateSpaceHeaderViewController;
+
     public ActivityAllAppsContainerView(Context context) {
         this(context, null);
     }
@@ -207,6 +214,11 @@
                 this,
                 mActivityContext.getStatsLogManager(),
                 UserCache.INSTANCE.get(mActivityContext));
+        mPrivateProfileManager = new PrivateProfileManager(
+                mActivityContext.getSystemService(UserManager.class),
+                this,
+                mActivityContext.getStatsLogManager(),
+                UserCache.INSTANCE.get(mActivityContext));
         mAH = Arrays.asList(null, null, null);
         mNavBarScrimPaint = new Paint();
         mNavBarScrimPaint.setColor(Themes.getNavBarScrimColor(mActivityContext));
@@ -246,13 +258,20 @@
      */
     protected void initContent() {
         mMainAdapterProvider = mSearchUiDelegate.createMainAdapterProvider();
+        if (Flags.enablePrivateSpace()) {
+            mPrivateSpaceHeaderViewController =
+                    new PrivateSpaceHeaderViewController(mPrivateProfileManager);
+        }
 
         mAH.set(AdapterHolder.MAIN, new AdapterHolder(AdapterHolder.MAIN,
-                new AlphabeticalAppsList<>(mActivityContext, mAllAppsStore, null)));
+                new AlphabeticalAppsList<>(mActivityContext,
+                        mAllAppsStore,
+                        null,
+                        mPrivateProfileManager)));
         mAH.set(AdapterHolder.WORK, new AdapterHolder(AdapterHolder.WORK,
-                new AlphabeticalAppsList<>(mActivityContext, mAllAppsStore, mWorkManager)));
+                new AlphabeticalAppsList<>(mActivityContext, mAllAppsStore, mWorkManager, null)));
         mAH.set(SEARCH, new AdapterHolder(SEARCH,
-                new AlphabeticalAppsList<>(mActivityContext, null, null)));
+                new AlphabeticalAppsList<>(mActivityContext, null, null, null)));
 
         getLayoutInflater().inflate(R.layout.all_apps_content, this);
         mHeader = findViewById(R.id.all_apps_header);
@@ -592,7 +611,7 @@
         } else {
             mainRecyclerView = findViewById(R.id.apps_list_view);
             workRecyclerView = null;
-            mAH.get(AdapterHolder.MAIN).setup(mainRecyclerView, null);
+            mAH.get(AdapterHolder.MAIN).setup(mainRecyclerView, mPersonalMatcher);
             mAH.get(AdapterHolder.WORK).mRecyclerView = null;
         }
         setUpCustomRecyclerViewPool(
@@ -860,7 +879,7 @@
 
     protected BaseAllAppsAdapter<T> createAdapter(AlphabeticalAppsList<T> appsList) {
         return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), appsList,
-                mMainAdapterProvider);
+                mMainAdapterProvider, mPrivateSpaceHeaderViewController);
     }
 
     // TODO(b/216683257): Remove when Taskbar All Apps supports search.
@@ -973,13 +992,19 @@
 
     @VisibleForTesting
     public void onAppsUpdated() {
-        mHasWorkApps = mWorkManager.hasWorkApps();
+        mHasWorkApps = Stream.of(mAllAppsStore.getApps())
+                .anyMatch(mWorkManager.getItemInfoMatcher());
+        mHasPrivateApps = Stream.of(mAllAppsStore.getApps())
+                .anyMatch(mPrivateProfileManager.getItemInfoMatcher());
         if (!isSearching()) {
             rebindAdapters();
         }
         if (mHasWorkApps) {
             mWorkManager.reset();
         }
+        if (mHasPrivateApps) {
+            mPrivateProfileManager.reset();
+        }
 
         mActivityContext.getStatsLogManager().logger()
                 .withCardinality(mAllAppsStore.getApps().length)
@@ -1245,6 +1270,10 @@
         return mAH.get(SEARCH).mAppsList;
     }
 
+    public AlphabeticalAppsList<T> getPersonalAppList() {
+        return mAH.get(MAIN).mAppsList;
+    }
+
     public FloatingHeaderView getFloatingHeaderView() {
         return mHeader;
     }
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index df383bf..5f002b5 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -73,8 +73,9 @@
 
 
     public AllAppsGridAdapter(T activityContext, LayoutInflater inflater,
-            AlphabeticalAppsList apps, SearchAdapterProvider<?> adapterProvider) {
-        super(activityContext, inflater, apps, adapterProvider);
+            AlphabeticalAppsList apps, SearchAdapterProvider<?> adapterProvider,
+            PrivateSpaceHeaderViewController privateSpaceHeaderViewController) {
+        super(activityContext, inflater, apps, adapterProvider, privateSpaceHeaderViewController);
         mGridLayoutMgr = new AppsGridLayoutManager(mActivityContext);
         mGridLayoutMgr.setSpanSizeLookup(new GridSpanSizer());
         setAppsPerRow(activityContext.getDeviceProfile().numShownAllAppsColumns);
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index ee4b5bc..328516e 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -20,6 +20,7 @@
 import androidx.annotation.Nullable;
 import androidx.recyclerview.widget.DiffUtil;
 
+import com.android.launcher3.Flags;
 import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.model.data.ItemInfo;
@@ -47,6 +48,8 @@
 
     private final WorkProfileManager mWorkProviderManager;
 
+    private final PrivateProfileManager mPrivateProviderManager;
+
     /**
      * Info about a fast scroller section, depending if sections are merged, the fast scroller
      * sections will not be the same set as the section headers.
@@ -68,6 +71,7 @@
 
     // The set of apps from the system
     private final List<AppInfo> mApps = new ArrayList<>();
+    private final List<AppInfo> mPrivateApps = new ArrayList<>();
     @Nullable
     private final AllAppsStore<T> mAllAppsStore;
 
@@ -87,11 +91,12 @@
     private Predicate<ItemInfo> mItemFilter;
 
     public AlphabeticalAppsList(Context context, @Nullable AllAppsStore<T> appsStore,
-            WorkProfileManager workProfileManager) {
+            WorkProfileManager workProfileManager, PrivateProfileManager privateProfileManager) {
         mAllAppsStore = appsStore;
         mActivityContext = ActivityContext.lookupContext(context);
         mAppNameComparator = new AppInfoComparator(context);
         mWorkProviderManager = workProfileManager;
+        mPrivateProviderManager = privateProfileManager;
         mNumAppsPerRowAllApps = mActivityContext.getDeviceProfile().numShownAllAppsColumns;
         if (mAllAppsStore != null) {
             mAllAppsStore.addUpdateListener(this);
@@ -197,12 +202,20 @@
         }
         // Sort the list of apps
         mApps.clear();
+        mPrivateApps.clear();
 
         Stream<AppInfo> appSteam = Stream.of(mAllAppsStore.getApps());
+        Stream<AppInfo> privateAppStream = Stream.of(mAllAppsStore.getApps());
+
         if (!hasSearchResults() && mItemFilter != null) {
             appSteam = appSteam.filter(mItemFilter);
+            if (mPrivateProviderManager != null) {
+                privateAppStream = privateAppStream
+                        .filter(mPrivateProviderManager.getItemInfoMatcher());
+            }
         }
         appSteam = appSteam.sorted(mAppNameComparator);
+        privateAppStream = privateAppStream.sorted(mAppNameComparator);
 
         // As a special case for some languages (currently only Simplified Chinese), we may need to
         // coalesce sections
@@ -221,6 +234,7 @@
         }
 
         appSteam.forEachOrdered(mApps::add);
+        privateAppStream.forEachOrdered(mPrivateApps::add);
         // Recompose the set of adapter items from the current set of apps
         if (mSearchResults.isEmpty()) {
             updateAdapterItems();
@@ -250,18 +264,10 @@
                 addApps = mWorkProviderManager.shouldShowWorkApps();
             }
             if (addApps) {
-                String lastSectionName = null;
-                for (AppInfo info : mApps) {
-                    mAdapterItems.add(AdapterItem.asApp(info));
-
-                    String sectionName = info.sectionName;
-                    // Create a new section if the section names do not match
-                    if (!sectionName.equals(lastSectionName)) {
-                        lastSectionName = sectionName;
-                        mFastScrollerSections.add(new FastScrollSectionInfo(sectionName, position));
-                    }
-                    position++;
-                }
+                addAppsWithSections(mApps, position);
+            }
+            if (Flags.enablePrivateSpace()) {
+                addPrivateSpaceItems(position);
             }
         }
         mAccessibilityResultsCount = (int) mAdapterItems.stream()
@@ -275,7 +281,8 @@
             int rowIndex = -1;
             for (AdapterItem item : mAdapterItems) {
                 item.rowIndex = 0;
-                if (BaseAllAppsAdapter.isDividerViewType(item.viewType)) {
+                if (BaseAllAppsAdapter.isDividerViewType(item.viewType)
+                        || BaseAllAppsAdapter.isPrivateSpaceHeaderView(item.viewType)) {
                     numAppsInSection = 0;
                 } else if (BaseAllAppsAdapter.isIconViewType(item.viewType)) {
                     if (numAppsInSection % mNumAppsPerRowAllApps == 0) {
@@ -297,6 +304,40 @@
         }
     }
 
+    void addPrivateSpaceItems(int position) {
+        if (mPrivateProviderManager != null
+                && !mPrivateProviderManager.isPrivateSpaceHidden()
+                && !mPrivateApps.isEmpty()) {
+            // Always add PS Header if Space is present and visible.
+            position += mPrivateProviderManager.addPrivateSpaceHeader(mAdapterItems);
+            int privateSpaceState = mPrivateProviderManager.getCurrentState();
+            switch (privateSpaceState) {
+                case PrivateProfileManager.STATE_DISABLED:
+                case PrivateProfileManager.STATE_TRANSITION:
+                    break;
+                case PrivateProfileManager.STATE_ENABLED:
+                    // Add PS Apps only in Enabled State.
+                    addAppsWithSections(mPrivateApps, position);
+                    break;
+            }
+        }
+    }
+
+    private void addAppsWithSections(List<AppInfo> appList, int startPosition) {
+        String lastSectionName = null;
+        for (AppInfo info : appList) {
+            mAdapterItems.add(AdapterItem.asApp(info));
+
+            String sectionName = info.sectionName;
+            // Create a new section if the section names do not match
+            if (!sectionName.equals(lastSectionName)) {
+                lastSectionName = sectionName;
+                mFastScrollerSections.add(new FastScrollSectionInfo(sectionName, startPosition));
+            }
+            startPosition++;
+        }
+    }
+
     private static class MyDiffCallback extends DiffUtil.Callback {
 
         private final List<AdapterItem> mOldList;
@@ -328,4 +369,4 @@
         }
     }
 
-}
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
index bce38a3..5e26ea5 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
@@ -22,6 +22,7 @@
 import android.view.View.OnFocusChangeListener;
 import android.view.View.OnLongClickListener;
 import android.view.ViewGroup;
+import android.widget.RelativeLayout;
 import android.widget.TextView;
 
 import androidx.recyclerview.widget.RecyclerView;
@@ -139,9 +140,16 @@
     protected final OnClickListener mOnIconClickListener;
     protected final OnLongClickListener mOnIconLongClickListener;
     protected OnFocusChangeListener mIconFocusListener;
+    private final PrivateSpaceHeaderViewController mPrivateSpaceHeaderViewController;
 
     public BaseAllAppsAdapter(T activityContext, LayoutInflater inflater,
             AlphabeticalAppsList<T> apps, SearchAdapterProvider<?> adapterProvider) {
+        this(activityContext, inflater, apps, adapterProvider, null);
+    }
+
+    public BaseAllAppsAdapter(T activityContext, LayoutInflater inflater,
+            AlphabeticalAppsList<T> apps, SearchAdapterProvider<?> adapterProvider,
+            PrivateSpaceHeaderViewController privateSpaceHeaderViewController) {
         mActivityContext = activityContext;
         mApps = apps;
         mLayoutInflater = inflater;
@@ -150,6 +158,7 @@
         mOnIconLongClickListener = mActivityContext.getAllAppsItemLongClickListener();
 
         mAdapterProvider = adapterProvider;
+        mPrivateSpaceHeaderViewController = privateSpaceHeaderViewController;
     }
 
     /** Checks if the passed viewType represents all apps divider. */
@@ -162,6 +171,11 @@
         return isViewType(viewType, VIEW_TYPE_MASK_ICON);
     }
 
+    /** Checks if the passed viewType represents private space header. */
+    public static boolean isPrivateSpaceHeaderView(int viewType) {
+        return isViewType(viewType, VIEW_TYPE_MASK_PRIVATE_SPACE_HEADER);
+    }
+
     public void setIconFocusListener(OnFocusChangeListener focusListener) {
         mIconFocusListener = focusListener;
     }
@@ -230,6 +244,12 @@
                 break;
             }
             case VIEW_TYPE_PRIVATE_SPACE_HEADER:
+                RelativeLayout psHeaderLayout = holder.itemView.findViewById(
+                        R.id.ps_header_layout);
+                assert mPrivateSpaceHeaderViewController != null;
+                assert psHeaderLayout != null;
+                mPrivateSpaceHeaderViewController.addPrivateSpaceHeaderViewElements(psHeaderLayout);
+                break;
             case VIEW_TYPE_ALL_APPS_DIVIDER:
             case VIEW_TYPE_WORK_DISABLED_CARD:
                 // nothing to do
diff --git a/src/com/android/launcher3/allapps/PrivateAppsSectionDecorator.java b/src/com/android/launcher3/allapps/PrivateAppsSectionDecorator.java
index f7c9058..f4ed754 100644
--- a/src/com/android/launcher3/allapps/PrivateAppsSectionDecorator.java
+++ b/src/com/android/launcher3/allapps/PrivateAppsSectionDecorator.java
@@ -42,20 +42,19 @@
     private final RectF mTmpRect = new RectF();
     private final Context mContext;
     private final AlphabeticalAppsList<?> mAppsList;
-    private final PrivateProfileManager mPrivateProfileManager;
     private final UserCache mUserCache;
     private final Paint mPaint;
+    private final int mCornerRadius;
 
-    public PrivateAppsSectionDecorator(ActivityAllAppsContainerView<?> appsContainerView,
-            AlphabeticalAppsList<?> appsList,
-            PrivateProfileManager privateProfileManager) {
+    public PrivateAppsSectionDecorator(Context context, AlphabeticalAppsList<?> appsList) {
+        mContext = context;
         mAppsList = appsList;
-        mPrivateProfileManager = privateProfileManager;
-        mContext = appsContainerView.mActivityContext;
-        mUserCache = UserCache.getInstance(appsContainerView.mActivityContext);
+        mUserCache = UserCache.getInstance(context);
         mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        mPaint.setColor(ContextCompat.getColor(mContext,
+        mPaint.setColor(ContextCompat.getColor(context,
                 R.color.material_color_surface_container_high));
+        mCornerRadius = context.getResources().getDimensionPixelSize(
+                R.dimen.ps_container_corner_radius);
     }
 
     /** Decorates Private Space Header and Icon Rows to give the shape of a container. */
@@ -70,9 +69,7 @@
             int position = parent.getChildAdapterPosition(view);
             BaseAllAppsAdapter.AdapterItem adapterItem = mAppsList.getAdapterItems().get(position);
             // Rectangle that covers the bottom half of the PS Header View when Space is unlocked.
-            if (adapterItem.viewType == VIEW_TYPE_PRIVATE_SPACE_HEADER
-                    && mPrivateProfileManager
-                    .getCurrentState() == PrivateProfileManager.STATE_ENABLED) {
+            if (adapterItem.viewType == VIEW_TYPE_PRIVATE_SPACE_HEADER) {
                 // We flatten the bottom corners of the rectangle, so that it merges with
                 // the private space app row decorator.
                 mTmpRect.set(
@@ -103,9 +100,8 @@
                 iconView.getBottom());
         // Decorates last app row with rounded bottom corners.
         if (adapterPosition + numCol >= mAppsList.getAdapterItems().size()) {
-            int corner = mContext.getResources().getDimensionPixelSize(
-                    R.dimen.ps_container_corner_radius);
-            float[] mCornersBot = new float[]{0, 0, 0, 0, corner, corner, corner, corner};
+            float[] mCornersBot = new float[]{0, 0, 0, 0, mCornerRadius, mCornerRadius,
+                    mCornerRadius, mCornerRadius};
             mTmpPath.addRoundRect(mTmpRect, mCornersBot, Path.Direction.CW);
         } else {
             // Decorate other rows as a plain rectangle
diff --git a/src/com/android/launcher3/allapps/PrivateProfileManager.java b/src/com/android/launcher3/allapps/PrivateProfileManager.java
index ec01aee..3e73c6a 100644
--- a/src/com/android/launcher3/allapps/PrivateProfileManager.java
+++ b/src/com/android/launcher3/allapps/PrivateProfileManager.java
@@ -19,6 +19,7 @@
 import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.MAIN;
 import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_PRIVATE_SPACE_HEADER;
 import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED;
+import static com.android.launcher3.util.SettingsCache.PRIVATE_SPACE_HIDE_WHEN_LOCKED_URI;
 
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -29,6 +30,7 @@
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.util.Preconditions;
+import com.android.launcher3.util.SettingsCache;
 
 import java.util.ArrayList;
 import java.util.function.Predicate;
@@ -44,11 +46,12 @@
     private static final String PS_SETTINGS_FRAGMENT_VALUE = "AndroidPrivateSpace_personal";
     private final ActivityAllAppsContainerView<?> mAllApps;
     private final Predicate<UserHandle> mPrivateProfileMatcher;
+    private PrivateAppsSectionDecorator mPrivateAppsSectionDecorator;
 
     public PrivateProfileManager(UserManager userManager,
-            UserCache userCache,
-            ActivityAllAppsContainerView allApps,
-            StatsLogManager statsLogManager) {
+            ActivityAllAppsContainerView<?> allApps,
+            StatsLogManager statsLogManager,
+            UserCache userCache) {
         super(userManager, statsLogManager, userCache);
         mAllApps = allApps;
         mPrivateProfileMatcher = (user) -> userCache.getUserInfo(user).isPrivate();
@@ -75,9 +78,8 @@
 
     /** Whether private profile should be hidden on Launcher. */
     public boolean isPrivateSpaceHidden() {
-        // TODO (b/289223923): Update this when we are able to read PsSettingsFlag
-        //  from SettingsProvider.
-        return false;
+        return getCurrentState() == STATE_DISABLED && SettingsCache.INSTANCE
+                    .get(mAllApps.mActivityContext).getValue(PRIVATE_SPACE_HIDE_WHEN_LOCKED_URI, 0);
     }
 
     /** Resets the current state of Private Profile, w.r.t. to Launcher. */
@@ -86,6 +88,7 @@
                 .hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED);
         int updatedState = isEnabled ? STATE_ENABLED : STATE_DISABLED;
         setCurrentState(updatedState);
+        resetPrivateSpaceDecorator(updatedState);
     }
 
     /** Opens the Private Space Settings Entry Point. */
@@ -102,11 +105,29 @@
         Preconditions.assertNonUiThread();
         Intent psSettingsIntent = new Intent(SAFETY_CENTER_INTENT);
         psSettingsIntent.putExtra(PS_SETTINGS_FRAGMENT_KEY, PS_SETTINGS_FRAGMENT_VALUE);
-        ResolveInfo resolveInfo = mAllApps.getContext().getPackageManager()
+        ResolveInfo resolveInfo = mAllApps.mActivityContext.getPackageManager()
                 .resolveActivity(psSettingsIntent, PackageManager.MATCH_SYSTEM_ONLY);
         return resolveInfo != null;
     }
 
+    void resetPrivateSpaceDecorator(int updatedState) {
+        if (updatedState == STATE_ENABLED) {
+            // Add Private Space Decorator to the Recycler view.
+            if (mPrivateAppsSectionDecorator == null) {
+                mPrivateAppsSectionDecorator = new PrivateAppsSectionDecorator(
+                        mAllApps.mActivityContext,
+                        mAllApps.mAH.get(MAIN).mAppsList);
+            }
+            mAllApps.mAH.get(MAIN).mRecyclerView.addItemDecoration(mPrivateAppsSectionDecorator);
+        } else {
+            // Remove Private Space Decorator from the Recycler view.
+            if (mPrivateAppsSectionDecorator != null) {
+                mAllApps.mAH.get(MAIN).mRecyclerView
+                        .removeItemDecoration(mPrivateAppsSectionDecorator);
+            }
+        }
+    }
+
     /** Posts quiet mode enable/disable call for private profile. */
     private void enableQuietMode(boolean enable) {
         setQuietMode(enable);
diff --git a/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java b/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java
index 9420b4c..c49d0b1 100644
--- a/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java
+++ b/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java
@@ -19,6 +19,7 @@
 import static com.android.launcher3.allapps.PrivateProfileManager.STATE_DISABLED;
 import static com.android.launcher3.allapps.PrivateProfileManager.STATE_ENABLED;
 import static com.android.launcher3.allapps.PrivateProfileManager.STATE_TRANSITION;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
 import android.view.View;
 import android.widget.ImageButton;
@@ -49,7 +50,7 @@
         //Add image and action for private space settings button
         ImageButton settingsButton = parent.findViewById(R.id.ps_settings_button);
         assert settingsButton != null;
-        addPrivateSpaceSettingsButton(settingsButton);
+        UI_HELPER_EXECUTOR.post(() -> addPrivateSpaceSettingsButton(settingsButton));
 
         //Add image for private space transitioning view
         ImageView transitionView = parent.findViewById(R.id.ps_transition_image);
diff --git a/src/com/android/launcher3/util/SettingsCache.java b/src/com/android/launcher3/util/SettingsCache.java
index 29ec5ab..2ab6dc3 100644
--- a/src/com/android/launcher3/util/SettingsCache.java
+++ b/src/com/android/launcher3/util/SettingsCache.java
@@ -55,6 +55,9 @@
     /** Hidden field Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED */
     public static final String ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED =
             "swipe_bottom_to_notification_enabled";
+    /** Hidden field Settings.Secure.HIDE_PRIVATESPACE_ENTRY_POINT */
+    public static final Uri PRIVATE_SPACE_HIDE_WHEN_LOCKED_URI =
+            Settings.Secure.getUriFor("hide_privatespace_entry_point");
     public static final Uri ROTATION_SETTING_URI =
             Settings.System.getUriFor(ACCELEROMETER_ROTATION);