From 2461d61e14f245546effa00f76d49c3a17d2af0f Mon Sep 17 00:00:00 2001 From: Perumaal S Date: Mon, 3 Jun 2019 10:21:47 -0700 Subject: [PATCH 01/20] Re-enable chips in qt-r1-dev Fixes: 134164918 Change-Id: Ib5441a40ad8043afbe32d6c4c40808676cdcdb20 --- src/com/android/launcher3/config/BaseFlags.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java index 7e20d11c2b..54d0db1006 100644 --- a/src/com/android/launcher3/config/BaseFlags.java +++ b/src/com/android/launcher3/config/BaseFlags.java @@ -105,7 +105,7 @@ abstract class BaseFlags { "ENABLE_QUICKSTEP_LIVE_TILE", false, "Enable live tile in Quickstep overview"); public static final TogglableFlag ENABLE_HINTS_IN_OVERVIEW = new TogglableFlag( - "ENABLE_HINTS_IN_OVERVIEW", false, + "ENABLE_HINTS_IN_OVERVIEW", true, "Show chip hints and gleams on the overview screen"); public static final TogglableFlag FAKE_LANDSCAPE_UI = new TogglableFlag( From f3231f417db08185ec204b247d331dba6a9b0383 Mon Sep 17 00:00:00 2001 From: Zak Cohen Date: Mon, 3 Jun 2019 14:58:18 -0700 Subject: [PATCH 02/20] Remove unused hints code. This layout is handled by the provider of the hints now. Test: manual Change-Id: Ifc0db2395a7503b1b03dcb796961ef6647c0413b --- .../RecentsViewStateController.java | 18 ----- .../com/android/quickstep/hints/HintUtil.java | 78 ------------------- .../com/android/quickstep/hints/HintView.java | 71 ----------------- .../hints/ProactiveHintsContainer.java | 55 ------------- .../hints/UiHintListenerConstants.java | 28 ------- .../quickstep/hints/UiInterfaceConstants.java | 34 -------- .../quickstep/views/LauncherRecentsView.java | 65 ---------------- res/layout/launcher.xml | 5 -- res/layout/proactive_hints_container.xml | 20 ----- res/values/dimens.xml | 5 -- src/com/android/launcher3/DeviceProfile.java | 7 -- 11 files changed, 386 deletions(-) delete mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintUtil.java delete mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintView.java delete mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java delete mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiHintListenerConstants.java delete mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiInterfaceConstants.java delete mode 100644 res/layout/proactive_hints_container.xml diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 1d36d1aae8..b5d84247a8 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -32,7 +32,6 @@ import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager.AnimationConfig; import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.PropertySetter; -import com.android.quickstep.hints.ProactiveHintsContainer; import com.android.quickstep.views.ClearAllButton; import com.android.quickstep.views.LauncherRecentsView; import com.android.quickstep.views.RecentsView; @@ -55,14 +54,6 @@ public final class RecentsViewStateController extends if (state.overviewUi) { mRecentsView.updateEmptyMessage(); mRecentsView.resetTaskVisuals(); - mRecentsView.setHintVisibility(1f); - } else { - mRecentsView.setHintVisibility(0f); - ProactiveHintsContainer - proactiveHintsContainer = mRecentsView.getProactiveHintsContainer(); - if (proactiveHintsContainer != null) { - proactiveHintsContainer.removeAllViews(); - } } setAlphas(PropertySetter.NO_ANIM_PROPERTY_SETTER, state.getVisibleElements(mLauncher)); mRecentsView.setFullscreenProgress(state.getOverviewFullscreenProgress()); @@ -75,14 +66,6 @@ public final class RecentsViewStateController extends if (!toState.overviewUi) { builder.addOnFinishRunnable(mRecentsView::resetTaskVisuals); - mRecentsView.setHintVisibility(0f); - builder.addOnFinishRunnable(() -> { - ProactiveHintsContainer - proactiveHintsContainer = mRecentsView.getProactiveHintsContainer(); - if (proactiveHintsContainer != null) { - proactiveHintsContainer.removeAllViews(); - } - }); } if (toState.overviewUi) { @@ -94,7 +77,6 @@ public final class RecentsViewStateController extends updateAnim.setDuration(config.duration); builder.play(updateAnim); mRecentsView.updateEmptyMessage(); - builder.addOnFinishRunnable(() -> mRecentsView.setHintVisibility(1f)); } PropertySetter propertySetter = config.getPropertySetter(builder); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintUtil.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintUtil.java deleted file mode 100644 index f2d40ecc4d..0000000000 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintUtil.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.quickstep.hints; - -import android.app.PendingIntent; -import android.graphics.drawable.Icon; -import android.os.Bundle; - -public final class HintUtil { - - public static final String ID_KEY = "id"; - public static final String ICON_KEY = "icon"; - public static final String TEXT_KEY = "text"; - public static final String TAP_ACTION_KEY = "tap_action"; - - private HintUtil() {} - - public static Bundle makeHint(String id, Icon icon, CharSequence text) { - Bundle hint = new Bundle(); - hint.putString(ID_KEY, id); - hint.putParcelable(ICON_KEY, icon); - hint.putCharSequence(TEXT_KEY, text); - return hint; - } - - public static Bundle makeHint(Icon icon, CharSequence text, PendingIntent tapAction) { - Bundle hint = new Bundle(); - hint.putParcelable(ICON_KEY, icon); - hint.putCharSequence(TEXT_KEY, text); - hint.putParcelable(TAP_ACTION_KEY, tapAction); - return hint; - } - - public static String getId(Bundle hint) { - String id = hint.getString(ID_KEY); - if (id == null) { - throw new IllegalArgumentException("Hint does not contain an ID"); - } - return id; - } - - public static Icon getIcon(Bundle hint) { - Icon icon = hint.getParcelable(ICON_KEY); - if (icon == null) { - throw new IllegalArgumentException("Hint does not contain an icon"); - } - return icon; - } - - public static CharSequence getText(Bundle hint) { - CharSequence text = hint.getCharSequence(TEXT_KEY); - if (text == null) { - throw new IllegalArgumentException("Hint does not contain text"); - } - return text; - } - - public static PendingIntent getTapAction(Bundle hint) { - PendingIntent tapAction = hint.getParcelable(TAP_ACTION_KEY); - if (tapAction == null) { - throw new IllegalArgumentException("Hint does not contain a tap action"); - } - return tapAction; - } -} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintView.java deleted file mode 100644 index 5399cc4efc..0000000000 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintView.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.quickstep.hints; - -import static com.android.quickstep.hints.HintUtil.getIcon; -import static com.android.quickstep.hints.HintUtil.getText; - -import android.content.Context; -import android.graphics.drawable.Icon; -import android.os.Bundle; -import android.util.AttributeSet; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.annotation.Nullable; - -import com.android.launcher3.R; - -public class HintView extends LinearLayout { - private ImageView mIconView; - private TextView mLabelView; - - public HintView(Context context) { - super(context); - } - - public HintView(Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - } - - public HintView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - public HintView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - public void setHint(Bundle hint) { - mLabelView.setText(getText(hint)); - - Icon icon = getIcon(hint); - if (icon == null) { - mIconView.setVisibility(GONE); - } else { - mIconView.setImageIcon(icon); - mIconView.setVisibility(VISIBLE); - } - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - mIconView = findViewById(R.id.icon); - mLabelView = findViewById(R.id.label); - } -} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java deleted file mode 100644 index 74a48517b2..0000000000 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.android.quickstep.hints; - -import android.content.Context; -import android.util.AttributeSet; -import android.util.FloatProperty; -import android.view.View; -import android.widget.FrameLayout; - -public class ProactiveHintsContainer extends FrameLayout { - - public static final FloatProperty HINT_VISIBILITY = - new FloatProperty("hint_visibility") { - @Override - public void setValue(ProactiveHintsContainer proactiveHintsContainer, float v) { - proactiveHintsContainer.setHintVisibility(v); - } - - @Override - public Float get(ProactiveHintsContainer proactiveHintsContainer) { - return proactiveHintsContainer.mHintVisibility; - } - }; - - private float mHintVisibility; - - public ProactiveHintsContainer(Context context) { - super(context); - } - - public ProactiveHintsContainer(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public ProactiveHintsContainer(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - public ProactiveHintsContainer(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - public void setView(View v) { - removeAllViews(); - addView(v); - } - - public void setHintVisibility(float v) { - if (v == 1) { - setVisibility(VISIBLE); - } else { - setVisibility(GONE); - } - mHintVisibility = v; - } -} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiHintListenerConstants.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiHintListenerConstants.java deleted file mode 100644 index 420033dd61..0000000000 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiHintListenerConstants.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.quickstep.hints; - -public final class UiHintListenerConstants { - - private UiHintListenerConstants() {} - - // Operations - public static final int ON_HINTS_RETURNED_CODE = 5; - - // Keys - public static final String SESSION_ID_KEY = "session_id"; - public static final String HINTS_KEY = "hints"; -} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiInterfaceConstants.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiInterfaceConstants.java deleted file mode 100644 index 01406130fb..0000000000 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiInterfaceConstants.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.quickstep.hints; - -public final class UiInterfaceConstants { - - private UiInterfaceConstants() {} - - // Operations - public static final int ON_HINT_TAP_CODE = 4; - - public static final int REQUEST_HINTS_CODE = 7; - - // Keys - public static final String SESSION_ID_KEY = "session_id"; - public static final String HINT_ID_KEY = "hint_id"; - public static final String WIDTH_PX_KEY = "width_px"; - public static final String HEIGHT_PX_KEY = "height_px"; - public static final String HINT_SPACE_WIDTH_PX_KEY = "hint_space_width_px"; - public static final String HINT_SPACE_HEIGHT_PX_KEY = "hint_space_height_px"; -} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java index deedd21adb..3b23bd1095 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java @@ -30,13 +30,10 @@ import android.annotation.TargetApi; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; -import android.graphics.RectF; import android.os.Build; import android.util.AttributeSet; import android.view.View; -import androidx.annotation.Nullable; - import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; @@ -44,11 +41,8 @@ import com.android.launcher3.R; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.appprediction.PredictionUiStateManager; import com.android.launcher3.appprediction.PredictionUiStateManager.Client; -import com.android.launcher3.util.PendingAnimation; -import com.android.launcher3.views.BaseDragLayer; import com.android.launcher3.views.ScrimView; import com.android.quickstep.SysUINavigationMode; -import com.android.quickstep.hints.ProactiveHintsContainer; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.ClipAnimationHelper.TransformParams; import com.android.quickstep.util.LayoutUtils; @@ -60,8 +54,6 @@ import com.android.quickstep.util.LayoutUtils; public class LauncherRecentsView extends RecentsView { private final TransformParams mTransformParams = new TransformParams(); - private final int mChipOverhang; - @Nullable private ProactiveHintsContainer mProactiveHintsContainer; public LauncherRecentsView(Context context) { this(context, null); @@ -74,16 +66,6 @@ public class LauncherRecentsView extends RecentsView { public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setContentAlpha(0); - mChipOverhang = (int) context.getResources().getDimension(R.dimen.chip_hint_overhang); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - View hintContainer = mActivity.findViewById(R.id.hints); - mProactiveHintsContainer = - hintContainer instanceof ProactiveHintsContainer - ? (ProactiveHintsContainer) hintContainer : null; } @Override @@ -102,11 +84,6 @@ public class LauncherRecentsView extends RecentsView { } } - @Nullable - public ProactiveHintsContainer getProactiveHintsContainer() { - return mProactiveHintsContainer; - } - @Override public void draw(Canvas canvas) { maybeDrawEmptyMessage(canvas); @@ -160,23 +137,6 @@ public class LauncherRecentsView extends RecentsView { @Override protected void getTaskSize(DeviceProfile dp, Rect outRect) { LayoutUtils.calculateLauncherTaskSize(getContext(), dp, outRect); - if (mProactiveHintsContainer != null) { - BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) mProactiveHintsContainer.getLayoutParams(); - params.bottomMargin = getHeight() - outRect.bottom - mChipOverhang; - params.width = outRect.width(); - } - } - - @Override - public PendingAnimation createTaskLauncherAnimation(TaskView tv, long duration) { - PendingAnimation anim = super.createTaskLauncherAnimation(tv, duration); - - if (mProactiveHintsContainer != null) { - anim.anim.play(ObjectAnimator.ofFloat( - mProactiveHintsContainer, ProactiveHintsContainer.HINT_VISIBILITY, 0)); - } - - return anim; } @Override @@ -194,31 +154,6 @@ public class LauncherRecentsView extends RecentsView { } } - @Override - public PendingAnimation createTaskDismissAnimation(TaskView taskView, boolean animateTaskView, - boolean shouldRemoveTask, long duration) { - PendingAnimation anim = super.createTaskDismissAnimation(taskView, animateTaskView, - shouldRemoveTask, duration); - - if (mProactiveHintsContainer != null) { - anim.anim.play(ObjectAnimator.ofFloat( - mProactiveHintsContainer, ProactiveHintsContainer.HINT_VISIBILITY, 0)); - anim.addEndListener(onEndListener -> { - if (!onEndListener.isSuccess) { - mProactiveHintsContainer.setHintVisibility(1); - } - }); - } - - return anim; - } - - public void setHintVisibility(float v) { - if (mProactiveHintsContainer != null) { - mProactiveHintsContainer.setHintVisibility(v); - } - } - @Override protected void onTaskLaunched(boolean success) { if (success) { diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml index 9cab9c2a5e..cca899bda8 100644 --- a/res/layout/launcher.xml +++ b/res/layout/launcher.xml @@ -48,11 +48,6 @@ layout="@layout/overview_panel" android:visibility="gone" /> - - - - \ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 0da56dafb9..4bcb8a7f43 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -232,11 +232,6 @@ 12sp 14sp - - 26dp - 194dp - 15dp - 8dp diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index c1f898c5d0..883e8c642b 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -99,10 +99,6 @@ public class DeviceProfile { public int folderChildTextSizePx; public int folderChildDrawablePaddingPx; - // Hints - public int chipHintHeightPx; - public int chipHintBottomMarginPx; - // Hotseat public int hotseatCellHeightPx; // In portrait: size = height, in landscape: size = width @@ -200,9 +196,6 @@ public class DeviceProfile { workspaceCellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x); - chipHintHeightPx = res.getDimensionPixelSize(R.dimen.chip_hint_height); - chipHintBottomMarginPx = res.getDimensionPixelSize(R.dimen.chip_hint_bottom_margin); - hotseatBarTopPaddingPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding); hotseatBarBottomPaddingPx = (isTallDevice ? 0 From 9d8b1376e8b8cffefe548164da9e284cf7584fcb Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Mon, 3 Jun 2019 15:59:02 -0700 Subject: [PATCH 03/20] Adding some state for fallback recents View Maintaining a boolean corresponding to overview or QuickSwitch which updates the visuals for RecentsView accordingly Bug: 134166337 Change-Id: If1aec99257de4db1796335f2cf39d2d35789915b --- .../FallbackActivityControllerHelper.java | 30 ++++++-- .../android/quickstep/RecentsActivity.java | 9 ++- .../fallback/FallbackRecentsView.java | 68 +++++++++++++++++++ 3 files changed, 100 insertions(+), 7 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java index dc58a4efc9..2c42fd63a6 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java @@ -17,6 +17,7 @@ package com.android.quickstep; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; +import static com.android.quickstep.fallback.FallbackRecentsView.ZOOM_PROGRESS; import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA; import android.animation.Animator; @@ -33,6 +34,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.userevent.nano.LauncherLogProto; +import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.util.LayoutUtils; import com.android.quickstep.util.RemoteAnimationTargetSet; import com.android.quickstep.views.RecentsView; @@ -120,11 +122,14 @@ public final class FallbackActivityControllerHelper implements return (transitionLength) -> { }; } - RecentsView rv = activity.getOverviewPanel(); + FallbackRecentsView rv = activity.getOverviewPanel(); rv.setContentAlpha(0); rv.getClearAllButton().setVisibilityAlpha(0); rv.setDisallowScrollToClearAll(true); + boolean fromState = !animateActivity; + rv.setInOverviewState(fromState); + return new AnimationFactory() { boolean isAnimatingToRecents = false; @@ -141,15 +146,28 @@ public final class FallbackActivityControllerHelper implements @Override public void createActivityController(long transitionLength) { - if (!isAnimatingToRecents) { - return; + AnimatorSet animatorSet = new AnimatorSet(); + if (isAnimatingToRecents) { + ObjectAnimator anim = ObjectAnimator.ofFloat(rv, CONTENT_ALPHA, 0, 1); + anim.setDuration(transitionLength).setInterpolator(LINEAR); + animatorSet.play(anim); } - ObjectAnimator anim = ObjectAnimator.ofFloat(rv, CONTENT_ALPHA, 0, 1); + ObjectAnimator anim = ObjectAnimator.ofFloat(rv, ZOOM_PROGRESS, 1, 0); anim.setDuration(transitionLength).setInterpolator(LINEAR); - AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(anim); - callback.accept(AnimatorPlaybackController.wrap(animatorSet, transitionLength)); + + AnimatorPlaybackController controller = + AnimatorPlaybackController.wrap(animatorSet, transitionLength); + + // Since we are changing the start position of the UI, reapply the state, at the end + controller.setEndAction(() -> { + boolean endState = true; + rv.setInOverviewState(controller.getInterpolatedProgress() > 0.5 ? + endState : fromState); + }); + + callback.accept(controller); } }; } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java index 5decc3ed6c..32a92618ae 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java @@ -125,7 +125,14 @@ public final class RecentsActivity extends BaseRecentsActivity { @Override public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats, AnimationResult result) { - result.setAnimation(composeRecentsLaunchAnimator(taskView, targetCompats)); + AnimatorSet anim = composeRecentsLaunchAnimator(taskView, targetCompats); + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mFallbackRecentsView.resetViewUI(); + } + }); + result.setAnimation(anim); } }; return ActivityOptionsCompat.makeRemoteAnimation(new RemoteAnimationAdapterCompat( diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java index e254e240aa..b0adbc5bd9 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -15,19 +15,45 @@ */ package com.android.quickstep.fallback; +import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; + import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; import android.util.AttributeSet; +import android.util.FloatProperty; import android.view.View; import com.android.launcher3.DeviceProfile; +import com.android.launcher3.LauncherState.ScaleAndTranslation; +import com.android.launcher3.Utilities; import com.android.quickstep.RecentsActivity; import com.android.quickstep.util.LayoutUtils; import com.android.quickstep.views.RecentsView; +import com.android.quickstep.views.TaskView; public class FallbackRecentsView extends RecentsView { + public static final FloatProperty ZOOM_PROGRESS = + new FloatProperty ("zoomInProgress") { + + @Override + public void setValue(FallbackRecentsView view, float value) { + view.setZoomProgress(value); + } + + @Override + public Float get(FallbackRecentsView view) { + return view.mZoomInProgress; + } + }; + + private float mZoomInProgress = 0; + private boolean mInOverviewState = true; + + private float mZoomScale = 1f; + private float mZoomTranslationY = 0f; + public FallbackRecentsView(Context context, AttributeSet attrs) { this(context, attrs, 0); } @@ -70,4 +96,46 @@ public class FallbackRecentsView extends RecentsView { // Just use the activity task size for multi-window as well. return false; } + + public void resetViewUI() { + setZoomProgress(0); + resetTaskVisuals(); + } + + public void setInOverviewState(boolean inOverviewState) { + if (mInOverviewState != inOverviewState) { + mInOverviewState = inOverviewState; + if (mInOverviewState) { + resetTaskVisuals(); + } else { + setZoomProgress(1); + } + } + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + + if (getTaskViewCount() == 0) { + mZoomScale = 1f; + mZoomTranslationY = 0f; + } else { + TaskView dummyTask = getTaskViewAt(0); + ScaleAndTranslation sat = getTempClipAnimationHelper() + .updateForFullscreenOverview(dummyTask) + .getScaleAndTranslation(); + mZoomScale = sat.scale; + mZoomTranslationY = sat.translationY; + } + + setZoomProgress(mZoomInProgress); + } + + public void setZoomProgress(float progress) { + mZoomInProgress = progress; + SCALE_PROPERTY.set(this, Utilities.mapRange(mZoomInProgress, 1, mZoomScale)); + TRANSLATION_Y.set(this, Utilities.mapRange(mZoomInProgress, 0, mZoomTranslationY)); + FULLSCREEN_PROGRESS.set(this, mZoomInProgress); + } } From ed6a3eada7fa960972b68bb55a2e91844a22c04f Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 4 Jun 2019 10:40:31 -0700 Subject: [PATCH 04/20] Use device locked input consumer when an activity is showing when locked Bug: 133871965 Change-Id: I51a32a99990813e510c757e5e295a09f041c0514 --- .../com/android/quickstep/TouchInteractionService.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 294a997f3d..cbc94ba1f6 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -27,6 +27,8 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_N import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED; import android.annotation.TargetApi; import android.app.ActivityManager; @@ -543,9 +545,11 @@ public class TouchInteractionService extends Service implements if (!useSharedState) { mSwipeSharedState.clearAllState(); } - if (mKM.isDeviceLocked()) { + if ((mSystemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0 + || mKM.isDeviceLocked()) { // This handles apps launched in direct boot mode (e.g. dialer) as well as apps launched - // while device is locked even after exiting direct boot mode (e.g. camera). + // while device is locked after exiting direct boot mode (e.g. camera), or if the + // app is showing over the lockscreen (even if not locked) return createDeviceLockedInputConsumer(runningTaskInfo); } From 1b52c7e5de68e37320447c7dd65406f62570e51f Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 31 May 2019 13:30:13 -0700 Subject: [PATCH 05/20] Some RecentsView layout fixes > Only creating task overlay for one view at a time > Fixing setOverviewStateEnabled called twice when going between OVERVIEW and BACKGROUND state Bug: 132815672 Bug: 122345781 Change-Id: I51ac5b0744af87194eca08e07fd2c75b8fa0d3e0 --- .../uioverrides/RecentsUiFactory.java | 9 ----- .../states/BackgroundAppState.java | 3 -- .../uioverrides/states/OverviewState.java | 8 ---- .../android/quickstep/TaskOverlayFactory.java | 40 ++++++++++--------- .../fallback/FallbackRecentsView.java | 1 + .../quickstep/views/LauncherRecentsView.java | 20 +++++++++- .../android/quickstep/views/RecentsView.java | 34 +++++++++++----- .../android/quickstep/views/TaskMenuView.java | 3 +- .../quickstep/views/TaskThumbnailView.java | 31 +++++++++----- .../com/android/quickstep/views/TaskView.java | 15 +++---- src/com/android/launcher3/LauncherState.java | 3 -- 11 files changed, 94 insertions(+), 73 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java index 336cdc93fe..d84362c9f2 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java @@ -204,15 +204,6 @@ public abstract class RecentsUiFactory { } } - /** - * Clean-up logic that occurs when recents is no longer in use/visible. - * - * @param launcher the launcher activity - */ - public static void resetOverview(Launcher launcher) { - launcher.getOverviewPanel().reset(); - } - /** * Recents logic that triggers when launcher state changes or launcher activity stops/resumes. * diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java index 8436fe5f9d..f1d6450a5f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java @@ -21,7 +21,6 @@ import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.Launcher; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.userevent.nano.LauncherLogProto; -import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.LayoutUtils; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; @@ -45,8 +44,6 @@ public class BackgroundAppState extends OverviewState { @Override public void onStateEnabled(Launcher launcher) { - RecentsView rv = launcher.getOverviewPanel(); - rv.setOverviewStateEnabled(true); AbstractFloatingView.closeAllOpenViews(launcher, false); } diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java index cda03dcde1..9a99c15522 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java @@ -86,17 +86,9 @@ public class OverviewState extends LauncherState { @Override public void onStateEnabled(Launcher launcher) { - RecentsView rv = launcher.getOverviewPanel(); - rv.setOverviewStateEnabled(true); AbstractFloatingView.closeAllOpenViews(launcher); } - @Override - public void onStateDisabled(Launcher launcher) { - RecentsView rv = launcher.getOverviewPanel(); - rv.setOverviewStateEnabled(false); - } - @Override public void onStateTransitionEnd(Launcher launcher) { launcher.getRotationHelper().setCurrentStateRequest(REQUEST_ROTATE); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java index 84af109a3b..5104fb8801 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java @@ -36,8 +36,6 @@ import java.util.List; */ public class TaskOverlayFactory implements ResourceBasedOverride { - public static final String AIAI_PACKAGE = "com.google.android.as"; - /** Note that these will be shown in order from top to bottom, if available for the task. */ private static final TaskSystemShortcut[] MENU_OPTIONS = new TaskSystemShortcut[]{ new TaskSystemShortcut.AppInfo(), @@ -51,29 +49,33 @@ public class TaskOverlayFactory implements ResourceBasedOverride { new MainThreadInitializedObject<>(c -> Overrides.getObject(TaskOverlayFactory.class, c, R.string.task_overlay_factory_class)); + public List getEnabledShortcuts(TaskView taskView) { + final ArrayList shortcuts = new ArrayList<>(); + final BaseDraggingActivity activity = BaseActivity.fromContext(taskView.getContext()); + for (TaskSystemShortcut menuOption : MENU_OPTIONS) { + View.OnClickListener onClickListener = + menuOption.getOnClickListener(activity, taskView); + if (onClickListener != null) { + shortcuts.add(menuOption); + } + } + return shortcuts; + } + public TaskOverlay createOverlay(View thumbnailView) { return new TaskOverlay(); } public static class TaskOverlay { - public void setTaskInfo(Task task, ThumbnailData thumbnail, Matrix matrix) { - } + /** + * Called when the current task is interactive for the user + */ + public void initOverlay(Task task, ThumbnailData thumbnail, Matrix matrix) { } - public void reset() { - } - - public List getEnabledShortcuts(TaskView taskView) { - final ArrayList shortcuts = new ArrayList<>(); - final BaseDraggingActivity activity = BaseActivity.fromContext(taskView.getContext()); - for (TaskSystemShortcut menuOption : MENU_OPTIONS) { - View.OnClickListener onClickListener = - menuOption.getOnClickListener(activity, taskView); - if (onClickListener != null) { - shortcuts.add(menuOption); - } - } - return shortcuts; - } + /** + * Called when the overlay is no longer used. + */ + public void reset() { } } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java index e254e240aa..a5aa1bf527 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -35,6 +35,7 @@ public class FallbackRecentsView extends RecentsView { public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setOverviewStateEnabled(true); + setOverlayEnabled(true); } @Override diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java index deedd21adb..41628459c3 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java @@ -20,6 +20,7 @@ import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.RECENTS_CLEAR_ALL_BUTTON; +import static com.android.launcher3.LauncherState.SPRING_LOADED; import static com.android.launcher3.QuickstepAppTransitionManagerImpl.ALL_APPS_PROGRESS_OFF_SCREEN; import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; @@ -30,7 +31,6 @@ import android.annotation.TargetApi; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; -import android.graphics.RectF; import android.os.Build; import android.util.AttributeSet; import android.view.View; @@ -40,6 +40,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; +import com.android.launcher3.LauncherStateManager.StateListener; import com.android.launcher3.R; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.appprediction.PredictionUiStateManager; @@ -57,7 +58,7 @@ import com.android.quickstep.util.LayoutUtils; * {@link RecentsView} used in Launcher activity */ @TargetApi(Build.VERSION_CODES.O) -public class LauncherRecentsView extends RecentsView { +public class LauncherRecentsView extends RecentsView implements StateListener { private final TransformParams mTransformParams = new TransformParams(); private final int mChipOverhang; @@ -75,6 +76,7 @@ public class LauncherRecentsView extends RecentsView { super(context, attrs, defStyleAttr); setContentAlpha(0); mChipOverhang = (int) context.getResources().getDimension(R.dimen.chip_hint_overhang); + mActivity.getStateManager().addStateListener(this); } @Override @@ -286,6 +288,20 @@ public class LauncherRecentsView extends RecentsView { PredictionUiStateManager.INSTANCE.get(getContext()).switchClient(Client.HOME); } + @Override + public void onStateTransitionStart(LauncherState toState) { + setOverviewStateEnabled(toState.overviewUi); + } + + @Override + public void onStateTransitionComplete(LauncherState finalState) { + if (finalState == NORMAL || finalState == SPRING_LOADED) { + // Clean-up logic that occurs when recents is no longer in use/visible. + reset(); + } + setOverlayEnabled(finalState == OVERVIEW); + } + @Override public void setOverviewStateEnabled(boolean enabled) { super.setOverviewStateEnabled(enabled); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 1e1007e686..38bd46172f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -72,6 +72,9 @@ import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.ListView; +import androidx.annotation.Nullable; +import androidx.dynamicanimation.animation.SpringForce; + import com.android.launcher3.BaseActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; @@ -111,9 +114,6 @@ import com.android.systemui.shared.system.TaskStackChangeListener; import java.util.ArrayList; import java.util.function.Consumer; -import androidx.annotation.Nullable; -import androidx.dynamicanimation.animation.SpringForce; - /** * A list of recent tasks. */ @@ -168,8 +168,6 @@ public abstract class RecentsView extends PagedView impl // The threshold at which we update the SystemUI flags when animating from the task into the app public static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.85f; - private static final float[] sTempFloatArray = new float[3]; - protected final T mActivity; private final float mFastFlingVelocity; private final RecentsModel mModel; @@ -189,6 +187,7 @@ public abstract class RecentsView extends PagedView impl private boolean mDwbToastShown; private boolean mDisallowScrollToClearAll; + private boolean mOverlayEnabled; /** * TODO: Call reloadIdNeeded in onTaskStackChanged. @@ -428,11 +427,7 @@ public abstract class RecentsView extends PagedView impl // Clear the task data for the removed child if it was visible if (child != mClearAllButton) { TaskView taskView = (TaskView) child; - Task task = taskView.getTask(); - if (mHasVisibleTaskData.get(task.key.id)) { - mHasVisibleTaskData.delete(task.key.id); - taskView.onTaskListVisibilityChanged(false /* visible */); - } + mHasVisibleTaskData.delete(taskView.getTask().key.id); mTaskViewPool.recycle(taskView); } } @@ -455,7 +450,6 @@ public abstract class RecentsView extends PagedView impl public void setOverviewStateEnabled(boolean enabled) { mOverviewStateEnabled = enabled; updateTaskStackListenerState(); - if (!enabled) mDwbToastShown = false; } public void onDigitalWellbeingToastShown() { @@ -582,6 +576,7 @@ public abstract class RecentsView extends PagedView impl } resetTaskVisuals(); onTaskStackUpdated(); + updateEnabledOverlays(); } public int getTaskViewCount() { @@ -780,6 +775,7 @@ public abstract class RecentsView extends PagedView impl unloadVisibleTaskData(); setCurrentPage(0); + mDwbToastShown = false; } public @Nullable TaskView getRunningTaskView() { @@ -1545,6 +1541,7 @@ public abstract class RecentsView extends PagedView impl protected void notifyPageSwitchListener(int prevPage) { super.notifyPageSwitchListener(prevPage); loadVisibleTaskData(); + updateEnabledOverlays(); } @Override @@ -1685,4 +1682,19 @@ public abstract class RecentsView extends PagedView impl public ClipAnimationHelper getTempClipAnimationHelper() { return mTempClipAnimationHelper; } + + private void updateEnabledOverlays() { + int overlayEnabledPage = mOverlayEnabled ? getNextPage() : -1; + int taskCount = getTaskViewCount(); + for (int i = 0; i < taskCount; i++) { + ((TaskView) getChildAt(i)).setOverlayEnabled(i == overlayEnabledPage); + } + } + + public void setOverlayEnabled(boolean overlayEnabled) { + if (mOverlayEnabled != overlayEnabled) { + mOverlayEnabled = overlayEnabled; + updateEnabledOverlays(); + } + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java index c47e943bee..c1f6b82ec2 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java @@ -42,6 +42,7 @@ import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.util.Themes; import com.android.launcher3.views.BaseDragLayer; +import com.android.quickstep.TaskOverlayFactory; import com.android.quickstep.TaskSystemShortcut; import com.android.quickstep.TaskUtils; import com.android.quickstep.views.IconView.OnScaleUpdateListener; @@ -196,7 +197,7 @@ public class TaskMenuView extends AbstractFloatingView { final BaseDraggingActivity activity = BaseDraggingActivity.fromContext(getContext()); final List shortcuts = - taskView.getTaskOverlay().getEnabledShortcuts(taskView); + TaskOverlayFactory.INSTANCE.get(getContext()).getEnabledShortcuts(taskView); final int count = shortcuts.size(); for (int i = 0; i < count; ++i) { final TaskSystemShortcut menuOption = shortcuts.get(i); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java index df5831b088..8b8240d0a5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java @@ -98,6 +98,9 @@ public class TaskThumbnailView extends View { private float mDimAlphaMultiplier = 1f; private float mSaturation = 1f; + private boolean mOverlayEnabled; + private boolean mRotated; + public TaskThumbnailView(Context context) { this(context, null); } @@ -192,10 +195,6 @@ public class TaskThumbnailView extends View { return 0; } - public TaskOverlay getTaskOverlay() { - return mOverlay; - } - @Override protected void onDraw(Canvas canvas) { RectF currentDrawnInsets = mFullscreenParams.mCurrentDrawnInsets; @@ -257,6 +256,22 @@ public class TaskThumbnailView extends View { return (TaskView) getParent(); } + public void setOverlayEnabled(boolean overlayEnabled) { + if (mOverlayEnabled != overlayEnabled) { + mOverlayEnabled = overlayEnabled; + updateOverlay(); + } + } + + private void updateOverlay() { + // The overlay doesn't really work when the screenshot is rotated, so don't add it. + if (mOverlayEnabled && !mRotated && mBitmapShader != null && mThumbnailData != null) { + mOverlay.initOverlay(mTask, mThumbnailData, mMatrix); + } else { + mOverlay.reset(); + } + } + private void updateThumbnailPaintFilter() { int mul = (int) ((1 - mDimAlpha * mDimAlphaMultiplier) * 255); ColorFilter filter = getColorFilter(mul, mIsDarkTextTheme, mSaturation); @@ -351,12 +366,8 @@ public class TaskThumbnailView extends View { mPaint.setShader(mBitmapShader); } - if (isRotated) { - // The overlay doesn't really work when the screenshot is rotated, so don't add it. - mOverlay.reset(); - } else { - mOverlay.setTaskInfo(mTask, mThumbnailData, mMatrix); - } + mRotated = isRotated; + updateOverlay(); invalidate(); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java index f8d454f34e..bf3e91ff68 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java @@ -39,7 +39,6 @@ import android.os.Handler; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.Log; -import android.util.Property; import android.view.View; import android.view.ViewOutlineProvider; import android.view.accessibility.AccessibilityNodeInfo; @@ -253,10 +252,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { return mIconView; } - public TaskOverlayFactory.TaskOverlay getTaskOverlay() { - return mSnapshotView.getTaskOverlay(); - } - public AnimatorPlaybackController createLaunchAnimationForRunningTask() { final PendingAnimation pendingAnimation = getRecentsView().createTaskLauncherAnimation(this, RECENTS_LAUNCH_DURATION); @@ -488,6 +483,8 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { // Clear any references to the thumbnail (it will be re-read either from the cache or the // system on next bind) mSnapshotView.setThumbnail(mTask, null); + setOverlayEnabled(false); + onTaskListVisibilityChanged(false); if (mTask != null) { mTask.thumbnail = null; } @@ -608,7 +605,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { final Context context = getContext(); final List shortcuts = - mSnapshotView.getTaskOverlay().getEnabledShortcuts(this); + TaskOverlayFactory.INSTANCE.get(getContext()).getEnabledShortcuts(this); final int count = shortcuts.size(); for (int i = 0; i < count; ++i) { final TaskSystemShortcut menuOption = shortcuts.get(i); @@ -647,7 +644,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { } final List shortcuts = - mSnapshotView.getTaskOverlay().getEnabledShortcuts(this); + TaskOverlayFactory.INSTANCE.get(getContext()).getEnabledShortcuts(this); final int count = shortcuts.size(); for (int i = 0; i < count; ++i) { final TaskSystemShortcut menuOption = shortcuts.get(i); @@ -733,6 +730,10 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { return mShowScreenshot; } + public void setOverlayEnabled(boolean overlayEnabled) { + mSnapshotView.setOverlayEnabled(overlayEnabled); + } + /** * We update and subsequently draw these in {@link #setFullscreenProgress(float)}. */ diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java index 3a92dfb961..c63f976a87 100644 --- a/src/com/android/launcher3/LauncherState.java +++ b/src/com/android/launcher3/LauncherState.java @@ -258,9 +258,6 @@ public class LauncherState { * Called when the start transition ends and the user settles on this particular state. */ public void onStateTransitionEnd(Launcher launcher) { - if (this == NORMAL || this == SPRING_LOADED) { - UiFactory.resetOverview(launcher); - } if (this == NORMAL) { // Clear any rotation locks when going to normal state launcher.getRotationHelper().setCurrentStateRequest(REQUEST_NONE); From ae087dc9b8f4cbd2f8d44fd291298ab01ac696c6 Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 4 Jun 2019 19:25:03 -0700 Subject: [PATCH 06/20] Fade out scrim when swiping to home Bug: 134517106 Change-Id: Ica725e3a327c1c069e3859732ea6a878d361a3d8 --- .../util/StaggeredWorkspaceAnim.java | 22 ++++++++++++++++++- src/com/android/launcher3/Workspace.java | 4 ++++ .../WorkspaceStateTransitionAnimation.java | 5 ++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java index 837c2dc935..9eda2f9d4d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java @@ -28,13 +28,20 @@ import com.android.launcher3.CellLayout; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils.ViewProgressProperty; +import com.android.launcher3.LauncherState; +import com.android.launcher3.LauncherStateManager; +import com.android.launcher3.LauncherStateManager.AnimationConfig; import com.android.launcher3.R; import com.android.launcher3.ShortcutAndWidgetContainer; +import com.android.launcher3.anim.AnimatorSetBuilder; +import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.anim.SpringObjectAnimator; import java.util.ArrayList; import java.util.List; +import static com.android.launcher3.LauncherState.BACKGROUND_APP; +import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.anim.Interpolators.LINEAR; /** @@ -56,7 +63,7 @@ public class StaggeredWorkspaceAnim { private final float mSpringTransY; private final View mViewToIgnore; - private final List mAnimators = new ArrayList<>(); + private final List mAnimators = new ArrayList<>(); /** * @param floatingViewOriginalView The FloatingIconView's original view. @@ -104,6 +111,9 @@ public class StaggeredWorkspaceAnim { View qsb = launcher.findViewById(R.id.search_container_all_apps); addStaggeredAnimationForView(qsb, grid.inv.numRows + 2, totalRows); } + + addWorkspaceScrimAnimationForState(launcher, BACKGROUND_APP, 0); + addWorkspaceScrimAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS); } /** @@ -150,4 +160,14 @@ public class StaggeredWorkspaceAnim { alpha.setStartDelay(startDelay); mAnimators.add(alpha); } + + private void addWorkspaceScrimAnimationForState(Launcher launcher, LauncherState state, + long duration) { + AnimatorSetBuilder scrimAnimBuilder = new AnimatorSetBuilder(); + AnimationConfig scrimAnimConfig = new AnimationConfig(); + scrimAnimConfig.duration = duration; + PropertySetter scrimPropertySetter = scrimAnimConfig.getPropertySetter(scrimAnimBuilder); + launcher.getWorkspace().getStateTransitionAnimation().setScrim(scrimPropertySetter, state); + mAnimators.add(scrimAnimBuilder.build()); + } } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index f784226a51..9f846bbc4d 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -1394,6 +1394,10 @@ public class Workspace extends PagedView builder.play(stepAnimator); } + public WorkspaceStateTransitionAnimation getStateTransitionAnimation() { + return mStateTransitionAnimation; + } + public void updateAccessibilityFlags() { // TODO: Update the accessibility flags appropriately when dragging. int accessibilityFlag = mLauncher.getStateManager().getState().workspaceAccessibilityFlag; diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java index 8d0259d050..065d065682 100644 --- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java +++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java @@ -130,7 +130,10 @@ public class WorkspaceStateTransitionAnimation { propertySetter.setFloat(mWorkspace.getPageIndicator(), View.TRANSLATION_Y, hotseatScaleAndTranslation.translationY, translationInterpolator); - // Set scrim + setScrim(propertySetter, state); + } + + public void setScrim(PropertySetter propertySetter, LauncherState state) { WorkspaceAndHotseatScrim scrim = mLauncher.getDragLayer().getScrim(); propertySetter.setFloat(scrim, SCRIM_PROGRESS, state.getWorkspaceScrimAlpha(mLauncher), LINEAR); From 88dd84254c2508fee387a47ed153840c4f72143f Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Wed, 5 Jun 2019 11:07:17 -0700 Subject: [PATCH 07/20] Reduce alpha delay 25ms to reduce flashy feeling of appearing large. Bug: 123900446 Change-Id: Ia8ff74eb6b65affbf5c6c1599f4d168b459f324e --- .../android/launcher3/QuickstepAppTransitionManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java index dcf2e3c155..46161cbc8a 100644 --- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java @@ -108,7 +108,7 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans // Use a shorter duration for x or y translation to create a curve effect private static final long APP_LAUNCH_CURVED_DURATION = 250; private static final long APP_LAUNCH_ALPHA_DURATION = 50; - private static final long APP_LAUNCH_ALPHA_START_DELAY = 50; + private static final long APP_LAUNCH_ALPHA_START_DELAY = 25; // We scale the durations for the downward app launch animations (minus the scale animation). private static final float APP_LAUNCH_DOWN_DUR_SCALE_FACTOR = 0.8f; From 8d19146b7b90664e1290d1c186c93e6d17fa94e8 Mon Sep 17 00:00:00 2001 From: Zak Cohen Date: Mon, 3 Jun 2019 14:58:18 -0700 Subject: [PATCH 08/20] Remove unused hints code. This layout is handled by the provider of the hints now. Bug: 132886768 Test: manual Change-Id: Ifc0db2395a7503b1b03dcb796961ef6647c0413b (cherry picked from commit f3231f417db08185ec204b247d331dba6a9b0383) --- .../RecentsViewStateController.java | 18 ----- .../com/android/quickstep/hints/HintUtil.java | 78 ------------------- .../com/android/quickstep/hints/HintView.java | 71 ----------------- .../hints/ProactiveHintsContainer.java | 55 ------------- .../hints/UiHintListenerConstants.java | 28 ------- .../quickstep/hints/UiInterfaceConstants.java | 34 -------- .../quickstep/views/LauncherRecentsView.java | 64 --------------- res/layout/launcher.xml | 5 -- res/layout/proactive_hints_container.xml | 20 ----- res/values/dimens.xml | 5 -- src/com/android/launcher3/DeviceProfile.java | 7 -- 11 files changed, 385 deletions(-) delete mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintUtil.java delete mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintView.java delete mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java delete mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiHintListenerConstants.java delete mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiInterfaceConstants.java delete mode 100644 res/layout/proactive_hints_container.xml diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 1d36d1aae8..b5d84247a8 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -32,7 +32,6 @@ import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager.AnimationConfig; import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.PropertySetter; -import com.android.quickstep.hints.ProactiveHintsContainer; import com.android.quickstep.views.ClearAllButton; import com.android.quickstep.views.LauncherRecentsView; import com.android.quickstep.views.RecentsView; @@ -55,14 +54,6 @@ public final class RecentsViewStateController extends if (state.overviewUi) { mRecentsView.updateEmptyMessage(); mRecentsView.resetTaskVisuals(); - mRecentsView.setHintVisibility(1f); - } else { - mRecentsView.setHintVisibility(0f); - ProactiveHintsContainer - proactiveHintsContainer = mRecentsView.getProactiveHintsContainer(); - if (proactiveHintsContainer != null) { - proactiveHintsContainer.removeAllViews(); - } } setAlphas(PropertySetter.NO_ANIM_PROPERTY_SETTER, state.getVisibleElements(mLauncher)); mRecentsView.setFullscreenProgress(state.getOverviewFullscreenProgress()); @@ -75,14 +66,6 @@ public final class RecentsViewStateController extends if (!toState.overviewUi) { builder.addOnFinishRunnable(mRecentsView::resetTaskVisuals); - mRecentsView.setHintVisibility(0f); - builder.addOnFinishRunnable(() -> { - ProactiveHintsContainer - proactiveHintsContainer = mRecentsView.getProactiveHintsContainer(); - if (proactiveHintsContainer != null) { - proactiveHintsContainer.removeAllViews(); - } - }); } if (toState.overviewUi) { @@ -94,7 +77,6 @@ public final class RecentsViewStateController extends updateAnim.setDuration(config.duration); builder.play(updateAnim); mRecentsView.updateEmptyMessage(); - builder.addOnFinishRunnable(() -> mRecentsView.setHintVisibility(1f)); } PropertySetter propertySetter = config.getPropertySetter(builder); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintUtil.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintUtil.java deleted file mode 100644 index f2d40ecc4d..0000000000 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintUtil.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.quickstep.hints; - -import android.app.PendingIntent; -import android.graphics.drawable.Icon; -import android.os.Bundle; - -public final class HintUtil { - - public static final String ID_KEY = "id"; - public static final String ICON_KEY = "icon"; - public static final String TEXT_KEY = "text"; - public static final String TAP_ACTION_KEY = "tap_action"; - - private HintUtil() {} - - public static Bundle makeHint(String id, Icon icon, CharSequence text) { - Bundle hint = new Bundle(); - hint.putString(ID_KEY, id); - hint.putParcelable(ICON_KEY, icon); - hint.putCharSequence(TEXT_KEY, text); - return hint; - } - - public static Bundle makeHint(Icon icon, CharSequence text, PendingIntent tapAction) { - Bundle hint = new Bundle(); - hint.putParcelable(ICON_KEY, icon); - hint.putCharSequence(TEXT_KEY, text); - hint.putParcelable(TAP_ACTION_KEY, tapAction); - return hint; - } - - public static String getId(Bundle hint) { - String id = hint.getString(ID_KEY); - if (id == null) { - throw new IllegalArgumentException("Hint does not contain an ID"); - } - return id; - } - - public static Icon getIcon(Bundle hint) { - Icon icon = hint.getParcelable(ICON_KEY); - if (icon == null) { - throw new IllegalArgumentException("Hint does not contain an icon"); - } - return icon; - } - - public static CharSequence getText(Bundle hint) { - CharSequence text = hint.getCharSequence(TEXT_KEY); - if (text == null) { - throw new IllegalArgumentException("Hint does not contain text"); - } - return text; - } - - public static PendingIntent getTapAction(Bundle hint) { - PendingIntent tapAction = hint.getParcelable(TAP_ACTION_KEY); - if (tapAction == null) { - throw new IllegalArgumentException("Hint does not contain a tap action"); - } - return tapAction; - } -} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintView.java deleted file mode 100644 index 5399cc4efc..0000000000 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/HintView.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.quickstep.hints; - -import static com.android.quickstep.hints.HintUtil.getIcon; -import static com.android.quickstep.hints.HintUtil.getText; - -import android.content.Context; -import android.graphics.drawable.Icon; -import android.os.Bundle; -import android.util.AttributeSet; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.annotation.Nullable; - -import com.android.launcher3.R; - -public class HintView extends LinearLayout { - private ImageView mIconView; - private TextView mLabelView; - - public HintView(Context context) { - super(context); - } - - public HintView(Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - } - - public HintView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - public HintView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - public void setHint(Bundle hint) { - mLabelView.setText(getText(hint)); - - Icon icon = getIcon(hint); - if (icon == null) { - mIconView.setVisibility(GONE); - } else { - mIconView.setImageIcon(icon); - mIconView.setVisibility(VISIBLE); - } - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - mIconView = findViewById(R.id.icon); - mLabelView = findViewById(R.id.label); - } -} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java deleted file mode 100644 index 74a48517b2..0000000000 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.android.quickstep.hints; - -import android.content.Context; -import android.util.AttributeSet; -import android.util.FloatProperty; -import android.view.View; -import android.widget.FrameLayout; - -public class ProactiveHintsContainer extends FrameLayout { - - public static final FloatProperty HINT_VISIBILITY = - new FloatProperty("hint_visibility") { - @Override - public void setValue(ProactiveHintsContainer proactiveHintsContainer, float v) { - proactiveHintsContainer.setHintVisibility(v); - } - - @Override - public Float get(ProactiveHintsContainer proactiveHintsContainer) { - return proactiveHintsContainer.mHintVisibility; - } - }; - - private float mHintVisibility; - - public ProactiveHintsContainer(Context context) { - super(context); - } - - public ProactiveHintsContainer(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public ProactiveHintsContainer(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - public ProactiveHintsContainer(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - public void setView(View v) { - removeAllViews(); - addView(v); - } - - public void setHintVisibility(float v) { - if (v == 1) { - setVisibility(VISIBLE); - } else { - setVisibility(GONE); - } - mHintVisibility = v; - } -} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiHintListenerConstants.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiHintListenerConstants.java deleted file mode 100644 index 420033dd61..0000000000 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiHintListenerConstants.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.quickstep.hints; - -public final class UiHintListenerConstants { - - private UiHintListenerConstants() {} - - // Operations - public static final int ON_HINTS_RETURNED_CODE = 5; - - // Keys - public static final String SESSION_ID_KEY = "session_id"; - public static final String HINTS_KEY = "hints"; -} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiInterfaceConstants.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiInterfaceConstants.java deleted file mode 100644 index 01406130fb..0000000000 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/UiInterfaceConstants.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.quickstep.hints; - -public final class UiInterfaceConstants { - - private UiInterfaceConstants() {} - - // Operations - public static final int ON_HINT_TAP_CODE = 4; - - public static final int REQUEST_HINTS_CODE = 7; - - // Keys - public static final String SESSION_ID_KEY = "session_id"; - public static final String HINT_ID_KEY = "hint_id"; - public static final String WIDTH_PX_KEY = "width_px"; - public static final String HEIGHT_PX_KEY = "height_px"; - public static final String HINT_SPACE_WIDTH_PX_KEY = "hint_space_width_px"; - public static final String HINT_SPACE_HEIGHT_PX_KEY = "hint_space_height_px"; -} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java index 41628459c3..8ad5f27c33 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java @@ -35,8 +35,6 @@ import android.os.Build; import android.util.AttributeSet; import android.view.View; -import androidx.annotation.Nullable; - import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; @@ -45,11 +43,8 @@ import com.android.launcher3.R; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.appprediction.PredictionUiStateManager; import com.android.launcher3.appprediction.PredictionUiStateManager.Client; -import com.android.launcher3.util.PendingAnimation; -import com.android.launcher3.views.BaseDragLayer; import com.android.launcher3.views.ScrimView; import com.android.quickstep.SysUINavigationMode; -import com.android.quickstep.hints.ProactiveHintsContainer; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.ClipAnimationHelper.TransformParams; import com.android.quickstep.util.LayoutUtils; @@ -61,8 +56,6 @@ import com.android.quickstep.util.LayoutUtils; public class LauncherRecentsView extends RecentsView implements StateListener { private final TransformParams mTransformParams = new TransformParams(); - private final int mChipOverhang; - @Nullable private ProactiveHintsContainer mProactiveHintsContainer; public LauncherRecentsView(Context context) { this(context, null); @@ -75,19 +68,9 @@ public class LauncherRecentsView extends RecentsView implements StateL public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setContentAlpha(0); - mChipOverhang = (int) context.getResources().getDimension(R.dimen.chip_hint_overhang); mActivity.getStateManager().addStateListener(this); } - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - View hintContainer = mActivity.findViewById(R.id.hints); - mProactiveHintsContainer = - hintContainer instanceof ProactiveHintsContainer - ? (ProactiveHintsContainer) hintContainer : null; - } - @Override public void startHome() { mActivity.getStateManager().goToState(NORMAL); @@ -104,11 +87,6 @@ public class LauncherRecentsView extends RecentsView implements StateL } } - @Nullable - public ProactiveHintsContainer getProactiveHintsContainer() { - return mProactiveHintsContainer; - } - @Override public void draw(Canvas canvas) { maybeDrawEmptyMessage(canvas); @@ -162,23 +140,6 @@ public class LauncherRecentsView extends RecentsView implements StateL @Override protected void getTaskSize(DeviceProfile dp, Rect outRect) { LayoutUtils.calculateLauncherTaskSize(getContext(), dp, outRect); - if (mProactiveHintsContainer != null) { - BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) mProactiveHintsContainer.getLayoutParams(); - params.bottomMargin = getHeight() - outRect.bottom - mChipOverhang; - params.width = outRect.width(); - } - } - - @Override - public PendingAnimation createTaskLauncherAnimation(TaskView tv, long duration) { - PendingAnimation anim = super.createTaskLauncherAnimation(tv, duration); - - if (mProactiveHintsContainer != null) { - anim.anim.play(ObjectAnimator.ofFloat( - mProactiveHintsContainer, ProactiveHintsContainer.HINT_VISIBILITY, 0)); - } - - return anim; } @Override @@ -196,31 +157,6 @@ public class LauncherRecentsView extends RecentsView implements StateL } } - @Override - public PendingAnimation createTaskDismissAnimation(TaskView taskView, boolean animateTaskView, - boolean shouldRemoveTask, long duration) { - PendingAnimation anim = super.createTaskDismissAnimation(taskView, animateTaskView, - shouldRemoveTask, duration); - - if (mProactiveHintsContainer != null) { - anim.anim.play(ObjectAnimator.ofFloat( - mProactiveHintsContainer, ProactiveHintsContainer.HINT_VISIBILITY, 0)); - anim.addEndListener(onEndListener -> { - if (!onEndListener.isSuccess) { - mProactiveHintsContainer.setHintVisibility(1); - } - }); - } - - return anim; - } - - public void setHintVisibility(float v) { - if (mProactiveHintsContainer != null) { - mProactiveHintsContainer.setHintVisibility(v); - } - } - @Override protected void onTaskLaunched(boolean success) { if (success) { diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml index 9cab9c2a5e..cca899bda8 100644 --- a/res/layout/launcher.xml +++ b/res/layout/launcher.xml @@ -48,11 +48,6 @@ layout="@layout/overview_panel" android:visibility="gone" /> - - - - \ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 0da56dafb9..4bcb8a7f43 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -232,11 +232,6 @@ 12sp 14sp - - 26dp - 194dp - 15dp - 8dp diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index c1f898c5d0..883e8c642b 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -99,10 +99,6 @@ public class DeviceProfile { public int folderChildTextSizePx; public int folderChildDrawablePaddingPx; - // Hints - public int chipHintHeightPx; - public int chipHintBottomMarginPx; - // Hotseat public int hotseatCellHeightPx; // In portrait: size = height, in landscape: size = width @@ -200,9 +196,6 @@ public class DeviceProfile { workspaceCellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x); - chipHintHeightPx = res.getDimensionPixelSize(R.dimen.chip_hint_height); - chipHintBottomMarginPx = res.getDimensionPixelSize(R.dimen.chip_hint_bottom_margin); - hotseatBarTopPaddingPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding); hotseatBarBottomPaddingPx = (isTallDevice ? 0 From bda6b45341a4f88e318e041f44fa37b787b6de84 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 5 Jun 2019 12:07:07 -0700 Subject: [PATCH 09/20] Fixing wrong origin when launching new task from overview > Also removing some unnecessary layout passes during launch animation Bug: 133226418 Change-Id: I36fe69827853366deb7c56ca25f39e20c1a0b825 --- .../LauncherAppTransitionManagerImpl.java | 6 +++++- .../quickstep/views/LauncherRecentsView.java | 2 ++ .../android/quickstep/views/RecentsView.java | 21 ++++++++++++++++++- .../launcher3/views/FloatingIconView.java | 10 ++++++--- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java index 1042c60b88..eac4dce180 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java @@ -121,12 +121,16 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti alpha.setDuration(CONTENT_ALPHA_DURATION); alpha.setInterpolator(LINEAR); anim.play(alpha); + overview.setFreezeViewVisibility(true); ObjectAnimator transY = ObjectAnimator.ofFloat(overview, View.TRANSLATION_Y, trans); transY.setInterpolator(AGGRESSIVE_EASE); transY.setDuration(CONTENT_TRANSLATION_DURATION); anim.play(transY); - return mLauncher.getStateManager()::reapplyState; + return () -> { + overview.setFreezeViewVisibility(false); + mLauncher.getStateManager().reapplyState(); + }; } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java index 8ad5f27c33..5b2e27e539 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java @@ -227,6 +227,7 @@ public class LauncherRecentsView extends RecentsView implements StateL @Override public void onStateTransitionStart(LauncherState toState) { setOverviewStateEnabled(toState.overviewUi); + setFreezeViewVisibility(true); } @Override @@ -236,6 +237,7 @@ public class LauncherRecentsView extends RecentsView implements StateL reset(); } setOverlayEnabled(finalState == OVERVIEW); + setFreezeViewVisibility(false); } @Override diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 38bd46172f..e38a315f8a 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -188,6 +188,7 @@ public abstract class RecentsView extends PagedView impl private boolean mDwbToastShown; private boolean mDisallowScrollToClearAll; private boolean mOverlayEnabled; + private boolean mFreezeViewVisibility; /** * TODO: Call reloadIdNeeded in onTaskStackChanged. @@ -1302,7 +1303,25 @@ public abstract class RecentsView extends PagedView impl mEmptyMessagePaint.setAlpha(alphaInt); mEmptyIcon.setAlpha(alphaInt); - setVisibility(alpha > 0 ? VISIBLE : GONE); + if (alpha > 0) { + setVisibility(VISIBLE); + } else if (!mFreezeViewVisibility) { + setVisibility(GONE); + } + } + + /** + * Freezes the view visibility change. When frozen, the view will not change its visibility + * to gone due to alpha changes. + */ + public void setFreezeViewVisibility(boolean freezeViewVisibility) { + if (mFreezeViewVisibility != freezeViewVisibility) { + mFreezeViewVisibility = freezeViewVisibility; + + if (!mFreezeViewVisibility) { + setVisibility(mContentAlpha > 0 ? VISIBLE : GONE); + } + } } @Override diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index 95c96817a0..339681cd69 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -124,6 +124,7 @@ public class FloatingIconView extends View implements private boolean mIsVerticalBarLayout = false; private boolean mIsAdaptiveIcon = false; + private boolean mIsOpening; private @Nullable Drawable mBadge; private @Nullable Drawable mForeground; @@ -178,8 +179,10 @@ public class FloatingIconView extends View implements @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - getViewTreeObserver().addOnGlobalLayoutListener(this); - mLauncher.getRotationHelper().setCurrentTransitionRequest(REQUEST_LOCK); + if (!mIsOpening) { + getViewTreeObserver().addOnGlobalLayoutListener(this); + mLauncher.getRotationHelper().setCurrentTransitionRequest(REQUEST_LOCK); + } } @Override @@ -326,7 +329,7 @@ public class FloatingIconView extends View implements * - For BubbleTextView, we return the icon bounds. */ private float getLocationBoundsForView(View v, RectF outRect) { - boolean ignoreTransform = true; + boolean ignoreTransform = !mIsOpening; if (v instanceof DeepShortcutView) { v = ((DeepShortcutView) v).getBubbleText(); ignoreTransform = false; @@ -627,6 +630,7 @@ public class FloatingIconView extends View implements view.recycle(); view.mIsVerticalBarLayout = launcher.getDeviceProfile().isVerticalBarLayout(); + view.mIsOpening = isOpening; view.mOriginalIcon = originalView; view.mPositionOut = positionOut; From b88d4a64fd7049d4fbd461813c8ddf561f7d5c7c Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 5 Jun 2019 14:08:23 -0700 Subject: [PATCH 10/20] Allowing tracing to be enabled using command line on all build flavors Change-Id: I5f8ee996bdcede2393eeb4aaa1b45fec7619d405 --- src/com/android/launcher3/util/TraceHelper.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/com/android/launcher3/util/TraceHelper.java b/src/com/android/launcher3/util/TraceHelper.java index 4fea2e92ae..c24bb67813 100644 --- a/src/com/android/launcher3/util/TraceHelper.java +++ b/src/com/android/launcher3/util/TraceHelper.java @@ -27,16 +27,17 @@ import android.util.MutableLong; import com.android.launcher3.config.FeatureFlags; /** - * A wrapper around {@link Trace} to allow easier proguarding for production builds. + * A wrapper around {@link Trace} with some utility information. * * To enable any tracing log, execute the following command: + * $ adb shell setprop log.tag.LAUNCHER_TRACE VERBOSE * $ adb shell setprop log.tag.TAGNAME VERBOSE */ public class TraceHelper { - private static final boolean ENABLED = FeatureFlags.IS_DOGFOOD_BUILD; + private static final boolean ENABLED = isLoggable("LAUNCHER_TRACE", VERBOSE); - private static final boolean SYSTEM_TRACE = false; + private static final boolean SYSTEM_TRACE = ENABLED; private static final ArrayMap sUpTimes = ENABLED ? new ArrayMap<>() : null; public static void beginSection(String sectionName) { From 7a38854284d907b94ea8daa03fdc9a4bd94428c3 Mon Sep 17 00:00:00 2001 From: vadimt Date: Wed, 5 Jun 2019 15:44:17 -0700 Subject: [PATCH 11/20] Taking local screenshot before navigation state is restored Change-Id: Id8003b17c68af5b4882bdbf5e14a142875791cbc --- .../quickstep/AbstractQuickStepTest.java | 10 ++-- .../launcher3/ui/AbstractLauncherUiTest.java | 46 ++------------- .../launcher3/util/rule/FailureWatcher.java | 59 +++++++++++++++++++ 3 files changed, 70 insertions(+), 45 deletions(-) create mode 100644 tests/src/com/android/launcher3/util/rule/FailureWatcher.java diff --git a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java index c77726e617..cc79c9d282 100644 --- a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java +++ b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java @@ -18,14 +18,14 @@ package com.android.quickstep; import com.android.launcher3.ui.AbstractLauncherUiTest; -import org.junit.Rule; -import org.junit.rules.TestRule; +import org.junit.rules.RuleChain; /** * Base class for all instrumentation tests that deal with Quickstep. */ public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest { - @Rule - public TestRule mQuickstepOnOffExecutor = - new NavigationModeSwitchRule(mLauncher); + protected AbstractQuickStepTest() { + mOrderSensitiveRules = RuleChain.outerRule(new NavigationModeSwitchRule(mLauncher)). + around(mOrderSensitiveRules); + } } diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index c7c36b0d40..17a533523b 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -58,19 +58,17 @@ import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.tapl.LauncherInstrumentation; import com.android.launcher3.tapl.TestHelpers; import com.android.launcher3.util.Wait; +import com.android.launcher3.util.rule.FailureWatcher; import com.android.launcher3.util.rule.LauncherActivityRule; import com.android.launcher3.util.rule.ShellCommandRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; +import org.junit.rules.RuleChain; import org.junit.rules.TestRule; -import org.junit.rules.TestWatcher; -import org.junit.runner.Description; import org.junit.runners.model.Statement; -import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.IOException; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -93,7 +91,6 @@ public abstract class AbstractLauncherUiTest { public static final long SHORT_UI_TIMEOUT = 300; public static final long DEFAULT_UI_TIMEOUT = 10000; private static final String TAG = "AbstractLauncherUiTest"; - private static int sScreenshotCount = 0; protected MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor(); protected final UiDevice mDevice = UiDevice.getInstance(getInstrumentation()); @@ -167,42 +164,11 @@ public abstract class AbstractLauncherUiTest { } : base; @Rule - public TestWatcher mFailureWatcher = new TestWatcher() { - private void dumpViewHierarchy() { - final ByteArrayOutputStream stream = new ByteArrayOutputStream(); - try { - mDevice.dumpWindowHierarchy(stream); - stream.flush(); - stream.close(); - for (String line : stream.toString().split("\\r?\\n")) { - Log.e(TAG, line.trim()); - } - } catch (IOException e) { - Log.e(TAG, "error dumping XML to logcat", e); - } - } + public RuleChain mOrderSensitiveRules = RuleChain.outerRule(new FailureWatcher(this)); - @Override - protected void failed(Throwable e, Description description) { - if (mDevice == null) return; - final String pathname = getInstrumentation().getTargetContext(). - getFilesDir().getPath() + "/TaplTestScreenshot" + sScreenshotCount++ + ".png"; - Log.e(TAG, "Failed test " + description.getMethodName() + - ", screenshot will be saved to " + pathname + - ", track trace is below, UI object dump is further below:\n" + - Log.getStackTraceString(e)); - dumpViewHierarchy(); - - try { - final String dumpsysResult = mDevice.executeShellCommand( - "dumpsys activity service TouchInteractionService"); - Log.d(TAG, "TouchInteractionService: " + dumpsysResult); - } catch (IOException ex) { - } - - mDevice.takeScreenshot(new File(pathname)); - } - }; + public UiDevice getDevice() { + return mDevice; + } @Before public void setUp() throws Exception { diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java new file mode 100644 index 0000000000..09cc98de08 --- /dev/null +++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java @@ -0,0 +1,59 @@ +package com.android.launcher3.util.rule; + +import static androidx.test.InstrumentationRegistry.getInstrumentation; + +import android.util.Log; + +import com.android.launcher3.ui.AbstractLauncherUiTest; + +import org.junit.rules.TestWatcher; +import org.junit.runner.Description; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; + +public class FailureWatcher extends TestWatcher { + private static final String TAG = "FailureWatcher"; + private static int sScreenshotCount = 0; + private AbstractLauncherUiTest mAbstractLauncherUiTest; + + public FailureWatcher(AbstractLauncherUiTest abstractLauncherUiTest) { + mAbstractLauncherUiTest = abstractLauncherUiTest; + } + + private void dumpViewHierarchy() { + final ByteArrayOutputStream stream = new ByteArrayOutputStream(); + try { + mAbstractLauncherUiTest.getDevice().dumpWindowHierarchy(stream); + stream.flush(); + stream.close(); + for (String line : stream.toString().split("\\r?\\n")) { + Log.e(TAG, line.trim()); + } + } catch (IOException e) { + Log.e(TAG, "error dumping XML to logcat", e); + } + } + + @Override + protected void failed(Throwable e, Description description) { + if (mAbstractLauncherUiTest.getDevice() == null) return; + final String pathname = getInstrumentation().getTargetContext(). + getFilesDir().getPath() + "/TaplTestScreenshot" + sScreenshotCount++ + ".png"; + Log.e(TAG, "Failed test " + description.getMethodName() + + ", screenshot will be saved to " + pathname + + ", track trace is below, UI object dump is further below:\n" + + Log.getStackTraceString(e)); + dumpViewHierarchy(); + + try { + final String dumpsysResult = mAbstractLauncherUiTest.getDevice().executeShellCommand( + "dumpsys activity service TouchInteractionService"); + Log.d(TAG, "TouchInteractionService: " + dumpsysResult); + } catch (IOException ex) { + } + + mAbstractLauncherUiTest.getDevice().takeScreenshot(new File(pathname)); + } +} From df4727e8eeb33139d99614effd394be209213618 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Wed, 5 Jun 2019 17:03:39 -0700 Subject: [PATCH 12/20] Fix flicker to OVERVIEW state during quick switch Here's what was happening: - When animating to a new task, the launcher controller ends first (when quick switching it likely ends immediately since we're already scaled up). - Then we get onApplyWindowInsets(), which re-builds the launcher controller. - Finally, the window animation ends, invalidating the handler and ending the new controller, which sets the state to OVERVIEW. To fix this, never create a new controller if it has ever been started. Bug: 133508173 Change-Id: Ibd0e18e488353df73159ffbdd9a3b335bed57d98 --- .../com/android/quickstep/WindowTransformSwipeHandler.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index 87b7326648..45f34e72c1 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -267,6 +267,7 @@ public class WindowTransformSwipeHandler private MultiStateCallback mStateCallback; // Used to control launcher components throughout the swipe gesture. private AnimatorPlaybackController mLauncherTransitionController; + private boolean mHasLauncherTransitionControllerStarted; private T mActivity; private RecentsView mRecentsView; @@ -647,8 +648,7 @@ public class WindowTransformSwipeHandler } private void buildAnimationController() { - if (mGestureEndTarget == HOME || (mLauncherTransitionController != null - && mLauncherTransitionController.getAnimationPlayer().isStarted())) { + if (mGestureEndTarget == HOME || mHasLauncherTransitionControllerStarted) { // We don't want a new mLauncherTransitionController if mGestureEndTarget == HOME (it // has its own animation) or if we're already animating the current controller. return; @@ -1122,6 +1122,7 @@ public class WindowTransformSwipeHandler } mLauncherTransitionController.getAnimationPlayer().start(); } + mHasLauncherTransitionControllerStarted = true; } /** From 63013c5e5723117ce7dec97b88cac2abf21f9088 Mon Sep 17 00:00:00 2001 From: vadimt Date: Wed, 5 Jun 2019 18:34:23 -0700 Subject: [PATCH 13/20] Temporarily not using RuleChain as it mysteriously breaks tests Change-Id: I8bdd9a8ea12cfdbd92fe724181e7479cadcb26fe --- .../src/com/android/quickstep/AbstractQuickStepTest.java | 9 ++++----- .../com/android/launcher3/ui/AbstractLauncherUiTest.java | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java index cc79c9d282..c2c568bb61 100644 --- a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java +++ b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java @@ -18,14 +18,13 @@ package com.android.quickstep; import com.android.launcher3.ui.AbstractLauncherUiTest; -import org.junit.rules.RuleChain; +import org.junit.Rule; +import org.junit.rules.TestRule; /** * Base class for all instrumentation tests that deal with Quickstep. */ public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest { - protected AbstractQuickStepTest() { - mOrderSensitiveRules = RuleChain.outerRule(new NavigationModeSwitchRule(mLauncher)). - around(mOrderSensitiveRules); - } + @Rule + public TestRule mNavigationModeSwitcher = new NavigationModeSwitchRule(mLauncher); } diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 17a533523b..e5cc858bb2 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -65,8 +65,8 @@ import com.android.launcher3.util.rule.ShellCommandRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; -import org.junit.rules.RuleChain; import org.junit.rules.TestRule; +import org.junit.rules.TestWatcher; import org.junit.runners.model.Statement; import java.io.IOException; @@ -164,7 +164,7 @@ public abstract class AbstractLauncherUiTest { } : base; @Rule - public RuleChain mOrderSensitiveRules = RuleChain.outerRule(new FailureWatcher(this)); + public TestWatcher mFailureWatcher = new FailureWatcher(this); public UiDevice getDevice() { return mDevice; From d4c90e12e9b6b61d3c0374ee5899425c84ffe65b Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 4 Jun 2019 13:59:43 -0700 Subject: [PATCH 14/20] Freezing all apps updates during certain tests This CL adds a very low risk because most (but not all) changes affect only Launcher behavior during the test. This should fix a lab-only flake when all apps keeps changing while the test is working with it. Example: test figures out which icon to click, by the moment it clicks there, there is another icon there, or the icon is under the search box, and clicking opens IME. Switching test devices to airplane mode didn't help. The earlier change that prevents popup menu cancellation is not general enough. Now the tests are given an API to explicitly freeze and unfreeze all-apps, which should be a final solution. Bug: 132900132 Bug: 133765434 Change-Id: I8b81cc9be004482beb6cdcdd05406e2d9b4c7629 --- src/com/android/launcher3/Launcher.java | 6 +- .../allapps/AllAppsContainerView.java | 5 +- .../launcher3/allapps/AllAppsStore.java | 31 ++-- .../testing/TestInformationHandler.java | 30 ++++ .../launcher3/testing/TestProtocol.java | 5 + .../launcher3/ui/TaplTestsLauncher3.java | 170 +++++++++++------- .../com/android/launcher3/tapl/AllApps.java | 22 +++ .../tapl/LauncherInstrumentation.java | 6 + 8 files changed, 194 insertions(+), 81 deletions(-) diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 855535b0f3..67086a578d 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -80,6 +80,7 @@ import android.widget.Toast; import com.android.launcher3.DropTarget.DragObject; import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; import com.android.launcher3.allapps.AllAppsContainerView; +import com.android.launcher3.allapps.AllAppsStore; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.anim.PropertyListBuilder; @@ -2238,8 +2239,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } mPendingExecutor = executor; if (!isInState(ALL_APPS)) { - mAppsView.getAppsStore().setDeferUpdates(true); - mPendingExecutor.execute(() -> mAppsView.getAppsStore().setDeferUpdates(false)); + mAppsView.getAppsStore().enableDeferUpdates(AllAppsStore.DEFER_UPDATES_NEXT_DRAW); + mPendingExecutor.execute(() -> mAppsView.getAppsStore().disableDeferUpdates( + AllAppsStore.DEFER_UPDATES_NEXT_DRAW)); } executor.attachTo(this); diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index 0d43e214ef..d68ff4451d 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -628,11 +628,12 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo final boolean result = super.dispatchTouchEvent(ev); switch (ev.getActionMasked()) { case MotionEvent.ACTION_DOWN: - if (result) mAllAppsStore.setDeferUpdates(true); + if (result) mAllAppsStore.enableDeferUpdates( + AllAppsStore.DEFER_UPDATES_USER_INTERACTION); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: - mAllAppsStore.setDeferUpdates(false); + mAllAppsStore.disableDeferUpdates(AllAppsStore.DEFER_UPDATES_USER_INTERACTION); break; } return result; diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java index 8e7fec863b..160042e692 100644 --- a/src/com/android/launcher3/allapps/AllAppsStore.java +++ b/src/com/android/launcher3/allapps/AllAppsStore.java @@ -29,7 +29,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; -import java.util.Set; import java.util.function.Consumer; import java.util.function.Predicate; @@ -38,12 +37,19 @@ import java.util.function.Predicate; */ public class AllAppsStore { + // Defer updates flag used to defer all apps updates to the next draw. + public static final int DEFER_UPDATES_NEXT_DRAW = 1 << 0; + // Defer updates flag used to defer all apps updates while the user interacts with all apps. + public static final int DEFER_UPDATES_USER_INTERACTION = 1 << 1; + // Defer updates flag used to defer all apps updates by a test's request. + public static final int DEFER_UPDATES_TEST = 1 << 2; + private PackageUserKey mTempKey = new PackageUserKey(null, null); private final HashMap mComponentToAppMap = new HashMap<>(); private final List mUpdateListeners = new ArrayList<>(); private final ArrayList mIconContainers = new ArrayList<>(); - private boolean mDeferUpdates = false; + private int mDeferUpdatesFlags = 0; private boolean mUpdatePending = false; public Collection getApps() { @@ -62,17 +68,22 @@ public class AllAppsStore { return mComponentToAppMap.get(key); } - public void setDeferUpdates(boolean deferUpdates) { - if (mDeferUpdates != deferUpdates) { - mDeferUpdates = deferUpdates; + public void enableDeferUpdates(int flag) { + mDeferUpdatesFlags |= flag; + } - if (!mDeferUpdates && mUpdatePending) { - notifyUpdate(); - mUpdatePending = false; - } + public void disableDeferUpdates(int flag) { + mDeferUpdatesFlags &= ~flag; + if (mDeferUpdatesFlags == 0 && mUpdatePending) { + notifyUpdate(); + mUpdatePending = false; } } + public int getDeferUpdatesFlags() { + return mDeferUpdatesFlags; + } + /** * Adds or updates existing apps in the list */ @@ -95,7 +106,7 @@ public class AllAppsStore { private void notifyUpdate() { - if (mDeferUpdates) { + if (mDeferUpdatesFlags != 0) { mUpdatePending = true; return; } diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java index b8476aa1da..d2e196138c 100644 --- a/src/com/android/launcher3/testing/TestInformationHandler.java +++ b/src/com/android/launcher3/testing/TestInformationHandler.java @@ -23,9 +23,13 @@ import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherState; +import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.R; +import com.android.launcher3.allapps.AllAppsStore; import com.android.launcher3.util.ResourceBasedOverride; +import java.util.concurrent.ExecutionException; + public class TestInformationHandler implements ResourceBasedOverride { public static TestInformationHandler newInstance(Context context) { @@ -77,6 +81,32 @@ public class TestInformationHandler implements ResourceBasedOverride { case TestProtocol.REQUEST_DISABLE_DEBUG_TRACING: TestProtocol.sDebugTracing = false; break; + + case TestProtocol.REQUEST_FREEZE_APP_LIST: + new MainThreadExecutor().execute(() -> + mLauncher.getAppsView().getAppsStore().enableDeferUpdates( + AllAppsStore.DEFER_UPDATES_TEST)); + break; + + case TestProtocol.REQUEST_UNFREEZE_APP_LIST: + new MainThreadExecutor().execute(() -> + mLauncher.getAppsView().getAppsStore().disableDeferUpdates( + AllAppsStore.DEFER_UPDATES_TEST)); + break; + + case TestProtocol.REQUEST_APP_LIST_FREEZE_FLAGS: { + try { + final int deferUpdatesFlags = new MainThreadExecutor().submit(() -> + mLauncher.getAppsView().getAppsStore().getDeferUpdatesFlags()).get(); + response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, + deferUpdatesFlags); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + break; + } } return response; } diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 99efb22cf1..e60b665eaa 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -57,6 +57,7 @@ public final class TestProtocol { } public static final String TEST_INFO_RESPONSE_FIELD = "response"; + public static final String REQUEST_HOME_TO_OVERVIEW_SWIPE_HEIGHT = "home-to-overview-swipe-height"; public static final String REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT = @@ -65,6 +66,10 @@ public final class TestProtocol { "all-apps-to-overview-swipe-height"; public static final String REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT = "home-to-all-apps-swipe-height"; + public static final String REQUEST_FREEZE_APP_LIST = "freeze-app-list"; + public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list"; + public static final String REQUEST_APP_LIST_FREEZE_FLAGS = "app-list-freeze-flags"; + public static boolean sDebugTracing = false; public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing"; public static final String REQUEST_DISABLE_DEBUG_TRACING = "disable-debug-tracing"; diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java index 4f8b87c519..d171004fc1 100644 --- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java +++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java @@ -108,47 +108,63 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { @Test @Ignore public void testPressHomeOnAllAppsContextMenu() throws Exception { - mLauncher.getWorkspace().switchToAllApps().getAppIcon("TestActivity7").openMenu(); + final AllApps allApps = mLauncher.getWorkspace().switchToAllApps(); + allApps.freeze(); + try { + allApps.getAppIcon("TestActivity7").openMenu(); + } finally { + allApps.unfreeze(); + } mLauncher.pressHome(); } public static void runAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) { - assertNotNull("allApps parameter is null", allApps); + allApps.freeze(); + try { + assertNotNull("allApps parameter is null", allApps); - assertTrue( - "Launcher internal state is not All Apps", test.isInState(LauncherState.ALL_APPS)); + assertTrue( + "Launcher internal state is not All Apps", + test.isInState(LauncherState.ALL_APPS)); - // Test flinging forward and backward. - test.executeOnLauncher(launcher -> assertEquals( - "All Apps started in already scrolled state", 0, test.getAllAppsScroll(launcher))); + // Test flinging forward and backward. + test.executeOnLauncher(launcher -> assertEquals( + "All Apps started in already scrolled state", 0, + test.getAllAppsScroll(launcher))); - allApps.flingForward(); - assertTrue("Launcher internal state is not All Apps", - test.isInState(LauncherState.ALL_APPS)); - final Integer flingForwardY = test.getFromLauncher( - launcher -> test.getAllAppsScroll(launcher)); - test.executeOnLauncher( - launcher -> assertTrue("flingForward() didn't scroll App Apps", flingForwardY > 0)); + allApps.flingForward(); + assertTrue("Launcher internal state is not All Apps", + test.isInState(LauncherState.ALL_APPS)); + final Integer flingForwardY = test.getFromLauncher( + launcher -> test.getAllAppsScroll(launcher)); + test.executeOnLauncher( + launcher -> assertTrue("flingForward() didn't scroll App Apps", + flingForwardY > 0)); - allApps.flingBackward(); - assertTrue( - "Launcher internal state is not All Apps", test.isInState(LauncherState.ALL_APPS)); - final Integer flingBackwardY = test.getFromLauncher( - launcher -> test.getAllAppsScroll(launcher)); - test.executeOnLauncher(launcher -> assertTrue("flingBackward() didn't scroll App Apps", - flingBackwardY < flingForwardY)); + allApps.flingBackward(); + assertTrue( + "Launcher internal state is not All Apps", + test.isInState(LauncherState.ALL_APPS)); + final Integer flingBackwardY = test.getFromLauncher( + launcher -> test.getAllAppsScroll(launcher)); + test.executeOnLauncher(launcher -> assertTrue("flingBackward() didn't scroll App Apps", + flingBackwardY < flingForwardY)); - // Test scrolling down to YouTube. - assertNotNull("All apps: can't fine YouTube", allApps.getAppIcon("YouTube")); - // Test scrolling up to Camera. - assertNotNull("All apps: can't fine Camera", allApps.getAppIcon("Camera")); - // Test failing to find a non-existing app. - final AllApps allAppsFinal = allApps; - expectFail("All apps: could find a non-existing app", - () -> allAppsFinal.getAppIcon("NO APP")); + // Test scrolling down to YouTube. + assertNotNull("All apps: can't fine YouTube", allApps.getAppIcon("YouTube")); + // Test scrolling up to Camera. + assertNotNull("All apps: can't fine Camera", allApps.getAppIcon("Camera")); + // Test failing to find a non-existing app. + final AllApps allAppsFinal = allApps; + expectFail("All apps: could find a non-existing app", + () -> allAppsFinal.getAppIcon("NO APP")); - assertTrue( - "Launcher internal state is not All Apps", test.isInState(LauncherState.ALL_APPS)); + assertTrue( + "Launcher internal state is not All Apps", + test.isInState(LauncherState.ALL_APPS)); + } finally { + allApps.unfreeze(); + } } @Test @@ -199,12 +215,17 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { } public static void runIconLaunchFromAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) { - final AppIcon app = allApps.getAppIcon("TestActivity7"); - assertNotNull("AppIcon.launch returned null", app.launch(getAppPackageName())); - test.executeOnLauncher(launcher -> assertTrue( - "Launcher activity is the top activity; expecting another activity to be the top " - + "one", - test.isInBackground(launcher))); + allApps.freeze(); + try { + final AppIcon app = allApps.getAppIcon("TestActivity7"); + assertNotNull("AppIcon.launch returned null", app.launch(getAppPackageName())); + test.executeOnLauncher(launcher -> assertTrue( + "Launcher activity is the top activity; expecting another activity to be the top " + + "one", + test.isInBackground(launcher))); + } finally { + allApps.unfreeze(); + } } @Test @@ -260,20 +281,23 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { public void testLaunchMenuItem() throws Exception { if (!TestHelpers.isInLauncherProcess()) return; - final AppIconMenu menu = mLauncher. + final AllApps allApps = mLauncher. getWorkspace(). - switchToAllApps(). - getAppIcon(APP_NAME). - openMenu(); + switchToAllApps(); + allApps.freeze(); + try { + final AppIconMenu menu = allApps. + getAppIcon(APP_NAME). + openMenu(); - executeOnLauncher( - launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu", - isOptionsPopupVisible(launcher))); + executeOnLauncher( + launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu", + isOptionsPopupVisible(launcher))); - final AppIconMenuItem menuItem = menu.getMenuItem(1); - final String itemName = menuItem.getText(); - - menuItem.launch(getAppPackageName()); + menu.getMenuItem(1).launch(getAppPackageName()); + } finally { + allApps.unfreeze(); + } } @Test @@ -282,12 +306,18 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { // 1. Open all apps and wait for load complete. // 2. Drag icon to homescreen. // 3. Verify that the icon works on homescreen. - mLauncher.getWorkspace(). - switchToAllApps(). - getAppIcon(APP_NAME). - dragToWorkspace(). - getWorkspaceAppIcon(APP_NAME). - launch(getAppPackageName()); + final AllApps allApps = mLauncher.getWorkspace(). + switchToAllApps(); + allApps.freeze(); + try { + allApps. + getAppIcon(APP_NAME). + dragToWorkspace(). + getWorkspaceAppIcon(APP_NAME). + launch(getAppPackageName()); + } finally { + allApps.unfreeze(); + } executeOnLauncher(launcher -> assertTrue( "Launcher activity is the top activity; expecting another activity to be the top " + "one", @@ -302,21 +332,27 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { // 1. Open all apps and wait for load complete. // 2. Find the app and long press it to show shortcuts. // 3. Press icon center until shortcuts appear - final AppIconMenuItem menuItem = mLauncher. + final AllApps allApps = mLauncher. getWorkspace(). - switchToAllApps(). - getAppIcon(APP_NAME). - openMenu(). - getMenuItem(0); - final String shortcutName = menuItem.getText(); + switchToAllApps(); + allApps.freeze(); + try { + final AppIconMenuItem menuItem = allApps. + getAppIcon(APP_NAME). + openMenu(). + getMenuItem(0); + final String shortcutName = menuItem.getText(); - // 4. Drag the first shortcut to the home screen. - // 5. Verify that the shortcut works on home screen - // (the app opens and has the same text as the shortcut). - menuItem. - dragToWorkspace(). - getWorkspaceAppIcon(shortcutName). - launch(getAppPackageName()); + // 4. Drag the first shortcut to the home screen. + // 5. Verify that the shortcut works on home screen + // (the app opens and has the same text as the shortcut). + menuItem. + dragToWorkspace(). + getWorkspaceAppIcon(shortcutName). + launch(getAppPackageName()); + } finally { + allApps.unfreeze(); + } } public static String getAppPackageName() { diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java index d03035a871..21d763e30e 100644 --- a/tests/tapl/com/android/launcher3/tapl/AllApps.java +++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java @@ -48,6 +48,7 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { "apps_list_view"); // Wait for the recycler to populate. mLauncher.waitForObjectInContainer(appListRecycler, By.clazz(TextView.class)); + verifyNotFrozen("All apps freeze flags upon opening all apps"); } @Override @@ -210,4 +211,25 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { verifyActiveContainer(); } } + + /** + * Freezes updating app list upon app install/uninstall/update. + */ + public void freeze() { + mLauncher.getTestInfo(TestProtocol.REQUEST_FREEZE_APP_LIST); + } + + /** + * Resumes updating app list upon app install/uninstall/update. + */ + public void unfreeze() { + mLauncher.getTestInfo(TestProtocol.REQUEST_UNFREEZE_APP_LIST); + verifyNotFrozen("All apps freeze flags upon unfreezing"); + } + + private void verifyNotFrozen(String message) { + mLauncher.assertEquals(message, 0, mLauncher.getTestInfo( + TestProtocol.REQUEST_APP_LIST_FREEZE_FLAGS). + getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD)); + } } diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index e45fca8c0f..8ebe525657 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -292,6 +292,12 @@ public final class LauncherInstrumentation { } } + void assertEquals(String message, long expected, long actual) { + if (expected != actual) { + fail(message + " expected: " + expected + " but was: " + actual); + } + } + void assertNotEquals(String message, int unexpected, int actual) { if (unexpected == actual) { failEquals(message, actual); From 6f479ff9de9096000e5191521fb079353d2a946c Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 4 Jun 2019 14:06:07 -0700 Subject: [PATCH 15/20] Using a separate InputConsumer when Launcher is resumed but not focused When Launcher is not focused and we try to dispatch events to Launcher, it can lead to a inconsistent state. For eg, NavBarTouchController was trying to take launcher from NORMAL to NORMAL state causing the endCallback to be called immediately, which in turn didn't clear Swipedetetor state Bug: 132209249 Bug: 132815672 Change-Id: I82e4fdcb8fd5339e82fc8551f3a6e0b046d906f8 --- .../NavBarToHomeTouchController.java | 3 - .../quickstep/TouchInteractionService.java | 40 +++-- .../WindowTransformSwipeHandler.java | 4 +- .../inputconsumers/InputConsumer.java | 3 + .../OtherActivityInputConsumer.java | 28 +--- .../inputconsumers/OverviewInputConsumer.java | 8 +- .../OverviewWithoutFocusInputConsumer.java | 151 ++++++++++++++++++ .../quickstep/util/NavBarPosition.java | 55 +++++++ 8 files changed, 255 insertions(+), 37 deletions(-) create mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java create mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java index a6c4445619..d66af1ae24 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java @@ -98,9 +98,6 @@ public class NavBarToHomeTouchController implements TouchController, SwipeDetect if (mStartState == OVERVIEW || mStartState == ALL_APPS) { return true; } - if (!mLauncher.hasWindowFocus()) { - return true; - } if (AbstractFloatingView.getTopOpenView(mLauncher) != null) { return true; } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index cbc94ba1f6..dc354404af 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -62,6 +62,7 @@ import android.view.WindowManager; import androidx.annotation.BinderThread; +import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.R; import com.android.launcher3.ResourceUtils; @@ -79,6 +80,7 @@ import com.android.quickstep.inputconsumers.DeviceLockedInputConsumer; import com.android.quickstep.inputconsumers.InputConsumer; import com.android.quickstep.inputconsumers.OtherActivityInputConsumer; import com.android.quickstep.inputconsumers.OverviewInputConsumer; +import com.android.quickstep.inputconsumers.OverviewWithoutFocusInputConsumer; import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; @@ -566,10 +568,9 @@ public class TouchInteractionService extends Service implements info.id = mSwipeSharedState.nextRunningTaskId; return createOtherActivityInputConsumer(event, info); } else if (mSwipeSharedState.goingToLauncher || activityControl.isResumed()) { - return OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false); - } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && - activityControl.isInLiveTileMode()) { - return OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false); + return createOverviewInputConsumer(event); + } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityControl.isInLiveTileMode()) { + return createOverviewInputConsumer(event); } else if (mGestureBlockingActivity != null && runningTaskInfo != null && mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) { return InputConsumer.NO_OP; @@ -578,20 +579,24 @@ public class TouchInteractionService extends Service implements } } + private boolean disableHorizontalSwipe(MotionEvent event) { + // mExclusionRegion can change on binder thread, use a local instance here. + Region exclusionRegion = mExclusionRegion; + return mMode == Mode.NO_BUTTON && exclusionRegion != null + && exclusionRegion.contains((int) event.getX(), (int) event.getY()); + } + private OtherActivityInputConsumer createOtherActivityInputConsumer(MotionEvent event, RunningTaskInfo runningTaskInfo) { final ActivityControlHelper activityControl = mOverviewComponentObserver.getActivityControlHelper(); boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event); - // mExclusionRegion can change on binder thread, use a local instance here. - Region exclusionRegion = mExclusionRegion; - boolean disableHorizontalSwipe = mMode == Mode.NO_BUTTON && exclusionRegion != null - && exclusionRegion.contains((int) event.getX(), (int) event.getY()); return new OtherActivityInputConsumer(this, runningTaskInfo, mRecentsModel, mOverviewComponentObserver.getOverviewIntent(), activityControl, shouldDefer, mOverviewCallbacks, mInputConsumer, this::onConsumerInactive, - mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion, disableHorizontalSwipe); + mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion, + disableHorizontalSwipe(event)); } private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) { @@ -603,6 +608,23 @@ public class TouchInteractionService extends Service implements } } + public InputConsumer createOverviewInputConsumer(MotionEvent event) { + final ActivityControlHelper activityControl = + mOverviewComponentObserver.getActivityControlHelper(); + BaseDraggingActivity activity = activityControl.getCreatedActivity(); + if (activity == null) { + return InputConsumer.NO_OP; + } + + if (activity.getRootView().hasWindowFocus()) { + return new OverviewInputConsumer(activity, mInputMonitorCompat, + false /* startingInActivityBounds */); + } else { + return new OverviewWithoutFocusInputConsumer(this, mInputMonitorCompat, + disableHorizontalSwipe(event)); + } + } + /** * To be called by the consumer when it's no longer active. */ diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index 87b7326648..e2cf5ee189 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -858,7 +858,9 @@ public class WindowTransformSwipeHandler setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha); } - return OverviewInputConsumer.newInstance(mActivityControlHelper, null, true); + BaseDraggingActivity activity = mActivityControlHelper.getCreatedActivity(); + return activity == null + ? InputConsumer.NO_OP : new OverviewInputConsumer(activity, null, true); } private void endRunningWindowAnim() { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java index 6e7cb8fca8..489eb278fd 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java @@ -31,6 +31,7 @@ public interface InputConsumer { int TYPE_DEVICE_LOCKED = 1 << 4; int TYPE_ACCESSIBILITY = 1 << 5; int TYPE_SCREEN_PINNED = 1 << 6; + int TYPE_OVERVIEW_WITHOUT_FOCUS = 1 << 7; InputConsumer NO_OP = () -> TYPE_NO_OP; @@ -78,6 +79,8 @@ public interface InputConsumer { return "ACCESSIBILITY"; case TYPE_SCREEN_PINNED: return "SCREEN_PINNED"; + case TYPE_OVERVIEW_WITHOUT_FOCUS: + return "TYPE_OVERVIEW_WITHOUT_FOCUS"; default: return "NO_OP"; } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index 0ed4c99a6f..69b25db8f5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -28,7 +28,6 @@ import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_LANDSC import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_SEASCAPE; import static com.android.launcher3.util.RaceConditionTracker.ENTER; import static com.android.launcher3.util.RaceConditionTracker.EXIT; -import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; @@ -43,10 +42,8 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.view.MotionEvent; -import android.view.Surface; import android.view.VelocityTracker; import android.view.ViewConfiguration; -import android.view.WindowManager; import androidx.annotation.UiThread; @@ -65,6 +62,7 @@ import com.android.quickstep.WindowTransformSwipeHandler; import com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget; import com.android.quickstep.util.CachedEventDispatcher; import com.android.quickstep.util.MotionPauseDetector; +import com.android.quickstep.util.NavBarPosition; import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.BackgroundExecutor; @@ -95,7 +93,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private final SysUINavigationMode.Mode mMode; private final RectF mSwipeTouchRegion; - private final int mDisplayRotation; + private final NavBarPosition mNavBarPosition; private final Consumer mOnCompleteCallback; private final MotionPauseDetector mMotionPauseDetector; @@ -157,7 +155,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mInputConsumer = inputConsumer; mSwipeSharedState = swipeSharedState; - mDisplayRotation = getSystemService(WindowManager.class).getDefaultDisplay().getRotation(); + mNavBarPosition = new NavBarPosition(base); mDragSlop = QuickStepContract.getQuickStepDragSlopPx(); float slop = QuickStepContract.getQuickStepTouchSlopPx(); mSquaredTouchSlop = slop * slop; @@ -188,9 +186,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC if (mPassedDragSlop && mInteractionHandler != null && !mRecentsViewDispatcher.hasConsumer()) { mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher( - isNavBarOnLeft() - ? ROTATION_SEASCAPE - : (isNavBarOnRight() ? ROTATION_LANDSCAPE : RotationMode.NORMAL))); + mNavBarPosition.getRotationMode())); } int edgeFlags = ev.getEdgeFlags(); ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR); @@ -329,14 +325,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mInteractionHandler.onGestureStarted(); } - private boolean isNavBarOnRight() { - return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_90; - } - - private boolean isNavBarOnLeft() { - return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_270; - } - private void startTouchTrackingForWindowAnimation(long touchTimeMs) { TOUCH_INTERACTION_LOG.addLog("startRecentsAnimation"); @@ -382,8 +370,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC ViewConfiguration.get(this).getScaledMaximumFlingVelocity()); float velocityX = mVelocityTracker.getXVelocity(mActivePointerId); float velocityY = mVelocityTracker.getYVelocity(mActivePointerId); - float velocity = isNavBarOnRight() ? velocityX - : isNavBarOnLeft() ? -velocityX + float velocity = mNavBarPosition.isRightEdge() ? velocityX + : mNavBarPosition.isLeftEdge() ? -velocityX : velocityY; mInteractionHandler.updateDisplacement(getDisplacement(ev) - mStartDisplacement); @@ -444,9 +432,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } private float getDisplacement(MotionEvent ev) { - if (isNavBarOnRight()) { + if (mNavBarPosition.isRightEdge()) { return ev.getX() - mDownPos.x; - } else if (isNavBarOnLeft()) { + } else if (mNavBarPosition.isLeftEdge()) { return mDownPos.x - ev.getX(); } else { return ev.getY() - mDownPos.y; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java index bab3c71c60..4851e67e9d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java @@ -51,7 +51,7 @@ public class OverviewInputConsumer private final boolean mStartingInActivityBounds; private boolean mTargetHandledTouch; - OverviewInputConsumer(T activity, @Nullable InputMonitorCompat inputMonitor, + public OverviewInputConsumer(T activity, @Nullable InputMonitorCompat inputMonitor, boolean startingInActivityBounds) { mActivity = activity; mInputMonitor = inputMonitor; @@ -115,12 +115,12 @@ public class OverviewInputConsumer } } - public static InputConsumer newInstance(ActivityControlHelper activityHelper, - @Nullable InputMonitorCompat inputMonitor, boolean startingInActivityBounds) { + public static InputConsumer newInstanceWithinActivityBounds( + ActivityControlHelper activityHelper) { BaseDraggingActivity activity = activityHelper.getCreatedActivity(); if (activity == null) { return InputConsumer.NO_OP; } - return new OverviewInputConsumer(activity, inputMonitor, startingInActivityBounds); + return new OverviewInputConsumer(activity, null, true); } } \ No newline at end of file diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java new file mode 100644 index 0000000000..425b8b6b0b --- /dev/null +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.quickstep.inputconsumers; + +import static android.view.MotionEvent.ACTION_CANCEL; +import static android.view.MotionEvent.ACTION_DOWN; +import static android.view.MotionEvent.ACTION_MOVE; +import static android.view.MotionEvent.ACTION_UP; + +import static com.android.launcher3.Utilities.squaredHypot; +import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG; +import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; + +import android.content.Context; +import android.graphics.PointF; +import android.view.MotionEvent; +import android.view.VelocityTracker; +import android.view.ViewConfiguration; + +import com.android.launcher3.Utilities; +import com.android.quickstep.OverviewCallbacks; +import com.android.quickstep.util.NavBarPosition; +import com.android.systemui.shared.system.ActivityManagerWrapper; +import com.android.systemui.shared.system.InputMonitorCompat; + +public class OverviewWithoutFocusInputConsumer implements InputConsumer { + + private final InputMonitorCompat mInputMonitor; + private final boolean mDisableHorizontalSwipe; + private final PointF mDownPos = new PointF(); + private final float mSquaredTouchSlop; + private final Context mContext; + private final NavBarPosition mNavBarPosition; + + private boolean mInterceptedTouch; + private VelocityTracker mVelocityTracker; + + + public OverviewWithoutFocusInputConsumer(Context context, InputMonitorCompat inputMonitor, + boolean disableHorizontalSwipe) { + mInputMonitor = inputMonitor; + mDisableHorizontalSwipe = disableHorizontalSwipe; + mContext = context; + mSquaredTouchSlop = Utilities.squaredTouchSlop(context); + mNavBarPosition = new NavBarPosition(context); + + mVelocityTracker = VelocityTracker.obtain(); + } + + @Override + public int getType() { + return TYPE_OVERVIEW_WITHOUT_FOCUS; + } + + @Override + public boolean allowInterceptByParent() { + return !mInterceptedTouch; + } + + private void endTouchTracking() { + if (mVelocityTracker != null) { + mVelocityTracker.recycle(); + mVelocityTracker = null; + } + } + + @Override + public void onMotionEvent(MotionEvent ev) { + if (mVelocityTracker == null) { + return; + } + + mVelocityTracker.addMovement(ev); + switch (ev.getActionMasked()) { + case ACTION_DOWN: { + mDownPos.set(ev.getX(), ev.getY()); + break; + } + case ACTION_MOVE: { + if (!mInterceptedTouch) { + float displacementX = ev.getX() - mDownPos.x; + float displacementY = ev.getY() - mDownPos.y; + if (squaredHypot(displacementX, displacementY) >= mSquaredTouchSlop) { + if (mDisableHorizontalSwipe + && Math.abs(displacementX) > Math.abs(displacementY)) { + // Horizontal gesture is not allowed in this region + endTouchTracking(); + break; + } + + mInterceptedTouch = true; + + if (mInputMonitor != null) { + mInputMonitor.pilferPointers(); + } + } + } + break; + } + + case ACTION_CANCEL: + endTouchTracking(); + break; + + case ACTION_UP: { + finishTouchTracking(ev); + endTouchTracking(); + break; + } + } + } + + private void finishTouchTracking(MotionEvent ev) { + mVelocityTracker.computeCurrentVelocity(100); + float velocityX = mVelocityTracker.getXVelocity(); + float velocityY = mVelocityTracker.getYVelocity(); + float velocity = mNavBarPosition.isRightEdge() + ? -velocityX : (mNavBarPosition.isLeftEdge() ? velocityX : -velocityY); + + final boolean triggerQuickstep; + if (Math.abs(velocity) >= ViewConfiguration.get(mContext).getScaledMinimumFlingVelocity()) { + triggerQuickstep = velocity > 0; + } else { + float displacementX = mDisableHorizontalSwipe ? 0 : (ev.getX() - mDownPos.x); + float displacementY = ev.getY() - mDownPos.y; + triggerQuickstep = squaredHypot(displacementX, displacementY) >= mSquaredTouchSlop; + } + + if (triggerQuickstep) { + OverviewCallbacks.get(mContext).closeAllWindows(); + ActivityManagerWrapper.getInstance() + .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS); + TOUCH_INTERACTION_LOG.addLog("startQuickstep"); + } else { + // ignore + } + } +} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java new file mode 100644 index 0000000000..3ce341d8cf --- /dev/null +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.quickstep.util; + +import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_LANDSCAPE; +import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_SEASCAPE; +import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; + +import android.content.Context; +import android.view.Surface; +import android.view.WindowManager; + +import com.android.launcher3.graphics.RotationMode; +import com.android.quickstep.SysUINavigationMode; + +/** + * Utility class to check nav bar position + */ +public class NavBarPosition { + + private final SysUINavigationMode.Mode mMode; + private final int mDisplayRotation; + + public NavBarPosition(Context context) { + mMode = SysUINavigationMode.getMode(context); + mDisplayRotation = context.getSystemService(WindowManager.class) + .getDefaultDisplay().getRotation(); + } + + public boolean isRightEdge() { + return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_90; + } + + public boolean isLeftEdge() { + return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_270; + } + + public RotationMode getRotationMode() { + return isLeftEdge() ? ROTATION_SEASCAPE + : (isRightEdge() ? ROTATION_LANDSCAPE : RotationMode.NORMAL); + } +} From 44e9a873fcbdfb726eea84d801b708ed8aae860c Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 6 Jun 2019 13:40:05 -0700 Subject: [PATCH 16/20] Test: using RuleChain to create a correct order of rules. Change-Id: I2eeb933eab8e5f19b1f80d47566a511ddbdeb28b --- .../quickstep/AbstractQuickStepTest.java | 10 +++++++--- .../launcher3/ui/AbstractLauncherUiTest.java | 17 +++++++++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java index c2c568bb61..a412b3970f 100644 --- a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java +++ b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java @@ -18,13 +18,17 @@ package com.android.quickstep; import com.android.launcher3.ui.AbstractLauncherUiTest; -import org.junit.Rule; +import org.junit.rules.RuleChain; import org.junit.rules.TestRule; /** * Base class for all instrumentation tests that deal with Quickstep. */ public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest { - @Rule - public TestRule mNavigationModeSwitcher = new NavigationModeSwitchRule(mLauncher); + @Override + protected TestRule getRulesInsideActivityMonitor() { + return RuleChain. + outerRule(new NavigationModeSwitchRule(mLauncher)). + around(super.getRulesInsideActivityMonitor()); + } } diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index e5cc858bb2..64fe2d7d79 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -65,8 +65,8 @@ import com.android.launcher3.util.rule.ShellCommandRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; +import org.junit.rules.RuleChain; import org.junit.rules.TestRule; -import org.junit.rules.TestWatcher; import org.junit.runners.model.Statement; import java.io.IOException; @@ -94,7 +94,8 @@ public abstract class AbstractLauncherUiTest { protected MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor(); protected final UiDevice mDevice = UiDevice.getInstance(getInstrumentation()); - protected final LauncherInstrumentation mLauncher; + protected final LauncherInstrumentation mLauncher = + new LauncherInstrumentation(getInstrumentation()); protected Context mTargetContext; protected String mTargetPackage; @@ -105,11 +106,9 @@ public abstract class AbstractLauncherUiTest { throw new RuntimeException(e); } if (TestHelpers.isInLauncherProcess()) Utilities.enableRunningInTestHarnessForTests(); - mLauncher = new LauncherInstrumentation(getInstrumentation()); } - @Rule - public LauncherActivityRule mActivityMonitor = new LauncherActivityRule(); + protected final LauncherActivityRule mActivityMonitor = new LauncherActivityRule(); @Rule public ShellCommandRule mDefaultLauncherRule = @@ -163,8 +162,14 @@ public abstract class AbstractLauncherUiTest { } } : base; + protected TestRule getRulesInsideActivityMonitor() { + return new FailureWatcher(this); + } + @Rule - public TestWatcher mFailureWatcher = new FailureWatcher(this); + public TestRule mOrderSensitiveRules = RuleChain. + outerRule(mActivityMonitor). + around(getRulesInsideActivityMonitor()); public UiDevice getDevice() { return mDevice; From 0b1cb75ee8384528721f66fd1881013c53e5d750 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 5 Jun 2019 15:18:39 -0700 Subject: [PATCH 17/20] Disable seamless rotation for 3 and 2 button mode Bug: 134095068 Change-Id: I8603e49a85b5524a02c9085485a180b022e3f91e --- .../android/launcher3/uioverrides/UiFactory.java | 13 ++++++++----- src/com/android/launcher3/Launcher.java | 2 +- .../android/launcher3/states/RotationHelper.java | 9 +++++++-- .../android/launcher3/uioverrides/UiFactory.java | 3 +-- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java index 4891746140..97cd38a117 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java +++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java @@ -47,7 +47,6 @@ import com.android.launcher3.LauncherStateManager; import com.android.launcher3.LauncherStateManager.StateHandler; import com.android.launcher3.QuickstepAppTransitionManagerImpl; import com.android.launcher3.Utilities; -import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.proxy.ProxyActivityStarter; import com.android.launcher3.proxy.StartActivityParams; import com.android.quickstep.OverviewInteractionState; @@ -64,10 +63,14 @@ import java.util.zip.Deflater; public class UiFactory extends RecentsUiFactory { - public static Runnable enableLiveTouchControllerChanges(DragLayer dl) { - NavigationModeChangeListener listener = m -> dl.recreateControllers(); - SysUINavigationMode mode = SysUINavigationMode.INSTANCE.get(dl.getContext()); - mode.addModeChangeListener(listener); + public static Runnable enableLiveUIChanges(Launcher launcher) { + NavigationModeChangeListener listener = m -> { + launcher.getDragLayer().recreateControllers(); + launcher.getRotationHelper().setRotationHadDifferentUI(m != Mode.NO_BUTTON); + }; + SysUINavigationMode mode = SysUINavigationMode.INSTANCE.get(launcher); + SysUINavigationMode.Mode m = mode.addModeChangeListener(listener); + launcher.getRotationHelper().setRotationHadDifferentUI(m != Mode.NO_BUTTON); return () -> mode.removeModeChangeListener(listener); } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 855535b0f3..1afbe0098c 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1063,7 +1063,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, // Setup the drag layer mDragLayer.setup(mDragController, mWorkspace); - mCancelTouchController = UiFactory.enableLiveTouchControllerChanges(mDragLayer); + mCancelTouchController = UiFactory.enableLiveUIChanges(this); mWorkspace.setup(mDragController); // Until the workspace is bound, ensure that we keep the wallpaper offset locked to the diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java index cd96d6ed84..abf90e22c8 100644 --- a/src/com/android/launcher3/states/RotationHelper.java +++ b/src/com/android/launcher3/states/RotationHelper.java @@ -73,7 +73,8 @@ public class RotationHelper implements OnSharedPreferenceChangeListener { // This is used to defer setting rotation flags until the activity is being created private boolean mInitialized; - public boolean mDestroyed; + private boolean mDestroyed; + private boolean mRotationHasDifferentUI; private int mLastActivityFlags = -1; @@ -92,8 +93,12 @@ public class RotationHelper implements OnSharedPreferenceChangeListener { } } + public void setRotationHadDifferentUI(boolean rotationHasDifferentUI) { + mRotationHasDifferentUI = rotationHasDifferentUI; + } + public boolean homeScreenCanRotate() { - return mIgnoreAutoRotateSettings || mAutoRotateEnabled + return mRotationHasDifferentUI || mIgnoreAutoRotateSettings || mAutoRotateEnabled || mStateHandlerRequest != REQUEST_NONE || mLauncher.getDeviceProfile().isMultiWindowMode; } diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java index 550327d961..e41916cf47 100644 --- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java +++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java @@ -27,7 +27,6 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState.ScaleAndTranslation; import com.android.launcher3.LauncherStateManager.StateHandler; -import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.graphics.RotationMode; import com.android.launcher3.util.TouchController; @@ -40,7 +39,7 @@ public class UiFactory { launcher.getDragController(), new AllAppsSwipeController(launcher)}; } - public static Runnable enableLiveTouchControllerChanges(DragLayer dl) { + public static Runnable enableLiveUIChanges(Launcher l) { return null; } From 0f08db5eebb962a8515bde6f15cc51723b144ebd Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 6 Jun 2019 17:00:57 -0700 Subject: [PATCH 18/20] Add tracing for b/134532571 Bug: 134172603 Bug: 134532571 Change-Id: I75c8e0212a9b35d33842d5380fbe733b486be932 --- .../LauncherActivityControllerHelper.java | 5 ++++ .../WindowTransformSwipeHandler.java | 23 +++++++++++++++++++ src/com/android/launcher3/Launcher.java | 3 +++ .../launcher3/testing/TestProtocol.java | 1 + .../android/launcher3/tapl/Background.java | 2 ++ 5 files changed, 34 insertions(+) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java index d0a41f3b53..1b82bcb578 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java @@ -36,6 +36,7 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; import android.os.UserHandle; +import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.animation.Interpolator; @@ -53,6 +54,7 @@ import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.SpringObjectAnimator; import com.android.launcher3.compat.AccessibilityManagerCompat; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.views.FloatingIconView; import com.android.quickstep.SysUINavigationMode.Mode; @@ -174,6 +176,9 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe @Override public AnimationFactory prepareRecentsUI(Launcher activity, boolean activityVisible, boolean animateActivity, Consumer callback) { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "prepareRecentsUI"); + } final LauncherState startState = activity.getStateManager().getState(); LauncherState resetState = startState; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index 87b7326648..0f66ed8439 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -59,6 +59,7 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; +import android.util.Log; import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.View; @@ -83,6 +84,7 @@ import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.graphics.RotationMode; import com.android.launcher3.logging.UserEventDispatcher; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; @@ -457,17 +459,32 @@ public class WindowTransformSwipeHandler } private void onLauncherStart(final T activity) { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart"); + } if (mActivity != activity) { return; } + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 1"); + } if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) { return; } + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 2"); + } // If we've already ended the gesture and are going home, don't prepare recents UI, // as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL. if (mGestureEndTarget != HOME) { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 3"); + } Runnable initAnimFactory = () -> { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 4"); + } mAnimationFactory = mActivityControlHelper.prepareRecentsUI(mActivity, mWasLauncherAlreadyVisible, true, this::onAnimatorPlaybackControllerCreated); @@ -477,8 +494,14 @@ public class WindowTransformSwipeHandler // Launcher is visible, but might be about to stop. Thus, if we prepare recents // now, it might get overridden by moveToRestState() in onStop(). To avoid this, // wait until the next gesture (and possibly launcher) starts. + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 5"); + } mStateCallback.addCallback(STATE_GESTURE_STARTED, initAnimFactory); } else { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 6"); + } initAnimFactory.run(); } } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 855535b0f3..7e02168b66 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -879,6 +879,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, @Override protected void onStart() { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "Launcher.onStart"); + } RaceConditionTracker.onEvent(ON_START_EVT, ENTER); super.onStart(); if (mLauncherCallbacks != null) { diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 99efb22cf1..02e6bbdd79 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -72,4 +72,5 @@ public final class TestProtocol { public static final String NO_DRAG_TAG = "b/133009122"; public static final String NO_START_TAG = "b/132900132"; public static final String NO_START_TASK_TAG = "b/133765434"; + public static final String NO_OVERVIEW_EVENT_TAG = "b/134532571"; } diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java index ce952983f9..6c46192356 100644 --- a/tests/tapl/com/android/launcher3/tapl/Background.java +++ b/tests/tapl/com/android/launcher3/tapl/Background.java @@ -59,6 +59,7 @@ public class Background extends LauncherInstrumentation.VisibleContainer { } protected void goToOverviewUnchecked(int expectedState) { + mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); switch (mLauncher.getNavigationModel()) { case ZERO_BUTTON: { final int centerX = mLauncher.getDevice().getDisplayWidth() / 2; @@ -103,6 +104,7 @@ public class Background extends LauncherInstrumentation.VisibleContainer { mLauncher.waitForSystemUiObject("recent_apps").click(); break; } + mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); } protected String getSwipeHeightRequestName() { From 0aefac860ff0f5f01e6a35de098d7c5e7b9b8cd7 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Thu, 6 Jun 2019 16:10:03 -0700 Subject: [PATCH 19/20] Folder name should follow folder icon text color Bug: 134674880 Change-Id: Ic64e9a085bc689e90112a0e70a150aa1c237b033 --- res/layout/user_folder_icon_normalized.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/layout/user_folder_icon_normalized.xml b/res/layout/user_folder_icon_normalized.xml index 835fee2d3d..a1033f06ce 100644 --- a/res/layout/user_folder_icon_normalized.xml +++ b/res/layout/user_folder_icon_normalized.xml @@ -56,9 +56,9 @@ android:paddingBottom="@dimen/folder_label_padding_bottom" android:paddingTop="@dimen/folder_label_padding_top" android:singleLine="true" - android:textColor="?android:attr/textColorTertiary" + android:textColor="?attr/folderTextColor" android:textColorHighlight="?android:attr/colorControlHighlight" - android:textColorHint="?android:attr/textColorHint" + android:textColorHint="?attr/folderTextColor" android:textSize="@dimen/folder_label_text_size" /> Date: Fri, 7 Jun 2019 12:12:02 -0700 Subject: [PATCH 20/20] More tracing for b/133009122 Bug: 133009122 Change-Id: Ic843c3147d8a7513b6e2b8732af18458eae10d63 --- .../android/launcher3/dragndrop/DragController.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index 9d3c8f75dc..72a1abb833 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -27,6 +27,7 @@ import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; import android.os.IBinder; +import android.util.Log; import android.view.DragEvent; import android.view.HapticFeedbackConstants; import android.view.KeyEvent; @@ -491,6 +492,16 @@ public class DragController implements DragDriver.EventListener, TouchController mLastTouch[0] = x; mLastTouch[1] = y; + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_DRAG_TAG, + "handleMoveEvent Conditions " + + mIsInPreDrag + ", " + + (mIsInPreDrag && mOptions.preDragCondition != null) + ", " + + (mIsInPreDrag && mOptions.preDragCondition != null + && mOptions.preDragCondition.shouldStartDrag( + mDistanceSinceScroll))); + } + if (mIsInPreDrag && mOptions.preDragCondition != null && mOptions.preDragCondition.shouldStartDrag(mDistanceSinceScroll)) { if (TestProtocol.sDebugTracing) {