Merge "Move VibratorWrapper to AOSP" into tm-qpr-dev
diff --git a/quickstep/res/values-sw720dp/dimens.xml b/quickstep/res/values-sw720dp/dimens.xml
index 585f01e..28f7c5d 100644
--- a/quickstep/res/values-sw720dp/dimens.xml
+++ b/quickstep/res/values-sw720dp/dimens.xml
@@ -37,4 +37,7 @@
<!-- All Set page-->
<dimen name="allset_page_allset_text_size">42sp</dimen>
<dimen name="allset_page_swipe_up_text_size">16sp</dimen>
+
+ <!-- Transient taskbar -->
+ <dimen name="transient_taskbar_size">76dp</dimen>
</resources>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 7a3c35f..ad77768 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -281,8 +281,7 @@
<dimen name="taskbar_icon_size_kids">32dp</dimen>
<!-- Transient taskbar -->
- <dimen name="transient_taskbar_size">76dp</dimen>
- <dimen name="transient_taskbar_two_panels_size">72dp</dimen>
+ <dimen name="transient_taskbar_size">72dp</dimen>
<dimen name="transient_taskbar_margin">24dp</dimen>
<dimen name="transient_taskbar_shadow_blur">40dp</dimen>
<dimen name="transient_taskbar_key_shadow_distance">10dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
index a205d19..bbc0627 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
@@ -43,7 +43,7 @@
*/
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 @@
StatefulActivity<LauncherState> 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 @@
} 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/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 6d74526..731eea7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -284,9 +284,7 @@
private void updateIconSize(Resources resources) {
mDeviceProfile.iconSizePx = resources.getDimensionPixelSize(
DisplayController.isTransientTaskbar(this)
- ? mDeviceProfile.isTwoPanels
- ? R.dimen.transient_taskbar_two_panels_icon_size
- : R.dimen.transient_taskbar_icon_size
+ ? R.dimen.transient_taskbar_icon_size
: R.dimen.taskbar_icon_size);
mDeviceProfile.updateIconSize(1f, resources);
}
@@ -694,9 +692,7 @@
}
if (DisplayController.isTransientTaskbar(this)) {
- int taskbarSize = resources.getDimensionPixelSize(mDeviceProfile.isTwoPanels
- ? R.dimen.transient_taskbar_two_panels_size
- : R.dimen.transient_taskbar_size);
+ int taskbarSize = resources.getDimensionPixelSize(R.dimen.transient_taskbar_size);
return taskbarSize
+ (2 * resources.getDimensionPixelSize(R.dimen.transient_taskbar_margin))
+ resources.getDimensionPixelSize(R.dimen.transient_taskbar_shadow_blur);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
index b388512..a48b88f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
@@ -18,8 +18,8 @@
import android.graphics.Insets
import android.graphics.Region
import android.view.InsetsFrameProvider
-import android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES
import android.view.InsetsState
+import android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES
import android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT
import android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR
import android.view.ViewTreeObserver
@@ -82,29 +82,39 @@
val contentHeight = controllers.taskbarStashController.contentHeightToReportToApps
val tappableHeight = controllers.taskbarStashController.tappableHeightToReportToApps
for (provider in windowLayoutParams.providedInsets) {
- if (provider.type == ITYPE_EXTRA_NAVIGATION_BAR) {
+ if (provider.type == ITYPE_EXTRA_NAVIGATION_BAR
+ || provider.type == ITYPE_BOTTOM_MANDATORY_GESTURES) {
provider.insetsSize = getInsetsByNavMode(contentHeight)
- } else if (provider.type == ITYPE_BOTTOM_TAPPABLE_ELEMENT
- || provider.type == ITYPE_BOTTOM_MANDATORY_GESTURES) {
+ } else if (provider.type == ITYPE_BOTTOM_TAPPABLE_ELEMENT) {
provider.insetsSize = getInsetsByNavMode(tappableHeight)
}
}
val imeInsetsSize = getInsetsByNavMode(taskbarHeightForIme)
- // Use 0 insets for the VoiceInteractionWindow (assistant) when gesture nav is enabled.
- val visInsetsSize = getInsetsByNavMode(if (context.isGestureNav) 0 else tappableHeight)
val insetsSizeOverride = arrayOf(
InsetsFrameProvider.InsetsSizeOverride(
TYPE_INPUT_METHOD,
imeInsetsSize
),
+ )
+ // Use 0 tappableElement insets for the VoiceInteractionWindow when gesture nav is enabled.
+ val visInsetsSizeForGestureNavTappableElement = getInsetsByNavMode(0)
+ val insetsSizeOverrideForGestureNavTappableElement = arrayOf(
+ InsetsFrameProvider.InsetsSizeOverride(
+ TYPE_INPUT_METHOD,
+ imeInsetsSize
+ ),
InsetsFrameProvider.InsetsSizeOverride(
TYPE_VOICE_INTERACTION,
- visInsetsSize
- )
+ visInsetsSizeForGestureNavTappableElement
+ ),
)
for (provider in windowLayoutParams.providedInsets) {
- provider.insetsSizeOverrides = insetsSizeOverride
+ if (context.isGestureNav && provider.type == ITYPE_BOTTOM_TAPPABLE_ELEMENT) {
+ provider.insetsSizeOverrides = insetsSizeOverrideForGestureNavTappableElement
+ } else {
+ provider.insetsSizeOverrides = insetsSizeOverride
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 29b8ee3..c269648 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -202,9 +202,7 @@
Resources resources = mActivity.getResources();
boolean isTransientTaskbar = DisplayController.isTransientTaskbar(mActivity);
mUnstashedHeight = resources.getDimensionPixelSize(isTransientTaskbar
- ? (mActivity.getDeviceProfile().isTwoPanels
- ? R.dimen.transient_taskbar_two_panels_size
- : R.dimen.transient_taskbar_size)
+ ? R.dimen.transient_taskbar_size
: R.dimen.taskbar_size);
mStashedHeight = resources.getDimensionPixelSize(isTransientTaskbar
? R.dimen.transient_taskbar_stashed_size
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index a07e4d7..bb76846 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -141,6 +141,7 @@
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;
@@ -664,6 +665,20 @@
}
@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();
handlePendingActivityRequest();
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
index 308249c..c878278 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
@@ -59,10 +59,14 @@
// 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();
diff --git a/res/layout/work_mode_fab.xml b/res/layout/work_mode_fab.xml
index 81b28ba..c116c12 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.
-->
-<com.android.launcher3.allapps.WorkModeSwitch xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/TextHeadline"
+<com.android.launcher3.allapps.WorkModeSwitch
+ xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/work_mode_toggle"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_height="@dimen/work_fab_height"
android:layout_width="wrap_content"
- android:gravity="center"
- android:includeFontPadding="false"
- android:textDirection="locale"
- android:drawableTint="@color/all_apps_tab_text"
- android:textColor="@color/all_apps_tab_text"
- android:textSize="14sp"
+ android:minHeight="@dimen/work_fab_height"
+ android:gravity="center_vertical"
android:background="@drawable/work_apps_toggle_background"
android:forceHasOverlappingRendering="false"
- android:drawablePadding="8dp"
- android:drawableStart="@drawable/ic_corp_off"
- android:layout_marginBottom="@dimen/work_fab_margin_bottom"
- android:paddingLeft="@dimen/work_mode_fab_padding"
- android:paddingRight="@dimen/work_mode_fab_padding"
- android:text="@string/work_apps_pause_btn_text" />
\ No newline at end of file
+ android:contentDescription="@string/work_apps_pause_btn_text"
+ android:animateLayoutChanges="true">
+ <ImageView
+ android:id="@+id/work_icon"
+ android:layout_width="@dimen/work_fab_icon_size"
+ android:layout_height="@dimen/work_fab_icon_size"
+ android:importantForAccessibility="no"
+ android:src="@drawable/ic_corp_off"
+ android:scaleType="center"/>
+ <TextView
+ android:id="@+id/pause_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@color/all_apps_tab_text"
+ android:textSize="14sp"
+ android:includeFontPadding="false"
+ android:textDirection="locale"
+ android:text="@string/work_apps_pause_btn_text"
+ android:layout_marginStart="@dimen/work_fab_text_start_margin"
+ style="@style/TextHeadline"/>
+</com.android.launcher3.allapps.WorkModeSwitch>
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
index 09b2d6f..40e49f1 100644
--- a/res/values-sw720dp/dimens.xml
+++ b/res/values-sw720dp/dimens.xml
@@ -46,4 +46,7 @@
<!-- Folder spaces -->
<dimen name="folder_footer_horiz_padding">24dp</dimen>
+
+ <!-- Transient taskbar -->
+ <dimen name="transient_taskbar_icon_size">57dp</dimen>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 664c2f3..b57eb02 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -149,6 +149,8 @@
<!-- Floating action button inside work tab to toggle work profile -->
<dimen name="work_fab_height">56dp</dimen>
<dimen name="work_fab_radius">16dp</dimen>
+ <dimen name="work_fab_icon_size">24dp</dimen>
+ <dimen name="work_fab_text_start_margin">8dp</dimen>
<dimen name="work_card_padding_horizontal">10dp</dimen>
<dimen name="work_card_button_height">52dp</dimen>
<dimen name="work_fab_margin">16dp</dimen>
@@ -364,11 +366,9 @@
<dimen name="max_hotseat_icon_space">50dp</dimen>
<dimen name="min_hotseat_qsb_width">0dp</dimen>
<dimen name="taskbar_icon_size">44dp</dimen>
- <dimen name="transient_taskbar_icon_size">57dp</dimen>
- <dimen name="transient_taskbar_two_panels_icon_size">50dp</dimen>
+ <dimen name="transient_taskbar_icon_size">50dp</dimen>
<!-- Transient taskbar (placeholders to compile in Launcher3 without Quickstep) -->
<dimen name="transient_taskbar_size">0dp</dimen>
- <dimen name="transient_taskbar_two_panels_size">0dp</dimen>
<dimen name="transient_taskbar_margin">0dp</dimen>
<dimen name="transient_taskbar_shadow_blur">0dp</dimen>
<dimen name="transient_taskbar_key_shadow_distance">0dp</dimen>
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index b95b0af..25520e1 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -325,9 +325,7 @@
if (isTaskbarPresent) {
if (DisplayController.isTransientTaskbar(context)) {
- taskbarSize = res.getDimensionPixelSize(isTwoPanels
- ? R.dimen.transient_taskbar_two_panels_size
- : R.dimen.transient_taskbar_size);
+ taskbarSize = res.getDimensionPixelSize(R.dimen.transient_taskbar_size);
stashedTaskbarSize =
res.getDimensionPixelSize(R.dimen.transient_taskbar_stashed_size);
transientTaskbarMargin =
@@ -1050,12 +1048,9 @@
}
private void updateFolderCellSize(float scale, Resources res) {
- float invIconSizeDp = isVerticalBarLayout()
- ? inv.iconSize[INDEX_LANDSCAPE]
- : inv.iconSize[INDEX_DEFAULT];
+ float invIconSizeDp = inv.iconSize[mTypeIndex];
folderChildIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, scale));
- folderChildTextSizePx =
- pxFromSp(inv.iconTextSize[INDEX_DEFAULT], mMetrics, scale);
+ folderChildTextSizePx = pxFromSp(inv.iconTextSize[mTypeIndex], mMetrics, scale);
folderLabelTextSizePx = Math.max(pxFromSp(MIN_FOLDER_TEXT_SIZE_SP, mMetrics),
(int) (folderChildTextSizePx * folderLabelTextScale));
@@ -1376,7 +1371,7 @@
public int getOverviewActionsClaimedSpaceBelow() {
if (isTaskbarPresent) {
if (FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) {
- return taskbarSize + transientTaskbarMargin;
+ return taskbarSize + transientTaskbarMargin * 2;
}
return isGestureMode
@@ -1647,6 +1642,8 @@
overviewActionsTopMarginPx));
writer.println(prefix + pxToDpStr("overviewActionsHeight",
overviewActionsHeight));
+ writer.println(prefix + pxToDpStr("overviewActionsClaimedSpaceBelow",
+ getOverviewActionsClaimedSpaceBelow()));
writer.println(prefix + pxToDpStr("overviewActionsButtonSpacing",
overviewActionsButtonSpacing));
writer.println(prefix + pxToDpStr("overviewPageSpacing", overviewPageSpacing));
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 932f98a..6ea331d 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -207,12 +207,9 @@
public static final int CONTAINER_BOTTOM_WIDGETS_TRAY = -112;
public static final int CONTAINER_PIN_WIDGETS = -113;
public static final int CONTAINER_WALLPAPERS = -114;
- // Represents search results view.
- public static final int CONTAINER_SEARCH_RESULTS = -106;
public static final int CONTAINER_SHORTCUTS = -107;
public static final int CONTAINER_SETTINGS = -108;
public static final int CONTAINER_TASKSWITCHER = -109;
- public static final int CONTAINER_QSB = -110;
// Represents any of the extended containers implemented in non-AOSP variants.
public static final int EXTENDED_CONTAINERS = -200;
@@ -226,7 +223,6 @@
case CONTAINER_PREDICTION: return "prediction";
case CONTAINER_ALL_APPS: return "all_apps";
case CONTAINER_WIDGETS_TRAY: return "widgets_tray";
- case CONTAINER_SEARCH_RESULTS: return "search_result";
case CONTAINER_SHORTCUTS: return "shortcuts";
default: return String.valueOf(container);
}
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index 74316e2..ca08164 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -575,6 +575,10 @@
mAH.get(AdapterHolder.MAIN).setup(mViewPager.getChildAt(0), mPersonalMatcher);
mAH.get(AdapterHolder.WORK).setup(mViewPager.getChildAt(1), mWorkManager.getMatcher());
mAH.get(AdapterHolder.WORK).mRecyclerView.setId(R.id.apps_list_view_work);
+ if (FeatureFlags.ENABLE_EXPANDING_PAUSE_WORK_BUTTON.get()) {
+ mAH.get(AdapterHolder.WORK).mRecyclerView.addOnScrollListener(
+ mWorkManager.newScrollListener());
+ }
mViewPager.getPageIndicator().setActiveMarker(AdapterHolder.MAIN);
findViewById(R.id.tab_personal)
.setOnClickListener((View view) -> {
@@ -666,10 +670,10 @@
mViewPager = (AllAppsPagedView) newView;
mViewPager.initParentViews(this);
mViewPager.getPageIndicator().setOnActivePageChangedListener(this);
- if (mWorkManager.attachWorkModeSwitch()) {
- mWorkManager.getWorkModeSwitch().post(
- () -> 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 aadd0b5..c9466a8 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.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 @@
if (!dp.isGestureMode && dp.isTaskbarPresent) {
bottomMargin += dp.taskbarSize;
- } else {
- bottomMargin += insets.bottom;
}
lp.bottomMargin = bottomMargin;
@@ -113,58 +120,32 @@
@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 @@
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 cfac985..547b74c 100644
--- a/src/com/android/launcher3/allapps/WorkProfileManager.java
+++ b/src/com/android/launcher3/allapps/WorkProfileManager.java
@@ -17,6 +17,10 @@
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.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 @@
@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 @@
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 @@
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 @@
}
private BaseAllAppsContainerView<?>.AdapterHolder getAH() {
- return mAllApps.mAH.get(BaseAllAppsContainerView.AdapterHolder.WORK);
+ return mAllApps.mAH.get(WORK);
}
public int getCurrentState() {
@@ -199,4 +224,40 @@
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 ce637ef..b46e43f 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -92,6 +92,10 @@
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");
@@ -369,6 +373,10 @@
"Enable the ability to generate monochromatic icons, if it is not provided by the app"
);
+ public static final BooleanFlag ENABLE_TASKBAR_EDU_TOOLTIP = getDebugFlag(
+ "ENABLE_TASKBAR_EDU_TOOLTIP", false,
+ "Enable the tooltip version of the Taskbar education flow.");
+
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
index 0eb86b1..9a961ca 100644
--- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java
+++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
@@ -17,31 +17,41 @@
package com.android.launcher3.graphics;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_DOWNLOAD_APP_UX_V2;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
+import android.os.SystemClock;
import android.util.Property;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.util.Themes;
+import com.android.launcher3.util.window.RefreshRateTracker;
+
+import java.util.WeakHashMap;
+import java.util.function.Function;
/**
* Extension of {@link FastBitmapDrawable} which shows a progress bar around the icon.
*/
-public class PreloadIconDrawable extends FastBitmapDrawable {
+public class PreloadIconDrawable extends FastBitmapDrawable implements Runnable {
private static final Property<PreloadIconDrawable, Float> INTERNAL_STATE =
new Property<PreloadIconDrawable, Float>(Float.TYPE, "internalStateProgress") {
@@ -67,12 +77,20 @@
// Duration = COMPLETE_ANIM_FRACTION * DURATION_SCALE
private static final float COMPLETE_ANIM_FRACTION = 0.3f;
- private static final float SMALL_SCALE = 0.7f;
+ private static final float SMALL_SCALE = ENABLE_DOWNLOAD_APP_UX_V2.get() ? 0.85f : 0.7f;
private static final float PROGRESS_STROKE_SCALE = 0.075f;
private static final int PRELOAD_ACCENT_COLOR_INDEX = 0;
private static final int PRELOAD_BACKGROUND_COLOR_INDEX = 1;
+ private static final int ALPHA_DURATION_MILLIS = 3000;
+ private static final float OVERLAY_ALPHA_RANGE = 127.5f;
+ private static final long WAVE_MOTION_DELAY_FACTOR_MILLIS = 100;
+ private static final WeakHashMap<Integer, PorterDuffColorFilter> COLOR_FILTER_MAP =
+ new WeakHashMap<>();
+ public static final Function<Integer, PorterDuffColorFilter> FILTER_FACTORY =
+ currArgb -> new PorterDuffColorFilter(currArgb, PorterDuff.Mode.SRC_ATOP);
+
private final Matrix mTmpMatrix = new Matrix();
private final PathMeasure mPathMeasure = new PathMeasure();
@@ -96,6 +114,9 @@
private boolean mRanFinishAnimation;
+ private int mOverlayAlpha = 127;
+ private int mRefreshRateMillis;
+
// Progress of the internal state. [0, 1] indicates the fraction of completed progress,
// [1, (1 + COMPLETE_ANIM_FRACTION)] indicates the progress of zoom animation.
private float mInternalStateProgress;
@@ -109,14 +130,16 @@
info,
IconPalette.getPreloadProgressColor(context, info.bitmap.color),
getPreloadColors(context),
- Utilities.isDarkTheme(context));
+ Utilities.isDarkTheme(context),
+ getRefreshRateMillis(context));
}
public PreloadIconDrawable(
ItemInfoWithIcon info,
int indicatorColor,
int[] preloadColors,
- boolean isDarkMode) {
+ boolean isDarkMode,
+ int refreshRateMillis) {
super(info.bitmap);
mItem = info;
mShapePath = GraphicsUtils.getShapePath(DEFAULT_PATH_SIZE);
@@ -130,6 +153,7 @@
mSystemAccentColor = preloadColors[PRELOAD_ACCENT_COLOR_INDEX];
mSystemBackgroundColor = preloadColors[PRELOAD_BACKGROUND_COLOR_INDEX];
mIsDarkMode = isDarkMode;
+ mRefreshRateMillis = refreshRateMillis;
setLevel(info.getProgressLevel());
setIsStartable(info.isAppStartable());
@@ -178,11 +202,17 @@
canvas.scale(mIconScale, mIconScale, bounds.exactCenterX(), bounds.exactCenterY());
super.drawInternal(canvas, bounds);
canvas.restoreToCount(saveCount);
+
+ if (ENABLE_DOWNLOAD_APP_UX_V2.get() && mInternalStateProgress == 0) {
+ reschedule();
+ }
}
@Override
protected void updateFilter() {
- setAlpha(mIsDisabled ? DISABLED_ICON_ALPHA : MAX_PAINT_ALPHA);
+ if (!ENABLE_DOWNLOAD_APP_UX_V2.get()) {
+ setAlpha(mIsDisabled ? DISABLED_ICON_ALPHA : MAX_PAINT_ALPHA);
+ }
}
/**
@@ -237,7 +267,7 @@
mCurrentAnim = ObjectAnimator.ofFloat(this, INTERNAL_STATE, finalProgress);
mCurrentAnim.setDuration(
(long) ((finalProgress - mInternalStateProgress) * DURATION_SCALE));
- mCurrentAnim.setInterpolator(Interpolators.LINEAR);
+ mCurrentAnim.setInterpolator(LINEAR);
if (isFinish) {
mCurrentAnim.addListener(new AnimatorListenerAdapter() {
@Override
@@ -253,13 +283,13 @@
/**
* Sets the internal progress and updates the UI accordingly
* for progress <= 0:
- * - icon in the small scale and disabled state
- * - progress track is visible
+ * - icon with pending motion
+ * - progress track is not visible
* - progress bar is not visible
- * for 0 < progress < 1
- * - icon in the small scale and disabled state
+ * for progress < 1
+ * - icon without pending motion
* - progress track is visible
- * - progress bar is visible with dominant color. Progress bar is drawn as a fraction of
+ * - progress bar is visible. Progress bar is drawn as a fraction of
* {@link #mScaledTrackPath}.
* @see PathMeasure#getSegment(float, float, Path, boolean)
* for 1 <= progress < (1 + COMPLETE_ANIM_FRACTION)
@@ -273,16 +303,18 @@
private void setInternalProgress(float progress) {
mInternalStateProgress = progress;
if (progress <= 0) {
- mIconScale = SMALL_SCALE;
+ mIconScale = ENABLE_DOWNLOAD_APP_UX_V2.get() ? 1 : SMALL_SCALE;
mScaledTrackPath.reset();
mTrackAlpha = MAX_PAINT_ALPHA;
- }
-
- if (progress < 1 && progress > 0) {
+ } else if (progress < 1) {
mPathMeasure.getSegment(0, progress * mTrackLength, mScaledProgressPath, true);
+ if (ENABLE_DOWNLOAD_APP_UX_V2.get()) {
+ mPaint.setColorFilter(null);
+ mPathMeasure.getSegment(0, mTrackLength, mScaledTrackPath, true);
+ }
mIconScale = SMALL_SCALE;
mTrackAlpha = MAX_PAINT_ALPHA;
- } else if (progress >= 1) {
+ } else {
setIsDisabled(mItem.isDisabled());
mScaledTrackPath.set(mScaledProgressPath);
float fraction = (progress - 1) / COMPLETE_ANIM_FRACTION;
@@ -310,6 +342,10 @@
return preloadColors;
}
+ private static int getRefreshRateMillis(Context context) {
+ return RefreshRateTracker.getSingleFrameMs(context);
+ }
+
/**
* Returns a FastBitmapDrawable with the icon.
*/
@@ -325,7 +361,75 @@
mItem,
mIndicatorColor,
new int[] {mSystemAccentColor, mSystemBackgroundColor},
- mIsDarkMode);
+ mIsDarkMode,
+ mRefreshRateMillis);
+ }
+
+ @Override
+ public void run() {
+ if (!ENABLE_DOWNLOAD_APP_UX_V2.get() || mInternalStateProgress > 0) {
+ return;
+ }
+ if (applyPendingIconOverlay()) {
+ invalidateSelf();
+ } else {
+ reschedule();
+ }
+ }
+
+ @Override
+ public boolean setVisible(boolean visible, boolean restart) {
+ boolean result = super.setVisible(visible, restart);
+ if (visible) {
+ reschedule();
+ } else {
+ unscheduleSelf(this);
+ }
+ return result;
+ }
+
+ private void reschedule() {
+ unscheduleSelf(this);
+
+ if (!isVisible()) {
+ return;
+ }
+
+ final long upTime = SystemClock.uptimeMillis();
+ scheduleSelf(this, upTime - ((upTime % mRefreshRateMillis)) + mRefreshRateMillis);
+ }
+
+
+ /**
+ * Apply an overlay on the pending icon with cascading motion based on its position.
+ * Returns {@code true} if the icon alpha is updated, so that we re-draw.
+ */
+ private boolean applyPendingIconOverlay() {
+ long waveMotionDelay = (mItem.cellX * WAVE_MOTION_DELAY_FACTOR_MILLIS)
+ + (mItem.cellY * WAVE_MOTION_DELAY_FACTOR_MILLIS);
+ long time = SystemClock.uptimeMillis();
+ int newAlpha = (int) Utilities.mapBoundToRange(
+ (float) (time + waveMotionDelay) % ALPHA_DURATION_MILLIS,
+ 0,
+ ALPHA_DURATION_MILLIS,
+ 0,
+ MAX_PAINT_ALPHA,
+ LINEAR);
+ if (newAlpha > OVERLAY_ALPHA_RANGE) {
+ newAlpha = (int) (OVERLAY_ALPHA_RANGE - (newAlpha % OVERLAY_ALPHA_RANGE));
+ }
+
+ boolean invalidate = false;
+ if (mOverlayAlpha != newAlpha) {
+ mOverlayAlpha = newAlpha;
+ int overlayColor = mIsDarkMode ? 0 : 255;
+ int currArgb = Color.argb(mOverlayAlpha, overlayColor, overlayColor, overlayColor);
+ mPaint.setColorFilter(COLOR_FILTER_MAP.computeIfAbsent(
+ currArgb,
+ FILTER_FACTORY));
+ invalidate = true;
+ }
+ return invalidate;
}
protected static class PreloadIconConstantState extends FastBitmapConstantState {
@@ -335,6 +439,7 @@
protected final int[] mPreloadColors;
protected final boolean mIsDarkMode;
protected final int mLevel;
+ protected final int mRefreshRateMillis;
public PreloadIconConstantState(
Bitmap bitmap,
@@ -342,13 +447,15 @@
ItemInfoWithIcon info,
int indicatorColor,
int[] preloadColors,
- boolean isDarkMode) {
+ boolean isDarkMode,
+ int refreshRateMillis) {
super(bitmap, iconColor);
mInfo = info;
mIndicatorColor = indicatorColor;
mPreloadColors = preloadColors;
mIsDarkMode = isDarkMode;
mLevel = info.getProgressLevel();
+ mRefreshRateMillis = refreshRateMillis;
}
@Override
@@ -357,7 +464,8 @@
mInfo,
mIndicatorColor,
mPreloadColors,
- mIsDarkMode);
+ mIsDarkMode,
+ mRefreshRateMillis);
}
}
}
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index 159af60..2dd44a4 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -21,7 +21,6 @@
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
-import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SEARCH_RESULTS;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SETTINGS;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SHORTCUTS;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_TASKSWITCHER;
@@ -54,7 +53,6 @@
import com.android.launcher3.logger.LauncherAtom.AllAppsContainer;
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
import com.android.launcher3.logger.LauncherAtom.PredictionContainer;
-import com.android.launcher3.logger.LauncherAtom.SearchResultContainer;
import com.android.launcher3.logger.LauncherAtom.SettingsContainer;
import com.android.launcher3.logger.LauncherAtom.Shortcut;
import com.android.launcher3.logger.LauncherAtom.ShortcutsContainer;
@@ -439,10 +437,6 @@
return ContainerInfo.newBuilder()
.setPredictionContainer(PredictionContainer.getDefaultInstance())
.build();
- case CONTAINER_SEARCH_RESULTS:
- return ContainerInfo.newBuilder()
- .setSearchResultContainer(SearchResultContainer.getDefaultInstance())
- .build();
case CONTAINER_SHORTCUTS:
return ContainerInfo.newBuilder()
.setShortcutsContainer(ShortcutsContainer.getDefaultInstance())
@@ -459,10 +453,12 @@
return ContainerInfo.newBuilder()
.setWallpapersContainer(WallpapersContainer.getDefaultInstance())
.build();
- case EXTENDED_CONTAINERS:
- return ContainerInfo.newBuilder()
- .setExtendedContainers(getExtendedContainer())
- .build();
+ default:
+ if (container <= EXTENDED_CONTAINERS) {
+ return ContainerInfo.newBuilder()
+ .setExtendedContainers(getExtendedContainer())
+ .build();
+ }
}
return ContainerInfo.getDefaultInstance();
}
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index 8e3daf3..c52890f 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -131,13 +131,20 @@
* Returns whether taskbar is transient.
*/
public static boolean isTransientTaskbar(Context context) {
+ return INSTANCE.get(context).isTransientTaskbar();
+ }
+
+ /**
+ * Returns whether taskbar is transient.
+ */
+ public boolean isTransientTaskbar() {
// TODO(b/258604917): When running in test harness, use !sTransientTaskbarStatusForTests
// once tests are updated to expect new persistent behavior such as not allowing long press
// to stash.
if (!Utilities.IS_RUNNING_IN_TEST_HARNESS && FORCE_PERSISTENT_TASKBAR.get()) {
return false;
}
- return getNavigationMode(context) == NavigationMode.NO_BUTTON
+ return getInfo().navigationMode == NavigationMode.NO_BUTTON
&& (Utilities.IS_RUNNING_IN_TEST_HARNESS
? sTransientTaskbarStatusForTests
: ENABLE_TRANSIENT_TASKBAR.get());
diff --git a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
index 98eb32e..10afe13 100644
--- a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
+++ b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
@@ -45,7 +45,8 @@
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 302fabd..ae9ba67 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -1466,19 +1466,22 @@
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 b2a2937..2c82c50 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -385,7 +385,7 @@
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));