From 08b06523a5f2fa861584fdbde53d9fd5577f49f9 Mon Sep 17 00:00:00 2001 From: Brandon Dayauon Date: Tue, 23 Jan 2024 14:13:05 -0800 Subject: [PATCH] Collapse private space container and animate header. - Just opposite of how it will expand. - RecyclerView.SmoothScroller is needed to scroll the container. - Need to separate the lock button because this way I can use animateLayout changes and it itself was its own drawable. Separated into icon and textView in a viewGroup. - Give the background the 10padding on the left and right so that when in animation, the icon can adjust the padding/margins there. - Using propertySetter to set animation - Animates the alpha of the settings alpha - updated test to account for the nested child views the test needs to inspect bug: 299294792 test: manual: Expand + Collapse Video: https://drive.google.com/file/d/1Og66eqmXv3THn0wO4_x6Tfp2AbwFWUwZ/view?usp=sharing Flag: ACONFIG com.android.launcher3.Flags.private_space_animation TEAMFOOD Change-Id: I96f1d172a481522d23b4cee996ddec65961fce78 --- res/drawable/ic_lock.xml | 24 +++ ...settings_button.xml => ic_ps_settings.xml} | 5 +- res/drawable/ps_lock_background.xml | 27 +++ res/drawable/ps_settings_background.xml | 23 +++ res/layout/private_space_header.xml | 66 +++++-- res/values/dimens.xml | 13 +- res/values/strings.xml | 1 + res/values/styles.xml | 1 + src/com/android/launcher3/BubbleTextView.java | 6 + .../launcher3/FastScrollRecyclerView.java | 1 - .../launcher3/allapps/BaseAllAppsAdapter.java | 1 + .../PrivateSpaceHeaderViewController.java | 183 +++++++++++++++--- .../PrivateSpaceHeaderViewControllerTest.java | 72 ++++--- 13 files changed, 346 insertions(+), 77 deletions(-) create mode 100644 res/drawable/ic_lock.xml rename res/drawable/{bg_ps_settings_button.xml => ic_ps_settings.xml} (93%) create mode 100644 res/drawable/ps_lock_background.xml create mode 100644 res/drawable/ps_settings_background.xml diff --git a/res/drawable/ic_lock.xml b/res/drawable/ic_lock.xml new file mode 100644 index 0000000000..055e6b43f0 --- /dev/null +++ b/res/drawable/ic_lock.xml @@ -0,0 +1,24 @@ + + + + diff --git a/res/drawable/bg_ps_settings_button.xml b/res/drawable/ic_ps_settings.xml similarity index 93% rename from res/drawable/bg_ps_settings_button.xml rename to res/drawable/ic_ps_settings.xml index c06e0c0249..47edeb85ef 100644 --- a/res/drawable/bg_ps_settings_button.xml +++ b/res/drawable/ic_ps_settings.xml @@ -15,13 +15,10 @@ --> - diff --git a/res/drawable/ps_lock_background.xml b/res/drawable/ps_lock_background.xml new file mode 100644 index 0000000000..b81c23fcb3 --- /dev/null +++ b/res/drawable/ps_lock_background.xml @@ -0,0 +1,27 @@ + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/ps_settings_background.xml b/res/drawable/ps_settings_background.xml new file mode 100644 index 0000000000..b0c6b5b0d1 --- /dev/null +++ b/res/drawable/ps_settings_background.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file diff --git a/res/layout/private_space_header.xml b/res/layout/private_space_header.xml index 24e290d180..0b0af87d97 100644 --- a/res/layout/private_space_header.xml +++ b/res/layout/private_space_header.xml @@ -18,6 +18,7 @@ - - - - + android:animateLayoutChanges="true"> + + + + + + 24dp 64dp 48dp - 36dp + 48dp 24dp 16dp 8dp 16sp - 36dp - 36dp + 40dp + 40dp 89dp 16dp + 20dp + 20dp + 10dp + 10dp + 8dp + 6dp + 10dp 136px diff --git a/res/values/strings.xml b/res/values/strings.xml index a4e7ec48aa..31c098cb2d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -465,6 +465,7 @@ Private Space Settings Lock/Unlock Private Space + Lock Private Space Transitioning diff --git a/res/values/styles.xml b/res/values/styles.xml index b83be351a3..401155dee5 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -441,5 +441,6 @@ 16sp @color/material_color_on_surface google-sans-text-medium + end diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 2f0c0968e9..38ddfec918 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -294,6 +294,12 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, mIconLoadRequest.cancel(); mIconLoadRequest = null; } + // Reset any shifty arrangements in case animation is disrupted. + setPivotY(0); + setAlpha(1); + setScaleY(1); + setTranslationY(0); + setVisibility(VISIBLE); } private void cancelDotScaleAnim() { diff --git a/src/com/android/launcher3/FastScrollRecyclerView.java b/src/com/android/launcher3/FastScrollRecyclerView.java index 7ec0a89cae..51c7a055ca 100644 --- a/src/com/android/launcher3/FastScrollRecyclerView.java +++ b/src/com/android/launcher3/FastScrollRecyclerView.java @@ -201,7 +201,6 @@ public abstract class FastScrollRecyclerView extends RecyclerView { if (mScrollbar != null) { mScrollbar.reattachThumbToScroll(); } - // Emphasized interpolators with 500ms duration smoothScrollBy(0, getAvailableScrollHeight(), Interpolators.EMPHASIZED, duration); } } diff --git a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java index 28c87b6fa7..27092f6041 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java @@ -258,6 +258,7 @@ public abstract class BaseAllAppsAdapter ex @Override public void onBindViewHolder(ViewHolder holder, int position) { + holder.itemView.setVisibility(View.VISIBLE); switch (holder.getItemViewType()) { case VIEW_TYPE_ICON: { AdapterItem adapterItem = mApps.getAdapterItems().get(position); diff --git a/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java b/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java index fcdfaa627b..91fcf8090f 100644 --- a/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java +++ b/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java @@ -16,7 +16,12 @@ package com.android.launcher3.allapps; +import static android.view.View.GONE; +import static android.view.View.VISIBLE; + +import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA; 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.allapps.PrivateProfileManager.STATE_DISABLED; import static com.android.launcher3.allapps.PrivateProfileManager.STATE_ENABLED; import static com.android.launcher3.allapps.PrivateProfileManager.STATE_TRANSITION; @@ -24,21 +29,37 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_PRIVATE_SPACE_SETTINGS_TAP; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_PRIVATE_SPACE_UNLOCK_TAP; -import android.view.View; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.LayoutTransition; +import android.animation.ValueAnimator; +import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.RelativeLayout; +import android.widget.TextView; +import androidx.recyclerview.widget.LinearSmoothScroller; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.app.animation.Interpolators; import com.android.launcher3.Flags; import com.android.launcher3.R; import com.android.launcher3.allapps.UserProfileManager.UserProfileState; +import com.android.launcher3.anim.AnimatedPropertySetter; +import com.android.launcher3.anim.PropertySetter; + +import java.util.List; /** * Controller which returns views to be added to Private Space Header based upon * {@link UserProfileState} */ public class PrivateSpaceHeaderViewController { - private static final int ANIMATION_DURATION = 2000; + private static final int EXPAND_SCROLL_DURATION = 2000; + private static final int EXPAND_COLLAPSE_DURATION = 800; + private static final int SETTINGS_OPACITY_DURATION = 160; private final ActivityAllAppsContainerView mAllApps; private final PrivateProfileManager mPrivateProfileManager; @@ -50,10 +71,17 @@ public class PrivateSpaceHeaderViewController { /** Add Private Space Header view elements based upon {@link UserProfileState} */ public void addPrivateSpaceHeaderViewElements(RelativeLayout parent) { + // Set the transition duration for the settings and lock button to animate. + ViewGroup settingsAndLockGroup = parent.findViewById(R.id.settingsAndLockGroup); + LayoutTransition settingsAndLockTransition = settingsAndLockGroup.getLayoutTransition(); + settingsAndLockTransition.enableTransitionType(LayoutTransition.CHANGING); + settingsAndLockTransition.setDuration(EXPAND_COLLAPSE_DURATION); + //Add quietMode image and action for lock/unlock button - ImageButton quietModeButton = parent.findViewById(R.id.ps_lock_unlock_button); - assert quietModeButton != null; - addQuietModeButton(quietModeButton); + ViewGroup lockButton = + parent.findViewById(R.id.ps_lock_unlock_button); + assert lockButton != null; + addLockButton(parent, lockButton); //Trigger lock/unlock action from header. addHeaderOnClickListener(parent); @@ -69,74 +97,181 @@ public class PrivateSpaceHeaderViewController { addTransitionImage(transitionView); } - private void addQuietModeButton(ImageButton quietModeButton) { + /** + * Adds the quietModeButton and attach onClickListener for the header to animate different + * states when clicked. + */ + private void addLockButton(ViewGroup psHeader, ViewGroup lockButton) { + TextView lockText = lockButton.findViewById(R.id.lock_text); switch (mPrivateProfileManager.getCurrentState()) { case STATE_ENABLED -> { - quietModeButton.setVisibility(View.VISIBLE); - quietModeButton.setImageResource(R.drawable.bg_ps_lock_button); - quietModeButton.setOnClickListener(view -> lockAction()); + lockText.setVisibility(VISIBLE); + lockButton.setVisibility(VISIBLE); + lockButton.setOnClickListener(view -> lockAction(psHeader)); } case STATE_DISABLED -> { - quietModeButton.setVisibility(View.VISIBLE); - quietModeButton.setImageResource(R.drawable.bg_ps_unlock_button); - quietModeButton.setOnClickListener(view -> unLockAction()); + lockText.setVisibility(GONE); + lockButton.setVisibility(VISIBLE); + lockButton.setOnClickListener(view -> unlockAction(psHeader)); } - default -> quietModeButton.setVisibility(View.GONE); + default -> lockButton.setVisibility(GONE); } } private void addHeaderOnClickListener(RelativeLayout header) { if (mPrivateProfileManager.getCurrentState() == STATE_DISABLED) { - header.setOnClickListener(view -> unLockAction()); + header.setOnClickListener(view -> unlockAction(header)); } else { header.setOnClickListener(null); } } - private void unLockAction() { + private void unlockAction(ViewGroup psHeader) { mPrivateProfileManager.logEvents(LAUNCHER_PRIVATE_SPACE_UNLOCK_TAP); - mPrivateProfileManager.unlockPrivateProfile((this::onPrivateProfileUnlocked)); + mPrivateProfileManager.unlockPrivateProfile((() -> onPrivateProfileUnlocked(psHeader))); } - private void lockAction() { + private void lockAction(ViewGroup psHeader) { mPrivateProfileManager.logEvents(LAUNCHER_PRIVATE_SPACE_LOCK_TAP); - mPrivateProfileManager.lockPrivateProfile(); + if (Flags.enablePrivateSpace() && Flags.privateSpaceAnimation()) { + updatePrivateStateAnimator(false, psHeader); + } else { + mPrivateProfileManager.lockPrivateProfile(); + } } private void addPrivateSpaceSettingsButton(ImageButton settingsButton) { if (mPrivateProfileManager.getCurrentState() == STATE_ENABLED && mPrivateProfileManager.isPrivateSpaceSettingsAvailable()) { - settingsButton.setVisibility(View.VISIBLE); + settingsButton.setVisibility(VISIBLE); + settingsButton.setAlpha(1f); settingsButton.setOnClickListener( view -> { mPrivateProfileManager.logEvents(LAUNCHER_PRIVATE_SPACE_SETTINGS_TAP); mPrivateProfileManager.openPrivateSpaceSettings(); }); } else { - settingsButton.setVisibility(View.GONE); + settingsButton.setVisibility(GONE); } } private void addTransitionImage(ImageView transitionImage) { if (mPrivateProfileManager.getCurrentState() == STATE_TRANSITION) { - transitionImage.setVisibility(View.VISIBLE); + transitionImage.setVisibility(VISIBLE); } else { - transitionImage.setVisibility(View.GONE); + transitionImage.setVisibility(GONE); } } - private void onPrivateProfileUnlocked() { + private void onPrivateProfileUnlocked(ViewGroup header) { // If we are on main adapter view, we apply the PS Container expansion animation and // then scroll down to load the entire container, making animation visible. ActivityAllAppsContainerView.AdapterHolder mainAdapterHolder = (ActivityAllAppsContainerView.AdapterHolder) mAllApps.mAH.get(MAIN); if (Flags.enablePrivateSpace() && Flags.privateSpaceAnimation() && mAllApps.getActiveRecyclerView() == mainAdapterHolder.mRecyclerView) { - mAllApps.getActiveRecyclerView().scrollToBottomWithMotion(ANIMATION_DURATION); + // Animate the text and settings icon. + updatePrivateStateAnimator(true, header); + mAllApps.getActiveRecyclerView().scrollToBottomWithMotion(EXPAND_SCROLL_DURATION); + } + } + + /** Finds the private space header to scroll to and set the private space icons to GONE. */ + private void collapse() { + AllAppsRecyclerView allAppsRecyclerView = mAllApps.getActiveRecyclerView(); + for (int i = allAppsRecyclerView.getChildCount() - 1; i > 0; i--) { + int adapterPosition = allAppsRecyclerView.getChildAdapterPosition( + allAppsRecyclerView.getChildAt(i)); + List allAppsAdapters = allAppsRecyclerView.getApps() + .getAdapterItems(); + if (adapterPosition < 0 || adapterPosition >= allAppsAdapters.size()) { + continue; + } + // Scroll to the private space header. + if (allAppsAdapters.get(adapterPosition).viewType == VIEW_TYPE_PRIVATE_SPACE_HEADER) { + // Note: SmoothScroller is meant to be used once. + RecyclerView.SmoothScroller smoothScroller = + new LinearSmoothScroller(mAllApps.getContext()) { + @Override protected int getVerticalSnapPreference() { + return LinearSmoothScroller.SNAP_TO_END; + } + }; + smoothScroller.setTargetPosition(adapterPosition); + RecyclerView.LayoutManager layoutManager = allAppsRecyclerView.getLayoutManager(); + if (layoutManager != null) { + layoutManager.startSmoothScroll(smoothScroller); + } + break; + } + // Make the private space apps gone to "collapse". + if (allAppsAdapters.get(adapterPosition).decorationInfo != null) { + allAppsRecyclerView.getChildAt(i).setVisibility(GONE); + } } } PrivateProfileManager getPrivateProfileManager() { return mPrivateProfileManager; } + + /** + * Scrolls up to the private space header and animates the collapsing of the text. + */ + private ValueAnimator animateCollapseAnimation(ViewGroup lockButton) { + float from = 1; + float to = 0; + ValueAnimator collapseAnim = ValueAnimator.ofFloat(from, to); + collapseAnim.setDuration(EXPAND_COLLAPSE_DURATION); + collapseAnim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + // scroll up + collapse(); + // Animate the collapsing of the text. + lockButton.findViewById(R.id.lock_text).setVisibility(GONE); + } + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + mPrivateProfileManager.lockPrivateProfile(); + } + }); + return collapseAnim; + } + + /** + * Using PropertySetter{@link PropertySetter}, we can update the view's attributes within an + * animation. At the moment, collapsing, setting alpha changes, and animating the text is done + * here. + */ + private void updatePrivateStateAnimator(boolean expand, ViewGroup psHeader) { + PropertySetter setter = new AnimatedPropertySetter(); + ViewGroup lockButton = psHeader.findViewById(R.id.ps_lock_unlock_button); + ImageButton settingsButton = psHeader.findViewById(R.id.ps_settings_button); + updateSettingsGearAlpha(settingsButton, expand, setter); + AnimatorSet animatorSet = setter.buildAnim(); + animatorSet.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + // Animate the collapsing of the text at the same time while updating lock button. + lockButton.findViewById(R.id.lock_text).setVisibility(expand ? VISIBLE : GONE); + } + }); + // Play the collapsing together of the stateAnimator to avoid being unable to scroll to the + // header. Otherwise the smooth scrolling will scroll higher when played with the state + // animator. + if (!expand) { + animatorSet.playTogether(animateCollapseAnimation(lockButton)); + } + animatorSet.setDuration(EXPAND_COLLAPSE_DURATION); + animatorSet.start(); + } + + /** Change the settings gear alpha when expanded or collapsed. */ + private void updateSettingsGearAlpha(ImageButton settingsButton, boolean expand, + PropertySetter setter) { + float toAlpha = expand ? 1 : 0; + setter.setFloat(settingsButton, VIEW_ALPHA, toAlpha, Interpolators.LINEAR) + .setDuration(SETTINGS_OPACITY_DURATION).setStartDelay(0); + } } diff --git a/tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewControllerTest.java b/tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewControllerTest.java index 92fff49581..490cb47eae 100644 --- a/tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewControllerTest.java +++ b/tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewControllerTest.java @@ -24,6 +24,7 @@ import static com.android.launcher3.allapps.UserProfileManager.STATE_TRANSITION; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; import android.content.Context; @@ -33,8 +34,11 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.view.LayoutInflater; import android.view.View; +import android.widget.ImageButton; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.RelativeLayout; +import android.widget.TextView; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -59,7 +63,6 @@ public class PrivateSpaceHeaderViewControllerTest { private static final int PS_TRANSITION_IMAGE_COUNT = 1; private Context mContext; - private LayoutInflater mLayoutInflater; private PrivateSpaceHeaderViewController mPsHeaderViewController; private RelativeLayout mPsHeaderLayout; @Mock @@ -71,16 +74,15 @@ public class PrivateSpaceHeaderViewControllerTest { public void setUp() { MockitoAnnotations.initMocks(this); mContext = new ActivityContextWrapper(getApplicationContext()); - mLayoutInflater = LayoutInflater.from(getApplicationContext()); mPsHeaderViewController = new PrivateSpaceHeaderViewController(mAllApps, mPrivateProfileManager); - mPsHeaderLayout = (RelativeLayout) mLayoutInflater.inflate(R.layout.private_space_header, - null); + mPsHeaderLayout = (RelativeLayout) LayoutInflater.from(mContext).inflate( + R.layout.private_space_header, null); } @Test public void privateProfileDisabled_psHeaderContainsLockedView() throws Exception { - Bitmap unlockButton = getBitmap(mContext.getDrawable(R.drawable.bg_ps_unlock_button)); + Bitmap unlockButton = getBitmap(mContext.getDrawable(R.drawable.ic_lock)); when(mPrivateProfileManager.getCurrentState()).thenReturn(STATE_DISABLED); mPsHeaderViewController.addPrivateSpaceHeaderViewElements(mPsHeaderLayout); @@ -93,11 +95,15 @@ public class PrivateSpaceHeaderViewControllerTest { if (view.getId() == R.id.ps_container_header) { totalContainerHeaderView += 1; assertEquals(View.VISIBLE, view.getVisibility()); - } else if (view.getId() == R.id.ps_lock_unlock_button - && view instanceof ImageView imageView) { + } else if (view.getId() == R.id.settingsAndLockGroup) { + ImageView lockIcon = view.findViewById(R.id.lock_icon); + assertTrue(getBitmap(lockIcon.getDrawable()).sameAs(unlockButton)); + assertEquals(View.VISIBLE, lockIcon.getVisibility()); + + // Verify textView shouldn't be showing when disabled. + TextView lockText = view.findViewById(R.id.lock_text); + assertEquals(View.GONE, lockText.getVisibility()); totalLockUnlockButtonView += 1; - assertEquals(View.VISIBLE, view.getVisibility()); - getBitmap(imageView.getDrawable()).sameAs(unlockButton); } else { assertEquals(View.GONE, view.getVisibility()); } @@ -108,8 +114,8 @@ public class PrivateSpaceHeaderViewControllerTest { @Test public void privateProfileEnabled_psHeaderContainsUnlockedView() throws Exception { - Bitmap lockImage = getBitmap(mContext.getDrawable(R.drawable.bg_ps_lock_button)); - Bitmap settingsImage = getBitmap(mContext.getDrawable(R.drawable.bg_ps_settings_button)); + Bitmap lockImage = getBitmap(mContext.getDrawable(R.drawable.ic_lock)); + Bitmap settingsImage = getBitmap(mContext.getDrawable(R.drawable.ic_ps_settings)); when(mPrivateProfileManager.getCurrentState()).thenReturn(STATE_ENABLED); when(mPrivateProfileManager.isPrivateSpaceSettingsAvailable()).thenReturn(true); @@ -124,16 +130,20 @@ public class PrivateSpaceHeaderViewControllerTest { if (view.getId() == R.id.ps_container_header) { totalContainerHeaderView += 1; assertEquals(View.VISIBLE, view.getVisibility()); - } else if (view.getId() == R.id.ps_lock_unlock_button - && view instanceof ImageView imageView) { - totalLockUnlockButtonView += 1; - assertEquals(View.VISIBLE, view.getVisibility()); - getBitmap(imageView.getDrawable()).sameAs(lockImage); - } else if (view.getId() == R.id.ps_settings_button - && view instanceof ImageView imageView) { + } else if (view.getId() == R.id.settingsAndLockGroup) { + // Look for settings button. + ImageButton settingsButton = view.findViewById(R.id.ps_settings_button); + assertEquals(View.VISIBLE, settingsButton.getVisibility()); totalSettingsImageView += 1; - assertEquals(View.VISIBLE, view.getVisibility()); - getBitmap(imageView.getDrawable()).sameAs(settingsImage); + assertTrue(getBitmap(settingsButton.getDrawable()).sameAs(settingsImage)); + + // Look for lock_icon and lock_text. + ImageView lockIcon = view.findViewById(R.id.lock_icon); + assertTrue(getBitmap(lockIcon.getDrawable()).sameAs(lockImage)); + assertEquals(View.VISIBLE, lockIcon.getVisibility()); + TextView lockText = view.findViewById(R.id.lock_text); + assertEquals(View.VISIBLE, lockText.getVisibility()); + totalLockUnlockButtonView += 1; } else { assertEquals(View.GONE, view.getVisibility()); } @@ -146,7 +156,7 @@ public class PrivateSpaceHeaderViewControllerTest { @Test public void privateProfileEnabledAndNoSettingsIntent_psHeaderContainsUnlockedView() throws Exception { - Bitmap lockImage = getBitmap(mContext.getDrawable(R.drawable.bg_ps_lock_button)); + Bitmap lockImage = getBitmap(mContext.getDrawable(R.drawable.ic_lock)); when(mPrivateProfileManager.getCurrentState()).thenReturn(STATE_ENABLED); when(mPrivateProfileManager.isPrivateSpaceSettingsAvailable()).thenReturn(false); @@ -161,11 +171,18 @@ public class PrivateSpaceHeaderViewControllerTest { if (view.getId() == R.id.ps_container_header) { totalContainerHeaderView += 1; assertEquals(View.VISIBLE, view.getVisibility()); - } else if (view.getId() == R.id.ps_lock_unlock_button - && view instanceof ImageView imageView) { + } else if (view.getId() == R.id.settingsAndLockGroup) { + // Ensure there is no settings button. + ImageButton settingsImage = view.findViewById(R.id.ps_settings_button); + assertEquals(View.GONE, settingsImage.getVisibility()); + + // Check lock icon and lock text is there. + ImageView lockIcon = view.findViewById(R.id.lock_icon); + assertTrue(getBitmap(lockIcon.getDrawable()).sameAs(lockImage)); + assertEquals(View.VISIBLE, lockIcon.getVisibility()); + TextView lockText = view.findViewById(R.id.lock_text); + assertEquals(View.VISIBLE, lockText.getVisibility()); totalLockUnlockButtonView += 1; - assertEquals(View.VISIBLE, view.getVisibility()); - getBitmap(imageView.getDrawable()).sameAs(lockImage); } else { assertEquals(View.GONE, view.getVisibility()); } @@ -194,7 +211,10 @@ public class PrivateSpaceHeaderViewControllerTest { && view instanceof ImageView imageView) { totalLockUnlockButtonView += 1; assertEquals(View.VISIBLE, view.getVisibility()); - getBitmap(imageView.getDrawable()).sameAs(transitionImage); + assertTrue(getBitmap(imageView.getDrawable()).sameAs(transitionImage)); + } else if (view.getId() == R.id.settingsAndLockGroup) { + LinearLayout lockUnlockButton = view.findViewById(R.id.ps_lock_unlock_button); + assertEquals(View.GONE, lockUnlockButton.getVisibility()); } else { assertEquals(View.GONE, view.getVisibility()); }