From befcfa40b9445bbbfb36818e0a715a1e9761e9b5 Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 19 Dec 2022 18:02:07 -0800 Subject: [PATCH 1/3] Not waiting for animations for Launcher clicks Waiting for animations to finish can make the test wait for too long if there is an ongoing animation somewhere, for example, in an app we are trying to swipe from. Test: presubmit Bug: 256567004 Change-Id: Ida494128a18342bee3dbdae6d713c854c86912c1 --- .../launcher3/tapl/AddToHomeScreenPrompt.java | 3 ++- .../tapl/LauncherInstrumentation.java | 23 +++++++++++-------- .../com/android/launcher3/tapl/Workspace.java | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java index 98eb32e818..10afe13d62 100644 --- a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java +++ b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java @@ -45,7 +45,8 @@ public class AddToHomeScreenPrompt { mLauncher.clickObject( mLauncher.waitForObjectInContainer( mWidgetCell.getParent().getParent().getParent().getParent(), - By.text(ADD_AUTOMATICALLY))); + By.text(ADD_AUTOMATICALLY)), + LauncherInstrumentation.GestureScope.OUTSIDE_WITHOUT_PILFER); mLauncher.waitUntilLauncherObjectGone(getSelector()); } } diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 302fabd92a..ae9ba6787b 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -1466,19 +1466,22 @@ public final class LauncherInstrumentation { return getRealDisplaySize().x - getWindowInsets().right - 1; } - void clickObject(UiObject2 object) { - waitForObjectEnabled(object, "clickObject"); - if (!isLauncher3() && getNavigationModel() != NavigationModel.THREE_BUTTON) { - expectEvent(TestProtocol.SEQUENCE_TIS, LauncherInstrumentation.EVENT_TOUCH_DOWN_TIS); - expectEvent(TestProtocol.SEQUENCE_TIS, LauncherInstrumentation.EVENT_TOUCH_UP_TIS); - } - object.click(); + /** + * Click on the ui object right away without waiting for animation. + * + * [UiObject2.click] would wait for all animations finished before clicking. Not waiting for + * animations because in some scenarios there is a playing animations when the click is + * attempted. + */ + void clickObject(UiObject2 uiObject, GestureScope gestureScope) { + final long clickTime = SystemClock.uptimeMillis(); + final Point center = uiObject.getVisibleCenter(); + sendPointer(clickTime, clickTime, MotionEvent.ACTION_DOWN, center, gestureScope); + sendPointer(clickTime, clickTime, MotionEvent.ACTION_UP, center, gestureScope); } void clickLauncherObject(UiObject2 object) { - expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_TOUCH_DOWN); - expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_TOUCH_UP); - clickObject(object); + clickObject(object, GestureScope.INSIDE); } void scrollToLastVisibleRow( diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java index b2a2937396..2c82c50eca 100644 --- a/tests/tapl/com/android/launcher3/tapl/Workspace.java +++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java @@ -385,7 +385,7 @@ public final class Workspace extends Home { Until.hasObject(installerAlert), LauncherInstrumentation.WAIT_TIME_MS)); final UiObject2 ok = device.findObject(By.text("OK")); assertNotNull("OK button is not shown", ok); - launcher.clickObject(ok); + launcher.clickObject(ok, LauncherInstrumentation.GestureScope.OUTSIDE_WITHOUT_PILFER); assertTrue("Uninstall alert is not dismissed after clicking OK", device.wait( Until.gone(installerAlert), LauncherInstrumentation.WAIT_TIME_MS)); From 0ea4768a022de332dde88926cf1a85ee2c7dd620 Mon Sep 17 00:00:00 2001 From: Ats Jenk Date: Wed, 14 Dec 2022 16:42:10 -0800 Subject: [PATCH 2/3] Taskbar fixes when apps move to desktop and back Fixes to taskbar state when tasks are moved to desktop and fullscreen. When freeform tasks are visible and we start a new task from taskbar, it first launches in fullscreen. Transition handler in WMSHell switches it to freeform as needed. This switch causes launcher activity to be paused and then resumed. Resuming launcher activity while freeform tasks are visible, puts the launcher into an incorrect state. (Launcher should appear paused while freeform tasks are visible). When a freeform task switches to fullscreen, freeform tasks are no longer visible. This causes us to resume the launcher activity. We should not do that if a fullscreen task is visible as it puts the launcher into an incorrect state. It appears resumed even though the activity is paused. Added a check to DesktopVisibilityController that checks if the activity is actually resumed before marking it appear as resumed. Test: manual, switch a task to freeform, launch another freeform task from taskbar, taskbar should continue to be available Test: manual, switch a task to freeform, switch the task back to fullscreen, taskbar should continue to be available Bug: 261234278 Change-Id: Ia8d208619fabfcc9bffff6d8d227b236cb62a00c --- .../DesktopVisibilityController.java | 13 ++++++++++--- .../launcher3/uioverrides/QuickstepLauncher.java | 16 +++++++++++++++- .../android/quickstep/views/DesktopTaskView.java | 6 +++++- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java index a205d19f3c..bbc0627517 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java @@ -43,7 +43,7 @@ public class DesktopVisibilityController { */ private boolean isDesktopModeSupported() { return SystemProperties.getBoolean("persist.wm.debug.desktop_mode", false) - || SystemProperties.getBoolean("persist.wm.debug.desktop_mode_2", false); + || SystemProperties.getBoolean("persist.wm.debug.desktop_mode_2", false); } /** @@ -81,7 +81,9 @@ public class DesktopVisibilityController { StatefulActivity activity = QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity(); View workspaceView = mLauncher.getWorkspace(); - if (activity == null || workspaceView == null || !isDesktopModeSupported()) return; + if (activity == null || workspaceView == null || !isDesktopModeSupported()) { + return; + } if (mFreeformTasksVisible) { workspaceView.setVisibility(View.INVISIBLE); @@ -93,7 +95,12 @@ public class DesktopVisibilityController { } else { workspaceView.setVisibility(View.VISIBLE); // If freeform isn't visible ensure that launcher appears resumed to behave normally. - activity.setResumed(); + // Check activity state before calling setResumed(). Launcher may have been actually + // paused (eg fullscreen task moved to front). + // In this case we should not mark the activity as resumed. + if (activity.isResumed()) { + activity.setResumed(); + } } } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 13d0be507a..462fd59507 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -96,7 +96,6 @@ import com.android.launcher3.logging.StatsLogManager.StatsLogger; import com.android.launcher3.model.BgDataModel.FixedContainerItems; import com.android.launcher3.model.WellbeingModel; import com.android.launcher3.model.data.ItemInfo; -import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.popup.SystemShortcut; import com.android.launcher3.proxy.ProxyActivityStarter; import com.android.launcher3.proxy.StartActivityParams; @@ -141,6 +140,7 @@ import com.android.quickstep.util.SplitSelectStateController; import com.android.quickstep.util.SplitToWorkspaceController; import com.android.quickstep.util.SplitWithKeyboardShortcutController; import com.android.quickstep.util.TISBindHelper; +import com.android.quickstep.views.DesktopTaskView; import com.android.quickstep.views.OverviewActionsView; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; @@ -661,6 +661,20 @@ public class QuickstepLauncher extends Launcher { } } + @Override + public void setResumed() { + if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED) { + DesktopVisibilityController controller = mDesktopVisibilityController; + if (controller != null && controller.areFreeformTasksVisible()) { + // Return early to skip setting activity to appear as resumed + // TODO(b/255649902): shouldn't be needed when we have a separate launcher state + // for desktop that we can use to control other parts of launcher + return; + } + } + super.setResumed(); + } + @Override protected void onDeferredResumed() { super.onDeferredResumed(); diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java index 308249cb1e..c878278da5 100644 --- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java +++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java @@ -59,10 +59,14 @@ import java.util.function.Consumer; // TODO(b/249371338): TaskView needs to be refactored to have better support for N tasks. public class DesktopTaskView extends TaskView { + /** Flag to indicate whether desktop windowing proto 2 is enabled */ + public static final boolean DESKTOP_IS_PROTO2_ENABLED = SystemProperties.getBoolean( + "persist.wm.debug.desktop_mode_2", false); + /** Flags to indicate whether desktop mode is available on the device */ public static final boolean DESKTOP_MODE_SUPPORTED = SystemProperties.getBoolean("persist.wm.debug.desktop_mode", false) - || SystemProperties.getBoolean("persist.wm.debug.desktop_mode_2", false); + || DESKTOP_IS_PROTO2_ENABLED; private static final String TAG = DesktopTaskView.class.getSimpleName(); From c9672b9002899219385500550ab69ebd460a0de3 Mon Sep 17 00:00:00 2001 From: Brandon Dayauon Date: Mon, 21 Nov 2022 16:30:28 -0800 Subject: [PATCH 3/3] Extend/shrink work button when scrolling most of the change was from this CL: ag/19223926 moved scroll listener definition to WorkProfileManager.java Added feature flag bug: 194188980 test: Video - https://drive.google.com/file/d/18UM7UDNQz-Z8Q2Sh8VEKHm9LXRVJaWFM/view?usp=sharing Change-Id: Ib80784e0f5108b28658141ca5e495a27fab34a3c --- res/layout/work_mode_fab.xml | 39 ++++--- res/values/dimens.xml | 2 + .../allapps/BaseAllAppsContainerView.java | 12 ++- .../launcher3/allapps/WorkModeSwitch.java | 101 ++++++++---------- .../launcher3/allapps/WorkProfileManager.java | 71 +++++++++++- .../launcher3/config/FeatureFlags.java | 4 + 6 files changed, 152 insertions(+), 77 deletions(-) diff --git a/res/layout/work_mode_fab.xml b/res/layout/work_mode_fab.xml index 81b28ba004..c116c12bad 100644 --- a/res/layout/work_mode_fab.xml +++ b/res/layout/work_mode_fab.xml @@ -12,24 +12,35 @@ See the License for the specific language governing permissions and limitations under the License. --> - \ No newline at end of file + android:contentDescription="@string/work_apps_pause_btn_text" + android:animateLayoutChanges="true"> + + + diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 664c2f3d5f..7df5a9e843 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -149,6 +149,8 @@ 56dp 16dp + 24dp + 8dp 10dp 52dp 16dp diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java index 74316e22d5..ca08164a05 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java @@ -575,6 +575,10 @@ public abstract class BaseAllAppsContainerView { @@ -666,10 +670,10 @@ public abstract class BaseAllAppsContainerView mAH.get(AdapterHolder.WORK).applyPadding()); - } + + mWorkManager.reset(); + post(() -> mAH.get(AdapterHolder.WORK).applyPadding()); + } else { mWorkManager.detachWorkModeSwitch(); mViewPager = null; diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java index aadd0b52de..c9466a8f43 100644 --- a/src/com/android/launcher3/allapps/WorkModeSwitch.java +++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java @@ -15,17 +15,19 @@ */ package com.android.launcher3.allapps; -import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TURN_OFF_WORK_APPS_TAP; import static com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.getTabWidth; +import android.animation.LayoutTransition; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; -import android.view.ViewGroup.MarginLayoutParams; import android.view.WindowInsets; -import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.core.graphics.Insets; import androidx.core.view.WindowInsetsCompat; @@ -37,55 +39,62 @@ import com.android.launcher3.anim.KeyboardInsetAnimationCallback; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.StringCache; import com.android.launcher3.views.ActivityContext; -import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip; - /** * Work profile toggle switch shown at the bottom of AllApps work tab */ -public class WorkModeSwitch extends Button implements Insettable, View.OnClickListener, - KeyboardInsetAnimationCallback.KeyboardInsetListener, - PersonalWorkSlidingTabStrip.OnActivePageChangedListener { +public class WorkModeSwitch extends LinearLayout implements Insettable, + KeyboardInsetAnimationCallback.KeyboardInsetListener { private static final int FLAG_FADE_ONGOING = 1 << 1; private static final int FLAG_TRANSLATION_ONGOING = 1 << 2; private static final int FLAG_PROFILE_TOGGLE_ONGOING = 1 << 3; + private static final int SCROLL_THRESHOLD_DP = 10; private final Rect mInsets = new Rect(); private final Rect mImeInsets = new Rect(); private int mFlags; - private boolean mWorkEnabled; - private boolean mOnWorkTab; + private final ActivityContext mActivityContext; - public WorkModeSwitch(Context context) { + // Threshold when user scrolls up/down to determine when should button extend/collapse + private final int mScrollThreshold; + private ImageView mIcon; + private TextView mTextView; + + public WorkModeSwitch(@NonNull Context context) { this(context, null, 0); } - public WorkModeSwitch(Context context, AttributeSet attrs) { + public WorkModeSwitch(@NonNull Context context, @NonNull AttributeSet attrs) { this(context, attrs, 0); } - public WorkModeSwitch(Context context, AttributeSet attrs, int defStyleAttr) { + public WorkModeSwitch(@NonNull Context context, @NonNull AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); + mScrollThreshold = Utilities.dpToPx(SCROLL_THRESHOLD_DP); + mActivityContext = ActivityContext.lookupContext(getContext()); } @Override protected void onFinishInflate() { super.onFinishInflate(); + + mIcon = findViewById(R.id.work_icon); + mTextView = findViewById(R.id.pause_text); setSelected(true); - setOnClickListener(this); if (Utilities.ATLEAST_R) { KeyboardInsetAnimationCallback keyboardInsetAnimationCallback = new KeyboardInsetAnimationCallback(this); setWindowInsetsAnimationCallback(keyboardInsetAnimationCallback); } - ActivityContext activityContext = ActivityContext.lookupContext(getContext()); - DeviceProfile grid = activityContext.getDeviceProfile(); - setInsets(grid.getInsets()); - StringCache cache = activityContext.getStringCache(); + setInsets(mActivityContext.getDeviceProfile().getInsets()); + StringCache cache = mActivityContext.getStringCache(); if (cache != null) { - setText(cache.workProfilePauseButton); + mTextView.setText(cache.workProfilePauseButton); } + + mIcon.setColorFilter(mTextView.getCurrentTextColor()); + getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING); } @Override @@ -102,8 +111,6 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi if (!dp.isGestureMode && dp.isTaskbarPresent) { bottomMargin += dp.taskbarSize; - } else { - bottomMargin += insets.bottom; } lp.bottomMargin = bottomMargin; @@ -113,58 +120,32 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); - DeviceProfile dp = ActivityContext.lookupContext(getContext()).getDeviceProfile(); View parent = (View) getParent(); + int allAppsLeftRightPadding = mActivityContext.getDeviceProfile().allAppsLeftRightPadding; int size = parent.getWidth() - parent.getPaddingLeft() - parent.getPaddingRight() - - 2 * dp.allAppsLeftRightPadding; + - 2 * allAppsLeftRightPadding; int tabWidth = getTabWidth(getContext(), size); - int shift = (size - tabWidth) / 2 + dp.allAppsLeftRightPadding; + int shift = (size - tabWidth) / 2 + allAppsLeftRightPadding; setTranslationX(Utilities.isRtl(getResources()) ? shift : -shift); } - @Override - public void onActivePageChanged(int page) { - mOnWorkTab = page == ActivityAllAppsContainerView.AdapterHolder.WORK; - updateVisibility(); - } - - @Override - public void onClick(View view) { - if (Utilities.ATLEAST_P && isEnabled()) { - setFlag(FLAG_PROFILE_TOGGLE_ONGOING); - ActivityContext activityContext = ActivityContext.lookupContext(getContext()); - activityContext.getStatsLogManager().logger().log(LAUNCHER_TURN_OFF_WORK_APPS_TAP); - activityContext.getAppsView().getWorkManager().setWorkProfileEnabled(false); - } - } - @Override public boolean isEnabled() { return super.isEnabled() && getVisibility() == VISIBLE && mFlags == 0; } - /** - * Sets the enabled or disabled state of the button - */ - public void updateCurrentState(boolean isEnabled) { - removeFlag(FLAG_PROFILE_TOGGLE_ONGOING); - if (mWorkEnabled != isEnabled) { - mWorkEnabled = isEnabled; - updateVisibility(); - } - } - - private void updateVisibility() { + public void animateVisibility(boolean visible) { clearAnimation(); - if (mWorkEnabled && mOnWorkTab) { + if (visible) { setFlag(FLAG_FADE_ONGOING); setVisibility(VISIBLE); + extend(); animate().alpha(1).withEndAction(() -> removeFlag(FLAG_FADE_ONGOING)).start(); } else if (getVisibility() != GONE) { setFlag(FLAG_FADE_ONGOING); animate().alpha(0).withEndAction(() -> { removeFlag(FLAG_FADE_ONGOING); - this.setVisibility(GONE); + setVisibility(GONE); }).start(); } } @@ -213,4 +194,16 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi private void removeFlag(int flag) { mFlags &= ~flag; } + + public void extend() { + mTextView.setVisibility(VISIBLE); + } + + public void shrink(){ + mTextView.setVisibility(GONE); + } + + public int getScrollThreshold() { + return mScrollThreshold; + } } diff --git a/src/com/android/launcher3/allapps/WorkProfileManager.java b/src/com/android/launcher3/allapps/WorkProfileManager.java index cfac985c2d..547b74c833 100644 --- a/src/com/android/launcher3/allapps/WorkProfileManager.java +++ b/src/com/android/launcher3/allapps/WorkProfileManager.java @@ -17,6 +17,10 @@ package com.android.launcher3.allapps; import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_DISABLED_CARD; import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_EDU_CARD; +import static com.android.launcher3.allapps.BaseAllAppsContainerView.AdapterHolder.MAIN; +import static com.android.launcher3.allapps.BaseAllAppsContainerView.AdapterHolder.SEARCH; +import static com.android.launcher3.allapps.BaseAllAppsContainerView.AdapterHolder.WORK; +import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TURN_OFF_WORK_APPS_TAP; import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION; import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION; import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED; @@ -28,14 +32,19 @@ import android.os.Process; import android.os.UserHandle; import android.os.UserManager; import android.util.Log; +import android.view.View; import androidx.annotation.IntDef; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; +import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.R; +import com.android.launcher3.Utilities; import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem; import com.android.launcher3.model.data.ItemInfo; +import com.android.launcher3.views.ActivityContext; import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip; import java.lang.annotation.Retention; @@ -104,8 +113,16 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP @Override public void onActivePageChanged(int page) { + updateWorkFAB(page); + } + + private void updateWorkFAB(int page) { if (mWorkModeSwitch != null) { - mWorkModeSwitch.onActivePageChanged(page); + if (page == MAIN || page == SEARCH) { + mWorkModeSwitch.animateVisibility(false); + } else if (page == WORK && mCurrentState == STATE_ENABLED) { + mWorkModeSwitch.animateVisibility(true); + } } } @@ -123,7 +140,12 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP getAH().mAppsList.updateAdapterItems(); } if (mWorkModeSwitch != null) { - mWorkModeSwitch.updateCurrentState(currentState == STATE_ENABLED); + updateWorkFAB(mAllApps.getCurrentPage()); + } + if (mCurrentState == STATE_ENABLED) { + attachWorkModeSwitch(); + } else if (mCurrentState == STATE_DISABLED) { + detachWorkModeSwitch(); } } @@ -140,13 +162,16 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP mWorkModeSwitch = (WorkModeSwitch) mAllApps.getLayoutInflater().inflate( R.layout.work_mode_fab, mAllApps, false); } - if (mWorkModeSwitch.getParent() != mAllApps) { + if (mWorkModeSwitch.getParent() == null) { mAllApps.addView(mWorkModeSwitch); } + if (mAllApps.getCurrentPage() != WORK) { + mWorkModeSwitch.animateVisibility(false); + } if (getAH() != null) { getAH().applyPadding(); } - mWorkModeSwitch.updateCurrentState(mCurrentState == STATE_ENABLED); + mWorkModeSwitch.setOnClickListener(this::onWorkFabClicked); return true; } /** @@ -169,7 +194,7 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP } private BaseAllAppsContainerView.AdapterHolder getAH() { - return mAllApps.mAH.get(BaseAllAppsContainerView.AdapterHolder.WORK); + return mAllApps.mAH.get(WORK); } public int getCurrentState() { @@ -199,4 +224,40 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP private boolean isEduSeen() { return mPreferences.getInt(KEY_WORK_EDU_STEP, 0) != 0; } + + private void onWorkFabClicked(View view) { + if (Utilities.ATLEAST_P && mCurrentState == STATE_ENABLED && mWorkModeSwitch.isEnabled()) { + ActivityContext activityContext = ActivityContext.lookupContext( + mWorkModeSwitch.getContext()); + activityContext.getStatsLogManager().logger().log(LAUNCHER_TURN_OFF_WORK_APPS_TAP); + setWorkProfileEnabled(false); + } + } + + public RecyclerView.OnScrollListener newScrollListener() { + return new RecyclerView.OnScrollListener() { + int totalDelta = 0; + @Override + public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState){ + if (newState == RecyclerView.SCROLL_STATE_IDLE) { + totalDelta = 0; + } + } + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + WorkModeSwitch fab = getWorkModeSwitch(); + if (fab == null){ + return; + } + totalDelta = Utilities.boundToRange(totalDelta, + -fab.getScrollThreshold(), fab.getScrollThreshold()) + dy; + boolean isScrollAtTop = recyclerView.computeVerticalScrollOffset() == 0; + if ((isScrollAtTop || totalDelta < -fab.getScrollThreshold())) { + fab.extend(); + } else if (totalDelta > fab.getScrollThreshold()) { + fab.shrink(); + } + } + }; + } } diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index ce637efa34..4658320582 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -92,6 +92,10 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_HIDE_HEADER = new DeviceFlag("ENABLE_HIDE_HEADER", true, "Hide header on keyboard before typing in all apps"); + public static final BooleanFlag ENABLE_EXPANDING_PAUSE_WORK_BUTTON = new DeviceFlag( + "ENABLE_EXPANDING_PAUSE_WORK_BUTTON", false, + "Expand and collapse pause work button while scrolling"); + public static final BooleanFlag ENABLE_HIDE_HEADER_STATIC = new DeviceFlag( "ENABLE_HIDE_HEADER_STATIC", false, "Hide keyboard suggestion strip");