Merging from ub-launcher3-rvc-dev @ build 6492476 am: 6e0d05fc41 am: 3cc9e2dcc1
Change-Id: Ia6be79352d96e6edcef08654a71adc485f845c33
This commit is contained in:
@@ -129,6 +129,7 @@ LOCAL_AAPT2_ONLY := true
|
|||||||
LOCAL_MODULE_TAGS := optional
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||||
|
SystemUI-statsd \
|
||||||
SystemUISharedLib \
|
SystemUISharedLib \
|
||||||
launcherprotosnano \
|
launcherprotosnano \
|
||||||
launcher_log_protos_lite
|
launcher_log_protos_lite
|
||||||
@@ -201,6 +202,7 @@ LOCAL_USE_AAPT2 := true
|
|||||||
LOCAL_MODULE_TAGS := optional
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||||
|
SystemUI-statsd \
|
||||||
SystemUISharedLib \
|
SystemUISharedLib \
|
||||||
launcherprotosnano \
|
launcherprotosnano \
|
||||||
launcher_log_protos_lite
|
launcher_log_protos_lite
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ message ItemInfo {
|
|||||||
Task task = 2;
|
Task task = 2;
|
||||||
Shortcut shortcut = 3;
|
Shortcut shortcut = 3;
|
||||||
Widget widget = 4;
|
Widget widget = 4;
|
||||||
|
FolderIcon folder_icon = 9;
|
||||||
}
|
}
|
||||||
// When used for launch event, stores the global predictive rank
|
// When used for launch event, stores the global predictive rank
|
||||||
optional int32 rank = 5;
|
optional int32 rank = 5;
|
||||||
@@ -92,6 +93,11 @@ message Task {
|
|||||||
optional int32 index = 3;
|
optional int32 index = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Represents folder in a closed state.
|
||||||
|
message FolderIcon {
|
||||||
|
optional int32 cardinality = 1;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
// Containers
|
// Containers
|
||||||
|
|
||||||
|
|||||||
@@ -24,13 +24,13 @@
|
|||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="32dp"
|
android:layout_height="32dp"
|
||||||
android:backgroundTint="?android:attr/colorAccent"
|
android:backgroundTint="?attr/eduHalfSheetBGColor"
|
||||||
android:background="@drawable/bottom_sheet_top_border" />
|
android:background="@drawable/bottom_sheet_top_border" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?android:attr/colorAccent"
|
android:background="?attr/eduHalfSheetBGColor"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
-95
@@ -16,39 +16,24 @@
|
|||||||
|
|
||||||
package com.android.launcher3;
|
package com.android.launcher3;
|
||||||
|
|
||||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
|
||||||
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
|
|
||||||
import static com.android.launcher3.LauncherState.NORMAL;
|
import static com.android.launcher3.LauncherState.NORMAL;
|
||||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
|
||||||
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
|
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
|
||||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
|
|
||||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRANSLATE;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
|
|
||||||
import static com.android.quickstep.TaskViewUtils.findTaskViewToLaunch;
|
import static com.android.quickstep.TaskViewUtils.findTaskViewToLaunch;
|
||||||
import static com.android.quickstep.TaskViewUtils.getRecentsWindowAnimator;
|
import static com.android.quickstep.TaskViewUtils.getRecentsWindowAnimator;
|
||||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
import android.animation.AnimatorSet;
|
import android.animation.AnimatorSet;
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.animation.ValueAnimator;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.launcher3.LauncherState.ScaleAndTranslation;
|
|
||||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
|
||||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||||
import com.android.launcher3.anim.Interpolators;
|
import com.android.launcher3.anim.Interpolators;
|
||||||
import com.android.launcher3.anim.SpringAnimationBuilder;
|
|
||||||
import com.android.launcher3.states.StateAnimationConfig;
|
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
import com.android.quickstep.views.TaskView;
|
import com.android.quickstep.views.TaskView;
|
||||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
@@ -59,13 +44,6 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
|||||||
*/
|
*/
|
||||||
public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransitionManagerImpl {
|
public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransitionManagerImpl {
|
||||||
|
|
||||||
public static final int INDEX_SHELF_ANIM = 0;
|
|
||||||
public static final int INDEX_RECENTS_FADE_ANIM = 1;
|
|
||||||
public static final int INDEX_RECENTS_TRANSLATE_X_ANIM = 2;
|
|
||||||
public static final int INDEX_PAUSE_TO_OVERVIEW_ANIM = 3;
|
|
||||||
|
|
||||||
public static final long ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW = 300;
|
|
||||||
|
|
||||||
public LauncherAppTransitionManagerImpl(Context context) {
|
public LauncherAppTransitionManagerImpl(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
@@ -151,77 +129,4 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti
|
|||||||
mLauncher.getStateManager().reapplyState();
|
mLauncher.getStateManager().reapplyState();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getStateElementAnimationsCount() {
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Animator createStateElementAnimation(int index, float... values) {
|
|
||||||
switch (index) {
|
|
||||||
case INDEX_SHELF_ANIM: {
|
|
||||||
AllAppsTransitionController aatc = mLauncher.getAllAppsController();
|
|
||||||
Animator springAnim = aatc.createSpringAnimation(values);
|
|
||||||
|
|
||||||
if ((OVERVIEW.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) {
|
|
||||||
// Translate hotseat with the shelf until reaching overview.
|
|
||||||
float overviewProgress = OVERVIEW.getVerticalProgress(mLauncher);
|
|
||||||
ScaleAndTranslation sat = OVERVIEW.getHotseatScaleAndTranslation(mLauncher);
|
|
||||||
float shiftRange = aatc.getShiftRange();
|
|
||||||
if (values.length == 1) {
|
|
||||||
values = new float[] {aatc.getProgress(), values[0]};
|
|
||||||
}
|
|
||||||
ValueAnimator hotseatAnim = ValueAnimator.ofFloat(values);
|
|
||||||
hotseatAnim.addUpdateListener(anim -> {
|
|
||||||
float progress = (Float) anim.getAnimatedValue();
|
|
||||||
if (progress >= overviewProgress || mLauncher.isInState(BACKGROUND_APP)) {
|
|
||||||
float hotseatShift = (progress - overviewProgress) * shiftRange;
|
|
||||||
mLauncher.getHotseat().setTranslationY(hotseatShift + sat.translationY);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
hotseatAnim.setInterpolator(LINEAR);
|
|
||||||
hotseatAnim.setDuration(springAnim.getDuration());
|
|
||||||
|
|
||||||
AnimatorSet anim = new AnimatorSet();
|
|
||||||
anim.play(hotseatAnim);
|
|
||||||
anim.play(springAnim);
|
|
||||||
return anim;
|
|
||||||
}
|
|
||||||
|
|
||||||
return springAnim;
|
|
||||||
}
|
|
||||||
case INDEX_RECENTS_FADE_ANIM:
|
|
||||||
return ObjectAnimator.ofFloat(mLauncher.getOverviewPanel(),
|
|
||||||
RecentsView.CONTENT_ALPHA, values);
|
|
||||||
case INDEX_RECENTS_TRANSLATE_X_ANIM: {
|
|
||||||
RecentsView rv = mLauncher.getOverviewPanel();
|
|
||||||
return new SpringAnimationBuilder(mLauncher)
|
|
||||||
.setMinimumVisibleChange(1f / rv.getPageOffsetScale())
|
|
||||||
.setDampingRatio(0.8f)
|
|
||||||
.setStiffness(250)
|
|
||||||
.setValues(values)
|
|
||||||
.build(rv, ADJACENT_PAGE_OFFSET);
|
|
||||||
}
|
|
||||||
case INDEX_PAUSE_TO_OVERVIEW_ANIM: {
|
|
||||||
StateAnimationConfig config = new StateAnimationConfig();
|
|
||||||
config.duration = ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
|
|
||||||
|
|
||||||
config.setInterpolator(ANIM_VERTICAL_PROGRESS, OVERSHOOT_1_2);
|
|
||||||
config.setInterpolator(ANIM_ALL_APPS_FADE, DEACCEL_3);
|
|
||||||
if ((OVERVIEW.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) {
|
|
||||||
config.setInterpolator(ANIM_HOTSEAT_SCALE, OVERSHOOT_1_2);
|
|
||||||
config.setInterpolator(ANIM_HOTSEAT_TRANSLATE, OVERSHOOT_1_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LauncherStateManager stateManager = mLauncher.getStateManager();
|
|
||||||
return stateManager.createAtomicAnimation(
|
|
||||||
stateManager.getCurrentStableState(), OVERVIEW, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return super.createStateElementAnimation(index, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-11
@@ -26,10 +26,10 @@ import android.os.UserManager;
|
|||||||
import com.android.launcher3.AbstractFloatingView;
|
import com.android.launcher3.AbstractFloatingView;
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.LauncherStateManager;
|
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.allapps.FloatingHeaderView;
|
import com.android.launcher3.allapps.FloatingHeaderView;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||||
import com.android.launcher3.views.ArrowTipView;
|
import com.android.launcher3.views.ArrowTipView;
|
||||||
import com.android.systemui.shared.system.LauncherEventUtil;
|
import com.android.systemui.shared.system.LauncherEventUtil;
|
||||||
|
|
||||||
@@ -71,17 +71,16 @@ public class AllAppsTipView {
|
|||||||
|
|
||||||
public static void scheduleShowIfNeeded(Launcher launcher) {
|
public static void scheduleShowIfNeeded(Launcher launcher) {
|
||||||
if (!hasSeenAllAppsTip(launcher)) {
|
if (!hasSeenAllAppsTip(launcher)) {
|
||||||
launcher.getStateManager().addStateListener(
|
launcher.getStateManager().addStateListener(new StateListener<LauncherState>() {
|
||||||
new LauncherStateManager.StateListener() {
|
@Override
|
||||||
@Override
|
public void onStateTransitionComplete(LauncherState finalState) {
|
||||||
public void onStateTransitionComplete(LauncherState finalState) {
|
if (finalState == ALL_APPS) {
|
||||||
if (finalState == ALL_APPS) {
|
if (showAllAppsTipIfNecessary(launcher)) {
|
||||||
if (showAllAppsTipIfNecessary(launcher)) {
|
launcher.getStateManager().removeStateListener(this);
|
||||||
launcher.getStateManager().removeStateListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -38,18 +38,18 @@ import androidx.core.content.ContextCompat;
|
|||||||
import com.android.launcher3.DeviceProfile;
|
import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.LauncherStateManager;
|
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.allapps.FloatingHeaderRow;
|
import com.android.launcher3.allapps.FloatingHeaderRow;
|
||||||
import com.android.launcher3.allapps.FloatingHeaderView;
|
import com.android.launcher3.allapps.FloatingHeaderView;
|
||||||
import com.android.launcher3.anim.PropertySetter;
|
import com.android.launcher3.anim.PropertySetter;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||||
import com.android.launcher3.util.Themes;
|
import com.android.launcher3.util.Themes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A view which shows a horizontal divider
|
* A view which shows a horizontal divider
|
||||||
*/
|
*/
|
||||||
@TargetApi(Build.VERSION_CODES.O)
|
@TargetApi(Build.VERSION_CODES.O)
|
||||||
public class AppsDividerView extends View implements LauncherStateManager.StateListener,
|
public class AppsDividerView extends View implements StateListener<LauncherState>,
|
||||||
FloatingHeaderRow {
|
FloatingHeaderRow {
|
||||||
|
|
||||||
private static final String ALL_APPS_VISITED_COUNT = "launcher.all_apps_visited_count";
|
private static final String ALL_APPS_VISITED_COUNT = "launcher.all_apps_visited_count";
|
||||||
|
|||||||
+3
-3
@@ -32,7 +32,6 @@ import com.android.launcher3.Launcher;
|
|||||||
import com.android.launcher3.LauncherAppState;
|
import com.android.launcher3.LauncherAppState;
|
||||||
import com.android.launcher3.LauncherSettings;
|
import com.android.launcher3.LauncherSettings;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.LauncherStateManager.StateListener;
|
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.allapps.AllAppsContainerView;
|
import com.android.launcher3.allapps.AllAppsContainerView;
|
||||||
import com.android.launcher3.allapps.AllAppsStore.OnUpdateListener;
|
import com.android.launcher3.allapps.AllAppsStore.OnUpdateListener;
|
||||||
@@ -41,6 +40,7 @@ import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
|
|||||||
import com.android.launcher3.model.data.ItemInfo;
|
import com.android.launcher3.model.data.ItemInfo;
|
||||||
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
||||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||||
import com.android.launcher3.util.ComponentKey;
|
import com.android.launcher3.util.ComponentKey;
|
||||||
import com.android.launcher3.util.MainThreadInitializedObject;
|
import com.android.launcher3.util.MainThreadInitializedObject;
|
||||||
@@ -63,8 +63,8 @@ import java.util.stream.IntStream;
|
|||||||
* 4) Maintains the current active client id (for the predictions) and all updates are performed on
|
* 4) Maintains the current active client id (for the predictions) and all updates are performed on
|
||||||
* that client id.
|
* that client id.
|
||||||
*/
|
*/
|
||||||
public class PredictionUiStateManager implements StateListener, ItemInfoUpdateReceiver,
|
public class PredictionUiStateManager implements StateListener<LauncherState>,
|
||||||
OnIDPChangeListener, OnUpdateListener {
|
ItemInfoUpdateReceiver, OnIDPChangeListener, OnUpdateListener {
|
||||||
|
|
||||||
public static final String LAST_PREDICTION_ENABLED_STATE = "last_prediction_enabled_state";
|
public static final String LAST_PREDICTION_ENABLED_STATE = "last_prediction_enabled_state";
|
||||||
|
|
||||||
|
|||||||
+26
@@ -46,6 +46,7 @@ import com.android.launcher3.model.data.ItemInfo;
|
|||||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||||
import com.android.launcher3.touch.ItemClickHandler;
|
import com.android.launcher3.touch.ItemClickHandler;
|
||||||
import com.android.launcher3.touch.ItemLongClickListener;
|
import com.android.launcher3.touch.ItemLongClickListener;
|
||||||
|
import com.android.launcher3.util.SafeCloseable;
|
||||||
import com.android.launcher3.views.DoubleShadowBubbleTextView;
|
import com.android.launcher3.views.DoubleShadowBubbleTextView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,6 +66,7 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView implements
|
|||||||
private final int mNormalizedIconRadius;
|
private final int mNormalizedIconRadius;
|
||||||
private final BlurMaskFilter mShadowFilter;
|
private final BlurMaskFilter mShadowFilter;
|
||||||
private int mPlateColor;
|
private int mPlateColor;
|
||||||
|
boolean mDrawForDrag = false;
|
||||||
|
|
||||||
|
|
||||||
public PredictedAppIcon(Context context) {
|
public PredictedAppIcon(Context context) {
|
||||||
@@ -188,6 +190,10 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void drawEffect(Canvas canvas, boolean isBadged) {
|
private void drawEffect(Canvas canvas, boolean isBadged) {
|
||||||
|
// Don't draw ring effect if item is about to be dragged.
|
||||||
|
if (mDrawForDrag) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
mRingPath.reset();
|
mRingPath.reset();
|
||||||
getShape().addToPath(mRingPath, getOutlineOffsetX(), getOutlineOffsetY(),
|
getShape().addToPath(mRingPath, getOutlineOffsetX(), getOutlineOffsetY(),
|
||||||
mNormalizedIconRadius);
|
mNormalizedIconRadius);
|
||||||
@@ -208,6 +214,26 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView implements
|
|||||||
canvas.drawPath(mRingPath, mIconRingPaint);
|
canvas.drawPath(mRingPath, mIconRingPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getSourceVisualDragBounds(Rect bounds) {
|
||||||
|
super.getSourceVisualDragBounds(bounds);
|
||||||
|
if (!mIsPinned) {
|
||||||
|
int internalSize = (int) (bounds.width() * RING_EFFECT_RATIO);
|
||||||
|
bounds.inset(internalSize, internalSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SafeCloseable prepareDrawDragView() {
|
||||||
|
mDrawForDrag = true;
|
||||||
|
invalidate();
|
||||||
|
SafeCloseable r = super.prepareDrawDragView();
|
||||||
|
return () -> {
|
||||||
|
r.close();
|
||||||
|
mDrawForDrag = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and returns a new instance of PredictedAppIcon from WorkspaceItemInfo
|
* Creates and returns a new instance of PredictedAppIcon from WorkspaceItemInfo
|
||||||
*/
|
*/
|
||||||
|
|||||||
+18
@@ -30,6 +30,7 @@ import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -48,6 +49,9 @@ import com.android.launcher3.model.data.AppInfo;
|
|||||||
import com.android.launcher3.model.data.ItemInfo;
|
import com.android.launcher3.model.data.ItemInfo;
|
||||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||||
import com.android.launcher3.popup.SystemShortcut;
|
import com.android.launcher3.popup.SystemShortcut;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
|
||||||
|
import com.android.launcher3.testing.TestProtocol;
|
||||||
|
import com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory;
|
||||||
import com.android.launcher3.uioverrides.touchcontrollers.FlingAndHoldTouchController;
|
import com.android.launcher3.uioverrides.touchcontrollers.FlingAndHoldTouchController;
|
||||||
import com.android.launcher3.uioverrides.touchcontrollers.LandscapeEdgeSwipeController;
|
import com.android.launcher3.uioverrides.touchcontrollers.LandscapeEdgeSwipeController;
|
||||||
import com.android.launcher3.uioverrides.touchcontrollers.NavBarToHomeTouchController;
|
import com.android.launcher3.uioverrides.touchcontrollers.NavBarToHomeTouchController;
|
||||||
@@ -243,6 +247,9 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TouchController[] createTouchControllers() {
|
public TouchController[] createTouchControllers() {
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "createTouchControllers.1");
|
||||||
|
}
|
||||||
Mode mode = SysUINavigationMode.getMode(this);
|
Mode mode = SysUINavigationMode.getMode(this);
|
||||||
|
|
||||||
ArrayList<TouchController> list = new ArrayList<>();
|
ArrayList<TouchController> list = new ArrayList<>();
|
||||||
@@ -250,7 +257,13 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
|
|||||||
if (mode == NO_BUTTON) {
|
if (mode == NO_BUTTON) {
|
||||||
list.add(new NoButtonQuickSwitchTouchController(this));
|
list.add(new NoButtonQuickSwitchTouchController(this));
|
||||||
list.add(new NavBarToHomeTouchController(this));
|
list.add(new NavBarToHomeTouchController(this));
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "createTouchControllers.2");
|
||||||
|
}
|
||||||
if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get()) {
|
if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get()) {
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "createTouchControllers.3");
|
||||||
|
}
|
||||||
list.add(new NoButtonNavbarToOverviewTouchController(this));
|
list.add(new NoButtonNavbarToOverviewTouchController(this));
|
||||||
} else {
|
} else {
|
||||||
list.add(new FlingAndHoldTouchController(this));
|
list.add(new FlingAndHoldTouchController(this));
|
||||||
@@ -279,6 +292,11 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
|
|||||||
return list.toArray(new TouchController[list.size()]);
|
return list.toArray(new TouchController[list.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AtomicAnimationFactory createAtomicAnimationFactory() {
|
||||||
|
return new QuickstepAtomicAnimationFactory(this);
|
||||||
|
}
|
||||||
|
|
||||||
private static final class LauncherTaskViewController extends
|
private static final class LauncherTaskViewController extends
|
||||||
TaskViewTouchController<Launcher> {
|
TaskViewTouchController<Launcher> {
|
||||||
|
|
||||||
|
|||||||
+9
-5
@@ -17,6 +17,7 @@ package com.android.launcher3.uioverrides.states;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.android.launcher3.BaseDraggingActivity;
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||||
@@ -54,11 +55,7 @@ public class BackgroundAppState extends OverviewState {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
||||||
return new float[] {getOverviewScale(launcher), NO_OFFSET};
|
return getOverviewScaleAndOffsetForBackgroundState(launcher);
|
||||||
}
|
|
||||||
|
|
||||||
private float getOverviewScale(Launcher launcher) {
|
|
||||||
return ((RecentsView) launcher.getOverviewPanel()).getMaxScaleForFullScreen();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -88,4 +85,11 @@ public class BackgroundAppState extends OverviewState {
|
|||||||
protected float getDepthUnchecked(Context context) {
|
protected float getDepthUnchecked(Context context) {
|
||||||
return 1f;
|
return 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float[] getOverviewScaleAndOffsetForBackgroundState(
|
||||||
|
BaseDraggingActivity activity) {
|
||||||
|
return new float[] {
|
||||||
|
((RecentsView) activity.getOverviewPanel()).getMaxScaleForFullScreen(),
|
||||||
|
NO_OFFSET};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-13
@@ -19,8 +19,8 @@ import android.content.Context;
|
|||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
|
||||||
|
import com.android.launcher3.BaseDraggingActivity;
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.R;
|
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
|
|
||||||
@@ -49,22 +49,25 @@ public class OverviewModalTaskState extends OverviewState {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
||||||
Resources res = launcher.getBaseContext().getResources();
|
return getOverviewScaleAndOffsetForModalState(launcher);
|
||||||
|
|
||||||
Rect out = new Rect();
|
|
||||||
launcher.<RecentsView>getOverviewPanel().getTaskSize(out);
|
|
||||||
int taskHeight = out.height();
|
|
||||||
|
|
||||||
float topMargin = res.getDimension(R.dimen.task_thumbnail_top_margin);
|
|
||||||
float bottomMargin = res.getDimension(R.dimen.task_thumbnail_bottom_margin_with_actions);
|
|
||||||
float newHeight = taskHeight + topMargin + bottomMargin;
|
|
||||||
float scale = newHeight / taskHeight;
|
|
||||||
|
|
||||||
return new float[] {scale, 0};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getOverviewModalness() {
|
public float getOverviewModalness() {
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float[] getOverviewScaleAndOffsetForModalState(BaseDraggingActivity activity) {
|
||||||
|
Resources res = activity.getResources();
|
||||||
|
|
||||||
|
Rect out = new Rect();
|
||||||
|
activity.<RecentsView>getOverviewPanel().getTaskSize(out);
|
||||||
|
int taskHeight = out.height();
|
||||||
|
activity.<RecentsView>getOverviewPanel().getModalTaskSize(out);
|
||||||
|
int newHeight = out.height();
|
||||||
|
|
||||||
|
float scale = (float) newHeight / taskHeight;
|
||||||
|
|
||||||
|
return new float[] {scale, NO_OFFSET};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-19
@@ -15,16 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.launcher3.uioverrides.states;
|
package com.android.launcher3.uioverrides.states;
|
||||||
|
|
||||||
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
|
|
||||||
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
|
||||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCRIM_FADE;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
|
||||||
|
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.LauncherState;
|
|
||||||
import com.android.launcher3.states.StateAnimationConfig;
|
|
||||||
|
|
||||||
public class OverviewPeekState extends OverviewState {
|
public class OverviewPeekState extends OverviewState {
|
||||||
private static final float OVERVIEW_OFFSET = 0.7f;
|
private static final float OVERVIEW_OFFSET = 0.7f;
|
||||||
@@ -37,14 +28,4 @@ public class OverviewPeekState extends OverviewState {
|
|||||||
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
||||||
return new float[] {NO_SCALE, OVERVIEW_OFFSET};
|
return new float[] {NO_SCALE, OVERVIEW_OFFSET};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void prepareForAtomicAnimation(Launcher launcher, LauncherState fromState,
|
|
||||||
StateAnimationConfig config) {
|
|
||||||
if (this == OVERVIEW_PEEK && fromState == NORMAL) {
|
|
||||||
config.setInterpolator(ANIM_OVERVIEW_FADE, INSTANT);
|
|
||||||
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, OVERSHOOT_1_7);
|
|
||||||
config.setInterpolator(ANIM_OVERVIEW_SCRIM_FADE, FAST_OUT_SLOW_IN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
-47
@@ -15,36 +15,21 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.launcher3.uioverrides.states;
|
package com.android.launcher3.uioverrides.states;
|
||||||
|
|
||||||
import static android.view.View.VISIBLE;
|
|
||||||
|
|
||||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
|
||||||
import static com.android.launcher3.anim.Interpolators.ACCEL;
|
|
||||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
|
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
|
||||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
|
||||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
|
|
||||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
|
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
|
||||||
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
|
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
|
|
||||||
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
||||||
import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
|
import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.animation.Interpolator;
|
|
||||||
|
|
||||||
import com.android.launcher3.DeviceProfile;
|
import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.Workspace;
|
import com.android.launcher3.Workspace;
|
||||||
import com.android.launcher3.states.StateAnimationConfig;
|
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
|
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
||||||
import com.android.quickstep.SysUINavigationMode;
|
import com.android.quickstep.SysUINavigationMode;
|
||||||
@@ -57,9 +42,6 @@ import com.android.quickstep.views.TaskView;
|
|||||||
*/
|
*/
|
||||||
public class OverviewState extends LauncherState {
|
public class OverviewState extends LauncherState {
|
||||||
|
|
||||||
// Scale recents takes before animating in
|
|
||||||
private static final float RECENTS_PREPARE_SCALE = 1.33f;
|
|
||||||
|
|
||||||
protected static final Rect sTempRect = new Rect();
|
protected static final Rect sTempRect = new Rect();
|
||||||
|
|
||||||
private static final int STATE_FLAGS = FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED
|
private static final int STATE_FLAGS = FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED
|
||||||
@@ -202,35 +184,6 @@ public class OverviewState extends LauncherState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void prepareForAtomicAnimation(Launcher launcher, LauncherState fromState,
|
|
||||||
StateAnimationConfig config) {
|
|
||||||
if ((fromState == NORMAL || fromState == HINT_STATE) && this == OVERVIEW) {
|
|
||||||
if (SysUINavigationMode.getMode(launcher) == NO_BUTTON) {
|
|
||||||
config.setInterpolator(ANIM_WORKSPACE_SCALE,
|
|
||||||
fromState == NORMAL ? ACCEL : OVERSHOOT_1_2);
|
|
||||||
config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCEL);
|
|
||||||
} else {
|
|
||||||
config.setInterpolator(ANIM_WORKSPACE_SCALE, OVERSHOOT_1_2);
|
|
||||||
|
|
||||||
// Scale up the recents, if it is not coming from the side
|
|
||||||
RecentsView overview = launcher.getOverviewPanel();
|
|
||||||
if (overview.getVisibility() != VISIBLE || overview.getContentAlpha() == 0) {
|
|
||||||
SCALE_PROPERTY.set(overview, RECENTS_PREPARE_SCALE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
config.setInterpolator(ANIM_WORKSPACE_FADE, OVERSHOOT_1_2);
|
|
||||||
config.setInterpolator(ANIM_OVERVIEW_SCALE, OVERSHOOT_1_2);
|
|
||||||
Interpolator translationInterpolator = ENABLE_OVERVIEW_ACTIONS.get()
|
|
||||||
&& removeShelfFromOverview(launcher)
|
|
||||||
? OVERSHOOT_1_2
|
|
||||||
: OVERSHOOT_1_7;
|
|
||||||
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, translationInterpolator);
|
|
||||||
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, translationInterpolator);
|
|
||||||
config.setInterpolator(ANIM_OVERVIEW_FADE, OVERSHOOT_1_2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static OverviewState newBackgroundState(int id) {
|
public static OverviewState newBackgroundState(int id) {
|
||||||
return new BackgroundAppState(id);
|
return new BackgroundAppState(id);
|
||||||
}
|
}
|
||||||
|
|||||||
+236
@@ -0,0 +1,236 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.launcher3.uioverrides.states;
|
||||||
|
|
||||||
|
import static android.view.View.VISIBLE;
|
||||||
|
|
||||||
|
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||||
|
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||||
|
import static com.android.launcher3.LauncherState.HINT_STATE;
|
||||||
|
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
|
||||||
|
import static com.android.launcher3.LauncherState.NORMAL;
|
||||||
|
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||||
|
import static com.android.launcher3.LauncherState.OVERVIEW_PEEK;
|
||||||
|
import static com.android.launcher3.anim.Interpolators.ACCEL;
|
||||||
|
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||||
|
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
|
||||||
|
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
|
||||||
|
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
|
||||||
|
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
||||||
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||||
|
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||||
|
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
|
||||||
|
import static com.android.launcher3.anim.Interpolators.clampToProgress;
|
||||||
|
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRANSLATE;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCRIM_FADE;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
|
||||||
|
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
||||||
|
import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
|
||||||
|
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorSet;
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.animation.Interpolator;
|
||||||
|
|
||||||
|
import com.android.launcher3.CellLayout;
|
||||||
|
import com.android.launcher3.Hotseat;
|
||||||
|
import com.android.launcher3.LauncherState;
|
||||||
|
import com.android.launcher3.LauncherState.ScaleAndTranslation;
|
||||||
|
import com.android.launcher3.Workspace;
|
||||||
|
import com.android.launcher3.allapps.AllAppsContainerView;
|
||||||
|
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||||
|
import com.android.launcher3.anim.SpringAnimationBuilder;
|
||||||
|
import com.android.launcher3.statemanager.StateManager;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
|
||||||
|
import com.android.launcher3.states.StateAnimationConfig;
|
||||||
|
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||||
|
import com.android.quickstep.SysUINavigationMode;
|
||||||
|
import com.android.quickstep.views.RecentsView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animation factory for quickstep specific transitions
|
||||||
|
*/
|
||||||
|
public class QuickstepAtomicAnimationFactory extends AtomicAnimationFactory<LauncherState> {
|
||||||
|
|
||||||
|
// Scale recents takes before animating in
|
||||||
|
private static final float RECENTS_PREPARE_SCALE = 1.33f;
|
||||||
|
|
||||||
|
public static final int INDEX_SHELF_ANIM = 0;
|
||||||
|
public static final int INDEX_RECENTS_FADE_ANIM = 1;
|
||||||
|
public static final int INDEX_RECENTS_TRANSLATE_X_ANIM = 2;
|
||||||
|
public static final int INDEX_PAUSE_TO_OVERVIEW_ANIM = 3;
|
||||||
|
private static final int ANIM_COUNT = 4;
|
||||||
|
|
||||||
|
public static final long ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW = 300;
|
||||||
|
|
||||||
|
private final QuickstepLauncher mLauncher;
|
||||||
|
|
||||||
|
public QuickstepAtomicAnimationFactory(QuickstepLauncher launcher) {
|
||||||
|
super(ANIM_COUNT);
|
||||||
|
mLauncher = launcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Animator createStateElementAnimation(int index, float... values) {
|
||||||
|
switch (index) {
|
||||||
|
case INDEX_SHELF_ANIM: {
|
||||||
|
AllAppsTransitionController aatc = mLauncher.getAllAppsController();
|
||||||
|
Animator springAnim = aatc.createSpringAnimation(values);
|
||||||
|
|
||||||
|
if ((OVERVIEW.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) {
|
||||||
|
// Translate hotseat with the shelf until reaching overview.
|
||||||
|
float overviewProgress = OVERVIEW.getVerticalProgress(mLauncher);
|
||||||
|
ScaleAndTranslation sat = OVERVIEW.getHotseatScaleAndTranslation(mLauncher);
|
||||||
|
float shiftRange = aatc.getShiftRange();
|
||||||
|
if (values.length == 1) {
|
||||||
|
values = new float[] {aatc.getProgress(), values[0]};
|
||||||
|
}
|
||||||
|
ValueAnimator hotseatAnim = ValueAnimator.ofFloat(values);
|
||||||
|
hotseatAnim.addUpdateListener(anim -> {
|
||||||
|
float progress = (Float) anim.getAnimatedValue();
|
||||||
|
if (progress >= overviewProgress || mLauncher.isInState(BACKGROUND_APP)) {
|
||||||
|
float hotseatShift = (progress - overviewProgress) * shiftRange;
|
||||||
|
mLauncher.getHotseat().setTranslationY(hotseatShift + sat.translationY);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
hotseatAnim.setInterpolator(LINEAR);
|
||||||
|
hotseatAnim.setDuration(springAnim.getDuration());
|
||||||
|
|
||||||
|
AnimatorSet anim = new AnimatorSet();
|
||||||
|
anim.play(hotseatAnim);
|
||||||
|
anim.play(springAnim);
|
||||||
|
return anim;
|
||||||
|
}
|
||||||
|
|
||||||
|
return springAnim;
|
||||||
|
}
|
||||||
|
case INDEX_RECENTS_FADE_ANIM:
|
||||||
|
return ObjectAnimator.ofFloat(mLauncher.getOverviewPanel(),
|
||||||
|
RecentsView.CONTENT_ALPHA, values);
|
||||||
|
case INDEX_RECENTS_TRANSLATE_X_ANIM: {
|
||||||
|
RecentsView rv = mLauncher.getOverviewPanel();
|
||||||
|
return new SpringAnimationBuilder(mLauncher)
|
||||||
|
.setMinimumVisibleChange(1f / rv.getPageOffsetScale())
|
||||||
|
.setDampingRatio(0.8f)
|
||||||
|
.setStiffness(250)
|
||||||
|
.setValues(values)
|
||||||
|
.build(rv, ADJACENT_PAGE_OFFSET);
|
||||||
|
}
|
||||||
|
case INDEX_PAUSE_TO_OVERVIEW_ANIM: {
|
||||||
|
StateAnimationConfig config = new StateAnimationConfig();
|
||||||
|
config.duration = ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
|
||||||
|
|
||||||
|
config.setInterpolator(ANIM_VERTICAL_PROGRESS, OVERSHOOT_1_2);
|
||||||
|
config.setInterpolator(ANIM_ALL_APPS_FADE, DEACCEL_3);
|
||||||
|
if ((OVERVIEW.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) {
|
||||||
|
config.setInterpolator(ANIM_HOTSEAT_SCALE, OVERSHOOT_1_2);
|
||||||
|
config.setInterpolator(ANIM_HOTSEAT_TRANSLATE, OVERSHOOT_1_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
StateManager<LauncherState> stateManager = mLauncher.getStateManager();
|
||||||
|
return stateManager.createAtomicAnimation(
|
||||||
|
stateManager.getCurrentStableState(), OVERVIEW, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return super.createStateElementAnimation(index, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepareForAtomicAnimation(LauncherState fromState, LauncherState toState,
|
||||||
|
StateAnimationConfig config) {
|
||||||
|
if (toState == NORMAL && fromState == OVERVIEW) {
|
||||||
|
config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
|
||||||
|
config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
|
||||||
|
config.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCEL, 0, 0.9f));
|
||||||
|
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL);
|
||||||
|
config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7);
|
||||||
|
Workspace workspace = mLauncher.getWorkspace();
|
||||||
|
|
||||||
|
// Start from a higher workspace scale, but only if we're invisible so we don't jump.
|
||||||
|
boolean isWorkspaceVisible = workspace.getVisibility() == VISIBLE;
|
||||||
|
if (isWorkspaceVisible) {
|
||||||
|
CellLayout currentChild = (CellLayout) workspace.getChildAt(
|
||||||
|
workspace.getCurrentPage());
|
||||||
|
isWorkspaceVisible = currentChild.getVisibility() == VISIBLE
|
||||||
|
&& currentChild.getShortcutsAndWidgets().getAlpha() > 0;
|
||||||
|
}
|
||||||
|
if (!isWorkspaceVisible) {
|
||||||
|
workspace.setScaleX(0.92f);
|
||||||
|
workspace.setScaleY(0.92f);
|
||||||
|
}
|
||||||
|
Hotseat hotseat = mLauncher.getHotseat();
|
||||||
|
boolean isHotseatVisible = hotseat.getVisibility() == VISIBLE && hotseat.getAlpha() > 0;
|
||||||
|
if (!isHotseatVisible) {
|
||||||
|
hotseat.setScaleX(0.92f);
|
||||||
|
hotseat.setScaleY(0.92f);
|
||||||
|
if (ENABLE_OVERVIEW_ACTIONS.get()) {
|
||||||
|
AllAppsContainerView qsbContainer = mLauncher.getAppsView();
|
||||||
|
View qsb = qsbContainer.getSearchView();
|
||||||
|
boolean qsbVisible = qsb.getVisibility() == VISIBLE && qsb.getAlpha() > 0;
|
||||||
|
if (!qsbVisible) {
|
||||||
|
qsbContainer.setScaleX(0.92f);
|
||||||
|
qsbContainer.setScaleY(0.92f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (toState == NORMAL && fromState == OVERVIEW_PEEK) {
|
||||||
|
// Keep fully visible until the very end (when overview is offscreen) to make invisible.
|
||||||
|
config.setInterpolator(ANIM_OVERVIEW_FADE, t -> t < 1 ? 0 : 1);
|
||||||
|
} else if (toState == OVERVIEW_PEEK && fromState == NORMAL) {
|
||||||
|
config.setInterpolator(ANIM_OVERVIEW_FADE, INSTANT);
|
||||||
|
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, OVERSHOOT_1_7);
|
||||||
|
config.setInterpolator(ANIM_OVERVIEW_SCRIM_FADE, FAST_OUT_SLOW_IN);
|
||||||
|
} else if ((fromState == NORMAL || fromState == HINT_STATE) && toState == OVERVIEW) {
|
||||||
|
if (SysUINavigationMode.getMode(mLauncher) == NO_BUTTON) {
|
||||||
|
config.setInterpolator(ANIM_WORKSPACE_SCALE,
|
||||||
|
fromState == NORMAL ? ACCEL : OVERSHOOT_1_2);
|
||||||
|
config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCEL);
|
||||||
|
} else {
|
||||||
|
config.setInterpolator(ANIM_WORKSPACE_SCALE, OVERSHOOT_1_2);
|
||||||
|
|
||||||
|
// Scale up the recents, if it is not coming from the side
|
||||||
|
RecentsView overview = mLauncher.getOverviewPanel();
|
||||||
|
if (overview.getVisibility() != VISIBLE || overview.getContentAlpha() == 0) {
|
||||||
|
SCALE_PROPERTY.set(overview, RECENTS_PREPARE_SCALE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config.setInterpolator(ANIM_WORKSPACE_FADE, OVERSHOOT_1_2);
|
||||||
|
config.setInterpolator(ANIM_OVERVIEW_SCALE, OVERSHOOT_1_2);
|
||||||
|
Interpolator translationInterpolator = ENABLE_OVERVIEW_ACTIONS.get()
|
||||||
|
&& removeShelfFromOverview(mLauncher)
|
||||||
|
? OVERSHOOT_1_2
|
||||||
|
: OVERSHOOT_1_7;
|
||||||
|
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, translationInterpolator);
|
||||||
|
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, translationInterpolator);
|
||||||
|
config.setInterpolator(ANIM_OVERVIEW_FADE, OVERSHOOT_1_2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
-5
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package com.android.launcher3.uioverrides.touchcontrollers;
|
package com.android.launcher3.uioverrides.touchcontrollers;
|
||||||
|
|
||||||
import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_PAUSE_TO_OVERVIEW_ANIM;
|
|
||||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||||
import static com.android.launcher3.LauncherState.NORMAL;
|
import static com.android.launcher3.LauncherState.NORMAL;
|
||||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||||
@@ -31,23 +30,26 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_S
|
|||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
|
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||||
|
import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_PAUSE_TO_OVERVIEW_ANIM;
|
||||||
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
import android.animation.AnimatorSet;
|
import android.animation.AnimatorSet;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewConfiguration;
|
import android.view.ViewConfiguration;
|
||||||
|
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.LauncherAppTransitionManagerImpl;
|
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||||
import com.android.launcher3.anim.Interpolators;
|
import com.android.launcher3.anim.Interpolators;
|
||||||
import com.android.launcher3.states.StateAnimationConfig;
|
import com.android.launcher3.states.StateAnimationConfig;
|
||||||
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
|
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
|
||||||
|
import com.android.launcher3.testing.TestProtocol;
|
||||||
|
import com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||||
import com.android.launcher3.util.VibratorWrapper;
|
import com.android.launcher3.util.VibratorWrapper;
|
||||||
import com.android.quickstep.SystemUiProxy;
|
import com.android.quickstep.SystemUiProxy;
|
||||||
@@ -82,7 +84,7 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected long getAtomicDuration() {
|
protected long getAtomicDuration() {
|
||||||
return LauncherAppTransitionManagerImpl.ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
|
return QuickstepAtomicAnimationFactory.ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -178,6 +180,9 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onDrag(float displacement, MotionEvent event) {
|
public boolean onDrag(float displacement, MotionEvent event) {
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "FlingAndHoldTouchController");
|
||||||
|
}
|
||||||
float upDisplacement = -displacement;
|
float upDisplacement = -displacement;
|
||||||
mMotionPauseDetector.setDisallowPause(!handlingOverviewAnim()
|
mMotionPauseDetector.setDisallowPause(!handlingOverviewAnim()
|
||||||
|| upDisplacement < mMotionPauseMinDisplacement
|
|| upDisplacement < mMotionPauseMinDisplacement
|
||||||
@@ -206,8 +211,8 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController {
|
|||||||
mPeekAnim.cancel();
|
mPeekAnim.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
Animator overviewAnim = mLauncher.getAppTransitionManager().createStateElementAnimation(
|
Animator overviewAnim = mLauncher.createAtomicAnimationFactory()
|
||||||
INDEX_PAUSE_TO_OVERVIEW_ANIM);
|
.createStateElementAnimation(INDEX_PAUSE_TO_OVERVIEW_ANIM);
|
||||||
mAtomicAnim = new AnimatorSet();
|
mAtomicAnim = new AnimatorSet();
|
||||||
mAtomicAnim.addListener(new AnimationSuccessListener() {
|
mAtomicAnim.addListener(new AnimationSuccessListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+21
@@ -25,6 +25,7 @@ import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
|||||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||||
|
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.animation.Interpolator;
|
import android.view.animation.Interpolator;
|
||||||
|
|
||||||
@@ -41,6 +42,7 @@ import com.android.launcher3.anim.PendingAnimation;
|
|||||||
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||||
import com.android.launcher3.config.FeatureFlags;
|
import com.android.launcher3.config.FeatureFlags;
|
||||||
import com.android.launcher3.states.StateAnimationConfig;
|
import com.android.launcher3.states.StateAnimationConfig;
|
||||||
|
import com.android.launcher3.testing.TestProtocol;
|
||||||
import com.android.launcher3.touch.SingleAxisSwipeDetector;
|
import com.android.launcher3.touch.SingleAxisSwipeDetector;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||||
@@ -94,18 +96,37 @@ public class NavBarToHomeTouchController implements TouchController,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean canInterceptTouch(MotionEvent ev) {
|
private boolean canInterceptTouch(MotionEvent ev) {
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "NavBarToHomeTouchController.canInterceptTouch "
|
||||||
|
+ ev);
|
||||||
|
}
|
||||||
boolean cameFromNavBar = (ev.getEdgeFlags() & Utilities.EDGE_NAV_BAR) != 0;
|
boolean cameFromNavBar = (ev.getEdgeFlags() & Utilities.EDGE_NAV_BAR) != 0;
|
||||||
if (!cameFromNavBar) {
|
if (!cameFromNavBar) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (mStartState.overviewUi || mStartState == ALL_APPS) {
|
if (mStartState.overviewUi || mStartState == ALL_APPS) {
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED,
|
||||||
|
"NavBarToHomeTouchController.canInterceptTouch true 1 "
|
||||||
|
+ mStartState.overviewUi + " " + (mStartState == ALL_APPS));
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
|
if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED,
|
||||||
|
"NavBarToHomeTouchController.canInterceptTouch true 2 "
|
||||||
|
+ AbstractFloatingView.getTopOpenView(mLauncher).getClass()
|
||||||
|
.getSimpleName());
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS.get()
|
if (FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS.get()
|
||||||
&& AssistantUtilities.isExcludedAssistantRunning()) {
|
&& AssistantUtilities.isExcludedAssistantRunning()) {
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED,
|
||||||
|
"NavBarToHomeTouchController.canInterceptTouch true 3");
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
+10
-2
@@ -27,14 +27,16 @@ import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
|||||||
import android.animation.AnimatorSet;
|
import android.animation.AnimatorSet;
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.LauncherStateManager;
|
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||||
|
import com.android.launcher3.statemanager.StateManager;
|
||||||
import com.android.launcher3.states.StateAnimationConfig;
|
import com.android.launcher3.states.StateAnimationConfig;
|
||||||
|
import com.android.launcher3.testing.TestProtocol;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||||
import com.android.launcher3.util.VibratorWrapper;
|
import com.android.launcher3.util.VibratorWrapper;
|
||||||
import com.android.quickstep.util.StaggeredWorkspaceAnim;
|
import com.android.quickstep.util.StaggeredWorkspaceAnim;
|
||||||
@@ -63,6 +65,9 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo
|
|||||||
public NoButtonNavbarToOverviewTouchController(Launcher l) {
|
public NoButtonNavbarToOverviewTouchController(Launcher l) {
|
||||||
super(l);
|
super(l);
|
||||||
mRecentsView = l.getOverviewPanel();
|
mRecentsView = l.getOverviewPanel();
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "NoButtonNavbarToOverviewTouchController.ctor");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -146,6 +151,9 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onDrag(float yDisplacement, float xDisplacement, MotionEvent event) {
|
public boolean onDrag(float yDisplacement, float xDisplacement, MotionEvent event) {
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "NoButtonNavbarToOverviewTouchController");
|
||||||
|
}
|
||||||
if (mMotionPauseDetector.isPaused()) {
|
if (mMotionPauseDetector.isPaused()) {
|
||||||
if (!mReachedOverview) {
|
if (!mReachedOverview) {
|
||||||
mStartDisplacement.set(xDisplacement, yDisplacement);
|
mStartDisplacement.set(xDisplacement, yDisplacement);
|
||||||
@@ -165,7 +173,7 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo
|
|||||||
protected void goToOverviewOnDragEnd(float velocity) {
|
protected void goToOverviewOnDragEnd(float velocity) {
|
||||||
float velocityDp = dpiFromPx(velocity);
|
float velocityDp = dpiFromPx(velocity);
|
||||||
boolean isFling = Math.abs(velocityDp) > 1;
|
boolean isFling = Math.abs(velocityDp) > 1;
|
||||||
LauncherStateManager stateManager = mLauncher.getStateManager();
|
StateManager<LauncherState> stateManager = mLauncher.getStateManager();
|
||||||
boolean goToHomeInsteadOfOverview = isFling;
|
boolean goToHomeInsteadOfOverview = isFling;
|
||||||
if (goToHomeInsteadOfOverview) {
|
if (goToHomeInsteadOfOverview) {
|
||||||
if (velocity > 0) {
|
if (velocity > 0) {
|
||||||
|
|||||||
+3
-3
@@ -16,7 +16,6 @@
|
|||||||
package com.android.launcher3.uioverrides.touchcontrollers;
|
package com.android.launcher3.uioverrides.touchcontrollers;
|
||||||
|
|
||||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||||
import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_PAUSE_TO_OVERVIEW_ANIM;
|
|
||||||
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
|
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
|
||||||
import static com.android.launcher3.LauncherState.NORMAL;
|
import static com.android.launcher3.LauncherState.NORMAL;
|
||||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||||
@@ -35,6 +34,7 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_T
|
|||||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||||
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT;
|
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT;
|
||||||
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP;
|
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP;
|
||||||
|
import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_PAUSE_TO_OVERVIEW_ANIM;
|
||||||
import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
|
import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
|
||||||
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
||||||
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.CANCEL;
|
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.CANCEL;
|
||||||
@@ -312,8 +312,8 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
|||||||
if (mMotionPauseDetector.isPaused() && noFling) {
|
if (mMotionPauseDetector.isPaused() && noFling) {
|
||||||
cancelAnimations();
|
cancelAnimations();
|
||||||
|
|
||||||
Animator overviewAnim = mLauncher.getAppTransitionManager().createStateElementAnimation(
|
Animator overviewAnim = mLauncher.createAtomicAnimationFactory()
|
||||||
INDEX_PAUSE_TO_OVERVIEW_ANIM);
|
.createStateElementAnimation(INDEX_PAUSE_TO_OVERVIEW_ANIM);
|
||||||
overviewAnim.addListener(new AnimatorListenerAdapter() {
|
overviewAnim.addListener(new AnimatorListenerAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animator animation) {
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
|||||||
+7
-5
@@ -58,6 +58,7 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
|||||||
private final SingleAxisSwipeDetector mDetector;
|
private final SingleAxisSwipeDetector mDetector;
|
||||||
private final RecentsView mRecentsView;
|
private final RecentsView mRecentsView;
|
||||||
private final int[] mTempCords = new int[2];
|
private final int[] mTempCords = new int[2];
|
||||||
|
private final boolean mIsRtl;
|
||||||
|
|
||||||
private PendingAnimation mPendingAnimation;
|
private PendingAnimation mPendingAnimation;
|
||||||
private AnimatorPlaybackController mCurrentAnimation;
|
private AnimatorPlaybackController mCurrentAnimation;
|
||||||
@@ -75,6 +76,7 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
|||||||
public TaskViewTouchController(T activity) {
|
public TaskViewTouchController(T activity) {
|
||||||
mActivity = activity;
|
mActivity = activity;
|
||||||
mRecentsView = activity.getOverviewPanel();
|
mRecentsView = activity.getOverviewPanel();
|
||||||
|
mIsRtl = Utilities.isRtl(activity.getResources());
|
||||||
SingleAxisSwipeDetector.Direction dir =
|
SingleAxisSwipeDetector.Direction dir =
|
||||||
mRecentsView.getPagedOrientationHandler().getOppositeSwipeDirection();
|
mRecentsView.getPagedOrientationHandler().getOppositeSwipeDirection();
|
||||||
mDetector = new SingleAxisSwipeDetector(activity, this, dir);
|
mDetector = new SingleAxisSwipeDetector(activity, this, dir);
|
||||||
@@ -201,8 +203,8 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
|||||||
mCurrentAnimationIsGoingUp = goingUp;
|
mCurrentAnimationIsGoingUp = goingUp;
|
||||||
BaseDragLayer dl = mActivity.getDragLayer();
|
BaseDragLayer dl = mActivity.getDragLayer();
|
||||||
final int secondaryLayerDimension = orientationHandler.getSecondaryDimension(dl);
|
final int secondaryLayerDimension = orientationHandler.getSecondaryDimension(dl);
|
||||||
long maxDuration = (long) (2 * secondaryLayerDimension);
|
long maxDuration = 2 * secondaryLayerDimension;
|
||||||
int verticalFactor = -orientationHandler.getTaskDismissDirectionFactor();
|
int verticalFactor = orientationHandler.getTaskDragDisplacementFactor(mIsRtl);
|
||||||
int secondaryTaskDimension = orientationHandler.getSecondaryDimension(mTaskBeingDragged);
|
int secondaryTaskDimension = orientationHandler.getSecondaryDimension(mTaskBeingDragged);
|
||||||
if (goingUp) {
|
if (goingUp) {
|
||||||
mPendingAnimation = mRecentsView.createTaskDismissAnimation(mTaskBeingDragged,
|
mPendingAnimation = mRecentsView.createTaskDismissAnimation(mTaskBeingDragged,
|
||||||
@@ -236,7 +238,7 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
|||||||
public void onDragStart(boolean start, float startDisplacement) {
|
public void onDragStart(boolean start, float startDisplacement) {
|
||||||
PagedOrientationHandler orientationHandler = mRecentsView.getPagedOrientationHandler();
|
PagedOrientationHandler orientationHandler = mRecentsView.getPagedOrientationHandler();
|
||||||
if (mCurrentAnimation == null) {
|
if (mCurrentAnimation == null) {
|
||||||
reInitAnimationController(orientationHandler.isGoingUp(startDisplacement));
|
reInitAnimationController(orientationHandler.isGoingUp(startDisplacement, mIsRtl));
|
||||||
mDisplacementShift = 0;
|
mDisplacementShift = 0;
|
||||||
} else {
|
} else {
|
||||||
mDisplacementShift = mCurrentAnimation.getProgressFraction() / mProgressMultiplier;
|
mDisplacementShift = mCurrentAnimation.getProgressFraction() / mProgressMultiplier;
|
||||||
@@ -250,7 +252,7 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
|||||||
PagedOrientationHandler orientationHandler = mRecentsView.getPagedOrientationHandler();
|
PagedOrientationHandler orientationHandler = mRecentsView.getPagedOrientationHandler();
|
||||||
float totalDisplacement = displacement + mDisplacementShift;
|
float totalDisplacement = displacement + mDisplacementShift;
|
||||||
boolean isGoingUp = totalDisplacement == 0 ? mCurrentAnimationIsGoingUp :
|
boolean isGoingUp = totalDisplacement == 0 ? mCurrentAnimationIsGoingUp :
|
||||||
orientationHandler.isGoingUp(totalDisplacement);
|
orientationHandler.isGoingUp(totalDisplacement, mIsRtl);
|
||||||
if (isGoingUp != mCurrentAnimationIsGoingUp) {
|
if (isGoingUp != mCurrentAnimationIsGoingUp) {
|
||||||
reInitAnimationController(isGoingUp);
|
reInitAnimationController(isGoingUp);
|
||||||
mFlingBlockCheck.blockFling();
|
mFlingBlockCheck.blockFling();
|
||||||
@@ -282,7 +284,7 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
|||||||
float interpolatedProgress = mCurrentAnimation.getInterpolatedProgress();
|
float interpolatedProgress = mCurrentAnimation.getInterpolatedProgress();
|
||||||
if (fling) {
|
if (fling) {
|
||||||
logAction = Touch.FLING;
|
logAction = Touch.FLING;
|
||||||
boolean goingUp = orientationHandler.isGoingUp(velocity);
|
boolean goingUp = orientationHandler.isGoingUp(velocity, mIsRtl);
|
||||||
goingToEnd = goingUp == mCurrentAnimationIsGoingUp;
|
goingToEnd = goingUp == mCurrentAnimationIsGoingUp;
|
||||||
} else {
|
} else {
|
||||||
logAction = Touch.SWIPE;
|
logAction = Touch.SWIPE;
|
||||||
|
|||||||
+5
-12
@@ -17,7 +17,6 @@ package com.android.quickstep;
|
|||||||
|
|
||||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||||
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
|
|
||||||
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
|
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
|
||||||
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
|
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
|
||||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
|
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
|
||||||
@@ -36,8 +35,8 @@ import com.android.launcher3.BaseDraggingActivity;
|
|||||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||||
import com.android.launcher3.statehandlers.DepthController;
|
import com.android.launcher3.statehandlers.DepthController;
|
||||||
import com.android.quickstep.util.AppWindowAnimationHelper;
|
import com.android.quickstep.util.AppWindowAnimationHelper;
|
||||||
import com.android.quickstep.util.AppWindowAnimationHelper.TransformParams;
|
|
||||||
import com.android.quickstep.util.RemoteAnimationProvider;
|
import com.android.quickstep.util.RemoteAnimationProvider;
|
||||||
|
import com.android.quickstep.util.TransformParams;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
||||||
@@ -75,14 +74,10 @@ final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> exten
|
|||||||
boolean onActivityReady(T activity, Boolean wasVisible) {
|
boolean onActivityReady(T activity, Boolean wasVisible) {
|
||||||
activity.<RecentsView>getOverviewPanel().showCurrentTask(mTargetTaskId);
|
activity.<RecentsView>getOverviewPanel().showCurrentTask(mTargetTaskId);
|
||||||
AbstractFloatingView.closeAllOpenViews(activity, wasVisible);
|
AbstractFloatingView.closeAllOpenViews(activity, wasVisible);
|
||||||
BaseActivityInterface.AnimationFactory factory =
|
BaseActivityInterface.AnimationFactory factory = mActivityInterface.prepareRecentsUI(
|
||||||
mActivityInterface.prepareRecentsUI(wasVisible,
|
wasVisible, (controller) -> {
|
||||||
false /* animate activity */, (controller) -> {
|
|
||||||
controller.dispatchOnStart();
|
controller.dispatchOnStart();
|
||||||
ValueAnimator anim = controller.getAnimationPlayer()
|
controller.getAnimationPlayer().end();
|
||||||
.setDuration(RECENTS_LAUNCH_DURATION);
|
|
||||||
anim.setInterpolator(FAST_OUT_SLOW_IN);
|
|
||||||
anim.start();
|
|
||||||
});
|
});
|
||||||
factory.onRemoteAnimationReceived(null);
|
factory.onRemoteAnimationReceived(null);
|
||||||
factory.createActivityInterface(RECENTS_LAUNCH_DURATION);
|
factory.createActivityInterface(RECENTS_LAUNCH_DURATION);
|
||||||
@@ -164,9 +159,7 @@ final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> exten
|
|||||||
valueAnimator.setDuration(RECENTS_LAUNCH_DURATION);
|
valueAnimator.setDuration(RECENTS_LAUNCH_DURATION);
|
||||||
valueAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
|
valueAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
|
||||||
valueAnimator.addUpdateListener((v) -> {
|
valueAnimator.addUpdateListener((v) -> {
|
||||||
params.setProgress((float) v.getAnimatedValue())
|
params.setProgress((float) v.getAnimatedValue()).setTargetSet(targets);
|
||||||
.setTargetSet(targets)
|
|
||||||
.setLauncherOnTop(true);
|
|
||||||
clipHelper.applyTransform(params);
|
clipHelper.applyTransform(params);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+268
-176
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.quickstep;
|
package com.android.quickstep;
|
||||||
|
|
||||||
|
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||||
|
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||||
import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
|
import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
|
||||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||||
@@ -23,44 +25,49 @@ import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
|||||||
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
|
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorSet;
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.Matrix;
|
||||||
|
import android.graphics.Matrix.ScaleToFit;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.Pair;
|
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
|
||||||
import android.view.animation.Interpolator;
|
import android.view.animation.Interpolator;
|
||||||
|
|
||||||
|
import androidx.annotation.CallSuper;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
|
|
||||||
import com.android.launcher3.BaseDraggingActivity;
|
import com.android.launcher3.BaseDraggingActivity;
|
||||||
import com.android.launcher3.DeviceProfile;
|
import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.InvariantDeviceProfile;
|
import com.android.launcher3.InvariantDeviceProfile;
|
||||||
import com.android.launcher3.R;
|
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||||
import com.android.launcher3.util.VibratorWrapper;
|
import com.android.launcher3.util.VibratorWrapper;
|
||||||
import com.android.launcher3.views.FloatingIconView;
|
import com.android.launcher3.views.FloatingIconView;
|
||||||
import com.android.quickstep.BaseActivityInterface.HomeAnimationFactory;
|
|
||||||
import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener;
|
import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener;
|
||||||
import com.android.quickstep.util.ActiveGestureLog;
|
import com.android.quickstep.util.ActiveGestureLog;
|
||||||
import com.android.quickstep.util.ActivityInitListener;
|
import com.android.quickstep.util.ActivityInitListener;
|
||||||
import com.android.quickstep.util.AppWindowAnimationHelper;
|
|
||||||
import com.android.quickstep.util.AppWindowAnimationHelper.TransformParams;
|
|
||||||
import com.android.quickstep.util.RecentsOrientedState;
|
|
||||||
import com.android.quickstep.util.RectFSpringAnim;
|
import com.android.quickstep.util.RectFSpringAnim;
|
||||||
|
import com.android.quickstep.util.TaskViewSimulator;
|
||||||
|
import com.android.quickstep.util.TransformParams;
|
||||||
|
import com.android.quickstep.util.TransformParams.BuilderProxy;
|
||||||
|
import com.android.quickstep.util.WindowSizeStrategy;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
import com.android.quickstep.views.TaskView;
|
import com.android.quickstep.views.TaskView;
|
||||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
import com.android.systemui.shared.system.InputConsumerController;
|
import com.android.systemui.shared.system.InputConsumerController;
|
||||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
||||||
|
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -93,7 +100,9 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
|||||||
protected final BaseActivityInterface<T> mActivityInterface;
|
protected final BaseActivityInterface<T> mActivityInterface;
|
||||||
protected final InputConsumerController mInputConsumer;
|
protected final InputConsumerController mInputConsumer;
|
||||||
|
|
||||||
protected AppWindowAnimationHelper mAppWindowAnimationHelper;
|
protected final TaskViewSimulator mTaskViewSimulator;
|
||||||
|
private AnimatorPlaybackController mWindowTransitionController;
|
||||||
|
|
||||||
protected final TransformParams mTransformParams = new TransformParams();
|
protected final TransformParams mTransformParams = new TransformParams();
|
||||||
|
|
||||||
// Shift in the range of [0, 1].
|
// Shift in the range of [0, 1].
|
||||||
@@ -113,27 +122,25 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
|||||||
protected T mActivity;
|
protected T mActivity;
|
||||||
protected Q mRecentsView;
|
protected Q mRecentsView;
|
||||||
protected DeviceProfile mDp;
|
protected DeviceProfile mDp;
|
||||||
private final int mPageSpacing;
|
|
||||||
|
|
||||||
protected Runnable mGestureEndCallback;
|
protected Runnable mGestureEndCallback;
|
||||||
|
|
||||||
protected MultiStateCallback mStateCallback;
|
protected MultiStateCallback mStateCallback;
|
||||||
|
|
||||||
protected boolean mCanceled;
|
protected boolean mCanceled;
|
||||||
protected int mFinishingRecentsAnimationForNewTaskId = -1;
|
|
||||||
|
|
||||||
private RecentsOrientedState mOrientedState;
|
private boolean mRecentsViewScrollLinked = false;
|
||||||
|
|
||||||
protected BaseSwipeUpHandler(Context context, RecentsAnimationDeviceState deviceState,
|
protected BaseSwipeUpHandler(Context context, RecentsAnimationDeviceState deviceState,
|
||||||
GestureState gestureState, InputConsumerController inputConsumer) {
|
GestureState gestureState, InputConsumerController inputConsumer,
|
||||||
|
WindowSizeStrategy windowSizeStrategy) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mDeviceState = deviceState;
|
mDeviceState = deviceState;
|
||||||
mGestureState = gestureState;
|
mGestureState = gestureState;
|
||||||
mActivityInterface = gestureState.getActivityInterface();
|
mActivityInterface = gestureState.getActivityInterface();
|
||||||
mActivityInitListener = mActivityInterface.createActivityInitListener(this::onActivityInit);
|
mActivityInitListener = mActivityInterface.createActivityInitListener(this::onActivityInit);
|
||||||
mInputConsumer = inputConsumer;
|
mInputConsumer = inputConsumer;
|
||||||
mAppWindowAnimationHelper = new AppWindowAnimationHelper(context);
|
mTaskViewSimulator = new TaskViewSimulator(context, windowSizeStrategy);
|
||||||
mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -193,13 +200,13 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
|||||||
updateFinalShift();
|
updateFinalShift();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mRecentsView.setAppWindowAnimationHelper(mAppWindowAnimationHelper);
|
|
||||||
runOnRecentsAnimationStart(() ->
|
runOnRecentsAnimationStart(() ->
|
||||||
mRecentsView.setRecentsAnimationTargets(mRecentsAnimationController,
|
mRecentsView.setRecentsAnimationTargets(mRecentsAnimationController,
|
||||||
mRecentsAnimationTargets));
|
mRecentsAnimationTargets));
|
||||||
|
mRecentsViewScrollLinked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void startNewTask(int successStateFlag, Consumer<Boolean> resultCallback) {
|
protected void startNewTask(Consumer<Boolean> resultCallback) {
|
||||||
// Launch the task user scrolled to (mRecentsView.getNextPage()).
|
// Launch the task user scrolled to (mRecentsView.getNextPage()).
|
||||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||||
// We finish recents animation inside launchTask() when live tile is enabled.
|
// We finish recents animation inside launchTask() when live tile is enabled.
|
||||||
@@ -210,24 +217,41 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
|||||||
if (!mCanceled) {
|
if (!mCanceled) {
|
||||||
TaskView nextTask = mRecentsView.getTaskView(taskId);
|
TaskView nextTask = mRecentsView.getTaskView(taskId);
|
||||||
if (nextTask != null) {
|
if (nextTask != null) {
|
||||||
|
mGestureState.updateLastStartedTaskId(taskId);
|
||||||
nextTask.launchTask(false /* animate */, true /* freezeTaskList */,
|
nextTask.launchTask(false /* animate */, true /* freezeTaskList */,
|
||||||
success -> {
|
success -> {
|
||||||
resultCallback.accept(success);
|
resultCallback.accept(success);
|
||||||
if (!success) {
|
if (success) {
|
||||||
|
if (mRecentsView.indexOfChild(nextTask)
|
||||||
|
== getLastAppearedTaskIndex()) {
|
||||||
|
onRestartLastAppearedTask();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
mActivityInterface.onLaunchTaskFailed();
|
mActivityInterface.onLaunchTaskFailed();
|
||||||
nextTask.notifyTaskLaunchFailed(TAG);
|
nextTask.notifyTaskLaunchFailed(TAG);
|
||||||
} else {
|
mRecentsAnimationController.finish(true /* toRecents */, null);
|
||||||
mActivityInterface.onLaunchTaskSuccess();
|
|
||||||
}
|
}
|
||||||
}, MAIN_EXECUTOR.getHandler());
|
}, MAIN_EXECUTOR.getHandler());
|
||||||
}
|
}
|
||||||
mStateCallback.setStateOnUiThread(successStateFlag);
|
|
||||||
}
|
}
|
||||||
mCanceled = false;
|
mCanceled = false;
|
||||||
}
|
}
|
||||||
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", true);
|
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when we successfully startNewTask() on the task that was previously running. Normally
|
||||||
|
* we call resumeLastTask() when returning to the previously running task, but this handles a
|
||||||
|
* specific edge case: if we switch from A to B, and back to A before B appears, we need to
|
||||||
|
* start A again to ensure it stays on top.
|
||||||
|
*/
|
||||||
|
@CallSuper
|
||||||
|
protected void onRestartLastAppearedTask() {
|
||||||
|
// Finish the controller here, since we won't get onTaskAppeared() for a task that already
|
||||||
|
// appeared.
|
||||||
|
mRecentsAnimationController.finish(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the given {@param action} if the recents animation has already started, or queues it to
|
* Runs the given {@param action} if the recents animation has already started, or queues it to
|
||||||
* be run when it is next started.
|
* be run when it is next started.
|
||||||
@@ -241,42 +265,36 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* TODO can we remove this now that we don't finish the controller until onTaskAppeared()?
|
||||||
* @return whether the recents animation has started and there are valid app targets.
|
* @return whether the recents animation has started and there are valid app targets.
|
||||||
*/
|
*/
|
||||||
protected boolean hasTargets() {
|
protected boolean hasTargets() {
|
||||||
return mRecentsAnimationTargets != null && mRecentsAnimationTargets.hasTargets();
|
return mRecentsAnimationTargets != null && mRecentsAnimationTargets.hasTargets();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateSource(Rect stackBounds, RemoteAnimationTargetCompat runningTarget) {
|
|
||||||
mAppWindowAnimationHelper.updateSource(stackBounds, runningTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRecentsAnimationStart(RecentsAnimationController recentsAnimationController,
|
public void onRecentsAnimationStart(RecentsAnimationController recentsAnimationController,
|
||||||
RecentsAnimationTargets targets) {
|
RecentsAnimationTargets targets) {
|
||||||
mRecentsAnimationController = recentsAnimationController;
|
mRecentsAnimationController = recentsAnimationController;
|
||||||
mRecentsAnimationTargets = targets;
|
mRecentsAnimationTargets = targets;
|
||||||
DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext);
|
DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext);
|
||||||
final Rect overviewStackBounds;
|
|
||||||
RemoteAnimationTargetCompat runningTaskTarget = targets.findTask(
|
RemoteAnimationTargetCompat runningTaskTarget = targets.findTask(
|
||||||
mGestureState.getRunningTaskId());
|
mGestureState.getRunningTaskId());
|
||||||
|
|
||||||
if (targets.minimizedHomeBounds != null && runningTaskTarget != null) {
|
if (targets.minimizedHomeBounds != null && runningTaskTarget != null) {
|
||||||
overviewStackBounds = mActivityInterface
|
Rect overviewStackBounds = mActivityInterface
|
||||||
.getOverviewWindowBounds(targets.minimizedHomeBounds, runningTaskTarget);
|
.getOverviewWindowBounds(targets.minimizedHomeBounds, runningTaskTarget);
|
||||||
dp = dp.getMultiWindowProfile(mContext, overviewStackBounds);
|
dp = dp.getMultiWindowProfile(mContext, overviewStackBounds);
|
||||||
} else {
|
} else {
|
||||||
// If we are not in multi-window mode, home insets should be same as system insets.
|
// If we are not in multi-window mode, home insets should be same as system insets.
|
||||||
dp = dp.copy(mContext);
|
dp = dp.copy(mContext);
|
||||||
overviewStackBounds = getStackBounds(dp);
|
|
||||||
}
|
}
|
||||||
dp.updateInsets(targets.homeContentInsets);
|
dp.updateInsets(targets.homeContentInsets);
|
||||||
dp.updateIsSeascape(mContext);
|
dp.updateIsSeascape(mContext);
|
||||||
if (runningTaskTarget != null) {
|
if (runningTaskTarget != null) {
|
||||||
updateSource(overviewStackBounds, runningTaskTarget);
|
mTaskViewSimulator.setPreview(runningTaskTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
mAppWindowAnimationHelper.prepareAnimation(dp);
|
|
||||||
initTransitionEndpoints(dp);
|
initTransitionEndpoints(dp);
|
||||||
|
|
||||||
// Notify when the animation starts
|
// Notify when the animation starts
|
||||||
@@ -306,51 +324,73 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Rect getStackBounds(DeviceProfile dp) {
|
@Override
|
||||||
if (mActivity != null) {
|
public void onTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget) {
|
||||||
int loc[] = new int[2];
|
if (mRecentsAnimationController != null) {
|
||||||
View rootView = mActivity.getRootView();
|
if (handleTaskAppeared(appearedTaskTarget)) {
|
||||||
rootView.getLocationOnScreen(loc);
|
mRecentsAnimationController.finish(false /* toRecents */,
|
||||||
return new Rect(loc[0], loc[1], loc[0] + rootView.getWidth(),
|
null /* onFinishComplete */);
|
||||||
loc[1] + rootView.getHeight());
|
mActivityInterface.onLaunchTaskSuccess();
|
||||||
} else {
|
}
|
||||||
return new Rect(0, 0, dp.widthPx, dp.heightPx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return Whether this was the task we were waiting to appear, and thus handled it. */
|
||||||
|
protected abstract boolean handleTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The index of the TaskView in RecentsView whose taskId matches the task that will
|
||||||
|
* resume if we finish the controller.
|
||||||
|
*/
|
||||||
|
protected int getLastAppearedTaskIndex() {
|
||||||
|
return mGestureState.getLastAppearedTaskId() != -1
|
||||||
|
? mRecentsView.getTaskIndexForId(mGestureState.getLastAppearedTaskId())
|
||||||
|
: mRecentsView.getRunningTaskIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Whether we are continuing a gesture that already landed on a new task,
|
||||||
|
* but before that task appeared.
|
||||||
|
*/
|
||||||
|
protected boolean hasStartedNewTask() {
|
||||||
|
return mGestureState.getLastStartedTaskId() != -1;
|
||||||
|
}
|
||||||
|
|
||||||
protected void initTransitionEndpoints(DeviceProfile dp) {
|
protected void initTransitionEndpoints(DeviceProfile dp) {
|
||||||
mDp = dp;
|
mDp = dp;
|
||||||
|
|
||||||
mTransitionDragLength = mActivityInterface.getSwipeUpDestinationAndLength(
|
mTransitionDragLength = mActivityInterface.getSwipeUpDestinationAndLength(
|
||||||
dp, mContext, TEMP_RECT);
|
dp, mContext, TEMP_RECT);
|
||||||
|
mTaskViewSimulator.setDp(dp);
|
||||||
|
mTaskViewSimulator.setLayoutRotation(
|
||||||
|
mDeviceState.getCurrentActiveRotation(),
|
||||||
|
mDeviceState.getDisplayRotation());
|
||||||
|
|
||||||
if (!dp.isMultiWindowMode) {
|
|
||||||
// When updating the target rect, also update the home bounds since the location on
|
|
||||||
// screen of the launcher window may be stale (position is not updated until first
|
|
||||||
// traversal after the window is resized). We only do this for non-multiwindow because
|
|
||||||
// we otherwise use the minimized home bounds provided by the system.
|
|
||||||
mAppWindowAnimationHelper.updateHomeBounds(getStackBounds(dp));
|
|
||||||
}
|
|
||||||
int displayRotation = 0;
|
|
||||||
if (mOrientedState != null && mOrientedState.isMultipleOrientationSupportedByDevice()) {
|
|
||||||
// TODO(b/150300347): The first recents animation after launcher is started with the
|
|
||||||
// foreground app not in landscape will look funky until that bug is fixed
|
|
||||||
displayRotation = mOrientedState.getDisplayRotation();
|
|
||||||
|
|
||||||
RectF tempRectF = new RectF(TEMP_RECT);
|
|
||||||
mOrientedState.mapRectFromRotation(displayRotation,
|
|
||||||
tempRectF, dp.widthPx, dp.heightPx);
|
|
||||||
tempRectF.roundOut(TEMP_RECT);
|
|
||||||
}
|
|
||||||
mAppWindowAnimationHelper.updateTargetRect(TEMP_RECT);
|
|
||||||
if (mDeviceState.isFullyGesturalNavMode()) {
|
if (mDeviceState.isFullyGesturalNavMode()) {
|
||||||
// We can drag all the way to the top of the screen.
|
// We can drag all the way to the top of the screen.
|
||||||
mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
|
mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
|
||||||
Pair<Float, Float> dragFactorStartAndMaxProgress =
|
|
||||||
mActivityInterface.getSwipeUpPullbackStartAndMaxProgress();
|
float startScale = mTaskViewSimulator.getFullScreenScale();
|
||||||
mDragLengthFactorStartPullback = dragFactorStartAndMaxProgress.first;
|
// Start pulling back when RecentsView scale is 0.75f, and let it go down to 0.5f.
|
||||||
mDragLengthFactorMaxPullback = dragFactorStartAndMaxProgress.second;
|
mDragLengthFactorStartPullback = (0.75f - startScale) / (1 - startScale);
|
||||||
|
mDragLengthFactorMaxPullback = (0.5f - startScale) / (1 - startScale);
|
||||||
|
} else {
|
||||||
|
mDragLengthFactor = 1;
|
||||||
|
mDragLengthFactorStartPullback = mDragLengthFactorMaxPullback = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnimatorSet anim = new AnimatorSet();
|
||||||
|
anim.setDuration(mTransitionDragLength * 2);
|
||||||
|
anim.setInterpolator(t -> t * mDragLengthFactor);
|
||||||
|
anim.play(ObjectAnimator.ofFloat(mTaskViewSimulator.recentsViewScale,
|
||||||
|
AnimatedFloat.VALUE,
|
||||||
|
mTaskViewSimulator.getFullScreenScale(), 1));
|
||||||
|
anim.play(ObjectAnimator.ofFloat(mTaskViewSimulator.fullScreenProgress,
|
||||||
|
AnimatedFloat.VALUE,
|
||||||
|
BACKGROUND_APP.getOverviewFullscreenProgress(),
|
||||||
|
OVERVIEW.getOverviewFullscreenProgress()));
|
||||||
|
mWindowTransitionController =
|
||||||
|
AnimatorPlaybackController.wrap(anim, mTransitionDragLength * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -361,9 +401,6 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
|||||||
protected boolean onActivityInit(Boolean alreadyOnHome) {
|
protected boolean onActivityInit(Boolean alreadyOnHome) {
|
||||||
T createdActivity = mActivityInterface.getCreatedActivity();
|
T createdActivity = mActivityInterface.getCreatedActivity();
|
||||||
if (createdActivity != null) {
|
if (createdActivity != null) {
|
||||||
mOrientedState = ((RecentsView) createdActivity.getOverviewPanel())
|
|
||||||
.getPagedViewOrientedState();
|
|
||||||
mAppWindowAnimationHelper = new AppWindowAnimationHelper(mOrientedState, mContext);
|
|
||||||
initTransitionEndpoints(InvariantDeviceProfile.INSTANCE.get(mContext)
|
initTransitionEndpoints(InvariantDeviceProfile.INSTANCE.get(mContext)
|
||||||
.getDeviceProfile(mContext));
|
.getDeviceProfile(mContext));
|
||||||
}
|
}
|
||||||
@@ -412,35 +449,23 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the transform on the recents animation without any additional null checks
|
* Applies the transform on the recents animation
|
||||||
*/
|
*/
|
||||||
protected void applyTransformUnchecked() {
|
protected void applyWindowTransform() {
|
||||||
float shift = mCurrentShift.value;
|
if (mWindowTransitionController != null) {
|
||||||
float offset = mRecentsView == null ? 0 : mRecentsView.getScrollOffsetScaled();
|
float progress = mCurrentShift.value / mDragLengthFactor;
|
||||||
float taskSize = getOrientationHandler()
|
mWindowTransitionController.setPlayFraction(progress);
|
||||||
.getPrimarySize(mAppWindowAnimationHelper.getTargetRect());
|
mTransformParams.setTargetSet(mRecentsAnimationTargets);
|
||||||
float offsetScale = getTaskCurveScaleForOffset(offset, taskSize);
|
|
||||||
mTransformParams
|
|
||||||
.setProgress(shift)
|
|
||||||
.setOffset(offset)
|
|
||||||
.setOffsetScale(offsetScale)
|
|
||||||
.setTargetSet(mRecentsAnimationTargets)
|
|
||||||
.setLauncherOnTop(true);
|
|
||||||
mAppWindowAnimationHelper.applyTransform(mTransformParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
private float getTaskCurveScaleForOffset(float offset, float taskSize) {
|
if (mRecentsViewScrollLinked) {
|
||||||
int dpPixel = getOrientationHandler().getShortEdgeLength(mDp);
|
mTaskViewSimulator.setScroll(mRecentsView.getScrollOffset());
|
||||||
float distanceToReachEdge = dpPixel / 2 + taskSize / 2 + mPageSpacing;
|
}
|
||||||
float interpolation = Math.min(1, offset / distanceToReachEdge);
|
mTaskViewSimulator.apply(mTransformParams);
|
||||||
return TaskView.getCurveScaleForInterpolation(interpolation);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PagedOrientationHandler getOrientationHandler() {
|
protected PagedOrientationHandler getOrientationHandler() {
|
||||||
if (mOrientedState == null) {
|
return mTaskViewSimulator.getOrientationState().getOrientationHandler();
|
||||||
return PagedOrientationHandler.PORTRAIT;
|
|
||||||
}
|
|
||||||
return mOrientedState.getOrientationHandler();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -451,104 +476,40 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
|||||||
protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
|
protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
|
||||||
HomeAnimationFactory homeAnimationFactory) {
|
HomeAnimationFactory homeAnimationFactory) {
|
||||||
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
|
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
|
||||||
final View floatingView = homeAnimationFactory.getFloatingView();
|
final FloatingIconView fiv = homeAnimationFactory.mIconView;
|
||||||
final boolean isFloatingIconView = floatingView instanceof FloatingIconView;
|
final boolean isFloatingIconView = fiv != null;
|
||||||
final RectF startRect = new RectF(
|
|
||||||
mAppWindowAnimationHelper.applyTransform(
|
mWindowTransitionController.setPlayFraction(startProgress / mDragLengthFactor);
|
||||||
mTransformParams.setProgress(startProgress)
|
mTaskViewSimulator.apply(mTransformParams
|
||||||
.setTargetSet(mRecentsAnimationTargets)
|
.setProgress(startProgress)
|
||||||
.setLauncherOnTop(false)));
|
.setTargetSet(mRecentsAnimationTargets));
|
||||||
if (isFloatingIconView) {
|
RectF cropRectF = new RectF(mTaskViewSimulator.getCurrentCropRect());
|
||||||
mOrientedState.mapInverseRectFromNormalOrientation(
|
|
||||||
startRect, mDp.widthPx, mDp.heightPx);
|
// Matrix to map a rect in Launcher space to window space
|
||||||
}
|
Matrix homeToWindowPositionMap = new Matrix();
|
||||||
|
mTaskViewSimulator.applyWindowToHomeRotation(homeToWindowPositionMap);
|
||||||
|
|
||||||
|
final RectF startRect = new RectF(cropRectF);
|
||||||
|
mTaskViewSimulator.getCurrentMatrix().mapRect(startRect);
|
||||||
|
// Move the startRect to Launcher space as floatingIconView runs in Launcher
|
||||||
|
Matrix windowToHomePositionMap = new Matrix();
|
||||||
|
homeToWindowPositionMap.invert(windowToHomePositionMap);
|
||||||
|
windowToHomePositionMap.mapRect(startRect);
|
||||||
|
|
||||||
RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mContext);
|
RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mContext);
|
||||||
if (isFloatingIconView) {
|
if (isFloatingIconView) {
|
||||||
FloatingIconView fiv = (FloatingIconView) floatingView;
|
|
||||||
anim.addAnimatorListener(fiv);
|
anim.addAnimatorListener(fiv);
|
||||||
fiv.setOnTargetChangeListener(anim::onTargetPositionChanged);
|
fiv.setOnTargetChangeListener(anim::onTargetPositionChanged);
|
||||||
fiv.setFastFinishRunnable(anim::end);
|
fiv.setFastFinishRunnable(anim::end);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimatorPlaybackController homeAnim = homeAnimationFactory.createActivityAnimationToHome();
|
SpringAnimationRunner runner = new SpringAnimationRunner(
|
||||||
|
homeAnimationFactory, cropRectF, homeToWindowPositionMap);
|
||||||
// End on a "round-enough" radius so that the shape reveal doesn't have to do too much
|
anim.addOnUpdateListener(runner);
|
||||||
// rounding at the end of the animation.
|
anim.addAnimatorListener(runner);
|
||||||
float startRadius = mAppWindowAnimationHelper.getCurrentCornerRadius();
|
|
||||||
float endRadius = startRect.width() / 6f;
|
|
||||||
|
|
||||||
float startTransformProgress = mTransformParams.getProgress();
|
|
||||||
float endTransformProgress = 1;
|
|
||||||
|
|
||||||
// We want the window alpha to be 0 once this threshold is met, so that the
|
|
||||||
// FolderIconView can be seen morphing into the icon shape.
|
|
||||||
final float windowAlphaThreshold = isFloatingIconView ? 1f - SHAPE_PROGRESS_DURATION : 1f;
|
|
||||||
final RectF rotatedRect = new RectF();
|
|
||||||
anim.addOnUpdateListener(new RectFSpringAnim.OnUpdateListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpdate(RectF currentRect, float progress) {
|
|
||||||
homeAnim.setPlayFraction(progress);
|
|
||||||
|
|
||||||
rotatedRect.set(currentRect);
|
|
||||||
if (isFloatingIconView) {
|
|
||||||
mOrientedState.mapRectFromNormalOrientation(
|
|
||||||
rotatedRect, mDp.widthPx, mDp.heightPx);
|
|
||||||
mTransformParams.setCornerRadius(endRadius * progress + startRadius
|
|
||||||
* (1f - progress));
|
|
||||||
}
|
|
||||||
mTransformParams.setProgress(
|
|
||||||
Utilities.mapRange(progress, startTransformProgress, endTransformProgress))
|
|
||||||
.setCurrentRect(rotatedRect)
|
|
||||||
.setTargetAlpha(getWindowAlpha(progress));
|
|
||||||
mAppWindowAnimationHelper.applyTransform(mTransformParams);
|
|
||||||
|
|
||||||
if (isFloatingIconView) {
|
|
||||||
((FloatingIconView) floatingView).update(currentRect, 1f, progress,
|
|
||||||
windowAlphaThreshold, mAppWindowAnimationHelper.getCurrentCornerRadius(),
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCancel() {
|
|
||||||
if (isFloatingIconView) {
|
|
||||||
((FloatingIconView) floatingView).fastFinish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
anim.addAnimatorListener(new AnimationSuccessListener() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationStart(Animator animation) {
|
|
||||||
homeAnim.dispatchOnStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationSuccess(Animator animator) {
|
|
||||||
homeAnim.getAnimationPlayer().end();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return anim;
|
return anim;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param progress The progress of the animation to the home screen.
|
|
||||||
* @return The current alpha to set on the animating app window.
|
|
||||||
*/
|
|
||||||
protected float getWindowAlpha(float progress) {
|
|
||||||
// Alpha interpolates between [1, 0] between progress values [start, end]
|
|
||||||
final float start = 0f;
|
|
||||||
final float end = 0.85f;
|
|
||||||
|
|
||||||
if (progress <= start) {
|
|
||||||
return 1f;
|
|
||||||
}
|
|
||||||
if (progress >= end) {
|
|
||||||
return 0f;
|
|
||||||
}
|
|
||||||
return Utilities.mapToRange(progress, start, end, 1, 0, ACCEL_1_5);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Factory {
|
public interface Factory {
|
||||||
|
|
||||||
BaseSwipeUpHandler newHandler(GestureState gestureState, long touchTimeMs,
|
BaseSwipeUpHandler newHandler(GestureState gestureState, long touchTimeMs,
|
||||||
@@ -588,4 +549,135 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param progress The progress of the animation to the home screen.
|
||||||
|
* @return The current alpha to set on the animating app window.
|
||||||
|
*/
|
||||||
|
protected float getWindowAlpha(float progress) {
|
||||||
|
// Alpha interpolates between [1, 0] between progress values [start, end]
|
||||||
|
final float start = 0f;
|
||||||
|
final float end = 0.85f;
|
||||||
|
|
||||||
|
if (progress <= start) {
|
||||||
|
return 1f;
|
||||||
|
}
|
||||||
|
if (progress >= end) {
|
||||||
|
return 0f;
|
||||||
|
}
|
||||||
|
return Utilities.mapToRange(progress, start, end, 1, 0, ACCEL_1_5);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract class HomeAnimationFactory {
|
||||||
|
|
||||||
|
private FloatingIconView mIconView;
|
||||||
|
|
||||||
|
public HomeAnimationFactory(@Nullable FloatingIconView iconView) {
|
||||||
|
mIconView = iconView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NonNull RectF getWindowTargetRect() {
|
||||||
|
PagedOrientationHandler orientationHandler = getOrientationHandler();
|
||||||
|
DeviceProfile dp = mDp;
|
||||||
|
final int halfIconSize = dp.iconSizePx / 2;
|
||||||
|
float primaryDimension = orientationHandler
|
||||||
|
.getPrimaryValue(dp.availableWidthPx, dp.availableHeightPx);
|
||||||
|
float secondaryDimension = orientationHandler
|
||||||
|
.getSecondaryValue(dp.availableWidthPx, dp.availableHeightPx);
|
||||||
|
final float targetX = primaryDimension / 2f;
|
||||||
|
final float targetY = secondaryDimension - dp.hotseatBarSizePx;
|
||||||
|
// Fallback to animate to center of screen.
|
||||||
|
return new RectF(targetX - halfIconSize, targetY - halfIconSize,
|
||||||
|
targetX + halfIconSize, targetY + halfIconSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract @NonNull AnimatorPlaybackController createActivityAnimationToHome();
|
||||||
|
|
||||||
|
public void playAtomicAnimation(float velocity) {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SpringAnimationRunner extends AnimationSuccessListener
|
||||||
|
implements RectFSpringAnim.OnUpdateListener, BuilderProxy {
|
||||||
|
|
||||||
|
final Rect mCropRect = new Rect();
|
||||||
|
final Matrix mMatrix = new Matrix();
|
||||||
|
|
||||||
|
final RectF mWindowCurrentRect = new RectF();
|
||||||
|
final Matrix mHomeToWindowPositionMap;
|
||||||
|
|
||||||
|
final FloatingIconView mFIV;
|
||||||
|
final AnimatorPlaybackController mHomeAnim;
|
||||||
|
final RectF mCropRectF;
|
||||||
|
|
||||||
|
final float mStartRadius;
|
||||||
|
final float mEndRadius;
|
||||||
|
final float mWindowAlphaThreshold;
|
||||||
|
|
||||||
|
SpringAnimationRunner(HomeAnimationFactory factory, RectF cropRectF,
|
||||||
|
Matrix homeToWindowPositionMap) {
|
||||||
|
mHomeAnim = factory.createActivityAnimationToHome();
|
||||||
|
mCropRectF = cropRectF;
|
||||||
|
mHomeToWindowPositionMap = homeToWindowPositionMap;
|
||||||
|
|
||||||
|
cropRectF.roundOut(mCropRect);
|
||||||
|
mFIV = factory.mIconView;
|
||||||
|
|
||||||
|
// End on a "round-enough" radius so that the shape reveal doesn't have to do too much
|
||||||
|
// rounding at the end of the animation.
|
||||||
|
mStartRadius = mTaskViewSimulator.getCurrentCornerRadius();
|
||||||
|
mEndRadius = cropRectF.width() / 2f;
|
||||||
|
|
||||||
|
// We want the window alpha to be 0 once this threshold is met, so that the
|
||||||
|
// FolderIconView can be seen morphing into the icon shape.
|
||||||
|
mWindowAlphaThreshold = mFIV != null ? 1f - SHAPE_PROGRESS_DURATION : 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdate(RectF currentRect, float progress) {
|
||||||
|
mHomeAnim.setPlayFraction(progress);
|
||||||
|
mHomeToWindowPositionMap.mapRect(mWindowCurrentRect, currentRect);
|
||||||
|
|
||||||
|
mMatrix.setRectToRect(mCropRectF, mWindowCurrentRect, ScaleToFit.FILL);
|
||||||
|
float cornerRadius = Utilities.mapRange(progress, mStartRadius, mEndRadius);
|
||||||
|
mTransformParams
|
||||||
|
.setTargetAlpha(getWindowAlpha(progress))
|
||||||
|
.setCornerRadius(cornerRadius);
|
||||||
|
|
||||||
|
mTransformParams.applySurfaceParams(mTransformParams.createSurfaceParams(this));
|
||||||
|
if (mFIV != null) {
|
||||||
|
mFIV.update(currentRect, 1f, progress,
|
||||||
|
mWindowAlphaThreshold, mMatrix.mapRadius(cornerRadius), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBuildParams(Builder builder, RemoteAnimationTargetCompat app, int targetMode,
|
||||||
|
TransformParams params) {
|
||||||
|
if (app.mode == targetMode
|
||||||
|
&& app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
|
||||||
|
builder.withMatrix(mMatrix)
|
||||||
|
.withWindowCrop(mCropRect)
|
||||||
|
.withCornerRadius(params.getCornerRadius());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancel() {
|
||||||
|
if (mFIV != null) {
|
||||||
|
mFIV.fastFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(Animator animation) {
|
||||||
|
mHomeAnim.dispatchOnStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationSuccess(Animator animator) {
|
||||||
|
mHomeAnim.getAnimationPlayer().end();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-65
@@ -15,25 +15,23 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.quickstep;
|
package com.android.quickstep;
|
||||||
|
|
||||||
|
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||||
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
||||||
import static com.android.quickstep.fallback.FallbackRecentsView.ZOOM_PROGRESS;
|
import static com.android.quickstep.fallback.RecentsState.BACKGROUND_APP;
|
||||||
|
import static com.android.quickstep.fallback.RecentsState.DEFAULT;
|
||||||
import static com.android.quickstep.util.WindowSizeStrategy.FALLBACK_RECENTS_SIZE_STRATEGY;
|
import static com.android.quickstep.util.WindowSizeStrategy.FALLBACK_RECENTS_SIZE_STRATEGY;
|
||||||
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
|
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
|
||||||
|
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
|
||||||
|
|
||||||
import android.animation.Animator;
|
|
||||||
import android.animation.AnimatorSet;
|
|
||||||
import android.animation.ObjectAnimator;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.launcher3.DeviceProfile;
|
import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
|
||||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||||
|
import com.android.launcher3.anim.PendingAnimation;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||||
import com.android.quickstep.fallback.FallbackRecentsView;
|
import com.android.quickstep.fallback.FallbackRecentsView;
|
||||||
import com.android.quickstep.util.ActivityInitListener;
|
import com.android.quickstep.util.ActivityInitListener;
|
||||||
@@ -89,54 +87,17 @@ public final class FallbackActivityInterface implements
|
|||||||
// set to zero prior to this class becoming active.
|
// set to zero prior to this class becoming active.
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
@Override
|
||||||
public HomeAnimationFactory prepareHomeUI() {
|
public AnimationFactory prepareRecentsUI(
|
||||||
|
boolean activityVisible, Consumer<AnimatorPlaybackController> callback) {
|
||||||
RecentsActivity activity = getCreatedActivity();
|
RecentsActivity activity = getCreatedActivity();
|
||||||
RecentsView recentsView = activity.getOverviewPanel();
|
if (activity == null) {
|
||||||
|
|
||||||
return new HomeAnimationFactory() {
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public RectF getWindowTargetRect() {
|
|
||||||
float centerX = recentsView.getPivotX();
|
|
||||||
float centerY = recentsView.getPivotY();
|
|
||||||
return new RectF(centerX, centerY, centerX, centerY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public AnimatorPlaybackController createActivityAnimationToHome() {
|
|
||||||
Animator anim = ObjectAnimator.ofFloat(recentsView, CONTENT_ALPHA, 0);
|
|
||||||
anim.addListener(new AnimationSuccessListener() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationSuccess(Animator animator) {
|
|
||||||
recentsView.startHome();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
AnimatorSet animatorSet = new AnimatorSet();
|
|
||||||
animatorSet.play(anim);
|
|
||||||
long accuracy = 2 * Math.max(recentsView.getWidth(), recentsView.getHeight());
|
|
||||||
return AnimatorPlaybackController.wrap(animatorSet, accuracy);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AnimationFactory prepareRecentsUI(boolean activityVisible,
|
|
||||||
boolean animateActivity, Consumer<AnimatorPlaybackController> callback) {
|
|
||||||
RecentsActivity activity = getCreatedActivity();
|
|
||||||
if (activityVisible) {
|
|
||||||
return (transitionLength) -> { };
|
return (transitionLength) -> { };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activity.getStateManager().goToState(BACKGROUND_APP);
|
||||||
FallbackRecentsView rv = activity.getOverviewPanel();
|
FallbackRecentsView rv = activity.getOverviewPanel();
|
||||||
rv.setContentAlpha(0);
|
rv.setContentAlpha(0);
|
||||||
rv.getClearAllButton().setVisibilityAlpha(0);
|
|
||||||
rv.setDisallowScrollToClearAll(true);
|
|
||||||
|
|
||||||
boolean fromState = !animateActivity;
|
|
||||||
rv.setInOverviewState(fromState);
|
|
||||||
|
|
||||||
return new AnimationFactory() {
|
return new AnimationFactory() {
|
||||||
|
|
||||||
@@ -154,27 +115,19 @@ public final class FallbackActivityInterface implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createActivityInterface(long transitionLength) {
|
public void createActivityInterface(long transitionLength) {
|
||||||
AnimatorSet animatorSet = new AnimatorSet();
|
PendingAnimation pa = new PendingAnimation(transitionLength * 2);
|
||||||
|
|
||||||
if (isAnimatingToRecents) {
|
if (isAnimatingToRecents) {
|
||||||
ObjectAnimator anim = ObjectAnimator.ofFloat(rv, CONTENT_ALPHA, 0, 1);
|
pa.addFloat(rv, CONTENT_ALPHA, 0, 1, LINEAR);
|
||||||
anim.setDuration(transitionLength).setInterpolator(LINEAR);
|
|
||||||
animatorSet.play(anim);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAnimator anim = ObjectAnimator.ofFloat(rv, ZOOM_PROGRESS, 1, 0);
|
pa.addFloat(rv, SCALE_PROPERTY, rv.getMaxScaleForFullScreen(), 1, LINEAR);
|
||||||
anim.setDuration(transitionLength).setInterpolator(LINEAR);
|
pa.addFloat(rv, FULLSCREEN_PROGRESS, 1, 0, LINEAR);
|
||||||
animatorSet.play(anim);
|
AnimatorPlaybackController controller = pa.createPlaybackController();
|
||||||
|
|
||||||
AnimatorPlaybackController controller =
|
|
||||||
AnimatorPlaybackController.wrap(animatorSet, transitionLength);
|
|
||||||
|
|
||||||
// Since we are changing the start position of the UI, reapply the state, at the end
|
// Since we are changing the start position of the UI, reapply the state, at the end
|
||||||
controller.setEndAction(() -> {
|
controller.setEndAction(() -> activity.getStateManager().goToState(
|
||||||
boolean endState = true;
|
controller.getInterpolatedProgress() > 0.5 ? DEFAULT : BACKGROUND_APP));
|
||||||
rv.setInOverviewState(controller.getInterpolatedProgress() > 0.5 ?
|
|
||||||
endState : fromState);
|
|
||||||
});
|
|
||||||
|
|
||||||
callback.accept(controller);
|
callback.accept(controller);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -190,7 +143,7 @@ public final class FallbackActivityInterface implements
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public RecentsActivity getCreatedActivity() {
|
public RecentsActivity getCreatedActivity() {
|
||||||
return BaseRecentsActivity.ACTIVITY_TRACKER.getCreatedActivity();
|
return RecentsActivity.ACTIVITY_TRACKER.getCreatedActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
+64
-43
@@ -24,6 +24,7 @@ import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
|
|||||||
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
|
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
|
||||||
import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID;
|
import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID;
|
||||||
import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL;
|
import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL;
|
||||||
|
import static com.android.quickstep.util.WindowSizeStrategy.FALLBACK_RECENTS_SIZE_STRATEGY;
|
||||||
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
|
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
@@ -32,25 +33,24 @@ import android.app.ActivityOptions;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
|
||||||
import com.android.launcher3.util.ObjectWrapper;
|
import com.android.launcher3.util.ObjectWrapper;
|
||||||
import com.android.quickstep.BaseActivityInterface.HomeAnimationFactory;
|
import com.android.quickstep.BaseActivityInterface.AnimationFactory;
|
||||||
import com.android.quickstep.GestureState.GestureEndTarget;
|
import com.android.quickstep.GestureState.GestureEndTarget;
|
||||||
import com.android.quickstep.fallback.FallbackRecentsView;
|
import com.android.quickstep.fallback.FallbackRecentsView;
|
||||||
import com.android.quickstep.util.RectFSpringAnim;
|
import com.android.quickstep.util.RectFSpringAnim;
|
||||||
import com.android.quickstep.views.TaskView;
|
|
||||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||||
import com.android.systemui.shared.system.ActivityOptionsCompat;
|
import com.android.systemui.shared.system.ActivityOptionsCompat;
|
||||||
import com.android.systemui.shared.system.InputConsumerController;
|
import com.android.systemui.shared.system.InputConsumerController;
|
||||||
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the navigation gestures when a 3rd party launcher is the default home activity.
|
* Handles the navigation gestures when a 3rd party launcher is the default home activity.
|
||||||
@@ -105,10 +105,16 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa
|
|||||||
private final PointF mEndVelocityPxPerMs = new PointF(0, 0.5f);
|
private final PointF mEndVelocityPxPerMs = new PointF(0, 0.5f);
|
||||||
private RunningWindowAnim mFinishAnimation;
|
private RunningWindowAnim mFinishAnimation;
|
||||||
|
|
||||||
|
// Used to control Recents components throughout the swipe gesture.
|
||||||
|
private AnimatorPlaybackController mLauncherTransitionController;
|
||||||
|
private boolean mHasLauncherTransitionControllerStarted;
|
||||||
|
|
||||||
|
private AnimationFactory mAnimationFactory = (t) -> { };
|
||||||
|
|
||||||
public FallbackSwipeHandler(Context context, RecentsAnimationDeviceState deviceState,
|
public FallbackSwipeHandler(Context context, RecentsAnimationDeviceState deviceState,
|
||||||
GestureState gestureState, InputConsumerController inputConsumer,
|
GestureState gestureState, InputConsumerController inputConsumer,
|
||||||
boolean isLikelyToStartNewTask, boolean continuingLastGesture) {
|
boolean isLikelyToStartNewTask, boolean continuingLastGesture) {
|
||||||
super(context, deviceState, gestureState, inputConsumer);
|
super(context, deviceState, gestureState, inputConsumer, FALLBACK_RECENTS_SIZE_STRATEGY);
|
||||||
|
|
||||||
mInQuickSwitchMode = isLikelyToStartNewTask || continuingLastGesture;
|
mInQuickSwitchMode = isLikelyToStartNewTask || continuingLastGesture;
|
||||||
mContinuingLastGesture = continuingLastGesture;
|
mContinuingLastGesture = continuingLastGesture;
|
||||||
@@ -118,9 +124,9 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa
|
|||||||
// Keep the home launcher invisible until we decide to land there.
|
// Keep the home launcher invisible until we decide to land there.
|
||||||
mLauncherAlpha.value = mRunningOverHome ? 1 : 0;
|
mLauncherAlpha.value = mRunningOverHome ? 1 : 0;
|
||||||
if (mSwipeUpOverHome) {
|
if (mSwipeUpOverHome) {
|
||||||
mAppWindowAnimationHelper.setBaseAlphaCallback((t, a) -> 1 - mLauncherAlpha.value);
|
mTransformParams.setBaseAlphaCallback((t, a) -> 1 - mLauncherAlpha.value);
|
||||||
} else {
|
} else {
|
||||||
mAppWindowAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value);
|
mTransformParams.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Going home has an extra long progress to ensure that it animates into the screen
|
// Going home has an extra long progress to ensure that it animates into the screen
|
||||||
@@ -156,7 +162,7 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa
|
|||||||
|
|
||||||
private void onLauncherAlphaChanged() {
|
private void onLauncherAlphaChanged() {
|
||||||
if (mRecentsAnimationTargets != null && mGestureState.getEndTarget() == null) {
|
if (mRecentsAnimationTargets != null && mGestureState.getEndTarget() == null) {
|
||||||
applyTransformUnchecked();
|
applyWindowTransform();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,10 +173,6 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa
|
|||||||
mRecentsView = mActivity.getOverviewPanel();
|
mRecentsView = mActivity.getOverviewPanel();
|
||||||
mRecentsView.setOnPageTransitionEndCallback(null);
|
mRecentsView.setOnPageTransitionEndCallback(null);
|
||||||
linkRecentsViewScroll();
|
linkRecentsViewScroll();
|
||||||
mRecentsView.setDisallowScrollToClearAll(true);
|
|
||||||
mRecentsView.getClearAllButton().setVisibilityAlpha(0);
|
|
||||||
mRecentsView.setZoomProgress(1);
|
|
||||||
|
|
||||||
if (!mContinuingLastGesture) {
|
if (!mContinuingLastGesture) {
|
||||||
if (mRunningOverHome) {
|
if (mRunningOverHome) {
|
||||||
mRecentsView.onGestureAnimationStart(mGestureState.getRunningTask());
|
mRecentsView.onGestureAnimationStart(mGestureState.getRunningTask());
|
||||||
@@ -180,9 +182,48 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa
|
|||||||
}
|
}
|
||||||
mStateCallback.setStateOnUiThread(STATE_RECENTS_PRESENT);
|
mStateCallback.setStateOnUiThread(STATE_RECENTS_PRESENT);
|
||||||
mDeviceState.enableMultipleRegions(false);
|
mDeviceState.enableMultipleRegions(false);
|
||||||
|
|
||||||
|
mAnimationFactory = mActivityInterface.prepareRecentsUI(alreadyOnHome,
|
||||||
|
this::onAnimatorPlaybackControllerCreated);
|
||||||
|
mAnimationFactory.createActivityInterface(mTransitionDragLength);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initTransitionEndpoints(DeviceProfile dp) {
|
||||||
|
super.initTransitionEndpoints(dp);
|
||||||
|
if (canCreateNewOrUpdateExistingLauncherTransitionController()) {
|
||||||
|
mAnimationFactory.createActivityInterface(mTransitionDragLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onAnimatorPlaybackControllerCreated(AnimatorPlaybackController anim) {
|
||||||
|
mLauncherTransitionController = anim;
|
||||||
|
mLauncherTransitionController.dispatchSetInterpolator(t -> t * mDragLengthFactor);
|
||||||
|
mLauncherTransitionController.dispatchOnStart();
|
||||||
|
updateLauncherTransitionProgress();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateLauncherTransitionProgress() {
|
||||||
|
if (mLauncherTransitionController == null
|
||||||
|
|| !canCreateNewOrUpdateExistingLauncherTransitionController()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Normalize the progress to 0 to 1, as the animation controller will clamp it to that
|
||||||
|
// anyway. The controller mimics the drag length factor by applying it to its interpolators.
|
||||||
|
float progress = mCurrentShift.value / mDragLengthFactor;
|
||||||
|
mLauncherTransitionController.setPlayFraction(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We don't want to change mLauncherTransitionController if mGestureState.getEndTarget() == HOME
|
||||||
|
* (it has its own animation) or if we're already animating the current controller.
|
||||||
|
* @return Whether we can create the launcher controller or update its progress.
|
||||||
|
*/
|
||||||
|
private boolean canCreateNewOrUpdateExistingLauncherTransitionController() {
|
||||||
|
return mGestureState.getEndTarget() != HOME && !mHasLauncherTransitionControllerStarted;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean moveWindowWithRecentsScroll() {
|
protected boolean moveWindowWithRecentsScroll() {
|
||||||
return mInQuickSwitchMode;
|
return mInQuickSwitchMode;
|
||||||
@@ -261,9 +302,8 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa
|
|||||||
updateOverviewThresholdPassed(mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW);
|
updateOverviewThresholdPassed(mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mRecentsAnimationTargets != null) {
|
applyWindowTransform();
|
||||||
applyTransformUnchecked();
|
updateLauncherTransitionProgress();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -320,15 +360,6 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mRecentsView != null) {
|
if (mRecentsView != null) {
|
||||||
if (mFinishingRecentsAnimationForNewTaskId != -1) {
|
|
||||||
TaskView newRunningTaskView = mRecentsView.getTaskView(
|
|
||||||
mFinishingRecentsAnimationForNewTaskId);
|
|
||||||
int newRunningTaskId = newRunningTaskView != null
|
|
||||||
? newRunningTaskView.getTask().key.id
|
|
||||||
: -1;
|
|
||||||
mRecentsView.setCurrentTask(newRunningTaskId);
|
|
||||||
mGestureState.setFinishingRecentsAnimationTaskId(newRunningTaskId);
|
|
||||||
}
|
|
||||||
mRecentsView.setOnScrollChangeListener(null);
|
mRecentsView.setOnScrollChangeListener(null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -401,7 +432,7 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NEW_TASK: {
|
case NEW_TASK: {
|
||||||
startNewTask(STATE_HANDLER_INVALIDATED, b -> {});
|
startNewTask(success -> { });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -416,7 +447,7 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa
|
|||||||
if (mRecentsView == null || !hasTargets()) {
|
if (mRecentsView == null || !hasTargets()) {
|
||||||
mGestureState.setEndTarget(LAST_TASK);
|
mGestureState.setEndTarget(LAST_TASK);
|
||||||
} else {
|
} else {
|
||||||
final int runningTaskIndex = mRecentsView.getRunningTaskIndex();
|
final int runningTaskIndex = getLastAppearedTaskIndex();
|
||||||
final int taskToLaunch = mRecentsView.getNextPage();
|
final int taskToLaunch = mRecentsView.getNextPage();
|
||||||
mGestureState.setEndTarget(
|
mGestureState.setEndTarget(
|
||||||
(runningTaskIndex >= 0 && taskToLaunch != runningTaskIndex)
|
(runningTaskIndex >= 0 && taskToLaunch != runningTaskIndex)
|
||||||
@@ -477,11 +508,7 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa
|
|||||||
RecentsAnimationTargets targets) {
|
RecentsAnimationTargets targets) {
|
||||||
super.onRecentsAnimationStart(controller, targets);
|
super.onRecentsAnimationStart(controller, targets);
|
||||||
mRecentsAnimationController.enableInputConsumer();
|
mRecentsAnimationController.enableInputConsumer();
|
||||||
|
applyWindowTransform();
|
||||||
if (mRunningOverHome) {
|
|
||||||
mAppWindowAnimationHelper.prepareAnimation(mDp);
|
|
||||||
}
|
|
||||||
applyTransformUnchecked();
|
|
||||||
|
|
||||||
mStateCallback.setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
|
mStateCallback.setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
|
||||||
}
|
}
|
||||||
@@ -494,23 +521,17 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa
|
|||||||
super.onRecentsAnimationCanceled(thumbnailData);
|
super.onRecentsAnimationCanceled(thumbnailData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean handleTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an animation that transforms the current app window into the home app.
|
* Creates an animation that transforms the current app window into the home app.
|
||||||
* @param startProgress The progress of {@link #mCurrentShift} to start the window from.
|
* @param startProgress The progress of {@link #mCurrentShift} to start the window from.
|
||||||
*/
|
*/
|
||||||
private RectFSpringAnim createWindowAnimationToHome(float startProgress, long duration) {
|
private RectFSpringAnim createWindowAnimationToHome(float startProgress, long duration) {
|
||||||
HomeAnimationFactory factory = new HomeAnimationFactory() {
|
HomeAnimationFactory factory = new HomeAnimationFactory(null) {
|
||||||
@Override
|
|
||||||
public RectF getWindowTargetRect() {
|
|
||||||
PagedOrientationHandler orientationHandler = mRecentsView != null
|
|
||||||
? mRecentsView.getPagedOrientationHandler()
|
|
||||||
: (mDp.isLandscape
|
|
||||||
? PagedOrientationHandler.LANDSCAPE
|
|
||||||
: PagedOrientationHandler.PORTRAIT);
|
|
||||||
return HomeAnimationFactory
|
|
||||||
.getDefaultWindowTargetRect(orientationHandler, mDp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AnimatorPlaybackController createActivityAnimationToHome() {
|
public AnimatorPlaybackController createActivityAnimationToHome() {
|
||||||
AnimatorSet anim = new AnimatorSet();
|
AnimatorSet anim = new AnimatorSet();
|
||||||
|
|||||||
+40
-139
@@ -16,32 +16,26 @@
|
|||||||
package com.android.quickstep;
|
package com.android.quickstep;
|
||||||
|
|
||||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||||
import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_RECENTS_FADE_ANIM;
|
|
||||||
import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_RECENTS_TRANSLATE_X_ANIM;
|
|
||||||
import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_SHELF_ANIM;
|
|
||||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||||
import static com.android.launcher3.LauncherState.NORMAL;
|
|
||||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||||
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
|
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
|
||||||
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
||||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||||
|
import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM;
|
||||||
|
import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_RECENTS_TRANSLATE_X_ANIM;
|
||||||
|
import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_SHELF_ANIM;
|
||||||
import static com.android.quickstep.LauncherSwipeHandler.RECENTS_ATTACH_DURATION;
|
import static com.android.quickstep.LauncherSwipeHandler.RECENTS_ATTACH_DURATION;
|
||||||
import static com.android.quickstep.util.WindowSizeStrategy.LAUNCHER_ACTIVITY_SIZE_STRATEGY;
|
import static com.android.quickstep.util.WindowSizeStrategy.LAUNCHER_ACTIVITY_SIZE_STRATEGY;
|
||||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||||
|
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorSet;
|
|
||||||
import android.animation.ObjectAnimator;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
import android.util.Log;
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.util.Pair;
|
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
|
||||||
import android.view.animation.Interpolator;
|
import android.view.animation.Interpolator;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
|
|
||||||
@@ -52,20 +46,19 @@ import com.android.launcher3.LauncherInitListener;
|
|||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.allapps.DiscoveryBounce;
|
import com.android.launcher3.allapps.DiscoveryBounce;
|
||||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||||
|
import com.android.launcher3.anim.PendingAnimation;
|
||||||
import com.android.launcher3.appprediction.PredictionUiStateManager;
|
import com.android.launcher3.appprediction.PredictionUiStateManager;
|
||||||
import com.android.launcher3.statehandlers.DepthController;
|
import com.android.launcher3.statehandlers.DepthController;
|
||||||
import com.android.launcher3.statehandlers.DepthController.ClampedDepthProperty;
|
import com.android.launcher3.statehandlers.DepthController.ClampedDepthProperty;
|
||||||
|
import com.android.launcher3.testing.TestProtocol;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||||
import com.android.launcher3.views.FloatingIconView;
|
|
||||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||||
import com.android.quickstep.util.ActivityInitListener;
|
import com.android.quickstep.util.ActivityInitListener;
|
||||||
import com.android.quickstep.util.LayoutUtils;
|
import com.android.quickstep.util.LayoutUtils;
|
||||||
import com.android.quickstep.util.ShelfPeekAnim;
|
import com.android.quickstep.util.ShelfPeekAnim;
|
||||||
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
|
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
|
||||||
import com.android.quickstep.util.StaggeredWorkspaceAnim;
|
|
||||||
import com.android.quickstep.views.LauncherRecentsView;
|
import com.android.quickstep.views.LauncherRecentsView;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
import com.android.quickstep.views.TaskView;
|
|
||||||
import com.android.systemui.plugins.shared.LauncherOverlayManager;
|
import com.android.systemui.plugins.shared.LauncherOverlayManager;
|
||||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
@@ -78,9 +71,6 @@ import java.util.function.Predicate;
|
|||||||
*/
|
*/
|
||||||
public final class LauncherActivityInterface implements BaseActivityInterface<Launcher> {
|
public final class LauncherActivityInterface implements BaseActivityInterface<Launcher> {
|
||||||
|
|
||||||
private Pair<Float, Float> mSwipeUpPullbackStartAndMaxProgress =
|
|
||||||
BaseActivityInterface.super.getSwipeUpPullbackStartAndMaxProgress();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect) {
|
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect) {
|
||||||
LAUNCHER_ACTIVITY_SIZE_STRATEGY.calculateTaskSize(context, dp, outRect);
|
LAUNCHER_ACTIVITY_SIZE_STRATEGY.calculateTaskSize(context, dp, outRect);
|
||||||
@@ -93,11 +83,6 @@ public final class LauncherActivityInterface implements BaseActivityInterface<La
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Pair<Float, Float> getSwipeUpPullbackStartAndMaxProgress() {
|
|
||||||
return mSwipeUpPullbackStartAndMaxProgress;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTransitionCancelled(boolean activityVisible) {
|
public void onTransitionCancelled(boolean activityVisible) {
|
||||||
Launcher launcher = getCreatedActivity();
|
Launcher launcher = getCreatedActivity();
|
||||||
@@ -148,66 +133,9 @@ public final class LauncherActivityInterface implements BaseActivityInterface<La
|
|||||||
launcher.onAssistantVisibilityChanged(visibility);
|
launcher.onAssistantVisibilityChanged(visibility);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
@Override
|
||||||
public HomeAnimationFactory prepareHomeUI() {
|
public AnimationFactory prepareRecentsUI(
|
||||||
Launcher launcher = getCreatedActivity();
|
boolean activityVisible, Consumer<AnimatorPlaybackController> callback) {
|
||||||
final DeviceProfile dp = launcher.getDeviceProfile();
|
|
||||||
final RecentsView recentsView = launcher.getOverviewPanel();
|
|
||||||
final TaskView runningTaskView = recentsView.getRunningTaskView();
|
|
||||||
final View workspaceView;
|
|
||||||
if (runningTaskView != null && runningTaskView.getTask().key.getComponent() != null) {
|
|
||||||
workspaceView = launcher.getWorkspace().getFirstMatchForAppClose(
|
|
||||||
runningTaskView.getTask().key.getComponent().getPackageName(),
|
|
||||||
UserHandle.of(runningTaskView.getTask().key.userId));
|
|
||||||
} else {
|
|
||||||
workspaceView = null;
|
|
||||||
}
|
|
||||||
final RectF iconLocation = new RectF();
|
|
||||||
boolean canUseWorkspaceView = workspaceView != null && workspaceView.isAttachedToWindow();
|
|
||||||
FloatingIconView floatingIconView = canUseWorkspaceView
|
|
||||||
? FloatingIconView.getFloatingIconView(launcher, workspaceView,
|
|
||||||
true /* hideOriginal */, iconLocation, false /* isOpening */)
|
|
||||||
: null;
|
|
||||||
setLauncherHideBackArrow(true);
|
|
||||||
return new HomeAnimationFactory() {
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public View getFloatingView() {
|
|
||||||
return floatingIconView;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public RectF getWindowTargetRect() {
|
|
||||||
if (canUseWorkspaceView) {
|
|
||||||
return iconLocation;
|
|
||||||
} else {
|
|
||||||
return HomeAnimationFactory
|
|
||||||
.getDefaultWindowTargetRect(recentsView.getPagedOrientationHandler(), dp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public AnimatorPlaybackController createActivityAnimationToHome() {
|
|
||||||
// Return an empty APC here since we have an non-user controlled animation to home.
|
|
||||||
long accuracy = 2 * Math.max(dp.widthPx, dp.heightPx);
|
|
||||||
return launcher.getStateManager().createAnimationToNewWorkspace(NORMAL, accuracy,
|
|
||||||
0 /* animComponents */);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void playAtomicAnimation(float velocity) {
|
|
||||||
new StaggeredWorkspaceAnim(launcher, velocity, true /* animateOverviewScrim */)
|
|
||||||
.start();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AnimationFactory prepareRecentsUI(boolean activityVisible,
|
|
||||||
boolean animateActivity, Consumer<AnimatorPlaybackController> callback) {
|
|
||||||
BaseQuickstepLauncher launcher = getCreatedActivity();
|
BaseQuickstepLauncher launcher = getCreatedActivity();
|
||||||
final LauncherState startState = launcher.getStateManager().getState();
|
final LauncherState startState = launcher.getStateManager().getState();
|
||||||
|
|
||||||
@@ -217,8 +145,7 @@ public final class LauncherActivityInterface implements BaseActivityInterface<La
|
|||||||
}
|
}
|
||||||
launcher.getStateManager().setRestState(resetState);
|
launcher.getStateManager().setRestState(resetState);
|
||||||
|
|
||||||
final LauncherState fromState = animateActivity ? BACKGROUND_APP : OVERVIEW;
|
launcher.getStateManager().goToState(BACKGROUND_APP, false);
|
||||||
launcher.getStateManager().goToState(fromState, false);
|
|
||||||
// Since all apps is not visible, we can safely reset the scroll position.
|
// Since all apps is not visible, we can safely reset the scroll position.
|
||||||
// This ensures then the next swipe up to all-apps starts from scroll 0.
|
// This ensures then the next swipe up to all-apps starts from scroll 0.
|
||||||
launcher.getAppsView().reset(false /* animate */);
|
launcher.getAppsView().reset(false /* animate */);
|
||||||
@@ -229,7 +156,7 @@ public final class LauncherActivityInterface implements BaseActivityInterface<La
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createActivityInterface(long transitionLength) {
|
public void createActivityInterface(long transitionLength) {
|
||||||
createActivityInterfaceInternal(launcher, fromState, transitionLength, callback);
|
callback.accept(createBackgroundToOverviewAnim(launcher, transitionLength));
|
||||||
// Creating the activity controller animation sometimes reapplies the launcher state
|
// Creating the activity controller animation sometimes reapplies the launcher state
|
||||||
// (because we set the animation as the current state animation), so we reapply the
|
// (because we set the animation as the current state animation), so we reapply the
|
||||||
// attached state here as well to ensure recents is shown/hidden appropriately.
|
// attached state here as well to ensure recents is shown/hidden appropriately.
|
||||||
@@ -283,74 +210,45 @@ public final class LauncherActivityInterface implements BaseActivityInterface<La
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createActivityInterfaceInternal(Launcher activity, LauncherState fromState,
|
private AnimatorPlaybackController createBackgroundToOverviewAnim(
|
||||||
long transitionLength, Consumer<AnimatorPlaybackController> callback) {
|
Launcher activity, long transitionLength) {
|
||||||
LauncherState endState = OVERVIEW;
|
|
||||||
if (fromState == endState) {
|
PendingAnimation pa = new PendingAnimation(transitionLength * 2);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AnimatorSet anim = new AnimatorSet();
|
|
||||||
if (!activity.getDeviceProfile().isVerticalBarLayout()
|
if (!activity.getDeviceProfile().isVerticalBarLayout()
|
||||||
&& SysUINavigationMode.getMode(activity) != Mode.NO_BUTTON) {
|
&& SysUINavigationMode.getMode(activity) != Mode.NO_BUTTON) {
|
||||||
// Don't animate the shelf when the mode is NO_BUTTON, because we update it atomically.
|
// Don't animate the shelf when the mode is NO_BUTTON, because we update it atomically.
|
||||||
anim.play(activity.getStateManager().createStateElementAnimation(
|
pa.add(activity.getStateManager().createStateElementAnimation(
|
||||||
INDEX_SHELF_ANIM,
|
INDEX_SHELF_ANIM,
|
||||||
fromState.getVerticalProgress(activity),
|
BACKGROUND_APP.getVerticalProgress(activity),
|
||||||
endState.getVerticalProgress(activity)));
|
OVERVIEW.getVerticalProgress(activity)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Animate the blur and wallpaper zoom
|
// Animate the blur and wallpaper zoom
|
||||||
DepthController depthController = getDepthController();
|
float fromDepthRatio = BACKGROUND_APP.getDepth(activity);
|
||||||
float fromDepthRatio = fromState.getDepth(activity);
|
float toDepthRatio = OVERVIEW.getDepth(activity);
|
||||||
float toDepthRatio = endState.getDepth(activity);
|
pa.addFloat(getDepthController(), new ClampedDepthProperty(fromDepthRatio, toDepthRatio),
|
||||||
Animator depthAnimator = ObjectAnimator.ofFloat(depthController,
|
fromDepthRatio, toDepthRatio, LINEAR);
|
||||||
new ClampedDepthProperty(fromDepthRatio, toDepthRatio),
|
|
||||||
fromDepthRatio, toDepthRatio);
|
|
||||||
anim.play(depthAnimator);
|
|
||||||
|
|
||||||
playScaleDownAnim(anim, activity, fromState, endState);
|
|
||||||
|
|
||||||
anim.setDuration(transitionLength * 2);
|
// Scale down recents from being full screen to being in overview.
|
||||||
anim.setInterpolator(LINEAR);
|
RecentsView recentsView = activity.getOverviewPanel();
|
||||||
AnimatorPlaybackController controller =
|
pa.addFloat(recentsView, SCALE_PROPERTY,
|
||||||
AnimatorPlaybackController.wrap(anim, transitionLength * 2);
|
BACKGROUND_APP.getOverviewScaleAndOffset(activity)[0],
|
||||||
|
OVERVIEW.getOverviewScaleAndOffset(activity)[0],
|
||||||
|
LINEAR);
|
||||||
|
pa.addFloat(recentsView, FULLSCREEN_PROGRESS,
|
||||||
|
BACKGROUND_APP.getOverviewFullscreenProgress(),
|
||||||
|
OVERVIEW.getOverviewFullscreenProgress(),
|
||||||
|
LINEAR);
|
||||||
|
|
||||||
|
AnimatorPlaybackController controller = pa.createPlaybackController();
|
||||||
activity.getStateManager().setCurrentUserControlledAnimation(controller);
|
activity.getStateManager().setCurrentUserControlledAnimation(controller);
|
||||||
|
|
||||||
// Since we are changing the start position of the UI, reapply the state, at the end
|
// Since we are changing the start position of the UI, reapply the state, at the end
|
||||||
controller.setEndAction(() -> {
|
controller.setEndAction(() -> activity.getStateManager().goToState(
|
||||||
activity.getStateManager().goToState(
|
controller.getInterpolatedProgress() > 0.5 ? OVERVIEW : BACKGROUND_APP, false));
|
||||||
controller.getInterpolatedProgress() > 0.5 ? endState : fromState, false);
|
return controller;
|
||||||
});
|
|
||||||
callback.accept(controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scale down recents from the center task being full screen to being in overview.
|
|
||||||
*/
|
|
||||||
private void playScaleDownAnim(AnimatorSet anim, Launcher launcher, LauncherState fromState,
|
|
||||||
LauncherState endState) {
|
|
||||||
RecentsView recentsView = launcher.getOverviewPanel();
|
|
||||||
if (recentsView.getCurrentPageTaskView() == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float fromFullscreenProgress = fromState.getOverviewFullscreenProgress();
|
|
||||||
float endFullscreenProgress = endState.getOverviewFullscreenProgress();
|
|
||||||
|
|
||||||
float fromScale = fromState.getOverviewScaleAndOffset(launcher)[0];
|
|
||||||
float endScale = endState.getOverviewScaleAndOffset(launcher)[0];
|
|
||||||
|
|
||||||
Animator scale = ObjectAnimator.ofFloat(recentsView, SCALE_PROPERTY, fromScale, endScale);
|
|
||||||
Animator applyFullscreenProgress = ObjectAnimator.ofFloat(recentsView,
|
|
||||||
RecentsView.FULLSCREEN_PROGRESS, fromFullscreenProgress, endFullscreenProgress);
|
|
||||||
anim.playTogether(scale, applyFullscreenProgress);
|
|
||||||
|
|
||||||
// Start pulling back when RecentsView scale is 0.75f, and let it go down to 0.5f.
|
|
||||||
float pullbackStartProgress = (0.75f - fromScale) / (endScale - fromScale);
|
|
||||||
float pullbackMaxProgress = (0.5f - fromScale) / (endScale - fromScale);
|
|
||||||
mSwipeUpPullbackStartAndMaxProgress = new Pair<>(
|
|
||||||
pullbackStartProgress, pullbackMaxProgress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -383,6 +281,9 @@ public final class LauncherActivityInterface implements BaseActivityInterface<La
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean switchToRecentsIfVisible(Runnable onCompleteCallback) {
|
public boolean switchToRecentsIfVisible(Runnable onCompleteCallback) {
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.OVERIEW_NOT_ALLAPPS, "switchToRecentsIfVisible");
|
||||||
|
}
|
||||||
Launcher launcher = getVisibleLauncher();
|
Launcher launcher = getVisibleLauncher();
|
||||||
if (launcher == null) {
|
if (launcher == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
+101
-114
@@ -17,8 +17,7 @@ package com.android.quickstep;
|
|||||||
|
|
||||||
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
|
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
|
||||||
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
|
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
|
||||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
import static com.android.launcher3.LauncherState.NORMAL;
|
||||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
|
||||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||||
@@ -32,7 +31,6 @@ import static com.android.quickstep.GestureState.GestureEndTarget.NEW_TASK;
|
|||||||
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
|
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
|
||||||
import static com.android.quickstep.GestureState.STATE_END_TARGET_ANIMATION_FINISHED;
|
import static com.android.quickstep.GestureState.STATE_END_TARGET_ANIMATION_FINISHED;
|
||||||
import static com.android.quickstep.GestureState.STATE_RECENTS_SCROLLING_FINISHED;
|
import static com.android.quickstep.GestureState.STATE_RECENTS_SCROLLING_FINISHED;
|
||||||
import static com.android.quickstep.GestureState.STATE_TASK_APPEARED_DURING_SWITCH;
|
|
||||||
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
|
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
|
||||||
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
|
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
|
||||||
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.HIDE;
|
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.HIDE;
|
||||||
@@ -42,17 +40,16 @@ import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHO
|
|||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorSet;
|
import android.animation.AnimatorSet;
|
||||||
import android.animation.ObjectAnimator;
|
|
||||||
import android.animation.TimeInterpolator;
|
import android.animation.TimeInterpolator;
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
import android.os.UserHandle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnApplyWindowInsetsListener;
|
import android.view.View.OnApplyWindowInsetsListener;
|
||||||
import android.view.ViewTreeObserver.OnDrawListener;
|
import android.view.ViewTreeObserver.OnDrawListener;
|
||||||
@@ -65,6 +62,7 @@ import androidx.annotation.UiThread;
|
|||||||
import com.android.launcher3.AbstractFloatingView;
|
import com.android.launcher3.AbstractFloatingView;
|
||||||
import com.android.launcher3.BaseDraggingActivity;
|
import com.android.launcher3.BaseDraggingActivity;
|
||||||
import com.android.launcher3.DeviceProfile;
|
import com.android.launcher3.DeviceProfile;
|
||||||
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||||
@@ -75,16 +73,16 @@ 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.Action.Touch;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
||||||
import com.android.launcher3.util.TraceHelper;
|
import com.android.launcher3.util.TraceHelper;
|
||||||
|
import com.android.launcher3.views.FloatingIconView;
|
||||||
import com.android.quickstep.BaseActivityInterface.AnimationFactory;
|
import com.android.quickstep.BaseActivityInterface.AnimationFactory;
|
||||||
import com.android.quickstep.BaseActivityInterface.HomeAnimationFactory;
|
|
||||||
import com.android.quickstep.GestureState.GestureEndTarget;
|
import com.android.quickstep.GestureState.GestureEndTarget;
|
||||||
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
|
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
|
||||||
import com.android.quickstep.util.ActiveGestureLog;
|
import com.android.quickstep.util.ActiveGestureLog;
|
||||||
import com.android.quickstep.util.AppWindowAnimationHelper.TargetAlphaProvider;
|
|
||||||
import com.android.quickstep.util.RectFSpringAnim;
|
import com.android.quickstep.util.RectFSpringAnim;
|
||||||
import com.android.quickstep.util.ShelfPeekAnim;
|
import com.android.quickstep.util.ShelfPeekAnim;
|
||||||
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
|
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
|
||||||
import com.android.quickstep.util.TaskViewSimulator;
|
import com.android.quickstep.util.StaggeredWorkspaceAnim;
|
||||||
|
import com.android.quickstep.util.TransformParams.TargetAlphaProvider;
|
||||||
import com.android.quickstep.views.LiveTileOverlay;
|
import com.android.quickstep.views.LiveTileOverlay;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
import com.android.quickstep.views.TaskView;
|
import com.android.quickstep.views.TaskView;
|
||||||
@@ -97,8 +95,8 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
|||||||
* Handles the navigation gestures when Launcher is the default home activity.
|
* Handles the navigation gestures when Launcher is the default home activity.
|
||||||
*/
|
*/
|
||||||
@TargetApi(Build.VERSION_CODES.O)
|
@TargetApi(Build.VERSION_CODES.O)
|
||||||
public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
public class LauncherSwipeHandler extends BaseSwipeUpHandler<Launcher, RecentsView>
|
||||||
extends BaseSwipeUpHandler<T, RecentsView> implements OnApplyWindowInsetsListener {
|
implements OnApplyWindowInsetsListener {
|
||||||
private static final String TAG = LauncherSwipeHandler.class.getSimpleName();
|
private static final String TAG = LauncherSwipeHandler.class.getSimpleName();
|
||||||
|
|
||||||
private static final String[] STATE_NAMES = DEBUG_STATES ? new String[16] : null;
|
private static final String[] STATE_NAMES = DEBUG_STATES ? new String[16] : null;
|
||||||
@@ -152,7 +150,6 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED;
|
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED;
|
||||||
|
|
||||||
public static final long MAX_SWIPE_DURATION = 350;
|
public static final long MAX_SWIPE_DURATION = 350;
|
||||||
public static final long MIN_SWIPE_DURATION = 80;
|
|
||||||
public static final long MIN_OVERSHOOT_DURATION = 120;
|
public static final long MIN_OVERSHOOT_DURATION = 120;
|
||||||
|
|
||||||
public static final float MIN_PROGRESS_FOR_OVERVIEW = 0.7f;
|
public static final float MIN_PROGRESS_FOR_OVERVIEW = 0.7f;
|
||||||
@@ -181,9 +178,6 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
private AnimatorPlaybackController mLauncherTransitionController;
|
private AnimatorPlaybackController mLauncherTransitionController;
|
||||||
private boolean mHasLauncherTransitionControllerStarted;
|
private boolean mHasLauncherTransitionControllerStarted;
|
||||||
|
|
||||||
private final TaskViewSimulator mTaskViewSimulator;
|
|
||||||
private AnimatorPlaybackController mWindowTransitionController;
|
|
||||||
|
|
||||||
private AnimationFactory mAnimationFactory = (t) -> { };
|
private AnimationFactory mAnimationFactory = (t) -> { };
|
||||||
|
|
||||||
private boolean mWasLauncherAlreadyVisible;
|
private boolean mWasLauncherAlreadyVisible;
|
||||||
@@ -204,11 +198,10 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
TaskAnimationManager taskAnimationManager, GestureState gestureState,
|
TaskAnimationManager taskAnimationManager, GestureState gestureState,
|
||||||
long touchTimeMs, boolean continuingLastGesture,
|
long touchTimeMs, boolean continuingLastGesture,
|
||||||
InputConsumerController inputConsumer) {
|
InputConsumerController inputConsumer) {
|
||||||
super(context, deviceState, gestureState, inputConsumer);
|
super(context, deviceState, gestureState, inputConsumer, LAUNCHER_ACTIVITY_SIZE_STRATEGY);
|
||||||
mTaskAnimationManager = taskAnimationManager;
|
mTaskAnimationManager = taskAnimationManager;
|
||||||
mTouchTimeMs = touchTimeMs;
|
mTouchTimeMs = touchTimeMs;
|
||||||
mContinuingLastGesture = continuingLastGesture;
|
mContinuingLastGesture = continuingLastGesture;
|
||||||
mTaskViewSimulator = new TaskViewSimulator(context, LAUNCHER_ACTIVITY_SIZE_STRATEGY);
|
|
||||||
|
|
||||||
initAfterSubclassConstructor();
|
initAfterSubclassConstructor();
|
||||||
initStateCallbacks();
|
initStateCallbacks();
|
||||||
@@ -264,8 +257,6 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
| STATE_RECENTS_SCROLLING_FINISHED,
|
| STATE_RECENTS_SCROLLING_FINISHED,
|
||||||
this::onSettledOnEndTarget);
|
this::onSettledOnEndTarget);
|
||||||
|
|
||||||
mGestureState.runOnceAtState(STATE_TASK_APPEARED_DURING_SWITCH, this::onTaskAppeared);
|
|
||||||
|
|
||||||
mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED, this::invalidateHandler);
|
mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED, this::invalidateHandler);
|
||||||
mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
|
mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
|
||||||
this::invalidateHandlerWithLauncher);
|
this::invalidateHandlerWithLauncher);
|
||||||
@@ -282,7 +273,7 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
@Override
|
@Override
|
||||||
protected boolean onActivityInit(Boolean alreadyOnHome) {
|
protected boolean onActivityInit(Boolean alreadyOnHome) {
|
||||||
super.onActivityInit(alreadyOnHome);
|
super.onActivityInit(alreadyOnHome);
|
||||||
final T activity = mActivityInterface.getCreatedActivity();
|
final Launcher activity = mActivityInterface.getCreatedActivity();
|
||||||
if (mActivity == activity) {
|
if (mActivity == activity) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -304,7 +295,6 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
|
|
||||||
mRecentsView = activity.getOverviewPanel();
|
mRecentsView = activity.getOverviewPanel();
|
||||||
mRecentsView.setOnPageTransitionEndCallback(null);
|
mRecentsView.setOnPageTransitionEndCallback(null);
|
||||||
linkRecentsViewScroll();
|
|
||||||
addLiveTileOverlay();
|
addLiveTileOverlay();
|
||||||
|
|
||||||
mStateCallback.setState(STATE_LAUNCHER_PRESENT);
|
mStateCallback.setState(STATE_LAUNCHER_PRESENT);
|
||||||
@@ -321,6 +311,8 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
// so we need to kick off switching to the overview predictions as soon as possible
|
// so we need to kick off switching to the overview predictions as soon as possible
|
||||||
mActivityInterface.updateOverviewPredictionState();
|
mActivityInterface.updateOverviewPredictionState();
|
||||||
}
|
}
|
||||||
|
linkRecentsViewScroll();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +322,7 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onLauncherStart() {
|
private void onLauncherStart() {
|
||||||
final T activity = mActivityInterface.getCreatedActivity();
|
final Launcher activity = mActivityInterface.getCreatedActivity();
|
||||||
if (mActivity != activity) {
|
if (mActivity != activity) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -343,8 +335,7 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
if (mGestureState.getEndTarget() != HOME) {
|
if (mGestureState.getEndTarget() != HOME) {
|
||||||
Runnable initAnimFactory = () -> {
|
Runnable initAnimFactory = () -> {
|
||||||
mAnimationFactory = mActivityInterface.prepareRecentsUI(
|
mAnimationFactory = mActivityInterface.prepareRecentsUI(
|
||||||
mWasLauncherAlreadyVisible, true,
|
mWasLauncherAlreadyVisible, this::onAnimatorPlaybackControllerCreated);
|
||||||
this::onAnimatorPlaybackControllerCreated);
|
|
||||||
maybeUpdateRecentsAttachedState(false /* animate */);
|
maybeUpdateRecentsAttachedState(false /* animate */);
|
||||||
};
|
};
|
||||||
if (mWasLauncherAlreadyVisible) {
|
if (mWasLauncherAlreadyVisible) {
|
||||||
@@ -521,34 +512,6 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
mAnimationFactory.createActivityInterface(mTransitionDragLength);
|
mAnimationFactory.createActivityInterface(mTransitionDragLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void updateSource(Rect stackBounds, RemoteAnimationTargetCompat runningTarget) {
|
|
||||||
super.updateSource(stackBounds, runningTarget);
|
|
||||||
mTaskViewSimulator.setPreview(runningTarget, mRecentsAnimationTargets);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void initTransitionEndpoints(DeviceProfile dp) {
|
|
||||||
super.initTransitionEndpoints(dp);
|
|
||||||
mTaskViewSimulator.setDp(dp);
|
|
||||||
mTaskViewSimulator.setLayoutRotation(
|
|
||||||
mDeviceState.getCurrentActiveRotation(),
|
|
||||||
mDeviceState.getDisplayRotation());
|
|
||||||
|
|
||||||
AnimatorSet anim = new AnimatorSet();
|
|
||||||
anim.setDuration(mTransitionDragLength * 2);
|
|
||||||
anim.setInterpolator(t -> t * mDragLengthFactor);
|
|
||||||
anim.play(ObjectAnimator.ofFloat(mTaskViewSimulator.recentsViewScale,
|
|
||||||
AnimatedFloat.VALUE,
|
|
||||||
mTaskViewSimulator.getFullScreenScale(), 1));
|
|
||||||
anim.play(ObjectAnimator.ofFloat(mTaskViewSimulator.fullScreenProgress,
|
|
||||||
AnimatedFloat.VALUE,
|
|
||||||
BACKGROUND_APP.getOverviewFullscreenProgress(),
|
|
||||||
OVERVIEW.getOverviewFullscreenProgress()));
|
|
||||||
mWindowTransitionController =
|
|
||||||
AnimatorPlaybackController.wrap(anim, mTransitionDragLength * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We don't want to change mLauncherTransitionController if mGestureState.getEndTarget() == HOME
|
* We don't want to change mLauncherTransitionController if mGestureState.getEndTarget() == HOME
|
||||||
* (it has its own animation) or if we're already animating the current controller.
|
* (it has its own animation) or if we're already animating the current controller.
|
||||||
@@ -579,18 +542,11 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateFinalShift() {
|
public void updateFinalShift() {
|
||||||
if (mRecentsAnimationTargets != null) {
|
|
||||||
// Base class expects applyTransformUnchecked to be called here.
|
|
||||||
// TODO: Remove this dependency for swipe-up animation.
|
|
||||||
// applyTransformUnchecked();
|
|
||||||
updateSysUiFlags(mCurrentShift.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||||
if (mRecentsAnimationTargets != null) {
|
if (mRecentsAnimationTargets != null) {
|
||||||
LiveTileOverlay.INSTANCE.update(
|
LiveTileOverlay.INSTANCE.update(
|
||||||
mAppWindowAnimationHelper.getCurrentRectWithInsets(),
|
mTaskViewSimulator.getCurrentCropRect(),
|
||||||
mAppWindowAnimationHelper.getCurrentCornerRadius());
|
mTaskViewSimulator.getCurrentCornerRadius());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,16 +558,8 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mWindowTransitionController != null) {
|
updateSysUiFlags(mCurrentShift.value);
|
||||||
float progress = mCurrentShift.value / mDragLengthFactor;
|
applyWindowTransform();
|
||||||
mWindowTransitionController.setPlayFraction(progress);
|
|
||||||
mTransformParams
|
|
||||||
.setTargetSet(mRecentsAnimationTargets)
|
|
||||||
.setLauncherOnTop(true);
|
|
||||||
|
|
||||||
mTaskViewSimulator.setScroll(mRecentsView == null ? 0 : mRecentsView.getScrollOffset());
|
|
||||||
mTaskViewSimulator.apply(mTransformParams);
|
|
||||||
}
|
|
||||||
updateLauncherTransitionProgress();
|
updateLauncherTransitionProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -685,7 +633,7 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
*/
|
*/
|
||||||
@UiThread
|
@UiThread
|
||||||
private void notifyGestureStartedAsync() {
|
private void notifyGestureStartedAsync() {
|
||||||
final T curActivity = mActivity;
|
final Launcher curActivity = mActivity;
|
||||||
if (curActivity != null) {
|
if (curActivity != null) {
|
||||||
// Once the gesture starts, we can no longer transition home through the button, so
|
// Once the gesture starts, we can no longer transition home through the button, so
|
||||||
// reset the force override of the activity visibility
|
// reset the force override of the activity visibility
|
||||||
@@ -771,20 +719,17 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onTaskAppeared() {
|
@Override
|
||||||
RemoteAnimationTargetCompat app = mGestureState.getAnimationTarget();
|
protected boolean handleTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget) {
|
||||||
if (mRecentsAnimationController != null && app != null) {
|
if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
|
||||||
|
return false;
|
||||||
// TODO(b/152480470): Update Task target animation after onTaskAppeared holistically.
|
|
||||||
/* android.util.Log.d("LauncherSwipeHandler", "onTaskAppeared");
|
|
||||||
|
|
||||||
final boolean result = mRecentsAnimationController.removeTaskTarget(app);
|
|
||||||
mGestureState.setAnimationTarget(null);
|
|
||||||
android.util.Log.d("LauncherSwipeHandler", "removeTask, result=" + result); */
|
|
||||||
|
|
||||||
mRecentsAnimationController.finish(false /* toRecents */,
|
|
||||||
null /* onFinishComplete */);
|
|
||||||
}
|
}
|
||||||
|
if (mStateCallback.hasStates(STATE_START_NEW_TASK)
|
||||||
|
&& appearedTaskTarget.taskId == mGestureState.getLastStartedTaskId()) {
|
||||||
|
reset();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GestureEndTarget calculateEndTarget(PointF velocity, float endVelocity, boolean isFling,
|
private GestureEndTarget calculateEndTarget(PointF velocity, float endVelocity, boolean isFling,
|
||||||
@@ -971,24 +916,61 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) {
|
Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) {
|
||||||
// Set the state, but don't notify until the animation completes
|
// Set the state, but don't notify until the animation completes
|
||||||
mGestureState.setEndTarget(target, false /* isAtomic */);
|
mGestureState.setEndTarget(target, false /* isAtomic */);
|
||||||
|
|
||||||
maybeUpdateRecentsAttachedState();
|
maybeUpdateRecentsAttachedState();
|
||||||
|
|
||||||
if (mGestureState.getEndTarget() == HOME) {
|
if (mGestureState.getEndTarget() == HOME) {
|
||||||
HomeAnimationFactory homeAnimFactory;
|
HomeAnimationFactory homeAnimFactory;
|
||||||
if (mActivity != null) {
|
if (mActivity != null) {
|
||||||
homeAnimFactory = mActivityInterface.prepareHomeUI();
|
final TaskView runningTaskView = mRecentsView.getRunningTaskView();
|
||||||
} else {
|
final View workspaceView;
|
||||||
homeAnimFactory = new HomeAnimationFactory() {
|
if (runningTaskView != null
|
||||||
@NonNull
|
&& runningTaskView.getTask().key.getComponent() != null) {
|
||||||
|
workspaceView = mActivity.getWorkspace().getFirstMatchForAppClose(
|
||||||
|
runningTaskView.getTask().key.getComponent().getPackageName(),
|
||||||
|
UserHandle.of(runningTaskView.getTask().key.userId));
|
||||||
|
} else {
|
||||||
|
workspaceView = null;
|
||||||
|
}
|
||||||
|
final RectF iconLocation = new RectF();
|
||||||
|
boolean canUseWorkspaceView =
|
||||||
|
workspaceView != null && workspaceView.isAttachedToWindow();
|
||||||
|
FloatingIconView floatingIconView = canUseWorkspaceView
|
||||||
|
? FloatingIconView.getFloatingIconView(mActivity, workspaceView,
|
||||||
|
true /* hideOriginal */, iconLocation, false /* isOpening */)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
mActivity.getRootView().setForceHideBackArrow(true);
|
||||||
|
|
||||||
|
homeAnimFactory = new HomeAnimationFactory(floatingIconView) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RectF getWindowTargetRect() {
|
public RectF getWindowTargetRect() {
|
||||||
RectF fallbackTarget = new RectF(mAppWindowAnimationHelper.getTargetRect());
|
if (canUseWorkspaceView) {
|
||||||
Utilities.scaleRectFAboutCenter(fallbackTarget, 0.25f);
|
return iconLocation;
|
||||||
return fallbackTarget;
|
} else {
|
||||||
|
return super.getWindowTargetRect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public AnimatorPlaybackController createActivityAnimationToHome() {
|
||||||
|
// Return an empty APC here since we have an non-user controlled animation
|
||||||
|
// to home.
|
||||||
|
long accuracy = 2 * Math.max(mDp.widthPx, mDp.heightPx);
|
||||||
|
return mActivity.getStateManager().createAnimationToNewWorkspace(
|
||||||
|
NORMAL, accuracy, 0 /* animComponents */);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void playAtomicAnimation(float velocity) {
|
||||||
|
new StaggeredWorkspaceAnim(mActivity, velocity,
|
||||||
|
true /* animateOverviewScrim */).start();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} else {
|
||||||
|
homeAnimFactory = new HomeAnimationFactory(null) {
|
||||||
@Override
|
@Override
|
||||||
public AnimatorPlaybackController createActivityAnimationToHome() {
|
public AnimatorPlaybackController createActivityAnimationToHome() {
|
||||||
return AnimatorPlaybackController.wrap(new AnimatorSet(), duration);
|
return AnimatorPlaybackController.wrap(new AnimatorSet(), duration);
|
||||||
@@ -1031,12 +1013,24 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
// skip doing any future work here for the current gesture.
|
// skip doing any future work here for the current gesture.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (target == NEW_TASK && mRecentsView != null
|
if (mRecentsView != null) {
|
||||||
&& mRecentsView.getNextPage() == mRecentsView.getRunningTaskIndex()) {
|
int taskToLaunch = mRecentsView.getNextPage();
|
||||||
// We are about to launch the current running task, so use LAST_TASK state
|
int runningTask = getLastAppearedTaskIndex();
|
||||||
// instead of NEW_TASK. This could happen, for example, if our scroll is
|
boolean hasStartedNewTask = hasStartedNewTask();
|
||||||
// aborted after we determined the target to be NEW_TASK.
|
if (target == NEW_TASK && taskToLaunch == runningTask
|
||||||
mGestureState.setEndTarget(LAST_TASK);
|
&& !hasStartedNewTask) {
|
||||||
|
// We are about to launch the current running task, so use LAST_TASK
|
||||||
|
// state instead of NEW_TASK. This could happen, for example, if our
|
||||||
|
// scroll is aborted after we determined the target to be NEW_TASK.
|
||||||
|
mGestureState.setEndTarget(LAST_TASK);
|
||||||
|
} else if (target == LAST_TASK && hasStartedNewTask) {
|
||||||
|
// We are about to re-launch the previously running task, but we can't
|
||||||
|
// just finish the controller like we normally would because that would
|
||||||
|
// instead resume the last task that appeared, and not ensure that this
|
||||||
|
// task is restored to the top. To address this, re-launch the task as
|
||||||
|
// if it were a new task.
|
||||||
|
mGestureState.setEndTarget(NEW_TASK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mGestureState.setState(STATE_END_TARGET_ANIMATION_FINISHED);
|
mGestureState.setState(STATE_END_TARGET_ANIMATION_FINISHED);
|
||||||
}
|
}
|
||||||
@@ -1160,8 +1154,9 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
private void startNewTaskInternal() {
|
private void startNewTaskInternal() {
|
||||||
startNewTask(STATE_HANDLER_INVALIDATED, success -> {
|
startNewTask(success -> {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
reset();
|
||||||
// We couldn't launch the task, so take user to overview so they can
|
// We couldn't launch the task, so take user to overview so they can
|
||||||
// decide what to do instead of staying in this broken state.
|
// decide what to do instead of staying in this broken state.
|
||||||
endLauncherTransitionController();
|
endLauncherTransitionController();
|
||||||
@@ -1171,6 +1166,12 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestartLastAppearedTask() {
|
||||||
|
super.onRestartLastAppearedTask();
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
private void reset() {
|
private void reset() {
|
||||||
mStateCallback.setStateOnUiThread(STATE_HANDLER_INVALIDATED);
|
mStateCallback.setStateOnUiThread(STATE_HANDLER_INVALIDATED);
|
||||||
}
|
}
|
||||||
@@ -1186,19 +1187,6 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
.getAnimationPlayer().isStarted()) {
|
.getAnimationPlayer().isStarted()) {
|
||||||
mLauncherTransitionController.getAnimationPlayer().cancel();
|
mLauncherTransitionController.getAnimationPlayer().cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mFinishingRecentsAnimationForNewTaskId != -1) {
|
|
||||||
// If we are canceling mid-starting a new task, switch to the screenshot since the
|
|
||||||
// recents animation has finished
|
|
||||||
switchToScreenshot();
|
|
||||||
TaskView newRunningTaskView = mRecentsView.getTaskView(
|
|
||||||
mFinishingRecentsAnimationForNewTaskId);
|
|
||||||
int newRunningTaskId = newRunningTaskView != null
|
|
||||||
? newRunningTaskView.getTask().key.id
|
|
||||||
: -1;
|
|
||||||
mRecentsView.setCurrentTask(newRunningTaskId);
|
|
||||||
mGestureState.setFinishingRecentsAnimationTaskId(newRunningTaskId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void invalidateHandler() {
|
private void invalidateHandler() {
|
||||||
@@ -1337,8 +1325,7 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setTargetAlphaProvider(TargetAlphaProvider provider) {
|
private void setTargetAlphaProvider(TargetAlphaProvider provider) {
|
||||||
mAppWindowAnimationHelper.setTaskAlphaCallback(provider);
|
mTransformParams.setTaskAlphaCallback(provider);
|
||||||
mTaskViewSimulator.setTaskAlphaCallback(provider);
|
|
||||||
updateFinalShift();
|
updateFinalShift();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.quickstep;
|
package com.android.quickstep;
|
||||||
|
|
||||||
|
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
|
||||||
|
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
|
||||||
|
|
||||||
import static com.android.launcher3.QuickstepAppTransitionManagerImpl.RECENTS_LAUNCH_DURATION;
|
import static com.android.launcher3.QuickstepAppTransitionManagerImpl.RECENTS_LAUNCH_DURATION;
|
||||||
import static com.android.launcher3.QuickstepAppTransitionManagerImpl.STATUS_BAR_TRANSITION_DURATION;
|
import static com.android.launcher3.QuickstepAppTransitionManagerImpl.STATUS_BAR_TRANSITION_DURATION;
|
||||||
import static com.android.launcher3.QuickstepAppTransitionManagerImpl.STATUS_BAR_TRANSITION_PRE_DELAY;
|
import static com.android.launcher3.QuickstepAppTransitionManagerImpl.STATUS_BAR_TRANSITION_PRE_DELAY;
|
||||||
@@ -29,21 +32,32 @@ import android.animation.AnimatorSet;
|
|||||||
import android.app.ActivityOptions;
|
import android.app.ActivityOptions;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.android.launcher3.AbstractFloatingView;
|
||||||
import com.android.launcher3.DeviceProfile;
|
import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.InvariantDeviceProfile;
|
import com.android.launcher3.InvariantDeviceProfile;
|
||||||
import com.android.launcher3.LauncherAnimationRunner;
|
import com.android.launcher3.LauncherAnimationRunner;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.anim.Interpolators;
|
import com.android.launcher3.anim.Interpolators;
|
||||||
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||||
|
import com.android.launcher3.statemanager.StateManager;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateHandler;
|
||||||
|
import com.android.launcher3.statemanager.StatefulActivity;
|
||||||
|
import com.android.launcher3.util.ActivityTracker;
|
||||||
import com.android.launcher3.util.ObjectWrapper;
|
import com.android.launcher3.util.ObjectWrapper;
|
||||||
|
import com.android.launcher3.util.SystemUiController;
|
||||||
|
import com.android.launcher3.util.Themes;
|
||||||
import com.android.launcher3.views.BaseDragLayer;
|
import com.android.launcher3.views.BaseDragLayer;
|
||||||
|
import com.android.quickstep.fallback.FallbackRecentsStateController;
|
||||||
import com.android.quickstep.fallback.FallbackRecentsView;
|
import com.android.quickstep.fallback.FallbackRecentsView;
|
||||||
import com.android.quickstep.fallback.RecentsRootView;
|
import com.android.quickstep.fallback.RecentsRootView;
|
||||||
|
import com.android.quickstep.fallback.RecentsState;
|
||||||
|
import com.android.quickstep.views.OverviewActionsView;
|
||||||
import com.android.quickstep.views.TaskView;
|
import com.android.quickstep.views.TaskView;
|
||||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
import com.android.systemui.shared.system.ActivityOptionsCompat;
|
import com.android.systemui.shared.system.ActivityOptionsCompat;
|
||||||
@@ -51,26 +65,40 @@ import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
|
|||||||
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
|
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
|
||||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
|
|
||||||
|
import java.io.FileDescriptor;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A recents activity that shows the recently launched tasks as swipable task cards.
|
* A recents activity that shows the recently launched tasks as swipable task cards.
|
||||||
* See {@link com.android.quickstep.views.RecentsView}.
|
* See {@link com.android.quickstep.views.RecentsView}.
|
||||||
*/
|
*/
|
||||||
public final class RecentsActivity extends BaseRecentsActivity {
|
public final class RecentsActivity extends StatefulActivity<RecentsState> {
|
||||||
|
|
||||||
public static final String EXTRA_THUMBNAIL = "thumbnailData";
|
public static final String EXTRA_THUMBNAIL = "thumbnailData";
|
||||||
public static final String EXTRA_TASK_ID = "taskID";
|
public static final String EXTRA_TASK_ID = "taskID";
|
||||||
|
public static final ActivityTracker<RecentsActivity> ACTIVITY_TRACKER =
|
||||||
|
new ActivityTracker<>();
|
||||||
|
|
||||||
private Handler mUiHandler = new Handler(Looper.getMainLooper());
|
private Handler mUiHandler = new Handler(Looper.getMainLooper());
|
||||||
private RecentsRootView mRecentsRootView;
|
private RecentsRootView mRecentsRootView;
|
||||||
private FallbackRecentsView mFallbackRecentsView;
|
private FallbackRecentsView mFallbackRecentsView;
|
||||||
|
private OverviewActionsView mActionsView;
|
||||||
|
|
||||||
@Override
|
private Configuration mOldConfig;
|
||||||
|
|
||||||
|
private StateManager<RecentsState> mStateManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init drag layer and overview panel views.
|
||||||
|
*/
|
||||||
protected void initViews() {
|
protected void initViews() {
|
||||||
setContentView(R.layout.fallback_recents_activity);
|
setContentView(R.layout.fallback_recents_activity);
|
||||||
mRecentsRootView = findViewById(R.id.drag_layer);
|
mRecentsRootView = findViewById(R.id.drag_layer);
|
||||||
mFallbackRecentsView = findViewById(R.id.overview_panel);
|
mFallbackRecentsView = findViewById(R.id.overview_panel);
|
||||||
|
mActionsView = findViewById(R.id.overview_actions_view);
|
||||||
|
|
||||||
mRecentsRootView.recreateControllers();
|
mRecentsRootView.recreateControllers();
|
||||||
mFallbackRecentsView.init(findViewById(R.id.overview_actions_view));
|
mFallbackRecentsView.init(mActionsView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -103,25 +131,38 @@ public final class RecentsActivity extends BaseRecentsActivity {
|
|||||||
intent.removeExtra(EXTRA_TASK_ID);
|
intent.removeExtra(EXTRA_TASK_ID);
|
||||||
intent.removeExtra(EXTRA_THUMBNAIL);
|
intent.removeExtra(EXTRA_THUMBNAIL);
|
||||||
super.onNewIntent(intent);
|
super.onNewIntent(intent);
|
||||||
|
ACTIVITY_TRACKER.handleNewIntent(this, intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Logic for when device configuration changes (rotation, screen size change, multi-window,
|
||||||
|
* etc.)
|
||||||
|
*/
|
||||||
protected void onHandleConfigChanged() {
|
protected void onHandleConfigChanged() {
|
||||||
super.onHandleConfigChanged();
|
mUserEventDispatcher = null;
|
||||||
|
initDeviceProfile();
|
||||||
|
|
||||||
|
AbstractFloatingView.closeOpenViews(this, true,
|
||||||
|
AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE);
|
||||||
|
dispatchDeviceProfileChanged();
|
||||||
|
|
||||||
|
reapplyUi();
|
||||||
mRecentsRootView.recreateControllers();
|
mRecentsRootView.recreateControllers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
protected void reapplyUi() {
|
* Generate the device profile to use in this activity.
|
||||||
mRecentsRootView.dispatchInsets();
|
* @return device profile
|
||||||
}
|
*/
|
||||||
|
|
||||||
@Override
|
|
||||||
protected DeviceProfile createDeviceProfile() {
|
protected DeviceProfile createDeviceProfile() {
|
||||||
DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this);
|
DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this);
|
||||||
|
DeviceProfile dp1 = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this);
|
||||||
|
|
||||||
|
// In case we are reusing IDP, create a copy so that we don't conflict with Launcher
|
||||||
|
// activity.
|
||||||
return (mRecentsRootView != null) && isInMultiWindowMode()
|
return (mRecentsRootView != null) && isInMultiWindowMode()
|
||||||
? dp.getMultiWindowProfile(this, getMultiWindowDisplaySize())
|
? dp.getMultiWindowProfile(this, getMultiWindowDisplaySize())
|
||||||
: super.createDeviceProfile();
|
: dp1.copy(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -139,6 +180,10 @@ public final class RecentsActivity extends BaseRecentsActivity {
|
|||||||
return (T) mFallbackRecentsView;
|
return (T) mFallbackRecentsView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OverviewActionsView getActionsView() {
|
||||||
|
return mActionsView;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void returnToHomescreen() {
|
public void returnToHomescreen() {
|
||||||
super.returnToHomescreen();
|
super.returnToHomescreen();
|
||||||
@@ -160,12 +205,7 @@ public final class RecentsActivity extends BaseRecentsActivity {
|
|||||||
RemoteAnimationTargetCompat[] wallpaperTargets, AnimationResult result) {
|
RemoteAnimationTargetCompat[] wallpaperTargets, AnimationResult result) {
|
||||||
AnimatorSet anim = composeRecentsLaunchAnimator(taskView, appTargets,
|
AnimatorSet anim = composeRecentsLaunchAnimator(taskView, appTargets,
|
||||||
wallpaperTargets);
|
wallpaperTargets);
|
||||||
anim.addListener(new AnimatorListenerAdapter() {
|
anim.addListener(resetStateListener());
|
||||||
@Override
|
|
||||||
public void onAnimationEnd(Animator animation) {
|
|
||||||
mFallbackRecentsView.resetViewUI();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
result.setAnimation(anim, RecentsActivity.this);
|
result.setAnimation(anim, RecentsActivity.this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -193,12 +233,7 @@ public final class RecentsActivity extends BaseRecentsActivity {
|
|||||||
.createAdjacentPageAnimForTaskLaunch(taskView);
|
.createAdjacentPageAnimForTaskLaunch(taskView);
|
||||||
adjacentAnimation.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
|
adjacentAnimation.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
|
||||||
adjacentAnimation.setDuration(RECENTS_LAUNCH_DURATION);
|
adjacentAnimation.setDuration(RECENTS_LAUNCH_DURATION);
|
||||||
adjacentAnimation.addListener(new AnimatorListenerAdapter() {
|
adjacentAnimation.addListener(resetStateListener());
|
||||||
@Override
|
|
||||||
public void onAnimationEnd(Animator animation) {
|
|
||||||
mFallbackRecentsView.resetTaskVisuals();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
target.play(adjacentAnimation);
|
target.play(adjacentAnimation);
|
||||||
}
|
}
|
||||||
return target;
|
return target;
|
||||||
@@ -210,13 +245,14 @@ public final class RecentsActivity extends BaseRecentsActivity {
|
|||||||
// onActivityStart callback.
|
// onActivityStart callback.
|
||||||
mFallbackRecentsView.setContentAlpha(1);
|
mFallbackRecentsView.setContentAlpha(1);
|
||||||
super.onStart();
|
super.onStart();
|
||||||
mFallbackRecentsView.resetTaskVisuals();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
mFallbackRecentsView.reset();
|
|
||||||
|
// Workaround for b/78520668, explicitly trim memory once UI is hidden
|
||||||
|
onTrimMemory(TRIM_MEMORY_UI_HIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -228,4 +264,98 @@ public final class RecentsActivity extends BaseRecentsActivity {
|
|||||||
public void onTaskLaunched() {
|
public void onTaskLaunched() {
|
||||||
mFallbackRecentsView.resetTaskVisuals();
|
mFallbackRecentsView.resetTaskVisuals();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
mStateManager = new StateManager<>(this, RecentsState.DEFAULT);
|
||||||
|
|
||||||
|
mOldConfig = new Configuration(getResources().getConfiguration());
|
||||||
|
initDeviceProfile();
|
||||||
|
initViews();
|
||||||
|
|
||||||
|
getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
|
||||||
|
Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
|
||||||
|
ACTIVITY_TRACKER.handleCreate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConfigurationChanged(Configuration newConfig) {
|
||||||
|
int diff = newConfig.diff(mOldConfig);
|
||||||
|
if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) {
|
||||||
|
onHandleConfigChanged();
|
||||||
|
}
|
||||||
|
mOldConfig.setTo(newConfig);
|
||||||
|
super.onConfigurationChanged(newConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize/update the device profile.
|
||||||
|
*/
|
||||||
|
private void initDeviceProfile() {
|
||||||
|
mDeviceProfile = createDeviceProfile();
|
||||||
|
onDeviceProfileInitiated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnterAnimationComplete() {
|
||||||
|
super.onEnterAnimationComplete();
|
||||||
|
// After the transition to home, enable the high-res thumbnail loader if it wasn't enabled
|
||||||
|
// as a part of quickstep, so that high-res thumbnails can load the next time we enter
|
||||||
|
// overview
|
||||||
|
RecentsModel.INSTANCE.get(this).getThumbnailCache()
|
||||||
|
.getHighResLoadingState().setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTrimMemory(int level) {
|
||||||
|
super.onTrimMemory(level);
|
||||||
|
RecentsModel.INSTANCE.get(this).onTrimMemory(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
ACTIVITY_TRACKER.onActivityDestroyed(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
// TODO: Launch the task we came from
|
||||||
|
startHome();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startHome() {
|
||||||
|
startActivity(new Intent(Intent.ACTION_MAIN)
|
||||||
|
.addCategory(Intent.CATEGORY_HOME)
|
||||||
|
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected StateHandler<RecentsState>[] createStateHandlers() {
|
||||||
|
return new StateHandler[] { new FallbackRecentsStateController(this) };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StateManager<RecentsState> getStateManager() {
|
||||||
|
return mStateManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
|
||||||
|
super.dump(prefix, fd, writer, args);
|
||||||
|
writer.println(prefix + "Misc:");
|
||||||
|
dumpMisc(prefix + "\t", writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AnimatorListenerAdapter resetStateListener() {
|
||||||
|
return new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
mFallbackRecentsView.resetTaskVisuals();
|
||||||
|
mStateManager.reapplyState();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.content.Context;
|
|||||||
import android.graphics.Insets;
|
import android.graphics.Insets;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.android.launcher3.BaseActivity;
|
import com.android.launcher3.BaseActivity;
|
||||||
import com.android.launcher3.BaseDraggingActivity;
|
import com.android.launcher3.BaseDraggingActivity;
|
||||||
@@ -109,16 +110,26 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
|||||||
public void initOverlay(Task task, ThumbnailData thumbnail, Matrix matrix) {
|
public void initOverlay(Task task, ThumbnailData thumbnail, Matrix matrix) {
|
||||||
ImageActionsApi imageApi = new ImageActionsApi(
|
ImageActionsApi imageApi = new ImageActionsApi(
|
||||||
mApplicationContext, mThumbnailView::getThumbnail);
|
mApplicationContext, mThumbnailView::getThumbnail);
|
||||||
|
final boolean isAllowedByPolicy = thumbnail.isRealSnapshot;
|
||||||
|
|
||||||
getActionsView().setCallbacks(new OverlayUICallbacks() {
|
getActionsView().setCallbacks(new OverlayUICallbacks() {
|
||||||
@Override
|
@Override
|
||||||
public void onShare() {
|
public void onShare() {
|
||||||
imageApi.startShareActivity();
|
if (isAllowedByPolicy) {
|
||||||
|
imageApi.startShareActivity();
|
||||||
|
} else {
|
||||||
|
showBlockedByPolicyMessage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScreenshot() {
|
public void onScreenshot() {
|
||||||
imageApi.saveScreenshot(mThumbnailView.getThumbnail(),
|
if (isAllowedByPolicy) {
|
||||||
getTaskSnapshotBounds(), getTaskSnapshotInsets(), task.key.id);
|
imageApi.saveScreenshot(mThumbnailView.getThumbnail(),
|
||||||
|
getTaskSnapshotBounds(), getTaskSnapshotInsets(), task.key.id);
|
||||||
|
} else {
|
||||||
|
showBlockedByPolicyMessage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -152,6 +163,13 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
|||||||
// TODO: return the real insets
|
// TODO: return the real insets
|
||||||
return Insets.of(0, 0, 0, 0);
|
return Insets.of(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showBlockedByPolicyMessage() {
|
||||||
|
Toast.makeText(
|
||||||
|
mThumbnailView.getContext(),
|
||||||
|
R.string.blocked_by_policy,
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import com.android.launcher3.model.data.ItemInfo;
|
|||||||
import com.android.launcher3.statehandlers.DepthController;
|
import com.android.launcher3.statehandlers.DepthController;
|
||||||
import com.android.quickstep.util.AppWindowAnimationHelper;
|
import com.android.quickstep.util.AppWindowAnimationHelper;
|
||||||
import com.android.quickstep.util.MultiValueUpdateListener;
|
import com.android.quickstep.util.MultiValueUpdateListener;
|
||||||
|
import com.android.quickstep.util.TransformParams;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
import com.android.quickstep.views.TaskView;
|
import com.android.quickstep.views.TaskView;
|
||||||
import com.android.systemui.shared.recents.model.Task;
|
import com.android.systemui.shared.recents.model.Task;
|
||||||
@@ -132,11 +133,10 @@ public final class TaskViewUtils {
|
|||||||
final RemoteAnimationTargets targets =
|
final RemoteAnimationTargets targets =
|
||||||
new RemoteAnimationTargets(appTargets, wallpaperTargets, MODE_OPENING);
|
new RemoteAnimationTargets(appTargets, wallpaperTargets, MODE_OPENING);
|
||||||
targets.addDependentTransactionApplier(applier);
|
targets.addDependentTransactionApplier(applier);
|
||||||
AppWindowAnimationHelper.TransformParams params =
|
TransformParams params =
|
||||||
new AppWindowAnimationHelper.TransformParams()
|
new TransformParams()
|
||||||
.setSyncTransactionApplier(applier)
|
.setSyncTransactionApplier(applier)
|
||||||
.setTargetSet(targets)
|
.setTargetSet(targets);
|
||||||
.setLauncherOnTop(true);
|
|
||||||
|
|
||||||
AnimatorSet animatorSet = new AnimatorSet();
|
AnimatorSet animatorSet = new AnimatorSet();
|
||||||
final RecentsView recentsView = v.getRecentsView();
|
final RecentsView recentsView = v.getRecentsView();
|
||||||
@@ -150,7 +150,7 @@ public final class TaskViewUtils {
|
|||||||
final RectF mThumbnailRect;
|
final RectF mThumbnailRect;
|
||||||
|
|
||||||
{
|
{
|
||||||
inOutHelper.setTaskAlphaCallback((t, alpha) -> mTaskAlpha.value);
|
params.setTaskAlphaCallback((t, alpha) -> mTaskAlpha.value);
|
||||||
inOutHelper.prepareAnimation(
|
inOutHelper.prepareAnimation(
|
||||||
BaseActivity.fromContext(v.getContext()).getDeviceProfile());
|
BaseActivity.fromContext(v.getContext()).getDeviceProfile());
|
||||||
inOutHelper.fromTaskThumbnailView(v.getThumbnail(), (RecentsView) v.getParent(),
|
inOutHelper.fromTaskThumbnailView(v.getThumbnail(), (RecentsView) v.getParent(),
|
||||||
@@ -175,7 +175,7 @@ public final class TaskViewUtils {
|
|||||||
v.getRecentsView().getClipAnimationHelper();
|
v.getRecentsView().getClipAnimationHelper();
|
||||||
if (liveTileAnimationHelper != null) {
|
if (liveTileAnimationHelper != null) {
|
||||||
// Append the surface transform params for the live tile app.
|
// Append the surface transform params for the live tile app.
|
||||||
AppWindowAnimationHelper.TransformParams liveTileParams =
|
TransformParams liveTileParams =
|
||||||
v.getRecentsView().getLiveTileParams(true /* mightNeedToRefill */);
|
v.getRecentsView().getLiveTileParams(true /* mightNeedToRefill */);
|
||||||
if (liveTileParams != null) {
|
if (liveTileParams != null) {
|
||||||
SurfaceParams[] liveTileSurfaceParams =
|
SurfaceParams[] liveTileSurfaceParams =
|
||||||
@@ -186,7 +186,7 @@ public final class TaskViewUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Apply surface transform using the surface params list.
|
// Apply surface transform using the surface params list.
|
||||||
AppWindowAnimationHelper.applySurfaceParams(params.getSyncTransactionApplier(),
|
params.applySurfaceParams(
|
||||||
surfaceParamsList.toArray(new SurfaceParams[surfaceParamsList.size()]));
|
surfaceParamsList.toArray(new SurfaceParams[surfaceParamsList.size()]));
|
||||||
// Get the task bounds for the app that's being opened after surface transform
|
// Get the task bounds for the app that's being opened after surface transform
|
||||||
// update.
|
// update.
|
||||||
|
|||||||
+31
-21
@@ -30,8 +30,6 @@ import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYS
|
|||||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED;
|
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.app.ActivityManager.RunningTaskInfo;
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.RemoteAction;
|
import android.app.RemoteAction;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
@@ -40,6 +38,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.graphics.Rect;
|
||||||
import android.graphics.Region;
|
import android.graphics.Region;
|
||||||
import android.graphics.drawable.Icon;
|
import android.graphics.drawable.Icon;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@@ -71,6 +70,7 @@ import com.android.launcher3.tracing.nano.TouchInteractionServiceProto;
|
|||||||
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
||||||
import com.android.launcher3.util.OnboardingPrefs;
|
import com.android.launcher3.util.OnboardingPrefs;
|
||||||
import com.android.launcher3.util.TraceHelper;
|
import com.android.launcher3.util.TraceHelper;
|
||||||
|
import com.android.launcher3.util.WindowBounds;
|
||||||
import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
|
import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
|
||||||
import com.android.quickstep.inputconsumers.AssistantInputConsumer;
|
import com.android.quickstep.inputconsumers.AssistantInputConsumer;
|
||||||
import com.android.quickstep.inputconsumers.DeviceLockedInputConsumer;
|
import com.android.quickstep.inputconsumers.DeviceLockedInputConsumer;
|
||||||
@@ -83,6 +83,7 @@ import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer;
|
|||||||
import com.android.quickstep.util.ActiveGestureLog;
|
import com.android.quickstep.util.ActiveGestureLog;
|
||||||
import com.android.quickstep.util.AssistantUtilities;
|
import com.android.quickstep.util.AssistantUtilities;
|
||||||
import com.android.quickstep.util.ProtoTracer;
|
import com.android.quickstep.util.ProtoTracer;
|
||||||
|
import com.android.quickstep.util.SplitScreenBounds;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
import com.android.systemui.plugins.OverscrollPlugin;
|
import com.android.systemui.plugins.OverscrollPlugin;
|
||||||
import com.android.systemui.plugins.PluginListener;
|
import com.android.systemui.plugins.PluginListener;
|
||||||
@@ -120,7 +121,7 @@ class ArgList extends LinkedList<String> {
|
|||||||
/**
|
/**
|
||||||
* Service connected by system-UI for handling touch interaction.
|
* Service connected by system-UI for handling touch interaction.
|
||||||
*/
|
*/
|
||||||
@TargetApi(Build.VERSION_CODES.Q)
|
@TargetApi(Build.VERSION_CODES.R)
|
||||||
public class TouchInteractionService extends Service implements PluginListener<OverscrollPlugin>,
|
public class TouchInteractionService extends Service implements PluginListener<OverscrollPlugin>,
|
||||||
ProtoTraceable<LauncherTraceProto> {
|
ProtoTraceable<LauncherTraceProto> {
|
||||||
|
|
||||||
@@ -231,6 +232,11 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
|||||||
MAIN_EXECUTOR.execute(() -> mDeviceState.setDeferredGestureRegion(region));
|
MAIN_EXECUTOR.execute(() -> mDeviceState.setDeferredGestureRegion(region));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onSplitScreenSecondaryBoundsChanged(Rect bounds, Rect insets) {
|
||||||
|
WindowBounds wb = new WindowBounds(bounds, insets);
|
||||||
|
MAIN_EXECUTOR.execute(() -> SplitScreenBounds.INSTANCE.setSecondaryWindowBounds(wb));
|
||||||
|
}
|
||||||
|
|
||||||
/** Deprecated methods **/
|
/** Deprecated methods **/
|
||||||
public void onQuickStep(MotionEvent motionEvent) { }
|
public void onQuickStep(MotionEvent motionEvent) { }
|
||||||
|
|
||||||
@@ -518,8 +524,13 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
|||||||
private GestureState createGestureState() {
|
private GestureState createGestureState() {
|
||||||
GestureState gestureState = new GestureState(mOverviewComponentObserver,
|
GestureState gestureState = new GestureState(mOverviewComponentObserver,
|
||||||
ActiveGestureLog.INSTANCE.generateAndSetLogId());
|
ActiveGestureLog.INSTANCE.generateAndSetLogId());
|
||||||
gestureState.updateRunningTask(TraceHelper.whitelistIpcs("getRunningTask.0",
|
if (mTaskAnimationManager.isRecentsAnimationRunning()) {
|
||||||
() -> mAM.getRunningTask(false /* filterOnlyVisibleRecents */)));
|
gestureState.updateRunningTask(mGestureState.getRunningTask());
|
||||||
|
gestureState.updateLastStartedTaskId(mGestureState.getLastStartedTaskId());
|
||||||
|
} else {
|
||||||
|
gestureState.updateRunningTask(TraceHelper.whitelistIpcs("getRunningTask.0",
|
||||||
|
() -> mAM.getRunningTask(false /* filterOnlyVisibleRecents */)));
|
||||||
|
}
|
||||||
return gestureState;
|
return gestureState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,15 +610,24 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleOrientationSetup(InputConsumer baseInputConsumer) {
|
private void handleOrientationSetup(InputConsumer baseInputConsumer) {
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "handleOrientationSetup.1");
|
||||||
|
}
|
||||||
if (!isFixedRotationTransformEnabled(this)) {
|
if (!isFixedRotationTransformEnabled(this)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mDeviceState.enableMultipleRegions(baseInputConsumer instanceof OtherActivityInputConsumer);
|
mDeviceState.enableMultipleRegions(baseInputConsumer instanceof OtherActivityInputConsumer);
|
||||||
BaseDraggingActivity activity =
|
BaseDraggingActivity activity =
|
||||||
mOverviewComponentObserver.getActivityInterface().getCreatedActivity();
|
mOverviewComponentObserver.getActivityInterface().getCreatedActivity();
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "handleOrientationSetup.2");
|
||||||
|
}
|
||||||
if (activity == null || !(activity.getOverviewPanel() instanceof RecentsView)) {
|
if (activity == null || !(activity.getOverviewPanel() instanceof RecentsView)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "handleOrientationSetup.3");
|
||||||
|
}
|
||||||
((RecentsView) activity.getOverviewPanel())
|
((RecentsView) activity.getOverviewPanel())
|
||||||
.setLayoutRotation(mDeviceState.getCurrentActiveRotation(),
|
.setLayoutRotation(mDeviceState.getCurrentActiveRotation(),
|
||||||
mDeviceState.getDisplayRotation());
|
mDeviceState.getDisplayRotation());
|
||||||
@@ -637,14 +657,7 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
|||||||
runningComponent != null && runningComponent.equals(homeComponent);
|
runningComponent != null && runningComponent.equals(homeComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (previousGestureState.getFinishingRecentsAnimationTaskId() > 0) {
|
if (gestureState.getRunningTask() == null) {
|
||||||
// If the finish animation was interrupted, then continue using the other activity input
|
|
||||||
// consumer but with the next task as the running task
|
|
||||||
RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
|
|
||||||
info.id = previousGestureState.getFinishingRecentsAnimationTaskId();
|
|
||||||
gestureState.updateRunningTask(info);
|
|
||||||
return createOtherActivityInputConsumer(previousGestureState, gestureState, event);
|
|
||||||
} else if (gestureState.getRunningTask() == null) {
|
|
||||||
return mResetGestureInputConsumer;
|
return mResetGestureInputConsumer;
|
||||||
} else if (previousGestureState.isRunningAnimationToLauncher()
|
} else if (previousGestureState.isRunningAnimationToLauncher()
|
||||||
|| gestureState.getActivityInterface().isResumed()
|
|| gestureState.getActivityInterface().isResumed()
|
||||||
@@ -658,25 +671,22 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
|||||||
} else if (mDeviceState.isGestureBlockedActivity(gestureState.getRunningTask())) {
|
} else if (mDeviceState.isGestureBlockedActivity(gestureState.getRunningTask())) {
|
||||||
return mResetGestureInputConsumer;
|
return mResetGestureInputConsumer;
|
||||||
} else {
|
} else {
|
||||||
return createOtherActivityInputConsumer(previousGestureState, gestureState, event);
|
return createOtherActivityInputConsumer(gestureState, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputConsumer createOtherActivityInputConsumer(GestureState previousGestureState,
|
private InputConsumer createOtherActivityInputConsumer(GestureState gestureState,
|
||||||
GestureState gestureState, MotionEvent event) {
|
MotionEvent event) {
|
||||||
|
|
||||||
final boolean shouldDefer;
|
|
||||||
final BaseSwipeUpHandler.Factory factory;
|
final BaseSwipeUpHandler.Factory factory;
|
||||||
|
|
||||||
if (!mOverviewComponentObserver.isHomeAndOverviewSame()) {
|
if (!mOverviewComponentObserver.isHomeAndOverviewSame()) {
|
||||||
shouldDefer = previousGestureState.getFinishingRecentsAnimationTaskId() < 0;
|
|
||||||
factory = mFallbackSwipeHandlerFactory;
|
factory = mFallbackSwipeHandlerFactory;
|
||||||
} else {
|
} else {
|
||||||
shouldDefer = gestureState.getActivityInterface().deferStartingActivity(mDeviceState,
|
|
||||||
event);
|
|
||||||
factory = mLauncherSwipeHandlerFactory;
|
factory = mLauncherSwipeHandlerFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final boolean shouldDefer = !mOverviewComponentObserver.isHomeAndOverviewSame()
|
||||||
|
|| gestureState.getActivityInterface().deferStartingActivity(mDeviceState, event);
|
||||||
final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event);
|
final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event);
|
||||||
return new OtherActivityInputConsumer(this, mDeviceState, mTaskAnimationManager,
|
return new OtherActivityInputConsumer(this, mDeviceState, mTaskAnimationManager,
|
||||||
gestureState, shouldDefer, this::onConsumerInactive,
|
gestureState, shouldDefer, this::onConsumerInactive,
|
||||||
|
|||||||
+94
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.fallback;
|
||||||
|
|
||||||
|
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||||
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MODAL;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE;
|
||||||
|
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||||
|
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||||
|
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
|
||||||
|
import static com.android.quickstep.views.RecentsView.TASK_MODALNESS;
|
||||||
|
|
||||||
|
import com.android.launcher3.anim.PendingAnimation;
|
||||||
|
import com.android.launcher3.anim.PropertySetter;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateHandler;
|
||||||
|
import com.android.launcher3.states.StateAnimationConfig;
|
||||||
|
import com.android.launcher3.util.MultiValueAlpha;
|
||||||
|
import com.android.quickstep.RecentsActivity;
|
||||||
|
import com.android.quickstep.views.ClearAllButton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State controller for fallback recents activity
|
||||||
|
*/
|
||||||
|
public class FallbackRecentsStateController implements StateHandler<RecentsState> {
|
||||||
|
|
||||||
|
private final StateAnimationConfig mNoConfig = new StateAnimationConfig();
|
||||||
|
private final RecentsActivity mActivity;
|
||||||
|
private final FallbackRecentsView mRecentsView;
|
||||||
|
|
||||||
|
public FallbackRecentsStateController(RecentsActivity activity) {
|
||||||
|
mActivity = activity;
|
||||||
|
mRecentsView = activity.getOverviewPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setState(RecentsState state) {
|
||||||
|
mRecentsView.updateEmptyMessage();
|
||||||
|
mRecentsView.resetTaskVisuals();
|
||||||
|
setProperties(state, mNoConfig, PropertySetter.NO_ANIM_PROPERTY_SETTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setStateWithAnimation(RecentsState toState, StateAnimationConfig config,
|
||||||
|
PendingAnimation setter) {
|
||||||
|
if (!config.hasAnimationFlag(PLAY_ATOMIC_OVERVIEW_PEEK | PLAY_ATOMIC_OVERVIEW_SCALE)) {
|
||||||
|
// The entire recents animation is played atomically.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (config.hasAnimationFlag(SKIP_OVERVIEW)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// While animating into recents, update the visible task data as needed
|
||||||
|
setter.addOnFrameCallback(mRecentsView::loadVisibleTaskData);
|
||||||
|
mRecentsView.updateEmptyMessage();
|
||||||
|
|
||||||
|
setProperties(toState, config, setter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setProperties(RecentsState state, StateAnimationConfig config,
|
||||||
|
PropertySetter setter) {
|
||||||
|
float buttonAlpha = state.hasButtons() ? 1 : 0;
|
||||||
|
setter.setFloat(mRecentsView.getClearAllButton(), ClearAllButton.VISIBILITY_ALPHA,
|
||||||
|
buttonAlpha, LINEAR);
|
||||||
|
setter.setFloat(mActivity.getActionsView().getVisibilityAlpha(),
|
||||||
|
MultiValueAlpha.VALUE, buttonAlpha, LINEAR);
|
||||||
|
|
||||||
|
float[] scaleAndOffset = state.getOverviewScaleAndOffset(mActivity);
|
||||||
|
setter.setFloat(mRecentsView, SCALE_PROPERTY, scaleAndOffset[0],
|
||||||
|
config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR));
|
||||||
|
setter.setFloat(mRecentsView, ADJACENT_PAGE_OFFSET, scaleAndOffset[1],
|
||||||
|
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR));
|
||||||
|
|
||||||
|
setter.setFloat(mRecentsView, TASK_MODALNESS, state.getOverviewModalness(),
|
||||||
|
config.getInterpolator(ANIM_OVERVIEW_MODAL, LINEAR));
|
||||||
|
setter.setFloat(mRecentsView, FULLSCREEN_PROGRESS, state.isFullScreen() ? 1 : 0, LINEAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
+42
-84
@@ -15,17 +15,17 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.quickstep.fallback;
|
package com.android.quickstep.fallback;
|
||||||
|
|
||||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
import static com.android.quickstep.fallback.RecentsState.DEFAULT;
|
||||||
|
import static com.android.quickstep.fallback.RecentsState.MODAL_TASK;
|
||||||
import static com.android.quickstep.util.WindowSizeStrategy.FALLBACK_RECENTS_SIZE_STRATEGY;
|
import static com.android.quickstep.util.WindowSizeStrategy.FALLBACK_RECENTS_SIZE_STRATEGY;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.app.ActivityManager.RunningTaskInfo;
|
import android.app.ActivityManager.RunningTaskInfo;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Canvas;
|
import android.os.Build;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.FloatProperty;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||||
import com.android.quickstep.RecentsActivity;
|
import com.android.quickstep.RecentsActivity;
|
||||||
import com.android.quickstep.views.OverviewActionsView;
|
import com.android.quickstep.views.OverviewActionsView;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
@@ -34,26 +34,9 @@ import com.android.systemui.shared.recents.model.Task.TaskKey;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class FallbackRecentsView extends RecentsView<RecentsActivity> {
|
@TargetApi(Build.VERSION_CODES.R)
|
||||||
|
public class FallbackRecentsView extends RecentsView<RecentsActivity>
|
||||||
public static final FloatProperty<FallbackRecentsView> ZOOM_PROGRESS =
|
implements StateListener<RecentsState> {
|
||||||
new FloatProperty<FallbackRecentsView> ("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 RunningTaskInfo mRunningTaskInfo;
|
private RunningTaskInfo mRunningTaskInfo;
|
||||||
|
|
||||||
@@ -63,6 +46,7 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
|
|||||||
|
|
||||||
public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
|
public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr, FALLBACK_RECENTS_SIZE_STRATEGY);
|
super(context, attrs, defStyleAttr, FALLBACK_RECENTS_SIZE_STRATEGY);
|
||||||
|
mActivity.getStateManager().addStateListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -77,71 +61,12 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
|
|||||||
mActivity.startHome();
|
mActivity.startHome();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewAdded(View child) {
|
|
||||||
super.onViewAdded(child);
|
|
||||||
updateEmptyMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewRemoved(View child) {
|
|
||||||
super.onViewRemoved(child);
|
|
||||||
updateEmptyMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(Canvas canvas) {
|
|
||||||
maybeDrawEmptyMessage(canvas);
|
|
||||||
super.draw(canvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
super.reset();
|
|
||||||
resetViewUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldUseMultiWindowTaskSizeStrategy() {
|
public boolean shouldUseMultiWindowTaskSizeStrategy() {
|
||||||
// Just use the activity task size for multi-window as well.
|
// Just use the activity task size for multi-window as well.
|
||||||
return false;
|
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
|
|
||||||
public void resetTaskVisuals() {
|
|
||||||
super.resetTaskVisuals();
|
|
||||||
setFullscreenProgress(mFullscreenProgress);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
||||||
super.onLayout(changed, left, top, right, bottom);
|
|
||||||
mZoomScale = getMaxScaleForFullScreen();
|
|
||||||
setZoomProgress(mZoomInProgress);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setZoomProgress(float progress) {
|
|
||||||
mZoomInProgress = progress;
|
|
||||||
SCALE_PROPERTY.set(this, Utilities.mapRange(mZoomInProgress, 1, mZoomScale));
|
|
||||||
FULLSCREEN_PROGRESS.set(this, mZoomInProgress);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onGestureAnimationStart(RunningTaskInfo runningTaskInfo) {
|
public void onGestureAnimationStart(RunningTaskInfo runningTaskInfo) {
|
||||||
mRunningTaskInfo = runningTaskInfo;
|
mRunningTaskInfo = runningTaskInfo;
|
||||||
onGestureAnimationStart(runningTaskInfo == null ? -1 : runningTaskInfo.taskId);
|
onGestureAnimationStart(runningTaskInfo == null ? -1 : runningTaskInfo.taskId);
|
||||||
@@ -178,4 +103,37 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
|
|||||||
}
|
}
|
||||||
super.applyLoadPlan(tasks);
|
super.applyLoadPlan(tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setModalStateEnabled(boolean isModalState) {
|
||||||
|
super.setModalStateEnabled(isModalState);
|
||||||
|
if (isModalState) {
|
||||||
|
mActivity.getStateManager().goToState(RecentsState.MODAL_TASK);
|
||||||
|
} else {
|
||||||
|
if (mActivity.isInState(RecentsState.MODAL_TASK)) {
|
||||||
|
mActivity.getStateManager().goToState(DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStateTransitionStart(RecentsState toState) {
|
||||||
|
setOverviewStateEnabled(true);
|
||||||
|
setFreezeViewVisibility(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStateTransitionComplete(RecentsState finalState) {
|
||||||
|
setOverlayEnabled(finalState == DEFAULT || finalState == MODAL_TASK);
|
||||||
|
setFreezeViewVisibility(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOverviewStateEnabled(boolean enabled) {
|
||||||
|
super.setOverviewStateEnabled(enabled);
|
||||||
|
if (enabled) {
|
||||||
|
RecentsState state = mActivity.getStateManager().getState();
|
||||||
|
setDisallowScrollToClearAll(!state.hasButtons());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.fallback;
|
||||||
|
|
||||||
|
import static com.android.launcher3.uioverrides.states.BackgroundAppState.getOverviewScaleAndOffsetForBackgroundState;
|
||||||
|
import static com.android.launcher3.uioverrides.states.OverviewModalTaskState.getOverviewScaleAndOffsetForModalState;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.android.launcher3.statemanager.BaseState;
|
||||||
|
import com.android.quickstep.RecentsActivity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State definition for Fallback recents
|
||||||
|
*/
|
||||||
|
public class RecentsState implements BaseState<RecentsState> {
|
||||||
|
|
||||||
|
private static final int FLAG_MODAL = BaseState.getFlag(0);
|
||||||
|
private static final int FLAG_HAS_BUTTONS = BaseState.getFlag(1);
|
||||||
|
private static final int FLAG_FULL_SCREEN = BaseState.getFlag(2);
|
||||||
|
|
||||||
|
public static final RecentsState DEFAULT = new RecentsState(0, FLAG_HAS_BUTTONS);
|
||||||
|
public static final RecentsState MODAL_TASK = new ModalState(1,
|
||||||
|
FLAG_DISABLE_RESTORE | FLAG_HAS_BUTTONS | FLAG_MODAL);
|
||||||
|
public static final RecentsState BACKGROUND_APP = new BackgroundAppState(2,
|
||||||
|
FLAG_DISABLE_RESTORE | FLAG_NON_INTERACTIVE | FLAG_FULL_SCREEN);
|
||||||
|
|
||||||
|
public final int ordinal;
|
||||||
|
private final int mFlags;
|
||||||
|
|
||||||
|
private static final float NO_OFFSET = 0;
|
||||||
|
private static final float NO_SCALE = 1;
|
||||||
|
|
||||||
|
public RecentsState(int id, int flags) {
|
||||||
|
this.ordinal = id;
|
||||||
|
this.mFlags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Ordinal-" + ordinal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean hasFlag(int mask) {
|
||||||
|
return (mFlags & mask) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTransitionDuration(Context context) {
|
||||||
|
return 250;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecentsState getHistoryForState(RecentsState previousState) {
|
||||||
|
return DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For this state, how modal should over view been shown. 0 modalness means all tasks drawn,
|
||||||
|
* 1 modalness means the current task is show on its own.
|
||||||
|
*/
|
||||||
|
public float getOverviewModalness() {
|
||||||
|
return hasFlag(FLAG_MODAL) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFullScreen() {
|
||||||
|
return hasFlag(FLAG_FULL_SCREEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasButtons() {
|
||||||
|
return hasFlag(FLAG_HAS_BUTTONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
|
||||||
|
return new float[] { NO_SCALE, NO_OFFSET };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class ModalState extends RecentsState {
|
||||||
|
|
||||||
|
public ModalState(int id, int flags) {
|
||||||
|
super(id, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
|
||||||
|
return getOverviewScaleAndOffsetForModalState(activity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class BackgroundAppState extends RecentsState {
|
||||||
|
public BackgroundAppState(int id, int flags) {
|
||||||
|
super(id, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
|
||||||
|
return getOverviewScaleAndOffsetForBackgroundState(activity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-6
@@ -21,8 +21,8 @@ import static android.view.MotionEvent.ACTION_UP;
|
|||||||
|
|
||||||
import static com.android.launcher3.Utilities.squaredHypot;
|
import static com.android.launcher3.Utilities.squaredHypot;
|
||||||
import static com.android.launcher3.Utilities.squaredTouchSlop;
|
import static com.android.launcher3.Utilities.squaredTouchSlop;
|
||||||
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
|
|
||||||
import static com.android.quickstep.LauncherSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW;
|
import static com.android.quickstep.LauncherSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW;
|
||||||
|
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
|
||||||
import static com.android.quickstep.util.ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID;
|
import static com.android.quickstep.util.ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID;
|
||||||
|
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
@@ -44,12 +44,13 @@ import com.android.quickstep.GestureState;
|
|||||||
import com.android.quickstep.InputConsumer;
|
import com.android.quickstep.InputConsumer;
|
||||||
import com.android.quickstep.LockScreenRecentsActivity;
|
import com.android.quickstep.LockScreenRecentsActivity;
|
||||||
import com.android.quickstep.MultiStateCallback;
|
import com.android.quickstep.MultiStateCallback;
|
||||||
|
import com.android.quickstep.RecentsAnimationCallbacks;
|
||||||
import com.android.quickstep.RecentsAnimationController;
|
import com.android.quickstep.RecentsAnimationController;
|
||||||
import com.android.quickstep.RecentsAnimationDeviceState;
|
import com.android.quickstep.RecentsAnimationDeviceState;
|
||||||
import com.android.quickstep.RecentsAnimationCallbacks;
|
|
||||||
import com.android.quickstep.RecentsAnimationTargets;
|
import com.android.quickstep.RecentsAnimationTargets;
|
||||||
import com.android.quickstep.TaskAnimationManager;
|
import com.android.quickstep.TaskAnimationManager;
|
||||||
import com.android.quickstep.util.AppWindowAnimationHelper;
|
import com.android.quickstep.util.AppWindowAnimationHelper;
|
||||||
|
import com.android.quickstep.util.TransformParams;
|
||||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
import com.android.systemui.shared.system.InputMonitorCompat;
|
import com.android.systemui.shared.system.InputMonitorCompat;
|
||||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
@@ -84,7 +85,7 @@ public class DeviceLockedInputConsumer implements InputConsumer,
|
|||||||
|
|
||||||
private final PointF mTouchDown = new PointF();
|
private final PointF mTouchDown = new PointF();
|
||||||
private final AppWindowAnimationHelper mAppWindowAnimationHelper;
|
private final AppWindowAnimationHelper mAppWindowAnimationHelper;
|
||||||
private final AppWindowAnimationHelper.TransformParams mTransformParams;
|
private final TransformParams mTransformParams;
|
||||||
private final Point mDisplaySize;
|
private final Point mDisplaySize;
|
||||||
private final MultiStateCallback mStateCallback;
|
private final MultiStateCallback mStateCallback;
|
||||||
|
|
||||||
@@ -105,7 +106,7 @@ public class DeviceLockedInputConsumer implements InputConsumer,
|
|||||||
mGestureState = gestureState;
|
mGestureState = gestureState;
|
||||||
mTouchSlopSquared = squaredTouchSlop(context);
|
mTouchSlopSquared = squaredTouchSlop(context);
|
||||||
mAppWindowAnimationHelper = new AppWindowAnimationHelper(context);
|
mAppWindowAnimationHelper = new AppWindowAnimationHelper(context);
|
||||||
mTransformParams = new AppWindowAnimationHelper.TransformParams();
|
mTransformParams = new TransformParams();
|
||||||
mInputMonitorCompat = inputMonitorCompat;
|
mInputMonitorCompat = inputMonitorCompat;
|
||||||
|
|
||||||
// Do not use DeviceProfile as the user data might be locked
|
// Do not use DeviceProfile as the user data might be locked
|
||||||
@@ -230,8 +231,7 @@ public class DeviceLockedInputConsumer implements InputConsumer,
|
|||||||
|
|
||||||
Utilities.scaleRectAboutCenter(displaySize, SCALE_DOWN);
|
Utilities.scaleRectAboutCenter(displaySize, SCALE_DOWN);
|
||||||
displaySize.offsetTo(displaySize.left, 0);
|
displaySize.offsetTo(displaySize.left, 0);
|
||||||
mTransformParams.setTargetSet(mRecentsAnimationTargets)
|
mTransformParams.setTargetSet(mRecentsAnimationTargets);
|
||||||
.setLauncherOnTop(true);
|
|
||||||
mAppWindowAnimationHelper.updateTargetRect(displaySize);
|
mAppWindowAnimationHelper.updateTargetRect(displaySize);
|
||||||
mAppWindowAnimationHelper.applyTransform(mTransformParams);
|
mAppWindowAnimationHelper.applyTransform(mTransformParams);
|
||||||
|
|
||||||
|
|||||||
+4
@@ -18,6 +18,7 @@ package com.android.quickstep.inputconsumers;
|
|||||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
@@ -95,6 +96,9 @@ public class OverviewInputConsumer<T extends BaseDraggingActivity>
|
|||||||
ev.setEdgeFlags(flags | Utilities.EDGE_NAV_BAR);
|
ev.setEdgeFlags(flags | Utilities.EDGE_NAV_BAR);
|
||||||
}
|
}
|
||||||
ev.offsetLocation(-mLocationOnScreen[0], -mLocationOnScreen[1]);
|
ev.offsetLocation(-mLocationOnScreen[0], -mLocationOnScreen[1]);
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "OverviewInputConsumer");
|
||||||
|
}
|
||||||
boolean handled = mEventReceiver.test(ev);
|
boolean handled = mEventReceiver.test(ev);
|
||||||
ev.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
|
ev.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
|
||||||
ev.setEdgeFlags(flags);
|
ev.setEdgeFlags(flags);
|
||||||
|
|||||||
+41
-259
@@ -15,11 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.quickstep.util;
|
package com.android.quickstep.util;
|
||||||
|
|
||||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
import static com.android.launcher3.Utilities.boundToRange;
|
||||||
|
import static com.android.launcher3.Utilities.mapRange;
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius;
|
import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius;
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.supportsRoundedCornersOnWindows;
|
import static com.android.systemui.shared.system.QuickStepContract.supportsRoundedCornersOnWindows;
|
||||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
|
|
||||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -36,9 +35,7 @@ import com.android.launcher3.BaseDraggingActivity;
|
|||||||
import com.android.launcher3.DeviceProfile;
|
import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.anim.Interpolators;
|
|
||||||
import com.android.launcher3.views.BaseDragLayer;
|
import com.android.launcher3.views.BaseDragLayer;
|
||||||
import com.android.quickstep.RemoteAnimationTargets;
|
|
||||||
import com.android.quickstep.SystemUiProxy;
|
import com.android.quickstep.SystemUiProxy;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
import com.android.quickstep.views.TaskThumbnailView;
|
import com.android.quickstep.views.TaskThumbnailView;
|
||||||
@@ -46,14 +43,14 @@ import com.android.systemui.shared.recents.utilities.RectFEvaluator;
|
|||||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
||||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
|
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
|
||||||
import com.android.systemui.shared.system.TransactionCompat;
|
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder;
|
||||||
import com.android.systemui.shared.system.WindowManagerWrapper;
|
import com.android.systemui.shared.system.WindowManagerWrapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to handle window clip animation
|
* Utility class to handle window clip animation
|
||||||
*/
|
*/
|
||||||
@TargetApi(Build.VERSION_CODES.P)
|
@TargetApi(Build.VERSION_CODES.P)
|
||||||
public class AppWindowAnimationHelper {
|
public class AppWindowAnimationHelper implements TransformParams.BuilderProxy {
|
||||||
|
|
||||||
// The bounds of the source app in device coordinates
|
// The bounds of the source app in device coordinates
|
||||||
private final RectF mSourceStackBounds = new RectF();
|
private final RectF mSourceStackBounds = new RectF();
|
||||||
@@ -94,9 +91,6 @@ public class AppWindowAnimationHelper {
|
|||||||
// Corner radius currently applied to transformed window.
|
// Corner radius currently applied to transformed window.
|
||||||
private float mCurrentCornerRadius;
|
private float mCurrentCornerRadius;
|
||||||
|
|
||||||
private TargetAlphaProvider mTaskAlphaCallback = (t, a) -> a;
|
|
||||||
private TargetAlphaProvider mBaseAlphaCallback = (t, a) -> 1;
|
|
||||||
|
|
||||||
public AppWindowAnimationHelper(RecentsOrientedState orientedState, Context context) {
|
public AppWindowAnimationHelper(RecentsOrientedState orientedState, Context context) {
|
||||||
Resources res = context.getResources();
|
Resources res = context.getResources();
|
||||||
mOrientedState = orientedState;
|
mOrientedState = orientedState;
|
||||||
@@ -167,7 +161,7 @@ public class AppWindowAnimationHelper {
|
|||||||
if (surfaceParams == null) {
|
if (surfaceParams == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
applySurfaceParams(params.mSyncTransactionApplier, surfaceParams);
|
params.applySurfaceParams(surfaceParams);
|
||||||
return mCurrentRect;
|
return mCurrentRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,97 +170,60 @@ public class AppWindowAnimationHelper {
|
|||||||
* the SurfaceParams to apply via {@link SyncRtSurfaceTransactionApplierCompat#applyParams}.
|
* the SurfaceParams to apply via {@link SyncRtSurfaceTransactionApplierCompat#applyParams}.
|
||||||
*/
|
*/
|
||||||
public SurfaceParams[] computeSurfaceParams(TransformParams params) {
|
public SurfaceParams[] computeSurfaceParams(TransformParams params) {
|
||||||
if (params.mTargetSet == null) {
|
if (params.getTargetSet() == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
float progress = Utilities.boundToRange(params.mProgress, 0, 1);
|
|
||||||
updateCurrentRect(params);
|
updateCurrentRect(params);
|
||||||
|
return params.createSurfaceParams(this);
|
||||||
|
}
|
||||||
|
|
||||||
SurfaceParams[] surfaceParams = new SurfaceParams[params.mTargetSet.unfilteredApps.length];
|
@Override
|
||||||
for (int i = 0; i < params.mTargetSet.unfilteredApps.length; i++) {
|
public void onBuildParams(Builder builder, RemoteAnimationTargetCompat app,
|
||||||
RemoteAnimationTargetCompat app = params.mTargetSet.unfilteredApps[i];
|
int targetMode, TransformParams params) {
|
||||||
SurfaceParams.Builder builder = new SurfaceParams.Builder(app.leash);
|
Rect crop = mTmpRect;
|
||||||
|
crop.set(app.screenSpaceBounds);
|
||||||
|
crop.offsetTo(0, 0);
|
||||||
|
float cornerRadius = 0f;
|
||||||
|
float scale = Math.max(mCurrentRect.width(), mTargetRect.width()) / crop.width();
|
||||||
|
if (app.mode == targetMode
|
||||||
|
&& app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
|
||||||
|
mTmpMatrix.setRectToRect(mSourceRect, mCurrentRect, ScaleToFit.FILL);
|
||||||
if (app.localBounds != null) {
|
if (app.localBounds != null) {
|
||||||
mTmpMatrix.setTranslate(0, 0);
|
mTmpMatrix.postTranslate(app.localBounds.left, app.localBounds.top);
|
||||||
if (app.activityType == ACTIVITY_TYPE_HOME && app.mode == MODE_CLOSING) {
|
|
||||||
mTmpMatrix.setTranslate(app.localBounds.left, app.localBounds.top);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
mTmpMatrix.setTranslate(app.position.x, app.position.y);
|
mTmpMatrix.postTranslate(app.position.x, app.position.y);
|
||||||
|
}
|
||||||
|
mCurrentClipRectF.roundOut(crop);
|
||||||
|
if (mSupportsRoundedCornersOnWindows) {
|
||||||
|
if (params.getCornerRadius() > -1) {
|
||||||
|
cornerRadius = params.getCornerRadius();
|
||||||
|
scale = mCurrentRect.width() / crop.width();
|
||||||
|
} else {
|
||||||
|
float windowCornerRadius = mUseRoundedCornersOnWindows
|
||||||
|
? mWindowCornerRadius : 0;
|
||||||
|
cornerRadius = mapRange(boundToRange(params.getProgress(), 0, 1),
|
||||||
|
windowCornerRadius, mTaskCornerRadius);
|
||||||
|
}
|
||||||
|
mCurrentCornerRadius = cornerRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect crop = mTmpRect;
|
builder.withMatrix(mTmpMatrix)
|
||||||
crop.set(app.screenSpaceBounds);
|
|
||||||
crop.offsetTo(0, 0);
|
|
||||||
float alpha;
|
|
||||||
float cornerRadius = 0f;
|
|
||||||
float scale = Math.max(mCurrentRect.width(), mTargetRect.width()) / crop.width();
|
|
||||||
if (app.mode == params.mTargetSet.targetMode) {
|
|
||||||
alpha = mTaskAlphaCallback.getAlpha(app, params.mTargetAlpha);
|
|
||||||
if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
|
|
||||||
mTmpMatrix.setRectToRect(mSourceRect, mCurrentRect, ScaleToFit.FILL);
|
|
||||||
if (app.localBounds != null) {
|
|
||||||
mTmpMatrix.postTranslate(app.localBounds.left, app.localBounds.top);
|
|
||||||
} else {
|
|
||||||
mTmpMatrix.postTranslate(app.position.x, app.position.y);
|
|
||||||
}
|
|
||||||
mCurrentClipRectF.roundOut(crop);
|
|
||||||
if (mSupportsRoundedCornersOnWindows) {
|
|
||||||
if (params.mCornerRadius > -1) {
|
|
||||||
cornerRadius = params.mCornerRadius;
|
|
||||||
scale = mCurrentRect.width() / crop.width();
|
|
||||||
} else {
|
|
||||||
float windowCornerRadius = mUseRoundedCornersOnWindows
|
|
||||||
? mWindowCornerRadius : 0;
|
|
||||||
cornerRadius = Utilities.mapRange(progress, windowCornerRadius,
|
|
||||||
mTaskCornerRadius);
|
|
||||||
}
|
|
||||||
mCurrentCornerRadius = cornerRadius;
|
|
||||||
}
|
|
||||||
// Fade out Assistant overlay.
|
|
||||||
if (app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT
|
|
||||||
&& app.isNotInRecents) {
|
|
||||||
alpha = 1 - Interpolators.DEACCEL_2_5.getInterpolation(progress);
|
|
||||||
}
|
|
||||||
} else if (params.mTargetSet.hasRecents) {
|
|
||||||
// If home has a different target then recents, reverse anim the
|
|
||||||
// home target.
|
|
||||||
alpha = 1 - (progress * params.mTargetAlpha);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
alpha = mBaseAlphaCallback.getAlpha(app, progress);
|
|
||||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && params.mLauncherOnTop) {
|
|
||||||
crop = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.withAlpha(alpha)
|
|
||||||
.withMatrix(mTmpMatrix)
|
|
||||||
.withWindowCrop(crop)
|
.withWindowCrop(crop)
|
||||||
// Since radius is in Surface space, but we draw the rounded corners in screen
|
// Since radius is in Surface space, but we draw the rounded corners in screen
|
||||||
// space, we have to undo the scale
|
// space, we have to undo the scale
|
||||||
.withCornerRadius(cornerRadius / scale);
|
.withCornerRadius(cornerRadius / scale);
|
||||||
surfaceParams[i] = builder.build();
|
|
||||||
}
|
}
|
||||||
return surfaceParams;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RectF updateCurrentRect(TransformParams params) {
|
public RectF updateCurrentRect(TransformParams params) {
|
||||||
if (params.mCurrentRect != null) {
|
if (params.getCurrentRect() != null) {
|
||||||
mCurrentRect.set(params.mCurrentRect);
|
mCurrentRect.set(params.getCurrentRect());
|
||||||
} else {
|
} else {
|
||||||
mTmpRectF.set(mTargetRect);
|
mTmpRectF.set(mTargetRect);
|
||||||
Utilities.scaleRectFAboutCenter(mTmpRectF, params.mOffsetScale);
|
mCurrentRect.set(mRectFEvaluator.evaluate(
|
||||||
mCurrentRect.set(mRectFEvaluator.evaluate(params.mProgress, mSourceRect, mTmpRectF));
|
params.getProgress(), mSourceRect, mTmpRectF));
|
||||||
if (mOrientedState == null
|
|
||||||
|| !mOrientedState.isMultipleOrientationSupportedByDevice()) {
|
|
||||||
mCurrentRect.offset(params.mOffset, 0);
|
|
||||||
} else {
|
|
||||||
int displayRotation = mOrientedState.getDisplayRotation();
|
|
||||||
int launcherRotation = mOrientedState.getLauncherRotation();
|
|
||||||
mOrientedState.getOrientationHandler().offsetTaskRect(mCurrentRect,
|
|
||||||
params.mOffset, displayRotation, launcherRotation);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateClipRect(params);
|
updateClipRect(params);
|
||||||
@@ -275,7 +232,7 @@ public class AppWindowAnimationHelper {
|
|||||||
|
|
||||||
private void updateClipRect(TransformParams params) {
|
private void updateClipRect(TransformParams params) {
|
||||||
// Don't clip past progress > 1.
|
// Don't clip past progress > 1.
|
||||||
float progress = Math.min(1, params.mProgress);
|
float progress = Math.min(1, params.getProgress());
|
||||||
mCurrentClipRectF.left = mSourceWindowClipInsets.left * progress;
|
mCurrentClipRectF.left = mSourceWindowClipInsets.left * progress;
|
||||||
mCurrentClipRectF.top = mSourceWindowClipInsets.top * progress;
|
mCurrentClipRectF.top = mSourceWindowClipInsets.top * progress;
|
||||||
mCurrentClipRectF.right =
|
mCurrentClipRectF.right =
|
||||||
@@ -289,28 +246,6 @@ public class AppWindowAnimationHelper {
|
|||||||
return mCurrentRectWithInsets;
|
return mCurrentRectWithInsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void applySurfaceParams(@Nullable SyncRtSurfaceTransactionApplierCompat
|
|
||||||
syncTransactionApplier, SurfaceParams[] params) {
|
|
||||||
if (syncTransactionApplier != null) {
|
|
||||||
syncTransactionApplier.scheduleApply(params);
|
|
||||||
} else {
|
|
||||||
TransactionCompat t = new TransactionCompat();
|
|
||||||
for (SurfaceParams param : params) {
|
|
||||||
SyncRtSurfaceTransactionApplierCompat.applyParams(t, param);
|
|
||||||
}
|
|
||||||
t.setEarlyWakeup();
|
|
||||||
t.apply();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTaskAlphaCallback(TargetAlphaProvider callback) {
|
|
||||||
mTaskAlphaCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBaseAlphaCallback(TargetAlphaProvider callback) {
|
|
||||||
mBaseAlphaCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fromTaskThumbnailView(TaskThumbnailView ttv, RecentsView rv,
|
public void fromTaskThumbnailView(TaskThumbnailView ttv, RecentsView rv,
|
||||||
@Nullable RemoteAnimationTargetCompat target) {
|
@Nullable RemoteAnimationTargetCompat target) {
|
||||||
BaseDraggingActivity activity = BaseDraggingActivity.fromContext(ttv.getContext());
|
BaseDraggingActivity activity = BaseDraggingActivity.fromContext(ttv.getContext());
|
||||||
@@ -386,157 +321,4 @@ public class AppWindowAnimationHelper {
|
|||||||
return mCurrentCornerRadius;
|
return mCurrentCornerRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface TargetAlphaProvider {
|
|
||||||
float getAlpha(RemoteAnimationTargetCompat target, float expectedAlpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class TransformParams {
|
|
||||||
private float mProgress;
|
|
||||||
private float mOffset;
|
|
||||||
private float mOffsetScale;
|
|
||||||
private @Nullable RectF mCurrentRect;
|
|
||||||
private float mTargetAlpha;
|
|
||||||
private float mCornerRadius;
|
|
||||||
private boolean mLauncherOnTop;
|
|
||||||
private RemoteAnimationTargets mTargetSet;
|
|
||||||
private SyncRtSurfaceTransactionApplierCompat mSyncTransactionApplier;
|
|
||||||
|
|
||||||
public TransformParams() {
|
|
||||||
mProgress = 0;
|
|
||||||
mOffset = 0;
|
|
||||||
mOffsetScale = 1;
|
|
||||||
mCurrentRect = null;
|
|
||||||
mTargetAlpha = 1;
|
|
||||||
mCornerRadius = -1;
|
|
||||||
mLauncherOnTop = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the progress of the transformation, where 0 is the source and 1 is the target. We
|
|
||||||
* automatically adjust properties such as currentRect and cornerRadius based on this
|
|
||||||
* progress, unless they are manually overridden by setting them on this TransformParams.
|
|
||||||
*/
|
|
||||||
public TransformParams setProgress(float progress) {
|
|
||||||
mProgress = progress;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the corner radius of the transformed window, in pixels. If unspecified (-1), we
|
|
||||||
* simply interpolate between the window's corner radius to the task view's corner radius,
|
|
||||||
* based on {@link #mProgress}.
|
|
||||||
*/
|
|
||||||
public TransformParams setCornerRadius(float cornerRadius) {
|
|
||||||
mCornerRadius = cornerRadius;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the current rect to show the transformed window, in device coordinates. This gives
|
|
||||||
* the caller manual control of where to show the window. If unspecified (null), we
|
|
||||||
* interpolate between {@link AppWindowAnimationHelper#mSourceRect} and
|
|
||||||
* {@link AppWindowAnimationHelper#mTargetRect}, based on {@link #mProgress}.
|
|
||||||
*/
|
|
||||||
public TransformParams setCurrentRect(RectF currentRect) {
|
|
||||||
mCurrentRect = currentRect;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the alpha of the transformed window. Default is 1.
|
|
||||||
*/
|
|
||||||
public TransformParams setTargetAlpha(float targetAlpha) {
|
|
||||||
mTargetAlpha = targetAlpha;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If {@link #mCurrentRect} is null (i.e. {@link #setCurrentRect(RectF)} hasn't overridden
|
|
||||||
* the default), then offset the current rect by this amount after computing the rect based
|
|
||||||
* on {@link #mProgress}.
|
|
||||||
*/
|
|
||||||
public TransformParams setOffset(float offset) {
|
|
||||||
mOffset = offset;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If {@link #mCurrentRect} is null (i.e. {@link #setCurrentRect(RectF)} hasn't overridden
|
|
||||||
* the default), then scale the current rect by this amount after computing the rect based
|
|
||||||
* on {@link #mProgress}.
|
|
||||||
*/
|
|
||||||
public TransformParams setOffsetScale(float offsetScale) {
|
|
||||||
mOffsetScale = offsetScale;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true, sets the crop = null and layer = Integer.MAX_VALUE for targets that don't match
|
|
||||||
* {@link #mTargetSet}.targetMode. (Currently only does this when live tiles are enabled.)
|
|
||||||
*/
|
|
||||||
public TransformParams setLauncherOnTop(boolean launcherOnTop) {
|
|
||||||
mLauncherOnTop = launcherOnTop;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the set of RemoteAnimationTargetCompats that are included in the transformation
|
|
||||||
* that these TransformParams help compute. These TransformParams generally only apply to
|
|
||||||
* the targetSet.apps which match the targetSet.targetMode (e.g. the MODE_CLOSING app when
|
|
||||||
* swiping to home).
|
|
||||||
*/
|
|
||||||
public TransformParams setTargetSet(RemoteAnimationTargets targetSet) {
|
|
||||||
mTargetSet = targetSet;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the SyncRtSurfaceTransactionApplierCompat that will apply the SurfaceParams that
|
|
||||||
* are computed based on these TransformParams.
|
|
||||||
*/
|
|
||||||
public TransformParams setSyncTransactionApplier(
|
|
||||||
SyncRtSurfaceTransactionApplierCompat applier) {
|
|
||||||
mSyncTransactionApplier = applier;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pubic getters so outside packages can read the values.
|
|
||||||
|
|
||||||
public float getProgress() {
|
|
||||||
return mProgress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getOffset() {
|
|
||||||
return mOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getOffsetScale() {
|
|
||||||
return mOffsetScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public RectF getCurrentRect() {
|
|
||||||
return mCurrentRect;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getTargetAlpha() {
|
|
||||||
return mTargetAlpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getCornerRadius() {
|
|
||||||
return mCornerRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isLauncherOnTop() {
|
|
||||||
return mLauncherOnTop;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RemoteAnimationTargets getTargetSet() {
|
|
||||||
return mTargetSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SyncRtSurfaceTransactionApplierCompat getSyncTransactionApplier() {
|
|
||||||
return mSyncTransactionApplier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.quickstep.util;
|
package com.android.quickstep.util;
|
||||||
|
|
||||||
import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_SHELF_ANIM;
|
|
||||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||||
|
import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_SHELF_ANIM;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
|
|||||||
+54
-69
@@ -19,8 +19,6 @@ import static android.view.Surface.ROTATION_0;
|
|||||||
|
|
||||||
import static com.android.launcher3.states.RotationHelper.deltaRotation;
|
import static com.android.launcher3.states.RotationHelper.deltaRotation;
|
||||||
import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE;
|
import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE;
|
||||||
import static com.android.quickstep.util.AppWindowAnimationHelper.applySurfaceParams;
|
|
||||||
import static com.android.quickstep.util.RecentsOrientedState.isFixedRotationTransformEnabled;
|
|
||||||
import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
|
import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
|
||||||
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
|
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
|
||||||
|
|
||||||
@@ -33,24 +31,20 @@ import android.graphics.RectF;
|
|||||||
import com.android.launcher3.DeviceProfile;
|
import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.anim.Interpolators;
|
|
||||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||||
import com.android.quickstep.AnimatedFloat;
|
import com.android.quickstep.AnimatedFloat;
|
||||||
import com.android.quickstep.RecentsAnimationTargets;
|
|
||||||
import com.android.quickstep.util.AppWindowAnimationHelper.TargetAlphaProvider;
|
|
||||||
import com.android.quickstep.util.AppWindowAnimationHelper.TransformParams;
|
|
||||||
import com.android.quickstep.views.RecentsView.ScrollState;
|
import com.android.quickstep.views.RecentsView.ScrollState;
|
||||||
import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper;
|
import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper;
|
||||||
import com.android.quickstep.views.TaskView;
|
import com.android.quickstep.views.TaskView;
|
||||||
import com.android.quickstep.views.TaskView.FullscreenDrawParams;
|
import com.android.quickstep.views.TaskView.FullscreenDrawParams;
|
||||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
|
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A utility class which emulates the layout behavior of TaskView and RecentsView
|
* A utility class which emulates the layout behavior of TaskView and RecentsView
|
||||||
*/
|
*/
|
||||||
public class TaskViewSimulator {
|
public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||||
|
|
||||||
private final Rect mTmpCropRect = new Rect();
|
private final Rect mTmpCropRect = new Rect();
|
||||||
private final RectF mTempRectF = new RectF();
|
private final RectF mTempRectF = new RectF();
|
||||||
@@ -66,14 +60,11 @@ public class TaskViewSimulator {
|
|||||||
|
|
||||||
private final Matrix mMatrix = new Matrix();
|
private final Matrix mMatrix = new Matrix();
|
||||||
private RemoteAnimationTargetCompat mRunningTarget;
|
private RemoteAnimationTargetCompat mRunningTarget;
|
||||||
private RecentsAnimationTargets mAllTargets;
|
|
||||||
|
|
||||||
private TargetAlphaProvider mTaskAlphaCallback = (t, a) -> a;
|
|
||||||
|
|
||||||
// Thumbnail view properties
|
// Thumbnail view properties
|
||||||
private final Rect mThumbnailPosition = new Rect();
|
private final Rect mThumbnailPosition = new Rect();
|
||||||
private final ThumbnailData mThumbnailData = new ThumbnailData();
|
private final ThumbnailData mThumbnailData = new ThumbnailData();
|
||||||
private final PreviewPositionHelper mPositionHelper;
|
private final PreviewPositionHelper mPositionHelper = new PreviewPositionHelper();
|
||||||
private final Matrix mInversePositionMatrix = new Matrix();
|
private final Matrix mInversePositionMatrix = new Matrix();
|
||||||
|
|
||||||
// TaskView properties
|
// TaskView properties
|
||||||
@@ -93,12 +84,8 @@ public class TaskViewSimulator {
|
|||||||
public TaskViewSimulator(Context context, WindowSizeStrategy sizeStrategy) {
|
public TaskViewSimulator(Context context, WindowSizeStrategy sizeStrategy) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mSizeStrategy = sizeStrategy;
|
mSizeStrategy = sizeStrategy;
|
||||||
mPositionHelper = new PreviewPositionHelper(context);
|
|
||||||
|
|
||||||
mOrientationState = new RecentsOrientedState(context, sizeStrategy, i -> { });
|
mOrientationState = new RecentsOrientedState(context, sizeStrategy, i -> { });
|
||||||
// We do not need to attach listeners as the simulator is created just for the gesture
|
|
||||||
// duration, and any settings are unlikely to change during this
|
|
||||||
mOrientationState.initWithoutListeners();
|
|
||||||
|
|
||||||
mCurrentFullscreenParams = new FullscreenDrawParams(context);
|
mCurrentFullscreenParams = new FullscreenDrawParams(context);
|
||||||
mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
|
mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
|
||||||
@@ -117,15 +104,7 @@ public class TaskViewSimulator {
|
|||||||
* @see com.android.quickstep.views.RecentsView#setLayoutRotation(int, int)
|
* @see com.android.quickstep.views.RecentsView#setLayoutRotation(int, int)
|
||||||
*/
|
*/
|
||||||
public void setLayoutRotation(int touchRotation, int displayRotation) {
|
public void setLayoutRotation(int touchRotation, int displayRotation) {
|
||||||
int launcherRotation;
|
mOrientationState.update(touchRotation, displayRotation);
|
||||||
if (!mOrientationState.isMultipleOrientationSupportedByDevice()
|
|
||||||
|| mOrientationState.isHomeRotationAllowed()) {
|
|
||||||
launcherRotation = displayRotation;
|
|
||||||
} else {
|
|
||||||
launcherRotation = ROTATION_0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mOrientationState.update(touchRotation, displayRotation, launcherRotation);
|
|
||||||
mLayoutValid = false;
|
mLayoutValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,10 +122,8 @@ public class TaskViewSimulator {
|
|||||||
/**
|
/**
|
||||||
* Sets the targets which the simulator will control
|
* Sets the targets which the simulator will control
|
||||||
*/
|
*/
|
||||||
public void setPreview(
|
public void setPreview(RemoteAnimationTargetCompat runningTarget) {
|
||||||
RemoteAnimationTargetCompat runningTarget, RecentsAnimationTargets allTargets) {
|
|
||||||
mRunningTarget = runningTarget;
|
mRunningTarget = runningTarget;
|
||||||
mAllTargets = allTargets;
|
|
||||||
|
|
||||||
mThumbnailData.insets.set(mRunningTarget.contentInsets);
|
mThumbnailData.insets.set(mRunningTarget.contentInsets);
|
||||||
// TODO: What is this?
|
// TODO: What is this?
|
||||||
@@ -169,10 +146,40 @@ public class TaskViewSimulator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an alternate function which can be used to control the alpha
|
* Returns the current clipped/visible window bounds in the window coordinate space
|
||||||
*/
|
*/
|
||||||
public void setTaskAlphaCallback(TargetAlphaProvider callback) {
|
public RectF getCurrentCropRect() {
|
||||||
mTaskAlphaCallback = callback;
|
// Crop rect is the inverse of thumbnail matrix
|
||||||
|
RectF insets = mCurrentFullscreenParams.mCurrentDrawnInsets;
|
||||||
|
mTempRectF.set(-insets.left, -insets.top,
|
||||||
|
mTaskRect.width() + insets.right, mTaskRect.height() + insets.bottom);
|
||||||
|
mInversePositionMatrix.mapRect(mTempRectF);
|
||||||
|
return mTempRectF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RecentsOrientedState getOrientationState() {
|
||||||
|
return mOrientationState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current transform applied to the window
|
||||||
|
*/
|
||||||
|
public Matrix getCurrentMatrix() {
|
||||||
|
return mMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the rotation on the matrix to so that it maps from launcher coordinate space to
|
||||||
|
* window coordinate space.
|
||||||
|
*/
|
||||||
|
public void applyWindowToHomeRotation(Matrix matrix) {
|
||||||
|
mMatrix.postTranslate(mDp.windowX, mDp.windowY);
|
||||||
|
postDisplayRotation(deltaRotation(
|
||||||
|
mOrientationState.getLauncherRotation(), mOrientationState.getDisplayRotation()),
|
||||||
|
mDp.widthPx, mDp.heightPx, matrix);
|
||||||
|
if (mRunningTarget != null) {
|
||||||
|
matrix.postTranslate(-mRunningTarget.position.x, -mRunningTarget.position.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -186,12 +193,12 @@ public class TaskViewSimulator {
|
|||||||
mLayoutValid = true;
|
mLayoutValid = true;
|
||||||
|
|
||||||
getFullScreenScale();
|
getFullScreenScale();
|
||||||
mThumbnailData.rotation = isFixedRotationTransformEnabled(mContext)
|
mThumbnailData.rotation = mOrientationState.getDisplayRotation();
|
||||||
? mOrientationState.getDisplayRotation() : mPositionHelper.getCurrentRotation();
|
|
||||||
|
|
||||||
mPositionHelper.updateThumbnailMatrix(mThumbnailPosition, mThumbnailData,
|
|
||||||
mTaskRect.width(), mTaskRect.height(), mDp);
|
|
||||||
|
|
||||||
|
mPositionHelper.updateThumbnailMatrix(
|
||||||
|
mThumbnailPosition, mThumbnailData,
|
||||||
|
mTaskRect.width(), mTaskRect.height(),
|
||||||
|
mDp, mOrientationState.getLauncherRotation());
|
||||||
mPositionHelper.getMatrix().invert(mInversePositionMatrix);
|
mPositionHelper.getMatrix().invert(mInversePositionMatrix);
|
||||||
|
|
||||||
PagedOrientationHandler poh = mOrientationState.getOrientationHandler();
|
PagedOrientationHandler poh = mOrientationState.getOrientationHandler();
|
||||||
@@ -201,7 +208,6 @@ public class TaskViewSimulator {
|
|||||||
mScrollValid = false;
|
mScrollValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!mScrollValid) {
|
if (!mScrollValid) {
|
||||||
mScrollValid = true;
|
mScrollValid = true;
|
||||||
int start = mOrientationState.getOrientationHandler()
|
int start = mOrientationState.getOrientationHandler()
|
||||||
@@ -233,11 +239,7 @@ public class TaskViewSimulator {
|
|||||||
|
|
||||||
// Apply recensView matrix
|
// Apply recensView matrix
|
||||||
mMatrix.postScale(recentsViewScale.value, recentsViewScale.value, mPivot.x, mPivot.y);
|
mMatrix.postScale(recentsViewScale.value, recentsViewScale.value, mPivot.x, mPivot.y);
|
||||||
postDisplayRotation(deltaRotation(
|
applyWindowToHomeRotation(mMatrix);
|
||||||
mOrientationState.getLauncherRotation(), mOrientationState.getDisplayRotation()),
|
|
||||||
mDp.widthPx, mDp.heightPx, mMatrix);
|
|
||||||
mMatrix.postTranslate(mDp.windowX - mRunningTarget.position.x,
|
|
||||||
mDp.windowY - mRunningTarget.position.y);
|
|
||||||
|
|
||||||
// Crop rect is the inverse of thumbnail matrix
|
// Crop rect is the inverse of thumbnail matrix
|
||||||
mTempRectF.set(-insets.left, -insets.top,
|
mTempRectF.set(-insets.left, -insets.top,
|
||||||
@@ -245,35 +247,18 @@ public class TaskViewSimulator {
|
|||||||
mInversePositionMatrix.mapRect(mTempRectF);
|
mInversePositionMatrix.mapRect(mTempRectF);
|
||||||
mTempRectF.roundOut(mTmpCropRect);
|
mTempRectF.roundOut(mTmpCropRect);
|
||||||
|
|
||||||
SurfaceParams[] surfaceParams = new SurfaceParams[mAllTargets.unfilteredApps.length];
|
params.applySurfaceParams(params.createSurfaceParams(this));
|
||||||
for (int i = 0; i < mAllTargets.unfilteredApps.length; i++) {
|
}
|
||||||
RemoteAnimationTargetCompat app = mAllTargets.unfilteredApps[i];
|
|
||||||
SurfaceParams.Builder builder = new SurfaceParams.Builder(app.leash);
|
|
||||||
|
|
||||||
if (app.mode == mAllTargets.targetMode) {
|
@Override
|
||||||
float alpha = mTaskAlphaCallback.getAlpha(app, params.getTargetAlpha());
|
public void onBuildParams(Builder builder, RemoteAnimationTargetCompat app,
|
||||||
if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
|
int targetMode, TransformParams params) {
|
||||||
// Fade out Assistant overlay.
|
if (app.mode == targetMode
|
||||||
if (app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT
|
&& app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
|
||||||
&& app.isNotInRecents) {
|
builder.withMatrix(mMatrix)
|
||||||
alpha = Interpolators.ACCEL_2.getInterpolation(fullScreenProgress.value);
|
.withWindowCrop(mTmpCropRect)
|
||||||
}
|
.withCornerRadius(getCurrentCornerRadius());
|
||||||
|
|
||||||
builder.withAlpha(alpha)
|
|
||||||
.withMatrix(mMatrix)
|
|
||||||
.withWindowCrop(mTmpCropRect)
|
|
||||||
.withCornerRadius(getCurrentCornerRadius());
|
|
||||||
} else if (params.getTargetSet().hasRecents) {
|
|
||||||
// If home has a different target then recents, reverse anim the home target.
|
|
||||||
builder.withAlpha(fullScreenProgress.value * params.getTargetAlpha());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
builder.withAlpha(1);
|
|
||||||
}
|
|
||||||
surfaceParams[i] = builder.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
applySurfaceParams(params.getSyncTransactionApplier(), surfaceParams);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,205 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 android.graphics.RectF;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.android.launcher3.Utilities;
|
||||||
|
import com.android.launcher3.anim.Interpolators;
|
||||||
|
import com.android.quickstep.RemoteAnimationTargets;
|
||||||
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
|
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
||||||
|
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
|
||||||
|
import com.android.systemui.shared.system.TransactionCompat;
|
||||||
|
|
||||||
|
public class TransformParams {
|
||||||
|
|
||||||
|
private float mProgress;
|
||||||
|
private @Nullable RectF mCurrentRect;
|
||||||
|
private float mTargetAlpha;
|
||||||
|
private float mCornerRadius;
|
||||||
|
private RemoteAnimationTargets mTargetSet;
|
||||||
|
private SyncRtSurfaceTransactionApplierCompat mSyncTransactionApplier;
|
||||||
|
|
||||||
|
private TargetAlphaProvider mTaskAlphaCallback = (t, a) -> a;
|
||||||
|
private TargetAlphaProvider mBaseAlphaCallback = (t, a) -> 1;
|
||||||
|
|
||||||
|
public TransformParams() {
|
||||||
|
mProgress = 0;
|
||||||
|
mCurrentRect = null;
|
||||||
|
mTargetAlpha = 1;
|
||||||
|
mCornerRadius = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the progress of the transformation, where 0 is the source and 1 is the target. We
|
||||||
|
* automatically adjust properties such as currentRect and cornerRadius based on this
|
||||||
|
* progress, unless they are manually overridden by setting them on this TransformParams.
|
||||||
|
*/
|
||||||
|
public TransformParams setProgress(float progress) {
|
||||||
|
mProgress = progress;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the corner radius of the transformed window, in pixels. If unspecified (-1), we
|
||||||
|
* simply interpolate between the window's corner radius to the task view's corner radius,
|
||||||
|
* based on {@link #mProgress}.
|
||||||
|
*/
|
||||||
|
public TransformParams setCornerRadius(float cornerRadius) {
|
||||||
|
mCornerRadius = cornerRadius;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current rect to show the transformed window, in device coordinates. This gives
|
||||||
|
* the caller manual control of where to show the window. If unspecified (null), we
|
||||||
|
* interpolate between {@link AppWindowAnimationHelper#mSourceRect} and
|
||||||
|
* {@link AppWindowAnimationHelper#mTargetRect}, based on {@link #mProgress}.
|
||||||
|
*/
|
||||||
|
public TransformParams setCurrentRect(RectF currentRect) {
|
||||||
|
mCurrentRect = currentRect;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the alpha of the transformed window. Default is 1.
|
||||||
|
*/
|
||||||
|
public TransformParams setTargetAlpha(float targetAlpha) {
|
||||||
|
mTargetAlpha = targetAlpha;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the set of RemoteAnimationTargetCompats that are included in the transformation
|
||||||
|
* that these TransformParams help compute. These TransformParams generally only apply to
|
||||||
|
* the targetSet.apps which match the targetSet.targetMode (e.g. the MODE_CLOSING app when
|
||||||
|
* swiping to home).
|
||||||
|
*/
|
||||||
|
public TransformParams setTargetSet(RemoteAnimationTargets targetSet) {
|
||||||
|
mTargetSet = targetSet;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the SyncRtSurfaceTransactionApplierCompat that will apply the SurfaceParams that
|
||||||
|
* are computed based on these TransformParams.
|
||||||
|
*/
|
||||||
|
public TransformParams setSyncTransactionApplier(
|
||||||
|
SyncRtSurfaceTransactionApplierCompat applier) {
|
||||||
|
mSyncTransactionApplier = applier;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an alternate function which can be used to control the alpha of target app
|
||||||
|
*/
|
||||||
|
public TransformParams setTaskAlphaCallback(TargetAlphaProvider callback) {
|
||||||
|
mTaskAlphaCallback = callback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an alternate function which can be used to control the alpha of non-target app
|
||||||
|
*/
|
||||||
|
public TransformParams setBaseAlphaCallback(TargetAlphaProvider callback) {
|
||||||
|
mBaseAlphaCallback = callback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SurfaceParams[] createSurfaceParams(BuilderProxy proxy) {
|
||||||
|
RemoteAnimationTargets targets = mTargetSet;
|
||||||
|
SurfaceParams[] surfaceParams = new SurfaceParams[targets.unfilteredApps.length];
|
||||||
|
for (int i = 0; i < targets.unfilteredApps.length; i++) {
|
||||||
|
RemoteAnimationTargetCompat app = targets.unfilteredApps[i];
|
||||||
|
SurfaceParams.Builder builder = new SurfaceParams.Builder(app.leash);
|
||||||
|
|
||||||
|
float progress = Utilities.boundToRange(getProgress(), 0, 1);
|
||||||
|
float alpha;
|
||||||
|
if (app.mode == targets.targetMode) {
|
||||||
|
alpha = mTaskAlphaCallback.getAlpha(app, getTargetAlpha());
|
||||||
|
if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
|
||||||
|
// Fade out Assistant overlay.
|
||||||
|
if (app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT
|
||||||
|
&& app.isNotInRecents) {
|
||||||
|
alpha = 1 - Interpolators.DEACCEL_2_5.getInterpolation(progress);
|
||||||
|
}
|
||||||
|
} else if (targets.hasRecents) {
|
||||||
|
// If home has a different target then recents, reverse anim the
|
||||||
|
// home target.
|
||||||
|
alpha = 1 - (progress * getTargetAlpha());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alpha = mBaseAlphaCallback.getAlpha(app, progress);
|
||||||
|
}
|
||||||
|
proxy.onBuildParams(builder.withAlpha(alpha), app, targets.targetMode, this);
|
||||||
|
surfaceParams[i] = builder.build();
|
||||||
|
}
|
||||||
|
return surfaceParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pubic getters so outside packages can read the values.
|
||||||
|
|
||||||
|
public float getProgress() {
|
||||||
|
return mProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public RectF getCurrentRect() {
|
||||||
|
return mCurrentRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getTargetAlpha() {
|
||||||
|
return mTargetAlpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getCornerRadius() {
|
||||||
|
return mCornerRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RemoteAnimationTargets getTargetSet() {
|
||||||
|
return mTargetSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SyncRtSurfaceTransactionApplierCompat getSyncTransactionApplier() {
|
||||||
|
return mSyncTransactionApplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applySurfaceParams(SurfaceParams[] params) {
|
||||||
|
if (mSyncTransactionApplier != null) {
|
||||||
|
mSyncTransactionApplier.scheduleApply(params);
|
||||||
|
} else {
|
||||||
|
TransactionCompat t = new TransactionCompat();
|
||||||
|
for (SurfaceParams param : params) {
|
||||||
|
SyncRtSurfaceTransactionApplierCompat.applyParams(t, param);
|
||||||
|
}
|
||||||
|
t.setEarlyWakeup();
|
||||||
|
t.apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface TargetAlphaProvider {
|
||||||
|
float getAlpha(RemoteAnimationTargetCompat target, float expectedAlpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface BuilderProxy {
|
||||||
|
|
||||||
|
void onBuildParams(SurfaceParams.Builder builder,
|
||||||
|
RemoteAnimationTargetCompat app, int targetMode, TransformParams params);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -64,7 +64,13 @@ public class ClearAllButton extends Button implements PageCallbacks {
|
|||||||
protected void onAttachedToWindow() {
|
protected void onAttachedToWindow() {
|
||||||
super.onAttachedToWindow();
|
super.onAttachedToWindow();
|
||||||
mParent = (RecentsView) getParent();
|
mParent = (RecentsView) getParent();
|
||||||
mIsRtl = !mParent.getPagedOrientationHandler().getRecentsRtlSetting(getResources());
|
mIsRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRtlPropertiesChanged(int layoutDirection) {
|
||||||
|
super.onRtlPropertiesChanged(layoutDirection);
|
||||||
|
mIsRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+18
-28
@@ -31,27 +31,24 @@ import android.animation.AnimatorSet;
|
|||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
import com.android.launcher3.BaseQuickstepLauncher;
|
import com.android.launcher3.BaseQuickstepLauncher;
|
||||||
import com.android.launcher3.Hotseat;
|
import com.android.launcher3.Hotseat;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.LauncherStateManager.StateListener;
|
|
||||||
import com.android.launcher3.anim.Interpolators;
|
import com.android.launcher3.anim.Interpolators;
|
||||||
import com.android.launcher3.appprediction.PredictionUiStateManager;
|
import com.android.launcher3.appprediction.PredictionUiStateManager;
|
||||||
import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
|
import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
|
||||||
import com.android.launcher3.statehandlers.DepthController;
|
import com.android.launcher3.statehandlers.DepthController;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||||
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
||||||
import com.android.launcher3.util.TraceHelper;
|
import com.android.launcher3.util.TraceHelper;
|
||||||
import com.android.launcher3.views.ScrimView;
|
import com.android.launcher3.views.ScrimView;
|
||||||
import com.android.quickstep.SysUINavigationMode;
|
import com.android.quickstep.SysUINavigationMode;
|
||||||
import com.android.quickstep.util.AppWindowAnimationHelper;
|
import com.android.quickstep.util.TransformParams;
|
||||||
import com.android.quickstep.util.AppWindowAnimationHelper.TransformParams;
|
|
||||||
import com.android.systemui.plugins.PluginListener;
|
import com.android.systemui.plugins.PluginListener;
|
||||||
import com.android.systemui.plugins.RecentsExtraCard;
|
import com.android.systemui.plugins.RecentsExtraCard;
|
||||||
|
|
||||||
@@ -60,7 +57,7 @@ import com.android.systemui.plugins.RecentsExtraCard;
|
|||||||
*/
|
*/
|
||||||
@TargetApi(Build.VERSION_CODES.O)
|
@TargetApi(Build.VERSION_CODES.O)
|
||||||
public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher>
|
public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher>
|
||||||
implements StateListener {
|
implements StateListener<LauncherState> {
|
||||||
|
|
||||||
private final TransformParams mTransformParams = new TransformParams();
|
private final TransformParams mTransformParams = new TransformParams();
|
||||||
|
|
||||||
@@ -124,24 +121,6 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(Canvas canvas) {
|
|
||||||
maybeDrawEmptyMessage(canvas);
|
|
||||||
super.draw(canvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewAdded(View child) {
|
|
||||||
super.onViewAdded(child);
|
|
||||||
updateEmptyMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onTaskStackUpdated() {
|
|
||||||
// Lazily update the empty message only when the task stack is reapplied
|
|
||||||
updateEmptyMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animates adjacent tasks and translate hotseat off screen as well.
|
* Animates adjacent tasks and translate hotseat off screen as well.
|
||||||
*/
|
*/
|
||||||
@@ -213,14 +192,14 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void redrawLiveTile(boolean mightNeedToRefill) {
|
public void redrawLiveTile(boolean mightNeedToRefill) {
|
||||||
AppWindowAnimationHelper.TransformParams transformParams = getLiveTileParams(mightNeedToRefill);
|
TransformParams transformParams = getLiveTileParams(mightNeedToRefill);
|
||||||
if (transformParams != null) {
|
if (transformParams != null) {
|
||||||
mAppWindowAnimationHelper.applyTransform(transformParams);
|
mAppWindowAnimationHelper.applyTransform(transformParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AppWindowAnimationHelper.TransformParams getLiveTileParams(
|
public TransformParams getLiveTileParams(
|
||||||
boolean mightNeedToRefill) {
|
boolean mightNeedToRefill) {
|
||||||
if (!mEnableDrawingLiveTile || mRecentsAnimationController == null
|
if (!mEnableDrawingLiveTile || mRecentsAnimationController == null
|
||||||
|| mRecentsAnimationTargets == null || mAppWindowAnimationHelper == null) {
|
|| mRecentsAnimationTargets == null || mAppWindowAnimationHelper == null) {
|
||||||
@@ -248,8 +227,7 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher>
|
|||||||
.setCurrentRect(mTempRectF)
|
.setCurrentRect(mTempRectF)
|
||||||
.setTargetAlpha(taskView.getAlpha())
|
.setTargetAlpha(taskView.getAlpha())
|
||||||
.setSyncTransactionApplier(mSyncTransactionApplier)
|
.setSyncTransactionApplier(mSyncTransactionApplier)
|
||||||
.setTargetSet(mRecentsAnimationTargets)
|
.setTargetSet(mRecentsAnimationTargets);
|
||||||
.setLauncherOnTop(true);
|
|
||||||
}
|
}
|
||||||
return mTransformParams;
|
return mTransformParams;
|
||||||
}
|
}
|
||||||
@@ -373,4 +351,16 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher>
|
|||||||
protected DepthController getDepthController() {
|
protected DepthController getDepthController() {
|
||||||
return mActivity.getDepthController();
|
return mActivity.getDepthController();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setModalStateEnabled(boolean isModalState) {
|
||||||
|
super.setModalStateEnabled(isModalState);
|
||||||
|
if (isModalState) {
|
||||||
|
mActivity.getStateManager().goToState(LauncherState.OVERVIEW_MODAL_TASK);
|
||||||
|
} else {
|
||||||
|
if (mActivity.isInState(LauncherState.OVERVIEW_MODAL_TASK)) {
|
||||||
|
mActivity.getStateManager().goToState(LauncherState.OVERVIEW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
@@ -31,6 +31,7 @@ import androidx.annotation.Nullable;
|
|||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.util.MultiValueAlpha;
|
import com.android.launcher3.util.MultiValueAlpha;
|
||||||
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
|
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
|
||||||
|
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||||
import com.android.quickstep.TaskOverlayFactory.OverlayUICallbacks;
|
import com.android.quickstep.TaskOverlayFactory.OverlayUICallbacks;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
@@ -141,4 +142,19 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
|
|||||||
public AlphaProperty getVisibilityAlpha() {
|
public AlphaProperty getVisibilityAlpha() {
|
||||||
return mMultiValueAlpha.getProperty(INDEX_VISIBILITY_ALPHA);
|
return mMultiValueAlpha.getProperty(INDEX_VISIBILITY_ALPHA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Updates vertical margins for different navigation mode. */
|
||||||
|
public void updateVerticalMarginForNavModeChange(Mode mode) {
|
||||||
|
int bottomMargin = 0;
|
||||||
|
if (mode == Mode.THREE_BUTTONS) {
|
||||||
|
bottomMargin = getResources()
|
||||||
|
.getDimensionPixelSize(R.dimen.overview_actions_bottom_margin_three_button);
|
||||||
|
} else {
|
||||||
|
bottomMargin = getResources()
|
||||||
|
.getDimensionPixelSize(R.dimen.overview_actions_bottom_margin_gesture);
|
||||||
|
}
|
||||||
|
LayoutParams params = (LayoutParams) getLayoutParams();
|
||||||
|
params.setMargins(
|
||||||
|
params.leftMargin, params.topMargin, params.rightMargin, bottomMargin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.quickstep.views;
|
package com.android.quickstep.views;
|
||||||
|
|
||||||
|
import static android.view.Surface.ROTATION_0;
|
||||||
|
|
||||||
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
|
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
|
||||||
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
|
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
|
||||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||||
@@ -30,8 +32,8 @@ import static com.android.launcher3.anim.Interpolators.ACCEL_2;
|
|||||||
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
|
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
|
||||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.TASK_DISMISS_SWIPE_UP;
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP;
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.TASK_LAUNCH_SWIPE_DOWN;
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN;
|
||||||
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
|
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
|
||||||
import static com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS;
|
import static com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS;
|
||||||
import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
|
import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
|
||||||
@@ -55,7 +57,6 @@ import android.app.ActivityManager;
|
|||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
@@ -123,14 +124,16 @@ import com.android.quickstep.TaskThumbnailCache;
|
|||||||
import com.android.quickstep.TaskUtils;
|
import com.android.quickstep.TaskUtils;
|
||||||
import com.android.quickstep.ViewUtils;
|
import com.android.quickstep.ViewUtils;
|
||||||
import com.android.quickstep.util.AppWindowAnimationHelper;
|
import com.android.quickstep.util.AppWindowAnimationHelper;
|
||||||
|
import com.android.quickstep.util.LayoutUtils;
|
||||||
import com.android.quickstep.util.RecentsOrientedState;
|
import com.android.quickstep.util.RecentsOrientedState;
|
||||||
|
import com.android.quickstep.util.SplitScreenBounds;
|
||||||
|
import com.android.quickstep.util.TransformParams;
|
||||||
import com.android.quickstep.util.WindowSizeStrategy;
|
import com.android.quickstep.util.WindowSizeStrategy;
|
||||||
import com.android.systemui.plugins.ResourceProvider;
|
import com.android.systemui.plugins.ResourceProvider;
|
||||||
import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
|
import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
|
||||||
import com.android.systemui.shared.recents.model.Task;
|
import com.android.systemui.shared.recents.model.Task;
|
||||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||||
import com.android.systemui.shared.system.ConfigurationCompat;
|
|
||||||
import com.android.systemui.shared.system.LauncherEventUtil;
|
import com.android.systemui.shared.system.LauncherEventUtil;
|
||||||
import com.android.systemui.shared.system.PackageManagerWrapper;
|
import com.android.systemui.shared.system.PackageManagerWrapper;
|
||||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
||||||
@@ -145,7 +148,8 @@ import java.util.function.Consumer;
|
|||||||
@TargetApi(Build.VERSION_CODES.P)
|
@TargetApi(Build.VERSION_CODES.P)
|
||||||
public abstract class RecentsView<T extends BaseActivity> extends PagedView implements Insettable,
|
public abstract class RecentsView<T extends BaseActivity> extends PagedView implements Insettable,
|
||||||
TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback,
|
TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback,
|
||||||
InvariantDeviceProfile.OnIDPChangeListener, TaskVisualsChangeListener {
|
InvariantDeviceProfile.OnIDPChangeListener, TaskVisualsChangeListener,
|
||||||
|
SplitScreenBounds.OnChangeListener {
|
||||||
|
|
||||||
private static final String TAG = RecentsView.class.getSimpleName();
|
private static final String TAG = RecentsView.class.getSimpleName();
|
||||||
|
|
||||||
@@ -507,7 +511,8 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
mIPinnedStackAnimationListener.setActivity(mActivity);
|
mIPinnedStackAnimationListener.setActivity(mActivity);
|
||||||
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(
|
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(
|
||||||
mIPinnedStackAnimationListener);
|
mIPinnedStackAnimationListener);
|
||||||
mOrientationState.init();
|
mOrientationState.initListeners();
|
||||||
|
SplitScreenBounds.INSTANCE.addOnChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -521,8 +526,9 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
RecentsModel.INSTANCE.get(getContext()).removeThumbnailChangeListener(this);
|
RecentsModel.INSTANCE.get(getContext()).removeThumbnailChangeListener(this);
|
||||||
mIdp.removeOnChangeListener(this);
|
mIdp.removeOnChangeListener(this);
|
||||||
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null);
|
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null);
|
||||||
|
SplitScreenBounds.INSTANCE.removeOnChangeListener(this);
|
||||||
mIPinnedStackAnimationListener.setActivity(null);
|
mIPinnedStackAnimationListener.setActivity(null);
|
||||||
mOrientationState.destroy();
|
mOrientationState.destroyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -548,6 +554,13 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
child.setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_LTR : View.LAYOUT_DIRECTION_RTL);
|
child.setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_LTR : View.LAYOUT_DIRECTION_RTL);
|
||||||
updateTaskStartIndex(child);
|
updateTaskStartIndex(child);
|
||||||
mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, false);
|
mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, false);
|
||||||
|
updateEmptyMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
maybeDrawEmptyMessage(canvas);
|
||||||
|
super.draw(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTaskStartIndex(View affectingView) {
|
private void updateTaskStartIndex(View affectingView) {
|
||||||
@@ -598,20 +611,20 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPageEndTransition() {
|
protected void onPageBeginTransition() {
|
||||||
super.onPageEndTransition();
|
super.onPageBeginTransition();
|
||||||
if (getNextPage() > 0) {
|
LayoutUtils.setViewEnabled(mActionsView, false);
|
||||||
setSwipeDownShouldLaunchApp(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onConfigurationChanged(Configuration newConfig) {
|
protected void onPageEndTransition() {
|
||||||
super.onConfigurationChanged(newConfig);
|
super.onPageEndTransition();
|
||||||
int windowConfigurationRotation = ConfigurationCompat
|
if (getScrollX() == getScrollForPage(getPageNearestToCenterOfScreen())) {
|
||||||
.getWindowConfigurationRotation(getResources().getConfiguration());
|
LayoutUtils.setViewEnabled(mActionsView, true);
|
||||||
setLayoutInternal(mOrientationState.getTouchRotation(),
|
}
|
||||||
mOrientationState.getDisplayRotation(), windowConfigurationRotation);
|
if (getNextPage() > 0) {
|
||||||
|
setSwipeDownShouldLaunchApp(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -760,7 +773,10 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
return taskViewCount;
|
return taskViewCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onTaskStackUpdated() { }
|
protected void onTaskStackUpdated() {
|
||||||
|
// Lazily update the empty message only when the task stack is reapplied
|
||||||
|
updateEmptyMessage();
|
||||||
|
}
|
||||||
|
|
||||||
public void resetTaskVisuals() {
|
public void resetTaskVisuals() {
|
||||||
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
|
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
|
||||||
@@ -827,6 +843,11 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), outRect);
|
mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), outRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets the task size for modal state. */
|
||||||
|
public void getModalTaskSize(Rect outRect) {
|
||||||
|
mSizeStrategy.calculateModalTaskSize(mActivity, mActivity.getDeviceProfile(), outRect);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean computeScrollHelper() {
|
protected boolean computeScrollHelper() {
|
||||||
boolean scrolling = super.computeScrollHelper();
|
boolean scrolling = super.computeScrollHelper();
|
||||||
@@ -958,6 +979,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
setCurrentPage(0);
|
setCurrentPage(0);
|
||||||
mDwbToastShown = false;
|
mDwbToastShown = false;
|
||||||
mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, 0);
|
mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, 0);
|
||||||
|
LayoutUtils.setViewEnabled(mActionsView, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable TaskView getRunningTaskView() {
|
public @Nullable TaskView getRunningTaskView() {
|
||||||
@@ -965,7 +987,15 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getRunningTaskIndex() {
|
public int getRunningTaskIndex() {
|
||||||
TaskView tv = getRunningTaskView();
|
return getTaskIndexForId(mRunningTaskId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the index of the task view whose id matches {@param taskId}.
|
||||||
|
* @return -1 if there is no task view for the task id, else the index of the task view.
|
||||||
|
*/
|
||||||
|
public int getTaskIndexForId(int taskId) {
|
||||||
|
TaskView tv = getTaskView(taskId);
|
||||||
return tv == null ? -1 : indexOfChild(tv);
|
return tv == null ? -1 : indexOfChild(tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1294,7 +1324,8 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
ComponentKey compKey = TaskUtils.getLaunchComponentKeyForTask(taskView.getTask().key);
|
ComponentKey compKey = TaskUtils.getLaunchComponentKeyForTask(taskView.getTask().key);
|
||||||
mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
|
mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
|
||||||
endState.logAction, Direction.UP, index, compKey);
|
endState.logAction, Direction.UP, index, compKey);
|
||||||
mActivity.getStatsLogManager().log(TASK_DISMISS_SWIPE_UP, taskView.buildProto());
|
mActivity.getStatsLogManager().log(
|
||||||
|
LAUNCHER_TASK_DISMISS_SWIPE_UP, taskView.buildProto());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1574,19 +1605,19 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setLayoutRotation(int touchRotation, int displayRotation) {
|
public void setLayoutRotation(int touchRotation, int displayRotation) {
|
||||||
int launcherRotation = mOrientationState.getLauncherRotation();
|
if (mOrientationState.update(touchRotation, displayRotation)) {
|
||||||
setLayoutInternal(touchRotation, displayRotation, launcherRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setLayoutInternal(int touchRotation, int displayRotation, int launcherRotation) {
|
|
||||||
if (mOrientationState.update(touchRotation, displayRotation, launcherRotation)) {
|
|
||||||
mOrientationHandler = mOrientationState.getOrientationHandler();
|
mOrientationHandler = mOrientationState.getOrientationHandler();
|
||||||
mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources());
|
mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources());
|
||||||
setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
|
setLayoutDirection(mIsRtl
|
||||||
|
? View.LAYOUT_DIRECTION_RTL
|
||||||
|
: View.LAYOUT_DIRECTION_LTR);
|
||||||
|
mClearAllButton.setLayoutDirection(mIsRtl
|
||||||
|
? View.LAYOUT_DIRECTION_LTR
|
||||||
|
: View.LAYOUT_DIRECTION_RTL);
|
||||||
mClearAllButton.setRotation(mOrientationHandler.getDegreesRotated());
|
mClearAllButton.setRotation(mOrientationHandler.getDegreesRotated());
|
||||||
mActivity.getDragLayer().recreateControllers();
|
mActivity.getDragLayer().recreateControllers();
|
||||||
mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION,
|
mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION,
|
||||||
touchRotation != 0 || launcherRotation != 0);
|
touchRotation != 0 || mOrientationState.getLauncherRotation() != ROTATION_0);
|
||||||
requestLayout();
|
requestLayout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1682,7 +1713,8 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
}
|
}
|
||||||
int count = getChildCount();
|
int count = getChildCount();
|
||||||
|
|
||||||
TaskView runningTask = mRunningTaskId == -1 ? null : getTaskView(mRunningTaskId);
|
TaskView runningTask = mRunningTaskId == -1 || !mRunningTaskTileHidden
|
||||||
|
? null : getTaskView(mRunningTaskId);
|
||||||
int midPoint = runningTask == null ? -1 : indexOfChild(runningTask);
|
int midPoint = runningTask == null ? -1 : indexOfChild(runningTask);
|
||||||
int currentPage = getCurrentPage();
|
int currentPage = getCurrentPage();
|
||||||
|
|
||||||
@@ -1872,8 +1904,8 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
|
mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
|
||||||
endState.logAction, Direction.DOWN, indexOfChild(tv),
|
endState.logAction, Direction.DOWN, indexOfChild(tv),
|
||||||
TaskUtils.getLaunchComponentKeyForTask(task.key));
|
TaskUtils.getLaunchComponentKeyForTask(task.key));
|
||||||
mActivity.getStatsLogManager().log(TASK_LAUNCH_SWIPE_DOWN, tv.buildProto()
|
mActivity.getStatsLogManager().log(
|
||||||
);
|
LAUNCHER_TASK_LAUNCH_SWIPE_DOWN, tv.buildProto());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
onTaskLaunched(false);
|
onTaskLaunched(false);
|
||||||
@@ -2059,14 +2091,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
return getScrollForPage(getRunningTaskIndex()) - mOrientationHandler.getPrimaryScroll(this);
|
return getScrollForPage(getRunningTaskIndex()) - mOrientationHandler.getPrimaryScroll(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return How many pixels the running task is offset on the x-axis due to the current scrollX
|
|
||||||
* and parent scale.
|
|
||||||
*/
|
|
||||||
public float getScrollOffsetScaled() {
|
|
||||||
return getScrollOffset() * mOrientationHandler.getPrimaryScale(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Consumer<MotionEvent> getEventDispatcher(float navbarRotation) {
|
public Consumer<MotionEvent> getEventDispatcher(float navbarRotation) {
|
||||||
float degreesRotated;
|
float degreesRotated;
|
||||||
if (navbarRotation == 0) {
|
if (navbarRotation == 0) {
|
||||||
@@ -2100,7 +2124,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
return mAppWindowAnimationHelper;
|
return mAppWindowAnimationHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppWindowAnimationHelper.TransformParams getLiveTileParams(
|
public TransformParams getLiveTileParams(
|
||||||
boolean mightNeedToRefill) {
|
boolean mightNeedToRefill) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -2145,18 +2169,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
updatePageOffsets();
|
updatePageOffsets();
|
||||||
if (getCurrentPageTaskView() != null) {
|
if (getCurrentPageTaskView() != null) {
|
||||||
getCurrentPageTaskView().setModalness(modalness);
|
getCurrentPageTaskView().setModalness(modalness);
|
||||||
TaskView tv = getCurrentPageTaskView();
|
|
||||||
|
|
||||||
// Move the task view up as it scales...
|
|
||||||
// ...the icon on taskview is hidden in modal state, so consider the top of the task
|
|
||||||
mTempFloatPoint[0] = 0;
|
|
||||||
mTempFloatPoint[1] = tv.getTop() + mTaskTopMargin;
|
|
||||||
// ...find the top after the transformation
|
|
||||||
getMatrix().mapPoints(mTempFloatPoint);
|
|
||||||
|
|
||||||
// ...make it match the top inset
|
|
||||||
float calcOffset = (mInsets.top - mTempFloatPoint[1]) * mTaskModalness;
|
|
||||||
tv.setTranslationY(calcOffset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2165,6 +2177,19 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSecondaryWindowBoundsChanged() {
|
||||||
|
// Invalidate the task view size
|
||||||
|
setInsets(mInsets);
|
||||||
|
requestLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables or disables modal state for RecentsView
|
||||||
|
* @param isModalState
|
||||||
|
*/
|
||||||
|
public void setModalStateEnabled(boolean isModalState) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to register callbacks for when our empty message state changes.
|
* Used to register callbacks for when our empty message state changes.
|
||||||
*
|
*
|
||||||
|
|||||||
+6
-16
@@ -90,7 +90,7 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
|||||||
|
|
||||||
// Contains the portion of the thumbnail that is clipped when fullscreen progress = 0.
|
// Contains the portion of the thumbnail that is clipped when fullscreen progress = 0.
|
||||||
private final Rect mPreviewRect = new Rect();
|
private final Rect mPreviewRect = new Rect();
|
||||||
private final PreviewPositionHelper mPreviewPositionHelper;
|
private final PreviewPositionHelper mPreviewPositionHelper = new PreviewPositionHelper();
|
||||||
// Initialize with dummy value. It is overridden later by TaskView
|
// Initialize with dummy value. It is overridden later by TaskView
|
||||||
private TaskView.FullscreenDrawParams mFullscreenParams = TEMP_PARAMS;
|
private TaskView.FullscreenDrawParams mFullscreenParams = TEMP_PARAMS;
|
||||||
|
|
||||||
@@ -122,7 +122,6 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
|||||||
mDimmingPaintAfterClearing.setColor(Color.BLACK);
|
mDimmingPaintAfterClearing.setColor(Color.BLACK);
|
||||||
mActivity = BaseActivity.fromContext(context);
|
mActivity = BaseActivity.fromContext(context);
|
||||||
mIsDarkTextTheme = Themes.getAttrBoolean(mActivity, R.attr.isWorkspaceDarkText);
|
mIsDarkTextTheme = Themes.getAttrBoolean(mActivity, R.attr.isWorkspaceDarkText);
|
||||||
mPreviewPositionHelper = new PreviewPositionHelper(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -349,8 +348,11 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
|||||||
if (mBitmapShader != null && mThumbnailData != null) {
|
if (mBitmapShader != null && mThumbnailData != null) {
|
||||||
mPreviewRect.set(0, 0, mThumbnailData.thumbnail.getWidth(),
|
mPreviewRect.set(0, 0, mThumbnailData.thumbnail.getWidth(),
|
||||||
mThumbnailData.thumbnail.getHeight());
|
mThumbnailData.thumbnail.getHeight());
|
||||||
|
int currentRotation = ConfigurationCompat.getWindowConfigurationRotation(
|
||||||
|
mActivity.getResources().getConfiguration());
|
||||||
mPreviewPositionHelper.updateThumbnailMatrix(mPreviewRect, mThumbnailData,
|
mPreviewPositionHelper.updateThumbnailMatrix(mPreviewRect, mThumbnailData,
|
||||||
getMeasuredWidth(), getMeasuredHeight(), mActivity.getDeviceProfile());
|
getMeasuredWidth(), getMeasuredHeight(), mActivity.getDeviceProfile(),
|
||||||
|
currentRotation);
|
||||||
|
|
||||||
mBitmapShader.setLocalMatrix(mPreviewPositionHelper.mMatrix);
|
mBitmapShader.setLocalMatrix(mPreviewPositionHelper.mMatrix);
|
||||||
mPaint.setShader(mBitmapShader);
|
mPaint.setShader(mBitmapShader);
|
||||||
@@ -417,17 +419,6 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
|||||||
private float mClipBottom = -1;
|
private float mClipBottom = -1;
|
||||||
private boolean mIsOrientationChanged;
|
private boolean mIsOrientationChanged;
|
||||||
|
|
||||||
private final Context mContext;
|
|
||||||
|
|
||||||
public PreviewPositionHelper(Context context) {
|
|
||||||
mContext = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurrentRotation() {
|
|
||||||
return ConfigurationCompat.getWindowConfigurationRotation(
|
|
||||||
mContext.getResources().getConfiguration());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Matrix getMatrix() {
|
public Matrix getMatrix() {
|
||||||
return mMatrix;
|
return mMatrix;
|
||||||
}
|
}
|
||||||
@@ -436,7 +427,7 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
|||||||
* Updates the matrix based on the provided parameters
|
* Updates the matrix based on the provided parameters
|
||||||
*/
|
*/
|
||||||
public void updateThumbnailMatrix(Rect thumbnailPosition, ThumbnailData thumbnailData,
|
public void updateThumbnailMatrix(Rect thumbnailPosition, ThumbnailData thumbnailData,
|
||||||
int canvasWidth, int canvasHeight, DeviceProfile dp) {
|
int canvasWidth, int canvasHeight, DeviceProfile dp, int currentRotation) {
|
||||||
boolean isRotated = false;
|
boolean isRotated = false;
|
||||||
boolean isOrientationDifferent;
|
boolean isOrientationDifferent;
|
||||||
mClipBottom = -1;
|
mClipBottom = -1;
|
||||||
@@ -451,7 +442,6 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
|||||||
|
|
||||||
final float thumbnailScale;
|
final float thumbnailScale;
|
||||||
int thumbnailRotation = thumbnailData.rotation;
|
int thumbnailRotation = thumbnailData.rotation;
|
||||||
int currentRotation = getCurrentRotation();
|
|
||||||
int deltaRotate = getRotationDelta(currentRotation, thumbnailRotation);
|
int deltaRotate = getRotationDelta(currentRotation, thumbnailRotation);
|
||||||
|
|
||||||
Rect deviceInsets = dp.getInsets();
|
Rect deviceInsets = dp.getInsets();
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
|
|||||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||||
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
|
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
|
||||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.TASK_LAUNCH_TAP;
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
@@ -212,7 +212,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
|||||||
mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
|
mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
|
||||||
Touch.TAP, Direction.NONE, getRecentsView().indexOfChild(this),
|
Touch.TAP, Direction.NONE, getRecentsView().indexOfChild(this),
|
||||||
TaskUtils.getLaunchComponentKeyForTask(getTask().key));
|
TaskUtils.getLaunchComponentKeyForTask(getTask().key));
|
||||||
mActivity.getStatsLogManager().log(TASK_LAUNCH_TAP, buildProto());
|
mActivity.getStatsLogManager().log(LAUNCHER_TASK_LAUNCH_TAP, buildProto());
|
||||||
});
|
});
|
||||||
|
|
||||||
mCurrentFullscreenParams = new FullscreenDrawParams(context);
|
mCurrentFullscreenParams = new FullscreenDrawParams(context);
|
||||||
@@ -449,13 +449,13 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
|||||||
|
|
||||||
public void setOrientationState(RecentsOrientedState orientationState) {
|
public void setOrientationState(RecentsOrientedState orientationState) {
|
||||||
PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler();
|
PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler();
|
||||||
boolean isRtl = orientationHandler.getRecentsRtlSetting(getResources());
|
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
|
||||||
LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
|
LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
|
||||||
int thumbnailPadding = (int) getResources().getDimension(R.dimen.task_thumbnail_top_margin);
|
int thumbnailPadding = (int) getResources().getDimension(R.dimen.task_thumbnail_top_margin);
|
||||||
LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
|
LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
|
||||||
switch (orientationHandler.getRotation()) {
|
switch (orientationHandler.getRotation()) {
|
||||||
case Surface.ROTATION_90:
|
case Surface.ROTATION_90:
|
||||||
iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL;
|
iconParams.gravity = (isRtl ? START : END) | CENTER_VERTICAL;
|
||||||
iconParams.rightMargin = -thumbnailPadding;
|
iconParams.rightMargin = -thumbnailPadding;
|
||||||
iconParams.leftMargin = 0;
|
iconParams.leftMargin = 0;
|
||||||
iconParams.topMargin = snapshotParams.topMargin / 2;
|
iconParams.topMargin = snapshotParams.topMargin / 2;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="recent_task_option_split_screen" msgid="5353188922202653570">"Splitscreen"</string>
|
<string name="recent_task_option_split_screen" msgid="5353188922202653570">"Splitscreen"</string>
|
||||||
<string name="recent_task_option_pin" msgid="7929860679018978258">"Anpinnen"</string>
|
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fixieren"</string>
|
||||||
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform-Modus"</string>
|
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform-Modus"</string>
|
||||||
<string name="recents_empty_message" msgid="7040467240571714191">"Keine kürzlich verwendeten Elemente"</string>
|
<string name="recents_empty_message" msgid="7040467240571714191">"Keine kürzlich verwendeten Elemente"</string>
|
||||||
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Einstellungen zur App-Nutzung"</string>
|
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Einstellungen zur App-Nutzung"</string>
|
||||||
|
|||||||
@@ -17,14 +17,15 @@
|
|||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<dimen name="task_thumbnail_top_margin">24dp</dimen>
|
<dimen name="task_thumbnail_top_margin">24dp</dimen>
|
||||||
<dimen name="task_thumbnail_bottom_margin_with_actions">44dp</dimen>
|
|
||||||
<dimen name="task_thumbnail_half_top_margin">12dp</dimen>
|
<dimen name="task_thumbnail_half_top_margin">12dp</dimen>
|
||||||
<dimen name="task_thumbnail_icon_size">48dp</dimen>
|
<dimen name="task_thumbnail_icon_size">48dp</dimen>
|
||||||
<!-- For screens without rounded corners -->
|
<!-- For screens without rounded corners -->
|
||||||
<dimen name="task_corner_radius_small">2dp</dimen>
|
<dimen name="task_corner_radius_small">2dp</dimen>
|
||||||
|
|
||||||
<!-- Overrideable in overlay that provides the Overview Actions. -->
|
<!-- Overrideable in overlay that provides the Overview Actions. -->
|
||||||
<dimen name="overview_actions_height">110dp</dimen>
|
<dimen name="overview_actions_height">66dp</dimen>
|
||||||
|
<dimen name="overview_actions_bottom_margin_gesture">16dp</dimen>
|
||||||
|
<dimen name="overview_actions_bottom_margin_three_button">8dp</dimen>
|
||||||
<dimen name="overview_actions_horizontal_margin">16dp</dimen>
|
<dimen name="overview_actions_horizontal_margin">16dp</dimen>
|
||||||
|
|
||||||
<dimen name="recents_page_spacing">10dp</dimen>
|
<dimen name="recents_page_spacing">10dp</dimen>
|
||||||
@@ -61,7 +62,8 @@
|
|||||||
<dimen name="task_card_menu_shadow_height">3dp</dimen>
|
<dimen name="task_card_menu_shadow_height">3dp</dimen>
|
||||||
<dimen name="task_card_menu_horizontal_padding">0dp</dimen>
|
<dimen name="task_card_menu_horizontal_padding">0dp</dimen>
|
||||||
<dimen name="portrait_task_card_horz_space">136dp</dimen>
|
<dimen name="portrait_task_card_horz_space">136dp</dimen>
|
||||||
<dimen name="portrait_task_card_horz_space_big_overview">24dp</dimen>
|
<dimen name="portrait_task_card_horz_space_big_overview">96dp</dimen>
|
||||||
|
<dimen name="portrait_modal_task_card_horz_space">60dp</dimen>
|
||||||
<dimen name="landscape_task_card_horz_space">200dp</dimen>
|
<dimen name="landscape_task_card_horz_space">200dp</dimen>
|
||||||
<dimen name="multi_window_task_card_horz_space">100dp</dimen>
|
<dimen name="multi_window_task_card_horz_space">100dp</dimen>
|
||||||
<!-- Copied from framework resource:
|
<!-- Copied from framework resource:
|
||||||
|
|||||||
@@ -128,16 +128,18 @@
|
|||||||
<!-- Feedback shown during interactive parts of Home gesture tutorial when the gesture is horizontal instead of vertical. [CHAR LIMIT=100] -->
|
<!-- Feedback shown during interactive parts of Home gesture tutorial when the gesture is horizontal instead of vertical. [CHAR LIMIT=100] -->
|
||||||
<string name="home_gesture_feedback_wrong_swipe_direction" translatable="false">Make sure you swipe straight up</string>
|
<string name="home_gesture_feedback_wrong_swipe_direction" translatable="false">Make sure you swipe straight up</string>
|
||||||
|
|
||||||
<!-- Title shown on the confirmation screen after successful gesture. [CHAR LIMIT=30] -->
|
<!-- Title shown on the confirmation screen after successful gesture. [CHAR LIMIT=30] -->
|
||||||
<string name="gesture_tutorial_confirm_title" translatable="false">All set</string>
|
<string name="gesture_tutorial_confirm_title" translatable="false">All set</string>
|
||||||
<!-- Button text shown on a button on the confirm screen. [CHAR LIMIT=14] -->
|
<!-- Button text shown on a button on the confirm screen to leave the tutorial. [CHAR LIMIT=14] -->
|
||||||
<string name="gesture_tutorial_action_button_label" translatable="false">Done</string>
|
<string name="gesture_tutorial_action_button_label_done" translatable="false">Done</string>
|
||||||
<!-- Button text shown on a text button on the confirm screen. [CHAR LIMIT=14] -->
|
<!-- Button text shown on a button to go to Settings. [CHAR LIMIT=14] -->
|
||||||
<string name="gesture_tutorial_action_text_button_label" translatable="false">Settings</string>
|
<string name="gesture_tutorial_action_button_label_settings" translatable="false">Settings</string>
|
||||||
|
|
||||||
<!-- ******* Overview ******* -->
|
<!-- ******* Overview ******* -->
|
||||||
<!-- Label for a button that causes the current overview app to be shared. [CHAR_LIMIT=40] -->
|
<!-- Label for a button that causes the current overview app to be shared. [CHAR_LIMIT=40] -->
|
||||||
<string name="action_share">Share</string>
|
<string name="action_share">Share</string>
|
||||||
<!-- Label for a button that causes a screen shot of the current app to be taken. [CHAR_LIMIT=40] -->
|
<!-- Label for a button that causes a screen shot of the current app to be taken. [CHAR_LIMIT=40] -->
|
||||||
<string name="action_screenshot">Screenshot</string>
|
<string name="action_screenshot">Screenshot</string>
|
||||||
|
<!-- Message shown when an action is blocked by a policy enforced by the app or the organization managing the device. [CHAR_LIMIT=NONE] -->
|
||||||
|
<string name="blocked_by_policy">This action isn\'t allowed by the app or your organization</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -79,8 +79,8 @@
|
|||||||
|
|
||||||
<style name="OverviewActionButton"
|
<style name="OverviewActionButton"
|
||||||
parent="@android:style/Widget.DeviceDefault.Button.Borderless">
|
parent="@android:style/Widget.DeviceDefault.Button.Borderless">
|
||||||
<item name="android:textColor">?attr/workspaceTextColor</item>
|
<item name="android:textColor">@color/overview_button</item>
|
||||||
<item name="android:drawableTint">?attr/workspaceTextColor</item>
|
<item name="android:drawableTint">@color/overview_button</item>
|
||||||
<item name="android:tint">?attr/workspaceTextColor</item>
|
<item name="android:tint">?attr/workspaceTextColor</item>
|
||||||
<item name="android:drawablePadding">4dp</item>
|
<item name="android:drawablePadding">4dp</item>
|
||||||
<item name="android:textAllCaps">false</item>
|
<item name="android:textAllCaps">false</item>
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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;
|
||||||
|
|
||||||
|
import static com.android.launcher3.util.LauncherUIHelper.doLayout;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Bitmap.Config;
|
||||||
|
|
||||||
|
import com.android.quickstep.fallback.FallbackRecentsView;
|
||||||
|
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.Robolectric;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.android.controller.ActivityController;
|
||||||
|
import org.robolectric.annotation.LooperMode;
|
||||||
|
import org.robolectric.annotation.LooperMode.Mode;
|
||||||
|
import org.robolectric.shadows.ShadowLooper;
|
||||||
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
@LooperMode(Mode.PAUSED)
|
||||||
|
public class RecentsActivityTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRecentsActivityCreates() {
|
||||||
|
ActivityController<RecentsActivity> controller =
|
||||||
|
Robolectric.buildActivity(RecentsActivity.class);
|
||||||
|
|
||||||
|
RecentsActivity launcher = controller.setup().get();
|
||||||
|
doLayout(launcher);
|
||||||
|
|
||||||
|
// TODO: Ensure that LauncherAppState is not created
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRecets_showCurrentTask() {
|
||||||
|
ActivityController<RecentsActivity> controller =
|
||||||
|
Robolectric.buildActivity(RecentsActivity.class);
|
||||||
|
|
||||||
|
RecentsActivity activity = controller.setup().get();
|
||||||
|
doLayout(activity);
|
||||||
|
|
||||||
|
FallbackRecentsView frv = activity.getOverviewPanel();
|
||||||
|
frv.showCurrentTask(22);
|
||||||
|
doLayout(activity);
|
||||||
|
|
||||||
|
ThumbnailData thumbnailData = new ThumbnailData();
|
||||||
|
ReflectionHelpers.setField(thumbnailData, "thumbnail",
|
||||||
|
Bitmap.createBitmap(300, 500, Config.ARGB_8888));
|
||||||
|
frv.switchToScreenshot(thumbnailData, () -> { });
|
||||||
|
ShadowLooper.idleMainLooper();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,7 +30,6 @@ import android.content.SharedPreferences;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.CancellationSignal;
|
import android.os.CancellationSignal;
|
||||||
|
|
||||||
import com.android.launcher3.LauncherStateManager.StateHandler;
|
|
||||||
import com.android.launcher3.config.FeatureFlags;
|
import com.android.launcher3.config.FeatureFlags;
|
||||||
import com.android.launcher3.model.WellbeingModel;
|
import com.android.launcher3.model.WellbeingModel;
|
||||||
import com.android.launcher3.popup.SystemShortcut;
|
import com.android.launcher3.popup.SystemShortcut;
|
||||||
@@ -38,6 +37,7 @@ import com.android.launcher3.proxy.ProxyActivityStarter;
|
|||||||
import com.android.launcher3.proxy.StartActivityParams;
|
import com.android.launcher3.proxy.StartActivityParams;
|
||||||
import com.android.launcher3.statehandlers.BackButtonAlphaHandler;
|
import com.android.launcher3.statehandlers.BackButtonAlphaHandler;
|
||||||
import com.android.launcher3.statehandlers.DepthController;
|
import com.android.launcher3.statehandlers.DepthController;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateHandler;
|
||||||
import com.android.launcher3.uioverrides.RecentsViewStateController;
|
import com.android.launcher3.uioverrides.RecentsViewStateController;
|
||||||
import com.android.launcher3.util.OnboardingPrefs;
|
import com.android.launcher3.util.OnboardingPrefs;
|
||||||
import com.android.launcher3.util.UiThreadHelper;
|
import com.android.launcher3.util.UiThreadHelper;
|
||||||
@@ -92,6 +92,9 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
|||||||
@Override
|
@Override
|
||||||
public void onNavigationModeChanged(Mode newMode) {
|
public void onNavigationModeChanged(Mode newMode) {
|
||||||
getDragLayer().recreateControllers();
|
getDragLayer().recreateControllers();
|
||||||
|
if (mActionsView != null && isOverviewActionsEnabled()) {
|
||||||
|
mActionsView.updateVerticalMarginForNavModeChange(newMode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -150,6 +153,7 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDeferredResumed() {
|
protected void onDeferredResumed() {
|
||||||
|
super.onDeferredResumed();
|
||||||
if (mPendingActivityRequestCode != -1 && isInState(NORMAL)) {
|
if (mPendingActivityRequestCode != -1 && isInState(NORMAL)) {
|
||||||
// Remove any active ProxyActivityStarter task and send RESULT_CANCELED to Launcher.
|
// Remove any active ProxyActivityStarter task and send RESULT_CANCELED to Launcher.
|
||||||
onActivityResult(mPendingActivityRequestCode, RESULT_CANCELED, null);
|
onActivityResult(mPendingActivityRequestCode, RESULT_CANCELED, null);
|
||||||
@@ -167,13 +171,18 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
|||||||
mActionsView = findViewById(R.id.overview_actions_view);
|
mActionsView = findViewById(R.id.overview_actions_view);
|
||||||
((RecentsView) getOverviewPanel()).init(mActionsView);
|
((RecentsView) getOverviewPanel()).init(mActionsView);
|
||||||
|
|
||||||
if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(this)) {
|
if (isOverviewActionsEnabled()) {
|
||||||
// Overview is above all other launcher elements, including qsb, so move it to the top.
|
// Overview is above all other launcher elements, including qsb, so move it to the top.
|
||||||
getOverviewPanel().bringToFront();
|
getOverviewPanel().bringToFront();
|
||||||
mActionsView.bringToFront();
|
mActionsView.bringToFront();
|
||||||
|
mActionsView.updateVerticalMarginForNavModeChange(SysUINavigationMode.getMode(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isOverviewActionsEnabled() {
|
||||||
|
return FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(this);
|
||||||
|
}
|
||||||
|
|
||||||
public <T extends OverviewActionsView> T getActionsView() {
|
public <T extends OverviewActionsView> T getActionsView() {
|
||||||
return (T) mActionsView;
|
return (T) mActionsView;
|
||||||
}
|
}
|
||||||
@@ -186,7 +195,7 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected StateHandler[] createStateHandlers() {
|
protected StateHandler<LauncherState>[] createStateHandlers() {
|
||||||
return new StateHandler[] {
|
return new StateHandler[] {
|
||||||
getAllAppsController(),
|
getAllAppsController(),
|
||||||
getWorkspace(),
|
getWorkspace(),
|
||||||
@@ -200,9 +209,8 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected OnboardingPrefs createOnboardingPrefs(SharedPreferences sharedPrefs,
|
protected OnboardingPrefs createOnboardingPrefs(SharedPreferences sharedPrefs) {
|
||||||
LauncherStateManager stateManager) {
|
return new QuickstepOnboardingPrefs(this, sharedPrefs);
|
||||||
return new QuickstepOnboardingPrefs(this, sharedPrefs, stateManager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -16,14 +16,13 @@
|
|||||||
|
|
||||||
package com.android.launcher3.statehandlers;
|
package com.android.launcher3.statehandlers;
|
||||||
|
|
||||||
import static com.android.launcher3.LauncherState.FLAG_HIDE_BACK_BUTTON;
|
|
||||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||||
import static com.android.quickstep.AnimatedFloat.VALUE;
|
import static com.android.quickstep.AnimatedFloat.VALUE;
|
||||||
|
|
||||||
import com.android.launcher3.BaseQuickstepLauncher;
|
import com.android.launcher3.BaseQuickstepLauncher;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.LauncherStateManager;
|
|
||||||
import com.android.launcher3.anim.PendingAnimation;
|
import com.android.launcher3.anim.PendingAnimation;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateHandler;
|
||||||
import com.android.launcher3.states.StateAnimationConfig;
|
import com.android.launcher3.states.StateAnimationConfig;
|
||||||
import com.android.launcher3.util.UiThreadHelper;
|
import com.android.launcher3.util.UiThreadHelper;
|
||||||
import com.android.quickstep.AnimatedFloat;
|
import com.android.quickstep.AnimatedFloat;
|
||||||
@@ -33,7 +32,7 @@ import com.android.quickstep.SystemUiProxy;
|
|||||||
/**
|
/**
|
||||||
* State handler for animating back button alpha
|
* State handler for animating back button alpha
|
||||||
*/
|
*/
|
||||||
public class BackButtonAlphaHandler implements LauncherStateManager.StateHandler {
|
public class BackButtonAlphaHandler implements StateHandler<LauncherState> {
|
||||||
|
|
||||||
private final BaseQuickstepLauncher mLauncher;
|
private final BaseQuickstepLauncher mLauncher;
|
||||||
private final AnimatedFloat mBackAlpha = new AnimatedFloat(this::updateBackAlpha);
|
private final AnimatedFloat mBackAlpha = new AnimatedFloat(this::updateBackAlpha);
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ import android.view.ViewTreeObserver;
|
|||||||
|
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.LauncherStateManager;
|
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.anim.PendingAnimation;
|
import com.android.launcher3.anim.PendingAnimation;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateHandler;
|
||||||
import com.android.launcher3.states.StateAnimationConfig;
|
import com.android.launcher3.states.StateAnimationConfig;
|
||||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
import com.android.systemui.shared.system.SurfaceControlCompat;
|
import com.android.systemui.shared.system.SurfaceControlCompat;
|
||||||
@@ -39,7 +39,7 @@ import com.android.systemui.shared.system.WallpaperManagerCompat;
|
|||||||
/**
|
/**
|
||||||
* Controls blur and wallpaper zoom, for the Launcher surface only.
|
* Controls blur and wallpaper zoom, for the Launcher surface only.
|
||||||
*/
|
*/
|
||||||
public class DepthController implements LauncherStateManager.StateHandler {
|
public class DepthController implements StateHandler<LauncherState> {
|
||||||
|
|
||||||
public static final FloatProperty<DepthController> DEPTH =
|
public static final FloatProperty<DepthController> DEPTH =
|
||||||
new FloatProperty<DepthController>("depth") {
|
new FloatProperty<DepthController>("depth") {
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ import androidx.annotation.NonNull;
|
|||||||
|
|
||||||
import com.android.launcher3.BaseQuickstepLauncher;
|
import com.android.launcher3.BaseQuickstepLauncher;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.LauncherStateManager.StateHandler;
|
|
||||||
import com.android.launcher3.anim.PendingAnimation;
|
import com.android.launcher3.anim.PendingAnimation;
|
||||||
import com.android.launcher3.graphics.OverviewScrim;
|
import com.android.launcher3.graphics.OverviewScrim;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateHandler;
|
||||||
import com.android.launcher3.states.StateAnimationConfig;
|
import com.android.launcher3.states.StateAnimationConfig;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ import com.android.quickstep.views.RecentsView;
|
|||||||
* @param <T> the recents view
|
* @param <T> the recents view
|
||||||
*/
|
*/
|
||||||
public abstract class BaseRecentsViewStateController<T extends RecentsView>
|
public abstract class BaseRecentsViewStateController<T extends RecentsView>
|
||||||
implements StateHandler {
|
implements StateHandler<LauncherState> {
|
||||||
protected final T mRecentsView;
|
protected final T mRecentsView;
|
||||||
protected final BaseQuickstepLauncher mLauncher;
|
protected final BaseQuickstepLauncher mLauncher;
|
||||||
|
|
||||||
|
|||||||
@@ -18,14 +18,11 @@ package com.android.quickstep;
|
|||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.Pair;
|
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.animation.Interpolator;
|
import android.view.animation.Interpolator;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
|
|
||||||
@@ -33,7 +30,6 @@ import com.android.launcher3.BaseDraggingActivity;
|
|||||||
import com.android.launcher3.DeviceProfile;
|
import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||||
import com.android.launcher3.statehandlers.DepthController;
|
import com.android.launcher3.statehandlers.DepthController;
|
||||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
|
||||||
import com.android.quickstep.util.ActivityInitListener;
|
import com.android.quickstep.util.ActivityInitListener;
|
||||||
import com.android.quickstep.util.ShelfPeekAnim;
|
import com.android.quickstep.util.ShelfPeekAnim;
|
||||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
@@ -52,24 +48,13 @@ public interface BaseActivityInterface<T extends BaseDraggingActivity> {
|
|||||||
|
|
||||||
int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect);
|
int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect);
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The progress of the swipe where we start resisting the user, where 0 is fullscreen
|
|
||||||
* and 1 is recents. These values should probably be greater than 1 to let the user swipe past
|
|
||||||
* recents before we start resisting them.
|
|
||||||
*/
|
|
||||||
default Pair<Float, Float> getSwipeUpPullbackStartAndMaxProgress() {
|
|
||||||
return new Pair<>(1.4f, 1.8f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void onSwipeUpToRecentsComplete();
|
void onSwipeUpToRecentsComplete();
|
||||||
|
|
||||||
default void onSwipeUpToHomeComplete() { }
|
default void onSwipeUpToHomeComplete() { }
|
||||||
void onAssistantVisibilityChanged(float visibility);
|
void onAssistantVisibilityChanged(float visibility);
|
||||||
|
|
||||||
@NonNull HomeAnimationFactory prepareHomeUI();
|
AnimationFactory prepareRecentsUI(
|
||||||
|
boolean activityVisible, Consumer<AnimatorPlaybackController> callback);
|
||||||
AnimationFactory prepareRecentsUI(boolean activityVisible, boolean animateActivity,
|
|
||||||
Consumer<AnimatorPlaybackController> callback);
|
|
||||||
|
|
||||||
ActivityInitListener createActivityInitListener(Predicate<Boolean> onInitListener);
|
ActivityInitListener createActivityInitListener(Predicate<Boolean> onInitListener);
|
||||||
|
|
||||||
@@ -152,35 +137,4 @@ public interface BaseActivityInterface<T extends BaseDraggingActivity> {
|
|||||||
*/
|
*/
|
||||||
default void setRecentsAttachedToAppWindow(boolean attached, boolean animate) { }
|
default void setRecentsAttachedToAppWindow(boolean attached, boolean animate) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HomeAnimationFactory {
|
|
||||||
|
|
||||||
/** Return the floating view that will animate in sync with the closing window. */
|
|
||||||
default @Nullable View getFloatingView() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull RectF getWindowTargetRect();
|
|
||||||
|
|
||||||
@NonNull AnimatorPlaybackController createActivityAnimationToHome();
|
|
||||||
|
|
||||||
default void playAtomicAnimation(float velocity) {
|
|
||||||
// No-op
|
|
||||||
}
|
|
||||||
|
|
||||||
static RectF getDefaultWindowTargetRect(PagedOrientationHandler orientationHandler,
|
|
||||||
DeviceProfile dp) {
|
|
||||||
final int halfIconSize = dp.iconSizePx / 2;
|
|
||||||
float primaryDimension = orientationHandler
|
|
||||||
.getPrimaryValue(dp.availableWidthPx, dp.availableHeightPx);
|
|
||||||
float secondaryDimension = orientationHandler
|
|
||||||
.getSecondaryValue(dp.availableWidthPx, dp.availableHeightPx);
|
|
||||||
final float targetX = primaryDimension / 2f;
|
|
||||||
final float targetY = secondaryDimension - dp.hotseatBarSizePx;
|
|
||||||
// Fallback to animate to center of screen.
|
|
||||||
return new RectF(targetX - halfIconSize, targetY - halfIconSize,
|
|
||||||
targetX + halfIconSize, targetY + halfIconSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,168 +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;
|
|
||||||
|
|
||||||
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
|
|
||||||
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import com.android.launcher3.AbstractFloatingView;
|
|
||||||
import com.android.launcher3.BaseDraggingActivity;
|
|
||||||
import com.android.launcher3.DeviceProfile;
|
|
||||||
import com.android.launcher3.InvariantDeviceProfile;
|
|
||||||
import com.android.launcher3.R;
|
|
||||||
import com.android.launcher3.util.ActivityTracker;
|
|
||||||
import com.android.launcher3.util.SystemUiController;
|
|
||||||
import com.android.launcher3.util.Themes;
|
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A base fallback recents activity that provides support for device profile changes, activity
|
|
||||||
* lifecycle tracking, and basic input handling from recents.
|
|
||||||
*
|
|
||||||
* This class is only used as a fallback in case the default launcher does not have a recents
|
|
||||||
* implementation.
|
|
||||||
*/
|
|
||||||
public abstract class BaseRecentsActivity extends BaseDraggingActivity {
|
|
||||||
|
|
||||||
public static final ActivityTracker<BaseRecentsActivity> ACTIVITY_TRACKER =
|
|
||||||
new ActivityTracker<>();
|
|
||||||
private Configuration mOldConfig;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
mOldConfig = new Configuration(getResources().getConfiguration());
|
|
||||||
initDeviceProfile();
|
|
||||||
initViews();
|
|
||||||
|
|
||||||
getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
|
|
||||||
Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
|
|
||||||
ACTIVITY_TRACKER.handleCreate(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Init drag layer and overview panel views.
|
|
||||||
*/
|
|
||||||
abstract protected void initViews();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConfigurationChanged(Configuration newConfig) {
|
|
||||||
int diff = newConfig.diff(mOldConfig);
|
|
||||||
if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) {
|
|
||||||
onHandleConfigChanged();
|
|
||||||
}
|
|
||||||
mOldConfig.setTo(newConfig);
|
|
||||||
super.onConfigurationChanged(newConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logic for when device configuration changes (rotation, screen size change, multi-window,
|
|
||||||
* etc.)
|
|
||||||
*/
|
|
||||||
protected void onHandleConfigChanged() {
|
|
||||||
mUserEventDispatcher = null;
|
|
||||||
initDeviceProfile();
|
|
||||||
|
|
||||||
AbstractFloatingView.closeOpenViews(this, true,
|
|
||||||
AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE);
|
|
||||||
dispatchDeviceProfileChanged();
|
|
||||||
|
|
||||||
reapplyUi();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize/update the device profile.
|
|
||||||
*/
|
|
||||||
private void initDeviceProfile() {
|
|
||||||
mDeviceProfile = createDeviceProfile();
|
|
||||||
onDeviceProfileInitiated();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate the device profile to use in this activity.
|
|
||||||
* @return device profile
|
|
||||||
*/
|
|
||||||
protected DeviceProfile createDeviceProfile() {
|
|
||||||
DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this);
|
|
||||||
|
|
||||||
// In case we are reusing IDP, create a copy so that we don't conflict with Launcher
|
|
||||||
// activity.
|
|
||||||
return dp.copy(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
|
|
||||||
// Workaround for b/78520668, explicitly trim memory once UI is hidden
|
|
||||||
onTrimMemory(TRIM_MEMORY_UI_HIDDEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnterAnimationComplete() {
|
|
||||||
super.onEnterAnimationComplete();
|
|
||||||
// After the transition to home, enable the high-res thumbnail loader if it wasn't enabled
|
|
||||||
// as a part of quickstep, so that high-res thumbnails can load the next time we enter
|
|
||||||
// overview
|
|
||||||
RecentsModel.INSTANCE.get(this).getThumbnailCache()
|
|
||||||
.getHighResLoadingState().setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTrimMemory(int level) {
|
|
||||||
super.onTrimMemory(level);
|
|
||||||
RecentsModel.INSTANCE.get(this).onTrimMemory(level);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onNewIntent(Intent intent) {
|
|
||||||
super.onNewIntent(intent);
|
|
||||||
ACTIVITY_TRACKER.handleNewIntent(this, intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
ACTIVITY_TRACKER.onActivityDestroyed(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBackPressed() {
|
|
||||||
// TODO: Launch the task we came from
|
|
||||||
startHome();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startHome() {
|
|
||||||
startActivity(new Intent(Intent.ACTION_MAIN)
|
|
||||||
.addCategory(Intent.CATEGORY_HOME)
|
|
||||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
|
|
||||||
super.dump(prefix, fd, writer, args);
|
|
||||||
writer.println(prefix + "Misc:");
|
|
||||||
dumpMisc(prefix + "\t", writer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -110,10 +110,6 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
|||||||
public static final int STATE_RECENTS_SCROLLING_FINISHED =
|
public static final int STATE_RECENTS_SCROLLING_FINISHED =
|
||||||
getFlagForIndex("STATE_RECENTS_SCROLLING_FINISHED");
|
getFlagForIndex("STATE_RECENTS_SCROLLING_FINISHED");
|
||||||
|
|
||||||
// Called when the new task appeared from quick switching.
|
|
||||||
public static final int STATE_TASK_APPEARED_DURING_SWITCH =
|
|
||||||
getFlagForIndex("STATE_TASK_APPEARED_DURING_SWITCH");
|
|
||||||
|
|
||||||
// Needed to interact with the current activity
|
// Needed to interact with the current activity
|
||||||
private final Intent mHomeIntent;
|
private final Intent mHomeIntent;
|
||||||
private final Intent mOverviewIntent;
|
private final Intent mOverviewIntent;
|
||||||
@@ -123,9 +119,8 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
|||||||
|
|
||||||
private ActivityManager.RunningTaskInfo mRunningTask;
|
private ActivityManager.RunningTaskInfo mRunningTask;
|
||||||
private GestureEndTarget mEndTarget;
|
private GestureEndTarget mEndTarget;
|
||||||
private RemoteAnimationTargetCompat mAnimationTarget;
|
private RemoteAnimationTargetCompat mLastAppearedTaskTarget;
|
||||||
// TODO: This can be removed once we stop finishing the animation when starting a new task
|
private int mLastStartedTaskId = -1;
|
||||||
private int mFinishingRecentsAnimationTaskId = -1;
|
|
||||||
|
|
||||||
public GestureState(OverviewComponentObserver componentObserver, int gestureId) {
|
public GestureState(OverviewComponentObserver componentObserver, int gestureId) {
|
||||||
mHomeIntent = componentObserver.getHomeIntent();
|
mHomeIntent = componentObserver.getHomeIntent();
|
||||||
@@ -143,7 +138,8 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
|||||||
mGestureId = other.mGestureId;
|
mGestureId = other.mGestureId;
|
||||||
mRunningTask = other.mRunningTask;
|
mRunningTask = other.mRunningTask;
|
||||||
mEndTarget = other.mEndTarget;
|
mEndTarget = other.mEndTarget;
|
||||||
mFinishingRecentsAnimationTaskId = other.mFinishingRecentsAnimationTaskId;
|
mLastAppearedTaskTarget = other.mLastAppearedTaskTarget;
|
||||||
|
mLastStartedTaskId = other.mLastStartedTaskId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GestureState() {
|
public GestureState() {
|
||||||
@@ -225,6 +221,35 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
|||||||
mRunningTask = runningTask;
|
mRunningTask = runningTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the last task that appeared during this gesture.
|
||||||
|
*/
|
||||||
|
public void updateLastAppearedTaskTarget(RemoteAnimationTargetCompat lastAppearedTaskTarget) {
|
||||||
|
mLastAppearedTaskTarget = lastAppearedTaskTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The id of the task that appeared during this gesture.
|
||||||
|
*/
|
||||||
|
public int getLastAppearedTaskId() {
|
||||||
|
return mLastAppearedTaskTarget != null ? mLastAppearedTaskTarget.taskId : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the last task that we started via startActivityFromRecents() during this gesture.
|
||||||
|
*/
|
||||||
|
public void updateLastStartedTaskId(int lastStartedTaskId) {
|
||||||
|
mLastStartedTaskId = lastStartedTaskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The id of the task that was most recently started during this gesture, or -1 if
|
||||||
|
* no task has been started yet (i.e. we haven't settled on a new task).
|
||||||
|
*/
|
||||||
|
public int getLastStartedTaskId() {
|
||||||
|
return mLastStartedTaskId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the end target for this gesture (if known).
|
* @return the end target for this gesture (if known).
|
||||||
*/
|
*/
|
||||||
@@ -232,14 +257,6 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
|||||||
return mEndTarget;
|
return mEndTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAnimationTarget(RemoteAnimationTargetCompat target) {
|
|
||||||
mAnimationTarget = target;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RemoteAnimationTargetCompat getAnimationTarget() {
|
|
||||||
return mAnimationTarget;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the end target of this gesture and immediately notifies the state changes.
|
* Sets the end target of this gesture and immediately notifies the state changes.
|
||||||
*/
|
*/
|
||||||
@@ -259,30 +276,9 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the id for the task that was about to be launched following the finish of the recents
|
|
||||||
* animation. Only defined between when the finish-recents call was made and the launch
|
|
||||||
* activity call is made.
|
|
||||||
*/
|
|
||||||
public int getFinishingRecentsAnimationTaskId() {
|
|
||||||
return mFinishingRecentsAnimationTaskId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the id for the task will be launched after the recents animation is finished. Once the
|
|
||||||
* animation has finished then the id will be reset to -1.
|
|
||||||
*/
|
|
||||||
public void setFinishingRecentsAnimationTaskId(int taskId) {
|
|
||||||
mFinishingRecentsAnimationTaskId = taskId;
|
|
||||||
mStateCallback.runOnceAtState(STATE_RECENTS_ANIMATION_FINISHED, () -> {
|
|
||||||
mFinishingRecentsAnimationTaskId = -1;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return whether the current gesture is still running a recents animation to a state in the
|
* @return whether the current gesture is still running a recents animation to a state in the
|
||||||
* Launcher or Recents activity.
|
* Launcher or Recents activity.
|
||||||
* Updates the running task for the gesture to be the given {@param runningTask}.
|
|
||||||
*/
|
*/
|
||||||
public boolean isRunningAnimationToLauncher() {
|
public boolean isRunningAnimationToLauncher() {
|
||||||
return isRecentsAnimationRunning() && mEndTarget != null && mEndTarget.isLauncher;
|
return isRecentsAnimationRunning() && mEndTarget != null && mEndTarget.isLauncher;
|
||||||
@@ -314,18 +310,13 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
|||||||
mStateCallback.setState(STATE_RECENTS_ANIMATION_ENDED);
|
mStateCallback.setState(STATE_RECENTS_ANIMATION_ENDED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTaskAppeared(RemoteAnimationTargetCompat app) {
|
|
||||||
mAnimationTarget = app;
|
|
||||||
mStateCallback.setState(STATE_TASK_APPEARED_DURING_SWITCH);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dump(PrintWriter pw) {
|
public void dump(PrintWriter pw) {
|
||||||
pw.println("GestureState:");
|
pw.println("GestureState:");
|
||||||
pw.println(" gestureID=" + mGestureId);
|
pw.println(" gestureID=" + mGestureId);
|
||||||
pw.println(" runningTask=" + mRunningTask);
|
pw.println(" runningTask=" + mRunningTask);
|
||||||
pw.println(" endTarget=" + mEndTarget);
|
pw.println(" endTarget=" + mEndTarget);
|
||||||
pw.println(" finishingRecentsAnimationTaskId=" + mFinishingRecentsAnimationTaskId);
|
pw.println(" lastAppearedTaskTarget=" + mLastAppearedTaskTarget);
|
||||||
|
pw.println(" lastStartedTaskId=" + mLastStartedTaskId);
|
||||||
pw.println(" isRecentsAnimationRunning=" + isRecentsAnimationRunning());
|
pw.println(" isRecentsAnimationRunning=" + isRecentsAnimationRunning());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,8 +154,7 @@ public class RecentTasksList extends TaskStackChangeListener {
|
|||||||
* Loads and creates a list of all the recent tasks.
|
* Loads and creates a list of all the recent tasks.
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
ArrayList<Task> loadTasksInBackground(int numTasks,
|
ArrayList<Task> loadTasksInBackground(int numTasks, boolean loadKeysOnly) {
|
||||||
boolean loadKeysOnly) {
|
|
||||||
int currentUserId = Process.myUserHandle().getIdentifier();
|
int currentUserId = Process.myUserHandle().getIdentifier();
|
||||||
ArrayList<Task> allTasks = new ArrayList<>();
|
ArrayList<Task> allTasks = new ArrayList<>();
|
||||||
List<ActivityManager.RecentTaskInfo> rawTasks =
|
List<ActivityManager.RecentTaskInfo> rawTasks =
|
||||||
@@ -174,9 +173,7 @@ public class RecentTasksList extends TaskStackChangeListener {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int taskCount = rawTasks.size();
|
for (ActivityManager.RecentTaskInfo rawTask : rawTasks) {
|
||||||
for (int i = 0; i < taskCount; i++) {
|
|
||||||
ActivityManager.RecentTaskInfo rawTask = rawTasks.get(i);
|
|
||||||
Task.TaskKey taskKey = new Task.TaskKey(rawTask);
|
Task.TaskKey taskKey = new Task.TaskKey(rawTask);
|
||||||
Task task;
|
Task task;
|
||||||
if (!loadKeysOnly) {
|
if (!loadKeysOnly) {
|
||||||
|
|||||||
@@ -159,6 +159,6 @@ public class RecentsAnimationCallbacks implements
|
|||||||
/**
|
/**
|
||||||
* Callback made when a task started from the recents is ready for an app transition.
|
* Callback made when a task started from the recents is ready for an app transition.
|
||||||
*/
|
*/
|
||||||
default void onTaskAppeared(RemoteAnimationTargetCompat app) {}
|
default void onTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.quickstep;
|
|||||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||||
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_INITIALIZED;
|
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_INITIALIZED;
|
||||||
|
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_STARTED;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -28,6 +29,7 @@ import com.android.launcher3.Utilities;
|
|||||||
import com.android.launcher3.config.FeatureFlags;
|
import com.android.launcher3.config.FeatureFlags;
|
||||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||||
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
|
|
||||||
public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAnimationListener {
|
public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAnimationListener {
|
||||||
|
|
||||||
@@ -36,6 +38,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
|||||||
private RecentsAnimationTargets mTargets;
|
private RecentsAnimationTargets mTargets;
|
||||||
// Temporary until we can hook into gesture state events
|
// Temporary until we can hook into gesture state events
|
||||||
private GestureState mLastGestureState;
|
private GestureState mLastGestureState;
|
||||||
|
private RemoteAnimationTargetCompat mLastAppearedTaskTarget;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preloads the recents animation.
|
* Preloads the recents animation.
|
||||||
@@ -79,6 +82,8 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
|||||||
}
|
}
|
||||||
mController = controller;
|
mController = controller;
|
||||||
mTargets = targets;
|
mTargets = targets;
|
||||||
|
mLastAppearedTaskTarget = mTargets.findTask(mLastGestureState.getRunningTaskId());
|
||||||
|
mLastGestureState.updateLastAppearedTaskTarget(mLastAppearedTaskTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -96,6 +101,20 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
|||||||
public void onRecentsAnimationFinished(RecentsAnimationController controller) {
|
public void onRecentsAnimationFinished(RecentsAnimationController controller) {
|
||||||
cleanUpRecentsAnimation(null /* canceledThumbnail */);
|
cleanUpRecentsAnimation(null /* canceledThumbnail */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget) {
|
||||||
|
if (mController != null) {
|
||||||
|
if (mLastAppearedTaskTarget == null
|
||||||
|
|| appearedTaskTarget.taskId != mLastAppearedTaskTarget.taskId) {
|
||||||
|
if (mLastAppearedTaskTarget != null) {
|
||||||
|
mController.removeTaskTarget(mLastAppearedTaskTarget);
|
||||||
|
}
|
||||||
|
mLastAppearedTaskTarget = appearedTaskTarget;
|
||||||
|
mLastGestureState.updateLastAppearedTaskTarget(mLastAppearedTaskTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
mCallbacks.addListener(gestureState);
|
mCallbacks.addListener(gestureState);
|
||||||
mCallbacks.addListener(listener);
|
mCallbacks.addListener(listener);
|
||||||
@@ -112,6 +131,9 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
|||||||
mCallbacks.removeListener(mLastGestureState);
|
mCallbacks.removeListener(mLastGestureState);
|
||||||
mLastGestureState = gestureState;
|
mLastGestureState = gestureState;
|
||||||
mCallbacks.addListener(gestureState);
|
mCallbacks.addListener(gestureState);
|
||||||
|
gestureState.setState(STATE_RECENTS_ANIMATION_INITIALIZED
|
||||||
|
| STATE_RECENTS_ANIMATION_STARTED);
|
||||||
|
gestureState.updateLastAppearedTaskTarget(mLastAppearedTaskTarget);
|
||||||
return mCallbacks;
|
return mCallbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,6 +193,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
|||||||
mCallbacks = null;
|
mCallbacks = null;
|
||||||
mTargets = null;
|
mTargets = null;
|
||||||
mLastGestureState = null;
|
mLastGestureState = null;
|
||||||
|
mLastAppearedTaskTarget = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dump() {
|
public void dump() {
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ final class BackGestureTutorialController extends TutorialController {
|
|||||||
@Override
|
@Override
|
||||||
Integer getActionButtonStringId() {
|
Integer getActionButtonStringId() {
|
||||||
if (mTutorialType == BACK_NAVIGATION_COMPLETE) {
|
if (mTutorialType == BACK_NAVIGATION_COMPLETE) {
|
||||||
return R.string.gesture_tutorial_action_button_label;
|
return R.string.gesture_tutorial_action_button_label_done;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ final class BackGestureTutorialController extends TutorialController {
|
|||||||
@Override
|
@Override
|
||||||
Integer getActionTextButtonStringId() {
|
Integer getActionTextButtonStringId() {
|
||||||
if (mTutorialType == BACK_NAVIGATION_COMPLETE) {
|
if (mTutorialType == BACK_NAVIGATION_COMPLETE) {
|
||||||
return R.string.gesture_tutorial_action_text_button_label;
|
return R.string.gesture_tutorial_action_button_label_settings;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,6 @@ final class BackGestureTutorialController extends TutorialController {
|
|||||||
@Override
|
@Override
|
||||||
void onActionTextButtonClicked(View button) {
|
void onActionTextButtonClicked(View button) {
|
||||||
mTutorialFragment.startSystemNavigationSetting();
|
mTutorialFragment.startSystemNavigationSetting();
|
||||||
mTutorialFragment.closeTutorial();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ final class HomeGestureTutorialController extends TutorialController {
|
|||||||
@Override
|
@Override
|
||||||
Integer getActionButtonStringId() {
|
Integer getActionButtonStringId() {
|
||||||
if (mTutorialType == HOME_NAVIGATION_COMPLETE) {
|
if (mTutorialType == HOME_NAVIGATION_COMPLETE) {
|
||||||
return R.string.gesture_tutorial_action_button_label;
|
return R.string.gesture_tutorial_action_button_label_done;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.quickstep.interaction;
|
package com.android.quickstep.interaction;
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Insets;
|
import android.graphics.Insets;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -35,8 +34,6 @@ import androidx.fragment.app.FragmentActivity;
|
|||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.quickstep.interaction.TutorialController.TutorialType;
|
import com.android.quickstep.interaction.TutorialController.TutorialType;
|
||||||
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
|
|
||||||
abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
||||||
|
|
||||||
private static final String LOG_TAG = "TutorialFragment";
|
private static final String LOG_TAG = "TutorialFragment";
|
||||||
@@ -182,14 +179,6 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void startSystemNavigationSetting() {
|
void startSystemNavigationSetting() {
|
||||||
try {
|
startActivity(new Intent("com.android.settings.GESTURE_NAVIGATION_SETTINGS"));
|
||||||
startActivityForResult(
|
|
||||||
Intent.parseUri(SYSTEM_NAVIGATION_SETTING_INTENT, /* flags= */ 0),
|
|
||||||
/* requestCode= */ 0);
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
Log.e(LOG_TAG, "The launch Intent Uri is wrong syntax: " + e);
|
|
||||||
} catch (ActivityNotFoundException e) {
|
|
||||||
Log.e(LOG_TAG, "The launch Activity not found: " + e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,17 +16,17 @@
|
|||||||
|
|
||||||
package com.android.quickstep.logging;
|
package com.android.quickstep.logging;
|
||||||
|
|
||||||
import static android.stats.launcher.nano.Launcher.ALLAPPS;
|
import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.FOLDER;
|
||||||
import static android.stats.launcher.nano.Launcher.BACKGROUND;
|
import static com.android.launcher3.logger.LauncherAtom.ItemInfo.ItemCase.WIDGET;
|
||||||
import static android.stats.launcher.nano.Launcher.HOME;
|
|
||||||
import static android.stats.launcher.nano.Launcher.OVERVIEW;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.launcher3.LauncherAppState;
|
import com.android.launcher3.LauncherAppState;
|
||||||
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.logger.LauncherAtom;
|
import com.android.launcher3.logger.LauncherAtom;
|
||||||
|
import com.android.launcher3.logging.InstanceId;
|
||||||
import com.android.launcher3.logging.StatsLogManager;
|
import com.android.launcher3.logging.StatsLogManager;
|
||||||
import com.android.launcher3.logging.StatsLogUtils;
|
|
||||||
import com.android.launcher3.model.AllAppsList;
|
import com.android.launcher3.model.AllAppsList;
|
||||||
import com.android.launcher3.model.BaseModelUpdateTask;
|
import com.android.launcher3.model.BaseModelUpdateTask;
|
||||||
import com.android.launcher3.model.BgDataModel;
|
import com.android.launcher3.model.BgDataModel;
|
||||||
@@ -34,11 +34,13 @@ import com.android.launcher3.model.data.FolderInfo;
|
|||||||
import com.android.launcher3.model.data.ItemInfo;
|
import com.android.launcher3.model.data.ItemInfo;
|
||||||
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
|
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
|
||||||
import com.android.launcher3.util.IntSparseArrayMap;
|
import com.android.launcher3.util.IntSparseArrayMap;
|
||||||
|
import com.android.launcher3.util.LogConfig;
|
||||||
|
import com.android.systemui.shared.system.SysUiStatsLog;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method calls the StatsLog hidden method until they are made available public.
|
* This class calls StatsLog compile time generated methods.
|
||||||
*
|
*
|
||||||
* To see if the logs are properly sent to statsd, execute following command.
|
* To see if the logs are properly sent to statsd, execute following command.
|
||||||
* $ adb root && adb shell statsd
|
* $ adb root && adb shell statsd
|
||||||
@@ -47,29 +49,69 @@ import java.util.ArrayList;
|
|||||||
*/
|
*/
|
||||||
public class StatsLogCompatManager extends StatsLogManager {
|
public class StatsLogCompatManager extends StatsLogManager {
|
||||||
|
|
||||||
private static final int SUPPORTED_TARGET_DEPTH = 2;
|
|
||||||
private static final String TAG = "StatsLog";
|
private static final String TAG = "StatsLog";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean IS_VERBOSE = Utilities.isPropertyEnabled(LogConfig.STATSLOG);
|
||||||
|
|
||||||
private static Context sContext;
|
private static Context sContext;
|
||||||
|
|
||||||
|
private static final int DEFAULT_WIDGET_SPAN_XY = 1;
|
||||||
|
private static final int DEFAULT_WORKSPACE_GRID_XY = -1;
|
||||||
|
private static final int DEFAULT_PAGE_INDEX = -2;
|
||||||
|
private static final InstanceId DEFAULT_INSTANCE_ID = InstanceId.fakeInstanceId(0);
|
||||||
|
|
||||||
public StatsLogCompatManager(Context context) {
|
public StatsLogCompatManager(Context context) {
|
||||||
sContext = context;
|
sContext = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs an event and accompanying {@link ItemInfo}
|
||||||
|
*/
|
||||||
|
public void log(LauncherEvent event, LauncherAtom.ItemInfo itemInfo) {
|
||||||
|
log(event, DEFAULT_INSTANCE_ID, itemInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs an event and accompanying {@link LauncherAtom.ItemInfo}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void verify() {
|
public void log(LauncherEvent event, InstanceId instanceId, LauncherAtom.ItemInfo itemInfo) {
|
||||||
if (!(StatsLogUtils.LAUNCHER_STATE_ALLAPPS == ALLAPPS
|
if (IS_VERBOSE) {
|
||||||
&& StatsLogUtils.LAUNCHER_STATE_BACKGROUND == BACKGROUND
|
Log.d(TAG, String.format("\n%s\n%s", event.name(), itemInfo));
|
||||||
&& StatsLogUtils.LAUNCHER_STATE_OVERVIEW == OVERVIEW
|
|
||||||
&& StatsLogUtils.LAUNCHER_STATE_HOME == HOME)) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"StatsLogUtil constants doesn't match enums in launcher.proto");
|
|
||||||
}
|
}
|
||||||
|
if (!Utilities.ATLEAST_R) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_EVENT,
|
||||||
|
SysUiStatsLog.LAUNCHER_UICHANGED__ACTION__DEFAULT_ACTION /* deprecated */,
|
||||||
|
SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__HOME /* TODO */,
|
||||||
|
SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__BACKGROUND /* TODO */,
|
||||||
|
null /* launcher extensions, deprecated */,
|
||||||
|
false /* quickstep_enabled, deprecated */,
|
||||||
|
event.getId() /* event_id */,
|
||||||
|
itemInfo.getItemCase().getNumber() /* target_id */,
|
||||||
|
instanceId.getId() /* instance_id TODO */,
|
||||||
|
0 /* uid TODO */,
|
||||||
|
getPackageName(itemInfo) /* package_name */,
|
||||||
|
getComponentName(itemInfo) /* component_name */,
|
||||||
|
getGridX(itemInfo, false) /* grid_x */,
|
||||||
|
getGridY(itemInfo, false) /* grid_y */,
|
||||||
|
getPageId(itemInfo, false) /* page_id */,
|
||||||
|
getGridX(itemInfo, true) /* grid_x_parent */,
|
||||||
|
getGridY(itemInfo, true) /* grid_y_parent */,
|
||||||
|
getPageId(itemInfo, true) /* page_id_parent */,
|
||||||
|
getHierarchy(itemInfo) /* hierarchy */,
|
||||||
|
itemInfo.getIsWork() /* is_work_profile */,
|
||||||
|
itemInfo.getRank() /* rank */,
|
||||||
|
0 /* fromState */,
|
||||||
|
0 /* toState */,
|
||||||
|
null /* edittext */,
|
||||||
|
0 /* cardinality */);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs the workspace layout information on the model thread.
|
* Logs the workspace layout information on the model thread.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void logSnapshot() {
|
public void logSnapshot() {
|
||||||
LauncherAppState.getInstance(sContext).getModel().enqueueModelUpdateTask(
|
LauncherAppState.getInstance(sContext).getModel().enqueueModelUpdateTask(
|
||||||
new SnapshotWorker());
|
new SnapshotWorker());
|
||||||
@@ -84,18 +126,160 @@ public class StatsLogCompatManager extends StatsLogManager {
|
|||||||
|
|
||||||
for (ItemInfo info : workspaceItems) {
|
for (ItemInfo info : workspaceItems) {
|
||||||
LauncherAtom.ItemInfo atomInfo = info.buildProto(null);
|
LauncherAtom.ItemInfo atomInfo = info.buildProto(null);
|
||||||
// call StatsLog method
|
writeSnapshot(atomInfo);
|
||||||
}
|
}
|
||||||
for (FolderInfo fInfo : folders) {
|
for (FolderInfo fInfo : folders) {
|
||||||
for (ItemInfo info : fInfo.contents) {
|
for (ItemInfo info : fInfo.contents) {
|
||||||
LauncherAtom.ItemInfo atomInfo = info.buildProto(fInfo);
|
LauncherAtom.ItemInfo atomInfo = info.buildProto(fInfo);
|
||||||
// call StatsLog method
|
writeSnapshot(atomInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ItemInfo info : appWidgets) {
|
for (ItemInfo info : appWidgets) {
|
||||||
LauncherAtom.ItemInfo atomInfo = info.buildProto(null);
|
LauncherAtom.ItemInfo atomInfo = info.buildProto(null);
|
||||||
// call StatsLog method
|
writeSnapshot(atomInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private static void writeSnapshot(LauncherAtom.ItemInfo itemInfo) {
|
||||||
|
if (IS_VERBOSE) {
|
||||||
|
Log.d(TAG, "\nwriteSnapshot:" + itemInfo);
|
||||||
|
}
|
||||||
|
if (!Utilities.ATLEAST_R) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_SNAPSHOT,
|
||||||
|
0 /* event_id */,
|
||||||
|
itemInfo.getItemCase().getNumber() /* target_id */,
|
||||||
|
0 /* instance_id */,
|
||||||
|
0 /* uid */,
|
||||||
|
getPackageName(itemInfo) /* package_name */,
|
||||||
|
getComponentName(itemInfo) /* component_name */,
|
||||||
|
getGridX(itemInfo, false) /* grid_x */,
|
||||||
|
getGridY(itemInfo, false) /* grid_y */,
|
||||||
|
getPageId(itemInfo, false) /* page_id */,
|
||||||
|
getGridX(itemInfo, true) /* grid_x_parent */,
|
||||||
|
getGridY(itemInfo, true) /* grid_y_parent */,
|
||||||
|
getPageId(itemInfo, true) /* page_id_parent */,
|
||||||
|
getHierarchy(itemInfo) /* hierarchy */,
|
||||||
|
itemInfo.getIsWork() /* is_work_profile */,
|
||||||
|
0 /* origin TODO */,
|
||||||
|
0 /* cardinality */,
|
||||||
|
getSpanX(itemInfo),
|
||||||
|
getSpanY(itemInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getSpanX(LauncherAtom.ItemInfo atomInfo) {
|
||||||
|
if (atomInfo.getItemCase() != WIDGET) {
|
||||||
|
return DEFAULT_WIDGET_SPAN_XY;
|
||||||
|
}
|
||||||
|
return atomInfo.getWidget().getSpanX();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getSpanY(LauncherAtom.ItemInfo atomInfo) {
|
||||||
|
if (atomInfo.getItemCase() != WIDGET) {
|
||||||
|
return DEFAULT_WIDGET_SPAN_XY;
|
||||||
|
}
|
||||||
|
return atomInfo.getWidget().getSpanY();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getPackageName(LauncherAtom.ItemInfo atomInfo) {
|
||||||
|
switch (atomInfo.getItemCase()) {
|
||||||
|
case APPLICATION:
|
||||||
|
return atomInfo.getApplication().getPackageName();
|
||||||
|
case SHORTCUT:
|
||||||
|
return atomInfo.getShortcut().getShortcutName();
|
||||||
|
case WIDGET:
|
||||||
|
return atomInfo.getWidget().getPackageName();
|
||||||
|
case TASK:
|
||||||
|
return atomInfo.getTask().getPackageName();
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getComponentName(LauncherAtom.ItemInfo atomInfo) {
|
||||||
|
switch (atomInfo.getItemCase()) {
|
||||||
|
case APPLICATION:
|
||||||
|
return atomInfo.getApplication().getComponentName();
|
||||||
|
case SHORTCUT:
|
||||||
|
return atomInfo.getShortcut().getShortcutName();
|
||||||
|
case WIDGET:
|
||||||
|
return atomInfo.getWidget().getComponentName();
|
||||||
|
case TASK:
|
||||||
|
return atomInfo.getTask().getComponentName();
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getGridX(LauncherAtom.ItemInfo info, boolean parent) {
|
||||||
|
switch (info.getContainerInfo().getContainerCase()) {
|
||||||
|
case WORKSPACE:
|
||||||
|
if (parent) {
|
||||||
|
return DEFAULT_WORKSPACE_GRID_XY;
|
||||||
|
} else {
|
||||||
|
return info.getContainerInfo().getWorkspace().getGridX();
|
||||||
|
}
|
||||||
|
case FOLDER:
|
||||||
|
if (parent) {
|
||||||
|
switch (info.getContainerInfo().getFolder().getParentContainerCase()) {
|
||||||
|
case WORKSPACE:
|
||||||
|
return info.getContainerInfo().getFolder().getWorkspace().getGridX();
|
||||||
|
default:
|
||||||
|
return DEFAULT_WORKSPACE_GRID_XY;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return info.getContainerInfo().getFolder().getGridX();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return DEFAULT_WORKSPACE_GRID_XY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getGridY(LauncherAtom.ItemInfo info, boolean parent) {
|
||||||
|
switch (info.getContainerInfo().getContainerCase()) {
|
||||||
|
case WORKSPACE:
|
||||||
|
if (parent) {
|
||||||
|
return DEFAULT_WORKSPACE_GRID_XY;
|
||||||
|
} else {
|
||||||
|
return info.getContainerInfo().getWorkspace().getGridY();
|
||||||
|
}
|
||||||
|
case FOLDER:
|
||||||
|
if (parent) {
|
||||||
|
switch (info.getContainerInfo().getFolder().getParentContainerCase()) {
|
||||||
|
case WORKSPACE:
|
||||||
|
return info.getContainerInfo().getFolder().getWorkspace().getGridY();
|
||||||
|
default:
|
||||||
|
return DEFAULT_WORKSPACE_GRID_XY;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return info.getContainerInfo().getFolder().getGridY();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return DEFAULT_WORKSPACE_GRID_XY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getPageId(LauncherAtom.ItemInfo info, boolean parent) {
|
||||||
|
switch (info.getContainerInfo().getContainerCase()) {
|
||||||
|
case HOTSEAT:
|
||||||
|
return info.getContainerInfo().getHotseat().getIndex();
|
||||||
|
case WORKSPACE:
|
||||||
|
return info.getContainerInfo().getWorkspace().getPageIndex();
|
||||||
|
default:
|
||||||
|
return DEFAULT_PAGE_INDEX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static int getHierarchy(LauncherAtom.ItemInfo info) {
|
||||||
|
// TODO
|
||||||
|
if (info.getContainerInfo().getContainerCase() == FOLDER) {
|
||||||
|
return info.getContainerInfo().getFolder().getParentContainerCase().getNumber() + 100;
|
||||||
|
} else {
|
||||||
|
return info.getContainerInfo().getContainerCase().getNumber();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import static com.android.quickstep.util.WindowSizeStrategy.LAUNCHER_ACTIVITY_SI
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.android.launcher3.DeviceProfile;
|
import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
@@ -66,4 +68,21 @@ public class LayoutUtils {
|
|||||||
return srcHeight / targetHeight;
|
return srcHeight / targetHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively sets view and all children enabled/disabled.
|
||||||
|
* @param viewGroup Top most parent view to change.
|
||||||
|
* @param enabled True = enable, False = disable.
|
||||||
|
*/
|
||||||
|
public static void setViewEnabled(ViewGroup viewGroup, boolean enabled) {
|
||||||
|
viewGroup.setEnabled(enabled);
|
||||||
|
for (int i = 0; i < viewGroup.getChildCount(); i++) {
|
||||||
|
View child = viewGroup.getChildAt(i);
|
||||||
|
if (child instanceof ViewGroup) {
|
||||||
|
setViewEnabled((ViewGroup) child, enabled);
|
||||||
|
} else {
|
||||||
|
child.setEnabled(enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_LSQ_VELOCITY_PROV
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
import com.android.launcher3.Alarm;
|
import com.android.launcher3.Alarm;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||||
|
import com.android.launcher3.testing.TestProtocol;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given positions along x- or y-axis, tracks velocity and acceleration and determines when there is
|
* Given positions along x- or y-axis, tracks velocity and acceleration and determines when there is
|
||||||
@@ -84,6 +86,9 @@ public class MotionPauseDetector {
|
|||||||
mSpeedSlow = res.getDimension(R.dimen.motion_pause_detector_speed_slow);
|
mSpeedSlow = res.getDimension(R.dimen.motion_pause_detector_speed_slow);
|
||||||
mSpeedSomewhatFast = res.getDimension(R.dimen.motion_pause_detector_speed_somewhat_fast);
|
mSpeedSomewhatFast = res.getDimension(R.dimen.motion_pause_detector_speed_somewhat_fast);
|
||||||
mSpeedFast = res.getDimension(R.dimen.motion_pause_detector_speed_fast);
|
mSpeedFast = res.getDimension(R.dimen.motion_pause_detector_speed_fast);
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "creating alarm");
|
||||||
|
}
|
||||||
mForcePauseTimeout = new Alarm();
|
mForcePauseTimeout = new Alarm();
|
||||||
mForcePauseTimeout.setOnAlarmListener(alarm -> updatePaused(true /* isPaused */));
|
mForcePauseTimeout.setOnAlarmListener(alarm -> updatePaused(true /* isPaused */));
|
||||||
mMakePauseHarderToTrigger = makePauseHarderToTrigger;
|
mMakePauseHarderToTrigger = makePauseHarderToTrigger;
|
||||||
@@ -120,6 +125,9 @@ public class MotionPauseDetector {
|
|||||||
* @param pointerIndex Index for the pointer being tracked in the motion event
|
* @param pointerIndex Index for the pointer being tracked in the motion event
|
||||||
*/
|
*/
|
||||||
public void addPosition(MotionEvent ev, int pointerIndex) {
|
public void addPosition(MotionEvent ev, int pointerIndex) {
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "setting alarm");
|
||||||
|
}
|
||||||
mForcePauseTimeout.setAlarm(mMakePauseHarderToTrigger
|
mForcePauseTimeout.setAlarm(mMakePauseHarderToTrigger
|
||||||
? HARDER_TRIGGER_TIMEOUT
|
? HARDER_TRIGGER_TIMEOUT
|
||||||
: FORCE_PAUSE_TIMEOUT);
|
: FORCE_PAUSE_TIMEOUT);
|
||||||
@@ -167,6 +175,9 @@ public class MotionPauseDetector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updatePaused(boolean isPaused) {
|
private void updatePaused(boolean isPaused) {
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "updatePaused: " + isPaused);
|
||||||
|
}
|
||||||
if (mDisallowPause) {
|
if (mDisallowPause) {
|
||||||
isPaused = false;
|
isPaused = false;
|
||||||
}
|
}
|
||||||
@@ -188,6 +199,9 @@ public class MotionPauseDetector {
|
|||||||
setOnMotionPauseListener(null);
|
setOnMotionPauseListener(null);
|
||||||
mIsPaused = mHasEverBeenPaused = false;
|
mIsPaused = mHasEverBeenPaused = false;
|
||||||
mSlowStartTime = 0;
|
mSlowStartTime = 0;
|
||||||
|
if (TestProtocol.sDebugTracing) {
|
||||||
|
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "canceling alarm");
|
||||||
|
}
|
||||||
mForcePauseTimeout.cancelAlarm();
|
mForcePauseTimeout.cancelAlarm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ import android.content.SharedPreferences;
|
|||||||
|
|
||||||
import com.android.launcher3.BaseQuickstepLauncher;
|
import com.android.launcher3.BaseQuickstepLauncher;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.LauncherStateManager;
|
import com.android.launcher3.statemanager.StateManager;
|
||||||
import com.android.launcher3.LauncherStateManager.StateListener;
|
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||||
import com.android.launcher3.util.OnboardingPrefs;
|
import com.android.launcher3.util.OnboardingPrefs;
|
||||||
import com.android.quickstep.SysUINavigationMode;
|
import com.android.quickstep.SysUINavigationMode;
|
||||||
|
|
||||||
@@ -35,23 +35,23 @@ import com.android.quickstep.SysUINavigationMode;
|
|||||||
*/
|
*/
|
||||||
public class QuickstepOnboardingPrefs extends OnboardingPrefs<BaseQuickstepLauncher> {
|
public class QuickstepOnboardingPrefs extends OnboardingPrefs<BaseQuickstepLauncher> {
|
||||||
|
|
||||||
public QuickstepOnboardingPrefs(BaseQuickstepLauncher launcher, SharedPreferences sharedPrefs,
|
public QuickstepOnboardingPrefs(BaseQuickstepLauncher launcher, SharedPreferences sharedPrefs) {
|
||||||
LauncherStateManager stateManager) {
|
super(launcher, sharedPrefs);
|
||||||
super(launcher, sharedPrefs, stateManager);
|
|
||||||
|
|
||||||
|
StateManager<LauncherState> stateManager = launcher.getStateManager();
|
||||||
if (!getBoolean(HOME_BOUNCE_SEEN)) {
|
if (!getBoolean(HOME_BOUNCE_SEEN)) {
|
||||||
mStateManager.addStateListener(new StateListener() {
|
stateManager.addStateListener(new StateListener<LauncherState>() {
|
||||||
@Override
|
@Override
|
||||||
public void onStateTransitionComplete(LauncherState finalState) {
|
public void onStateTransitionComplete(LauncherState finalState) {
|
||||||
boolean swipeUpEnabled = SysUINavigationMode.INSTANCE
|
boolean swipeUpEnabled = SysUINavigationMode.INSTANCE
|
||||||
.get(mLauncher).getMode().hasGestures;
|
.get(mLauncher).getMode().hasGestures;
|
||||||
LauncherState prevState = mStateManager.getLastState();
|
LauncherState prevState = stateManager.getLastState();
|
||||||
|
|
||||||
if (((swipeUpEnabled && finalState == OVERVIEW) || (!swipeUpEnabled
|
if (((swipeUpEnabled && finalState == OVERVIEW) || (!swipeUpEnabled
|
||||||
&& finalState == ALL_APPS && prevState == NORMAL) ||
|
&& finalState == ALL_APPS && prevState == NORMAL) ||
|
||||||
hasReachedMaxCount(HOME_BOUNCE_COUNT))) {
|
hasReachedMaxCount(HOME_BOUNCE_COUNT))) {
|
||||||
mSharedPrefs.edit().putBoolean(HOME_BOUNCE_SEEN, true).apply();
|
mSharedPrefs.edit().putBoolean(HOME_BOUNCE_SEEN, true).apply();
|
||||||
mStateManager.removeStateListener(this);
|
stateManager.removeStateListener(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -65,27 +65,27 @@ public class QuickstepOnboardingPrefs extends OnboardingPrefs<BaseQuickstepLaunc
|
|||||||
mSharedPrefs.edit().putBoolean(SHELF_BOUNCE_SEEN, shelfBounceSeen).apply();
|
mSharedPrefs.edit().putBoolean(SHELF_BOUNCE_SEEN, shelfBounceSeen).apply();
|
||||||
}
|
}
|
||||||
if (!shelfBounceSeen) {
|
if (!shelfBounceSeen) {
|
||||||
mStateManager.addStateListener(new StateListener() {
|
stateManager.addStateListener(new StateListener<LauncherState>() {
|
||||||
@Override
|
@Override
|
||||||
public void onStateTransitionComplete(LauncherState finalState) {
|
public void onStateTransitionComplete(LauncherState finalState) {
|
||||||
LauncherState prevState = mStateManager.getLastState();
|
LauncherState prevState = stateManager.getLastState();
|
||||||
|
|
||||||
if ((finalState == ALL_APPS && prevState == OVERVIEW) ||
|
if ((finalState == ALL_APPS && prevState == OVERVIEW) ||
|
||||||
hasReachedMaxCount(SHELF_BOUNCE_COUNT)) {
|
hasReachedMaxCount(SHELF_BOUNCE_COUNT)) {
|
||||||
mSharedPrefs.edit().putBoolean(SHELF_BOUNCE_SEEN, true).apply();
|
mSharedPrefs.edit().putBoolean(SHELF_BOUNCE_SEEN, true).apply();
|
||||||
mStateManager.removeStateListener(this);
|
stateManager.removeStateListener(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasReachedMaxCount(ALL_APPS_COUNT)) {
|
if (!hasReachedMaxCount(ALL_APPS_COUNT)) {
|
||||||
mStateManager.addStateListener(new StateListener() {
|
stateManager.addStateListener(new StateListener<LauncherState>() {
|
||||||
@Override
|
@Override
|
||||||
public void onStateTransitionComplete(LauncherState finalState) {
|
public void onStateTransitionComplete(LauncherState finalState) {
|
||||||
if (finalState == ALL_APPS) {
|
if (finalState == ALL_APPS) {
|
||||||
if (incrementEventCount(ALL_APPS_COUNT)) {
|
if (incrementEventCount(ALL_APPS_COUNT)) {
|
||||||
mStateManager.removeStateListener(this);
|
stateManager.removeStateListener(this);
|
||||||
mLauncher.getScrimView().updateDragHandleVisibility();
|
mLauncher.getScrimView().updateDragHandleVisibility();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import static android.view.Surface.ROTATION_180;
|
|||||||
import static android.view.Surface.ROTATION_270;
|
import static android.view.Surface.ROTATION_270;
|
||||||
import static android.view.Surface.ROTATION_90;
|
import static android.view.Surface.ROTATION_90;
|
||||||
|
|
||||||
|
import static com.android.launcher3.logging.LoggerUtils.extractObjectNameAndAddress;
|
||||||
import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
|
import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
|
||||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||||
|
|
||||||
@@ -36,7 +37,6 @@ import android.database.ContentObserver;
|
|||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -51,6 +51,7 @@ import com.android.launcher3.DeviceProfile;
|
|||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.testing.TestProtocol;
|
import com.android.launcher3.testing.TestProtocol;
|
||||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||||
|
import com.android.launcher3.util.WindowBounds;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.util.function.IntConsumer;
|
import java.util.function.IntConsumer;
|
||||||
@@ -84,7 +85,7 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
|
|
||||||
private @SurfaceRotation int mTouchRotation = ROTATION_0;
|
private @SurfaceRotation int mTouchRotation = ROTATION_0;
|
||||||
private @SurfaceRotation int mDisplayRotation = ROTATION_0;
|
private @SurfaceRotation int mDisplayRotation = ROTATION_0;
|
||||||
private @SurfaceRotation int mLauncherRotation = Surface.ROTATION_0;
|
private @SurfaceRotation int mLauncherRotation = ROTATION_0;
|
||||||
|
|
||||||
// Launcher activity supports multiple orientation, but fallback activity does not
|
// Launcher activity supports multiple orientation, but fallback activity does not
|
||||||
private static final int FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY = 1 << 0;
|
private static final int FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY = 1 << 0;
|
||||||
@@ -102,6 +103,8 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
private static final int FLAG_ROTATION_WATCHER_SUPPORTED = 1 << 6;
|
private static final int FLAG_ROTATION_WATCHER_SUPPORTED = 1 << 6;
|
||||||
// Whether to enable rotation watcher when multi-rotation is supported
|
// Whether to enable rotation watcher when multi-rotation is supported
|
||||||
private static final int FLAG_ROTATION_WATCHER_ENABLED = 1 << 7;
|
private static final int FLAG_ROTATION_WATCHER_ENABLED = 1 << 7;
|
||||||
|
// Enable home rotation for UI tests, ignoring home rotation value from prefs
|
||||||
|
private static final int FLAG_HOME_ROTATION_FORCE_ENABLED_FOR_TESTING = 1 << 8;
|
||||||
|
|
||||||
private static final int MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE =
|
private static final int MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE =
|
||||||
FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY
|
FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY
|
||||||
@@ -121,7 +124,6 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
private final WindowSizeStrategy mSizeStrategy;
|
private final WindowSizeStrategy mSizeStrategy;
|
||||||
|
|
||||||
private final Matrix mTmpMatrix = new Matrix();
|
private final Matrix mTmpMatrix = new Matrix();
|
||||||
private final Matrix mTmpInverseMatrix = new Matrix();
|
|
||||||
|
|
||||||
private int mFlags;
|
private int mFlags;
|
||||||
private int mPreviousRotation = ROTATION_0;
|
private int mPreviousRotation = ROTATION_0;
|
||||||
@@ -163,6 +165,10 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
if (mOrientationListener.canDetectOrientation()) {
|
if (mOrientationListener.canDetectOrientation()) {
|
||||||
mFlags |= FLAG_ROTATION_WATCHER_SUPPORTED;
|
mFlags |= FLAG_ROTATION_WATCHER_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialize external flags
|
||||||
|
updateAutoRotateSetting();
|
||||||
|
updateHomeRotationSetting();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -181,13 +187,15 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
* false otherwise
|
* false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean update(
|
public boolean update(
|
||||||
@SurfaceRotation int touchRotation, @SurfaceRotation int displayRotation,
|
@SurfaceRotation int touchRotation, @SurfaceRotation int displayRotation) {
|
||||||
@SurfaceRotation int launcherRotation) {
|
|
||||||
if (!isMultipleOrientationSupportedByDevice()) {
|
if (!isMultipleOrientationSupportedByDevice()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (mDisplayRotation == displayRotation && mTouchRotation == touchRotation
|
|
||||||
&& launcherRotation == mLauncherRotation) {
|
int launcherRotation = inferLauncherRotation(displayRotation);
|
||||||
|
if (mDisplayRotation == displayRotation
|
||||||
|
&& mTouchRotation == touchRotation
|
||||||
|
&& mLauncherRotation == launcherRotation) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,11 +203,10 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
mDisplayRotation = displayRotation;
|
mDisplayRotation = displayRotation;
|
||||||
mTouchRotation = touchRotation;
|
mTouchRotation = touchRotation;
|
||||||
|
|
||||||
if (canLauncherRotate() || mLauncherRotation == mTouchRotation) {
|
if (mLauncherRotation == mTouchRotation) {
|
||||||
// TODO(b/153476489) Need to determine when launcher is rotated
|
|
||||||
mOrientationHandler = PagedOrientationHandler.HOME_ROTATED;
|
mOrientationHandler = PagedOrientationHandler.HOME_ROTATED;
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "Set Orientation Handler: " + mOrientationHandler);
|
Log.d(TAG, "current RecentsOrientedState: " + this);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -212,11 +219,20 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
mOrientationHandler = PagedOrientationHandler.PORTRAIT;
|
mOrientationHandler = PagedOrientationHandler.PORTRAIT;
|
||||||
}
|
}
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "Set Orientation Handler: " + mOrientationHandler);
|
Log.d(TAG, "current RecentsOrientedState: " + this);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SurfaceRotation
|
||||||
|
private int inferLauncherRotation(@SurfaceRotation int displayRotation) {
|
||||||
|
if (!isMultipleOrientationSupportedByDevice() || isHomeRotationAllowed()) {
|
||||||
|
return displayRotation;
|
||||||
|
} else {
|
||||||
|
return ROTATION_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void setFlag(int mask, boolean enabled) {
|
private void setFlag(int mask, boolean enabled) {
|
||||||
boolean wasRotationEnabled = !TestProtocol.sDisableSensorRotation
|
boolean wasRotationEnabled = !TestProtocol.sDisableSensorRotation
|
||||||
&& mFlags == VALUE_ROTATION_WATCHER_ENABLED;
|
&& mFlags == VALUE_ROTATION_WATCHER_ENABLED;
|
||||||
@@ -241,7 +257,9 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
|
||||||
updateHomeRotationSetting();
|
if (ALLOW_ROTATION_PREFERENCE_KEY.equals(s)) {
|
||||||
|
updateHomeRotationSetting();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateAutoRotateSetting() {
|
private void updateAutoRotateSetting() {
|
||||||
@@ -255,23 +273,24 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes aany system values and registers corresponding change listeners. It must be
|
* Initializes any system values and registers corresponding change listeners. It must be
|
||||||
* paired with {@link #destroy()} call
|
* paired with {@link #destroyListeners()} call
|
||||||
*/
|
*/
|
||||||
public void init() {
|
public void initListeners() {
|
||||||
if (isMultipleOrientationSupportedByDevice()) {
|
if (isMultipleOrientationSupportedByDevice()) {
|
||||||
mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
|
mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
|
||||||
mContentResolver.registerContentObserver(
|
mContentResolver.registerContentObserver(
|
||||||
Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION),
|
Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION),
|
||||||
false, mSystemAutoRotateObserver);
|
false, mSystemAutoRotateObserver);
|
||||||
}
|
}
|
||||||
initWithoutListeners();
|
updateAutoRotateSetting();
|
||||||
|
updateHomeRotationSetting();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregisters any previously registered listeners.
|
* Unregisters any previously registered listeners.
|
||||||
*/
|
*/
|
||||||
public void destroy() {
|
public void destroyListeners() {
|
||||||
if (isMultipleOrientationSupportedByDevice()) {
|
if (isMultipleOrientationSupportedByDevice()) {
|
||||||
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
|
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
|
||||||
mContentResolver.unregisterContentObserver(mSystemAutoRotateObserver);
|
mContentResolver.unregisterContentObserver(mSystemAutoRotateObserver);
|
||||||
@@ -279,13 +298,8 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
setRotationWatcherEnabled(false);
|
setRotationWatcherEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void forceAllowRotationForTesting(boolean forceAllow) {
|
||||||
* Initializes the OrientationState without attaching any listeners. This can be used when
|
setFlag(FLAG_HOME_ROTATION_FORCE_ENABLED_FOR_TESTING, forceAllow);
|
||||||
* the object is short lived.
|
|
||||||
*/
|
|
||||||
public void initWithoutListeners() {
|
|
||||||
updateAutoRotateSetting();
|
|
||||||
updateHomeRotationSetting();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SurfaceRotation
|
@SurfaceRotation
|
||||||
@@ -310,7 +324,8 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
|
|
||||||
public boolean isHomeRotationAllowed() {
|
public boolean isHomeRotationAllowed() {
|
||||||
return (mFlags & (FLAG_HOME_ROTATION_ALLOWED_IN_PREFS | FLAG_MULTIWINDOW_ROTATION_ALLOWED))
|
return (mFlags & (FLAG_HOME_ROTATION_ALLOWED_IN_PREFS | FLAG_MULTIWINDOW_ROTATION_ALLOWED))
|
||||||
!= 0;
|
!= 0 ||
|
||||||
|
(mFlags & FLAG_HOME_ROTATION_FORCE_ENABLED_FOR_TESTING) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canLauncherRotate() {
|
public boolean canLauncherRotate() {
|
||||||
@@ -347,7 +362,8 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
float fullHeight = dp.heightPx - insets.top - insets.bottom;
|
float fullHeight = dp.heightPx - insets.top - insets.bottom;
|
||||||
|
|
||||||
if (dp.isMultiWindowMode) {
|
if (dp.isMultiWindowMode) {
|
||||||
mSizeStrategy.getMultiWindowSize(mContext, dp, outPivot);
|
WindowBounds bounds = SplitScreenBounds.INSTANCE.getSecondaryWindowBounds(mContext);
|
||||||
|
outPivot.set(bounds.availableSize.x, bounds.availableSize.y);
|
||||||
} else {
|
} else {
|
||||||
outPivot.set(fullWidth, fullHeight);
|
outPivot.set(fullWidth, fullHeight);
|
||||||
}
|
}
|
||||||
@@ -403,23 +419,6 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mapRectFromNormalOrientation(RectF src, int screenWidth, int screenHeight) {
|
|
||||||
mapRectFromRotation(mDisplayRotation, src, screenWidth, screenHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mapRectFromRotation(int rotation, RectF src, int screenWidth, int screenHeight) {
|
|
||||||
mTmpMatrix.reset();
|
|
||||||
postDisplayRotation(rotation, screenWidth, screenHeight, mTmpMatrix);
|
|
||||||
mTmpMatrix.mapRect(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mapInverseRectFromNormalOrientation(RectF src, int screenWidth, int screenHeight) {
|
|
||||||
mTmpMatrix.reset();
|
|
||||||
postDisplayRotation(mDisplayRotation, screenWidth, screenHeight, mTmpMatrix);
|
|
||||||
mTmpMatrix.invert(mTmpInverseMatrix);
|
|
||||||
mTmpInverseMatrix.mapRect(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SurfaceRotation
|
@SurfaceRotation
|
||||||
public static int getRotationForUserDegreesRotated(float degrees, int currentRotation) {
|
public static int getRotationForUserDegreesRotated(float degrees, int currentRotation) {
|
||||||
if (degrees == ORIENTATION_UNKNOWN) {
|
if (degrees == ORIENTATION_UNKNOWN) {
|
||||||
@@ -440,9 +439,13 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
if (degrees < (90 - threshold)) {
|
if (degrees < (90 - threshold)) {
|
||||||
return ROTATION_0;
|
return ROTATION_0;
|
||||||
}
|
}
|
||||||
if (degrees > (90 + threshold)) {
|
if (degrees > (90 + threshold) && degrees < 180) {
|
||||||
return ROTATION_180;
|
return ROTATION_180;
|
||||||
}
|
}
|
||||||
|
// flip from seascape to landscape
|
||||||
|
if (degrees > (180 + threshold) && degrees < 360) {
|
||||||
|
return ROTATION_90;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ROTATION_180:
|
case ROTATION_180:
|
||||||
if (degrees < (180 - threshold)) {
|
if (degrees < (180 - threshold)) {
|
||||||
@@ -453,12 +456,16 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ROTATION_90:
|
case ROTATION_90:
|
||||||
if (degrees < (270 - threshold)) {
|
if (degrees < (270 - threshold) && degrees > 90) {
|
||||||
return ROTATION_180;
|
return ROTATION_180;
|
||||||
}
|
}
|
||||||
if (degrees > (270 + threshold)) {
|
if (degrees > (270 + threshold) && degrees < 360) {
|
||||||
return ROTATION_0;
|
return ROTATION_0;
|
||||||
}
|
}
|
||||||
|
// flip from landscape to seascape
|
||||||
|
if (degrees > threshold && degrees < 180) {
|
||||||
|
return ROTATION_270;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -506,13 +513,15 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
boolean systemRotationOn = (mFlags & FLAG_SYSTEM_ROTATION_ALLOWED) != 0;
|
boolean systemRotationOn = (mFlags & FLAG_SYSTEM_ROTATION_ALLOWED) != 0;
|
||||||
return "["
|
return "["
|
||||||
+ "mDisplayRotation=" + mDisplayRotation
|
+ "this=" + extractObjectNameAndAddress(super.toString())
|
||||||
|
+ " mOrientationHandler=" +
|
||||||
|
extractObjectNameAndAddress(mOrientationHandler.toString())
|
||||||
|
+ " mDisplayRotation=" + mDisplayRotation
|
||||||
+ " mTouchRotation=" + mTouchRotation
|
+ " mTouchRotation=" + mTouchRotation
|
||||||
+ " mLauncherRotation=" + mLauncherRotation
|
+ " mLauncherRotation=" + mLauncherRotation
|
||||||
+ " mHomeRotation=" + isHomeRotationAllowed()
|
+ " mHomeRotation=" + isHomeRotationAllowed()
|
||||||
+ " mSystemRotation=" + systemRotationOn
|
+ " mSystemRotation=" + systemRotationOn
|
||||||
+ " mFlags=" + mFlags
|
+ " mFlags=" + mFlags
|
||||||
+ " mOrientationHandler=" + mOrientationHandler
|
|
||||||
+ "]";
|
+ "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 android.view.Surface.ROTATION_0;
|
||||||
|
import static android.view.Surface.ROTATION_180;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Insets;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.view.WindowInsets.Type;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.view.WindowMetrics;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.UiThread;
|
||||||
|
|
||||||
|
import com.android.launcher3.R;
|
||||||
|
import com.android.launcher3.util.DefaultDisplay;
|
||||||
|
import com.android.launcher3.util.WindowBounds;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to hold the information abound a window bounds for split screen
|
||||||
|
*/
|
||||||
|
@TargetApi(Build.VERSION_CODES.R)
|
||||||
|
public class SplitScreenBounds {
|
||||||
|
|
||||||
|
public static final SplitScreenBounds INSTANCE = new SplitScreenBounds();
|
||||||
|
private final ArrayList<OnChangeListener> mListeners = new ArrayList<>();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private WindowBounds mBounds;
|
||||||
|
|
||||||
|
private SplitScreenBounds() { }
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
public void setSecondaryWindowBounds(@NonNull WindowBounds bounds) {
|
||||||
|
if (!bounds.equals(mBounds)) {
|
||||||
|
mBounds = bounds;
|
||||||
|
for (OnChangeListener listener : mListeners) {
|
||||||
|
listener.onSecondaryWindowBoundsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NonNull WindowBounds getSecondaryWindowBounds(Context context) {
|
||||||
|
if (mBounds == null) {
|
||||||
|
mBounds = createDefaultWindowBounds(context);
|
||||||
|
}
|
||||||
|
return mBounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates window bounds as 50% of device size
|
||||||
|
*/
|
||||||
|
private static WindowBounds createDefaultWindowBounds(Context context) {
|
||||||
|
WindowMetrics wm = context.getSystemService(WindowManager.class).getMaximumWindowMetrics();
|
||||||
|
Insets insets = wm.getWindowInsets().getInsets(Type.systemBars());
|
||||||
|
|
||||||
|
WindowBounds bounds = new WindowBounds(wm.getBounds(),
|
||||||
|
new Rect(insets.left, insets.top, insets.right, insets.bottom));
|
||||||
|
int rotation = DefaultDisplay.INSTANCE.get(context).getInfo().rotation;
|
||||||
|
int halfDividerSize = context.getResources()
|
||||||
|
.getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;
|
||||||
|
|
||||||
|
if (rotation == ROTATION_0 || rotation == ROTATION_180) {
|
||||||
|
bounds.bounds.top = bounds.insets.top + bounds.availableSize.y / 2 + halfDividerSize;
|
||||||
|
bounds.insets.top = 0;
|
||||||
|
} else {
|
||||||
|
bounds.bounds.left = bounds.insets.left + bounds.availableSize.x / 2 + halfDividerSize;
|
||||||
|
bounds.insets.left = 0;
|
||||||
|
}
|
||||||
|
return new WindowBounds(bounds.bounds, bounds.insets);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addOnChangeListener(OnChangeListener listener) {
|
||||||
|
mListeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeOnChangeListener(OnChangeListener listener) {
|
||||||
|
mListeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to receive window bounds changes
|
||||||
|
*/
|
||||||
|
public interface OnChangeListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when window bounds for secondary window changes
|
||||||
|
*/
|
||||||
|
void onSecondaryWindowBoundsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,36 +16,35 @@
|
|||||||
package com.android.quickstep.util;
|
package com.android.quickstep.util;
|
||||||
|
|
||||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
|
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
|
||||||
|
import static com.android.quickstep.SysUINavigationMode.getMode;
|
||||||
import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
|
import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
|
||||||
import static com.android.quickstep.util.LayoutUtils.getDefaultSwipeHeight;
|
import static com.android.quickstep.util.LayoutUtils.getDefaultSwipeHeight;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.PointF;
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
import com.android.launcher3.DeviceProfile;
|
import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
|
import com.android.launcher3.util.WindowBounds;
|
||||||
|
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to wrap different layout behavior for Launcher and RecentsView
|
* Utility class to wrap different layout behavior for Launcher and RecentsView
|
||||||
* TODO: Merge is with {@link com.android.quickstep.BaseActivityInterface} once we remove the
|
* TODO: Merge is with {@link com.android.quickstep.BaseActivityInterface} once we remove the
|
||||||
* state dependent members from {@link com.android.quickstep.LauncherActivityInterface}
|
* state dependent members from {@link com.android.quickstep.LauncherActivityInterface}
|
||||||
*/
|
*/
|
||||||
|
@TargetApi(Build.VERSION_CODES.R)
|
||||||
public abstract class WindowSizeStrategy {
|
public abstract class WindowSizeStrategy {
|
||||||
|
|
||||||
private final PointF mTempPoint = new PointF();
|
|
||||||
public final boolean rotationSupportedByActivity;
|
public final boolean rotationSupportedByActivity;
|
||||||
|
|
||||||
private WindowSizeStrategy(boolean rotationSupportedByActivity) {
|
private WindowSizeStrategy(boolean rotationSupportedByActivity) {
|
||||||
this.rotationSupportedByActivity = rotationSupportedByActivity;
|
this.rotationSupportedByActivity = rotationSupportedByActivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the expected window size in multi-window mode
|
|
||||||
*/
|
|
||||||
public abstract void getMultiWindowSize(Context context, DeviceProfile dp, PointF out);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the taskView size for the provided device configuration
|
* Calculates the taskView size for the provided device configuration
|
||||||
*/
|
*/
|
||||||
@@ -57,35 +56,41 @@ public abstract class WindowSizeStrategy {
|
|||||||
|
|
||||||
private void calculateTaskSize(
|
private void calculateTaskSize(
|
||||||
Context context, DeviceProfile dp, float extraVerticalSpace, Rect outRect) {
|
Context context, DeviceProfile dp, float extraVerticalSpace, Rect outRect) {
|
||||||
float taskWidth, taskHeight, paddingHorz;
|
|
||||||
Resources res = context.getResources();
|
Resources res = context.getResources();
|
||||||
Rect insets = dp.getInsets();
|
|
||||||
final boolean showLargeTaskSize = showOverviewActions(context);
|
final boolean showLargeTaskSize = showOverviewActions(context);
|
||||||
|
|
||||||
|
final int paddingResId;
|
||||||
if (dp.isMultiWindowMode) {
|
if (dp.isMultiWindowMode) {
|
||||||
getMultiWindowSize(context, dp, mTempPoint);
|
paddingResId = R.dimen.multi_window_task_card_horz_space;
|
||||||
taskWidth = mTempPoint.x;
|
} else if (dp.isVerticalBarLayout()) {
|
||||||
taskHeight = mTempPoint.y;
|
paddingResId = R.dimen.landscape_task_card_horz_space;
|
||||||
paddingHorz = res.getDimension(R.dimen.multi_window_task_card_horz_space);
|
} else if (showLargeTaskSize) {
|
||||||
|
paddingResId = R.dimen.portrait_task_card_horz_space_big_overview;
|
||||||
|
} else {
|
||||||
|
paddingResId = R.dimen.portrait_task_card_horz_space;
|
||||||
|
}
|
||||||
|
float paddingHorz = res.getDimension(paddingResId);
|
||||||
|
float paddingVert = showLargeTaskSize
|
||||||
|
? 0 : res.getDimension(R.dimen.task_card_vert_space);
|
||||||
|
|
||||||
|
calculateTaskSizeInternal(context, dp, extraVerticalSpace, paddingHorz, paddingVert,
|
||||||
|
res.getDimension(R.dimen.task_thumbnail_top_margin), outRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calculateTaskSizeInternal(Context context, DeviceProfile dp,
|
||||||
|
float extraVerticalSpace, float paddingHorz, float paddingVert, float topIconMargin,
|
||||||
|
Rect outRect) {
|
||||||
|
float taskWidth, taskHeight;
|
||||||
|
Rect insets = dp.getInsets();
|
||||||
|
if (dp.isMultiWindowMode) {
|
||||||
|
WindowBounds bounds = SplitScreenBounds.INSTANCE.getSecondaryWindowBounds(context);
|
||||||
|
taskWidth = bounds.availableSize.x;
|
||||||
|
taskHeight = bounds.availableSize.y;
|
||||||
} else {
|
} else {
|
||||||
taskWidth = dp.availableWidthPx;
|
taskWidth = dp.availableWidthPx;
|
||||||
taskHeight = dp.availableHeightPx;
|
taskHeight = dp.availableHeightPx;
|
||||||
|
|
||||||
final int paddingResId;
|
|
||||||
if (dp.isVerticalBarLayout()) {
|
|
||||||
paddingResId = R.dimen.landscape_task_card_horz_space;
|
|
||||||
} else if (showLargeTaskSize) {
|
|
||||||
paddingResId = R.dimen.portrait_task_card_horz_space_big_overview;
|
|
||||||
} else {
|
|
||||||
paddingResId = R.dimen.portrait_task_card_horz_space;
|
|
||||||
}
|
|
||||||
paddingHorz = res.getDimension(paddingResId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float topIconMargin = res.getDimension(R.dimen.task_thumbnail_top_margin);
|
|
||||||
float paddingVert = showLargeTaskSize
|
|
||||||
? 0 : res.getDimension(R.dimen.task_card_vert_space);
|
|
||||||
|
|
||||||
// Note this should be same as dp.availableWidthPx and dp.availableHeightPx unless
|
// Note this should be same as dp.availableWidthPx and dp.availableHeightPx unless
|
||||||
// we override the insets ourselves.
|
// we override the insets ourselves.
|
||||||
int launcherVisibleWidth = dp.widthPx - insets.left - insets.right;
|
int launcherVisibleWidth = dp.widthPx - insets.left - insets.right;
|
||||||
@@ -107,26 +112,41 @@ public abstract class WindowSizeStrategy {
|
|||||||
Math.round(x) + Math.round(outWidth), Math.round(y) + Math.round(outHeight));
|
Math.round(x) + Math.round(outWidth), Math.round(y) + Math.round(outHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the modal taskView size for the provided device configuration
|
||||||
|
*/
|
||||||
|
public void calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect) {
|
||||||
|
float paddingHorz = context.getResources().getDimension(dp.isMultiWindowMode
|
||||||
|
? R.dimen.multi_window_task_card_horz_space
|
||||||
|
: dp.isVerticalBarLayout()
|
||||||
|
? R.dimen.landscape_task_card_horz_space
|
||||||
|
: R.dimen.portrait_modal_task_card_horz_space);
|
||||||
|
float extraVerticalSpace = getOverviewActionsHeight(context);
|
||||||
|
float paddingVert = 0;
|
||||||
|
float topIconMargin = 0;
|
||||||
|
calculateTaskSizeInternal(context, dp, extraVerticalSpace, paddingHorz, paddingVert,
|
||||||
|
topIconMargin, outRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the space that the overview actions will take, including margins. */
|
||||||
|
public float getOverviewActionsHeight(Context context) {
|
||||||
|
Resources res = context.getResources();
|
||||||
|
float actionsBottomMargin = 0;
|
||||||
|
if (getMode(context) == Mode.THREE_BUTTONS) {
|
||||||
|
actionsBottomMargin = res.getDimensionPixelSize(
|
||||||
|
R.dimen.overview_actions_bottom_margin_three_button);
|
||||||
|
} else {
|
||||||
|
actionsBottomMargin = res.getDimensionPixelSize(
|
||||||
|
R.dimen.overview_actions_bottom_margin_gesture);
|
||||||
|
}
|
||||||
|
float overviewActionsHeight = actionsBottomMargin
|
||||||
|
+ res.getDimensionPixelSize(R.dimen.overview_actions_height);
|
||||||
|
return overviewActionsHeight;
|
||||||
|
}
|
||||||
|
|
||||||
public static final WindowSizeStrategy LAUNCHER_ACTIVITY_SIZE_STRATEGY =
|
public static final WindowSizeStrategy LAUNCHER_ACTIVITY_SIZE_STRATEGY =
|
||||||
new WindowSizeStrategy(true) {
|
new WindowSizeStrategy(true) {
|
||||||
|
|
||||||
@Override
|
|
||||||
public void getMultiWindowSize(Context context, DeviceProfile dp, PointF out) {
|
|
||||||
DeviceProfile fullDp = dp.getFullScreenProfile();
|
|
||||||
// Use availableWidthPx and availableHeightPx instead of widthPx and heightPx to
|
|
||||||
// account for system insets
|
|
||||||
out.set(fullDp.availableWidthPx, fullDp.availableHeightPx);
|
|
||||||
float halfDividerSize = context.getResources()
|
|
||||||
.getDimension(R.dimen.multi_window_task_divider_size) / 2;
|
|
||||||
|
|
||||||
if (fullDp.isLandscape) {
|
|
||||||
out.x = out.x / 2 - halfDividerSize;
|
|
||||||
} else {
|
|
||||||
out.y = out.y / 2 - halfDividerSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
float getExtraSpace(Context context, DeviceProfile dp) {
|
float getExtraSpace(Context context, DeviceProfile dp) {
|
||||||
if (dp.isVerticalBarLayout()) {
|
if (dp.isVerticalBarLayout()) {
|
||||||
@@ -136,7 +156,7 @@ public abstract class WindowSizeStrategy {
|
|||||||
if (showOverviewActions(context)) {
|
if (showOverviewActions(context)) {
|
||||||
//TODO: this needs to account for the swipe gesture height and accessibility
|
//TODO: this needs to account for the swipe gesture height and accessibility
|
||||||
// UI when shown.
|
// UI when shown.
|
||||||
return res.getDimensionPixelSize(R.dimen.overview_actions_height);
|
return getOverviewActionsHeight(context);
|
||||||
} else {
|
} else {
|
||||||
return getDefaultSwipeHeight(context, dp) + dp.workspacePageIndicatorHeight
|
return getDefaultSwipeHeight(context, dp) + dp.workspacePageIndicatorHeight
|
||||||
+ res.getDimensionPixelSize(
|
+ res.getDimensionPixelSize(
|
||||||
@@ -150,10 +170,6 @@ public abstract class WindowSizeStrategy {
|
|||||||
|
|
||||||
public static final WindowSizeStrategy FALLBACK_RECENTS_SIZE_STRATEGY =
|
public static final WindowSizeStrategy FALLBACK_RECENTS_SIZE_STRATEGY =
|
||||||
new WindowSizeStrategy(false) {
|
new WindowSizeStrategy(false) {
|
||||||
@Override
|
|
||||||
public void getMultiWindowSize(Context context, DeviceProfile dp, PointF out) {
|
|
||||||
out.set(dp.widthPx, dp.heightPx);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
float getExtraSpace(Context context, DeviceProfile dp) {
|
float getExtraSpace(Context context, DeviceProfile dp) {
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import com.android.launcher3.ui.TaplTestsLauncher3;
|
|||||||
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
|
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -53,6 +54,18 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
|
|||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
TaplTestsLauncher3.initialize(this);
|
TaplTestsLauncher3.initialize(this);
|
||||||
|
executeOnLauncher(launcher -> {
|
||||||
|
RecentsView recentsView = launcher.getOverviewPanel();
|
||||||
|
recentsView.getPagedViewOrientedState().forceAllowRotationForTesting(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
executeOnLauncher(launcher -> {
|
||||||
|
RecentsView recentsView = launcher.getOverviewPanel();
|
||||||
|
recentsView.getPagedViewOrientedState().forceAllowRotationForTesting(false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startTestApps() throws Exception {
|
private void startTestApps() throws Exception {
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:alpha="1"
|
||||||
|
android:color="?attr/workspaceTextColor"
|
||||||
|
android:state_enabled="true" />
|
||||||
|
<item
|
||||||
|
android:alpha="?android:disabledAlpha"
|
||||||
|
android:color="?attr/workspaceTextColor"
|
||||||
|
android:state_enabled="false" />
|
||||||
|
</selector>
|
||||||
@@ -23,13 +23,13 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="32dp"
|
android:layout_height="32dp"
|
||||||
android:background="@drawable/bottom_sheet_top_border"
|
android:background="@drawable/bottom_sheet_top_border"
|
||||||
android:backgroundTint="?android:attr/colorAccent" />
|
android:backgroundTint="?attr/eduHalfSheetBGColor" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/view_wrapper"
|
android:id="@+id/view_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?android:attr/colorAccent"
|
android:background="?attr/eduHalfSheetBGColor"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingLeft="@dimen/bottom_sheet_edu_padding"
|
android:paddingLeft="@dimen/bottom_sheet_edu_padding"
|
||||||
android:paddingRight="@dimen/bottom_sheet_edu_padding">
|
android:paddingRight="@dimen/bottom_sheet_edu_padding">
|
||||||
|
|||||||
@@ -131,7 +131,7 @@
|
|||||||
<string name="accessibility_close" msgid="2277148124685870734">"بستن"</string>
|
<string name="accessibility_close" msgid="2277148124685870734">"بستن"</string>
|
||||||
<string name="notification_dismissed" msgid="6002233469409822874">"اعلان رد شد"</string>
|
<string name="notification_dismissed" msgid="6002233469409822874">"اعلان رد شد"</string>
|
||||||
<string name="all_apps_personal_tab" msgid="4190252696685155002">"شخصی"</string>
|
<string name="all_apps_personal_tab" msgid="4190252696685155002">"شخصی"</string>
|
||||||
<string name="all_apps_work_tab" msgid="4884822796154055118">"محل کار"</string>
|
<string name="all_apps_work_tab" msgid="4884822796154055118">"کاری"</string>
|
||||||
<string name="work_profile_toggle_label" msgid="3081029915775481146">"نمایه کاری"</string>
|
<string name="work_profile_toggle_label" msgid="3081029915775481146">"نمایه کاری"</string>
|
||||||
<string name="work_profile_edu_personal_apps" msgid="4155536355149317441">"دادههای شخصی از برنامههای کاری جدا است و از آن پنهان است"</string>
|
<string name="work_profile_edu_personal_apps" msgid="4155536355149317441">"دادههای شخصی از برنامههای کاری جدا است و از آن پنهان است"</string>
|
||||||
<string name="work_profile_edu_work_apps" msgid="237051938268703058">"برنامههای کاری و دادهها برای سرپرست فناوری اطلاعات نمایان هستند"</string>
|
<string name="work_profile_edu_work_apps" msgid="237051938268703058">"برنامههای کاری و دادهها برای سرپرست فناوری اطلاعات نمایان هستند"</string>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
|
||||||
<string name="work_folder_name" msgid="3753320833950115786">"કાર્યાલય"</string>
|
<string name="work_folder_name" msgid="3753320833950115786">"ઑફિસ"</string>
|
||||||
<string name="activity_not_found" msgid="8071924732094499514">"ઍપ્લિકેશન ઇન્સ્ટોલ થઈ નથી."</string>
|
<string name="activity_not_found" msgid="8071924732094499514">"ઍપ્લિકેશન ઇન્સ્ટોલ થઈ નથી."</string>
|
||||||
<string name="activity_not_available" msgid="7456344436509528827">"ઍપ્લિકેશન ઉપલબ્ધ નથી"</string>
|
<string name="activity_not_available" msgid="7456344436509528827">"ઍપ્લિકેશન ઉપલબ્ધ નથી"</string>
|
||||||
<string name="safemode_shortcut_error" msgid="9160126848219158407">"સુરક્ષિત મોડમાં ડાઉનલોડ કરેલ ઍપ્લિકેશન અક્ષમ કરી"</string>
|
<string name="safemode_shortcut_error" msgid="9160126848219158407">"સુરક્ષિત મોડમાં ડાઉનલોડ કરેલ ઍપ્લિકેશન અક્ષમ કરી"</string>
|
||||||
@@ -131,7 +131,7 @@
|
|||||||
<string name="accessibility_close" msgid="2277148124685870734">"બંધ કરો"</string>
|
<string name="accessibility_close" msgid="2277148124685870734">"બંધ કરો"</string>
|
||||||
<string name="notification_dismissed" msgid="6002233469409822874">"સૂચના છોડી દીધી"</string>
|
<string name="notification_dismissed" msgid="6002233469409822874">"સૂચના છોડી દીધી"</string>
|
||||||
<string name="all_apps_personal_tab" msgid="4190252696685155002">"મનગમતી ઍપ"</string>
|
<string name="all_apps_personal_tab" msgid="4190252696685155002">"મનગમતી ઍપ"</string>
|
||||||
<string name="all_apps_work_tab" msgid="4884822796154055118">"કાર્યાલયની ઍપ"</string>
|
<string name="all_apps_work_tab" msgid="4884822796154055118">"ઑફિસની ઍપ"</string>
|
||||||
<string name="work_profile_toggle_label" msgid="3081029915775481146">"ઑફિસની પ્રોફાઇલ"</string>
|
<string name="work_profile_toggle_label" msgid="3081029915775481146">"ઑફિસની પ્રોફાઇલ"</string>
|
||||||
<string name="work_profile_edu_personal_apps" msgid="4155536355149317441">"વ્યક્તિગત ડેટા ઑફિસ માટેની ઍપથી અલગ અને છુપાવીને રાખેલો છે"</string>
|
<string name="work_profile_edu_personal_apps" msgid="4155536355149317441">"વ્યક્તિગત ડેટા ઑફિસ માટેની ઍપથી અલગ અને છુપાવીને રાખેલો છે"</string>
|
||||||
<string name="work_profile_edu_work_apps" msgid="237051938268703058">"ઑફિસ માટેની ઍપ અને ડેટા તમારા IT વ્યવસ્થાપકને દેખાય છે"</string>
|
<string name="work_profile_edu_work_apps" msgid="237051938268703058">"ઑફિસ માટેની ઍપ અને ડેટા તમારા IT વ્યવસ્થાપકને દેખાય છે"</string>
|
||||||
|
|||||||
@@ -53,11 +53,11 @@
|
|||||||
<string name="app_info_drop_target_label" msgid="692894985365717661">"अनुप्रयोगको जानकारी"</string>
|
<string name="app_info_drop_target_label" msgid="692894985365717661">"अनुप्रयोगको जानकारी"</string>
|
||||||
<string name="install_drop_target_label" msgid="2539096853673231757">"स्थापना गर्नुहोस्"</string>
|
<string name="install_drop_target_label" msgid="2539096853673231757">"स्थापना गर्नुहोस्"</string>
|
||||||
<string name="permlab_install_shortcut" msgid="5632423390354674437">"सर्टकट स्थापना गर्नेहोस्"</string>
|
<string name="permlab_install_shortcut" msgid="5632423390354674437">"सर्टकट स्थापना गर्नेहोस्"</string>
|
||||||
<string name="permdesc_install_shortcut" msgid="923466509822011139">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा अनुप्रयोगलाई सर्टकटमा थप्नको लागि अनुमति दिनुहोस्।"</string>
|
<string name="permdesc_install_shortcut" msgid="923466509822011139">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा थप्नको लागि अनुमति दिनुहोस्।"</string>
|
||||||
<string name="permlab_read_settings" msgid="1941457408239617576">"गृह सेटिङहरू र सर्टकटहरू पढ्नुहोस्"</string>
|
<string name="permlab_read_settings" msgid="1941457408239617576">"गृह सेटिङहरू र सर्टकटहरू पढ्नुहोस्"</string>
|
||||||
<string name="permdesc_read_settings" msgid="5833423719057558387">"गृहमा एउटा अनुप्रयोगलाई सेटिङहरू र सर्टकटहरू पढ्न अनुमति दिनुहोस्।"</string>
|
<string name="permdesc_read_settings" msgid="5833423719057558387">"गृहमा एउटा एपलाई सेटिङहरू र सर्टकटहरू पढ्न अनुमति दिनुहोस्।"</string>
|
||||||
<string name="permlab_write_settings" msgid="3574213698004620587">"गृह सेटिङहरू र सर्टकटहरू लेख्नुहोस्"</string>
|
<string name="permlab_write_settings" msgid="3574213698004620587">"गृह सेटिङहरू र सर्टकटहरू लेख्नुहोस्"</string>
|
||||||
<string name="permdesc_write_settings" msgid="5440712911516509985">"गृहमा एउटा अनुप्रयोगलाई सेटिङ र सर्टकट बदल्न अनुमति दिनुहोस्।"</string>
|
<string name="permdesc_write_settings" msgid="5440712911516509985">"गृहमा एउटा एपलाई सेटिङ र सर्टकट बदल्न अनुमति दिनुहोस्।"</string>
|
||||||
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले फोन कलहरू गर्न अनुमति छैन"</string>
|
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले फोन कलहरू गर्न अनुमति छैन"</string>
|
||||||
<string name="gadget_error_text" msgid="6081085226050792095">"समस्या लोडिङ गर्ने विजेट"</string>
|
<string name="gadget_error_text" msgid="6081085226050792095">"समस्या लोडिङ गर्ने विजेट"</string>
|
||||||
<string name="gadget_setup_text" msgid="8274003207686040488">"सेटअप"</string>
|
<string name="gadget_setup_text" msgid="8274003207686040488">"सेटअप"</string>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="app_name" msgid="649227358658669779">"ଲଞ୍ଚର୍3"</string>
|
<string name="app_name" msgid="649227358658669779">"ଲଞ୍ଚର୍3"</string>
|
||||||
<string name="work_folder_name" msgid="3753320833950115786">"କାମ"</string>
|
<string name="work_folder_name" msgid="3753320833950115786">"ୱାର୍କ"</string>
|
||||||
<string name="activity_not_found" msgid="8071924732094499514">"ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇନାହିଁ"</string>
|
<string name="activity_not_found" msgid="8071924732094499514">"ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇନାହିଁ"</string>
|
||||||
<string name="activity_not_available" msgid="7456344436509528827">"ଆପ୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
|
<string name="activity_not_available" msgid="7456344436509528827">"ଆପ୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
|
||||||
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ନିରାପଦ ମୋଡରେ ଡାଉନଲୋଡ୍ ହେଇଥିବା ଆପ୍ ଅକ୍ଷମ କରାଗଲା"</string>
|
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ନିରାପଦ ମୋଡରେ ଡାଉନଲୋଡ୍ ହେଇଥିବା ଆପ୍ ଅକ୍ଷମ କରାଗଲା"</string>
|
||||||
@@ -131,7 +131,7 @@
|
|||||||
<string name="accessibility_close" msgid="2277148124685870734">"ବନ୍ଦ କରନ୍ତୁ"</string>
|
<string name="accessibility_close" msgid="2277148124685870734">"ବନ୍ଦ କରନ୍ତୁ"</string>
|
||||||
<string name="notification_dismissed" msgid="6002233469409822874">"ବିଜ୍ଞପ୍ତି ଖାରଜ କରାଗଲା"</string>
|
<string name="notification_dismissed" msgid="6002233469409822874">"ବିଜ୍ଞପ୍ତି ଖାରଜ କରାଗଲା"</string>
|
||||||
<string name="all_apps_personal_tab" msgid="4190252696685155002">"ବ୍ୟକ୍ତିଗତ"</string>
|
<string name="all_apps_personal_tab" msgid="4190252696685155002">"ବ୍ୟକ୍ତିଗତ"</string>
|
||||||
<string name="all_apps_work_tab" msgid="4884822796154055118">"କାମ"</string>
|
<string name="all_apps_work_tab" msgid="4884822796154055118">"ୱାର୍କ"</string>
|
||||||
<string name="work_profile_toggle_label" msgid="3081029915775481146">"ୱର୍କ ପ୍ରୋଫାଇଲ୍"</string>
|
<string name="work_profile_toggle_label" msgid="3081029915775481146">"ୱର୍କ ପ୍ରୋଫାଇଲ୍"</string>
|
||||||
<string name="work_profile_edu_personal_apps" msgid="4155536355149317441">"ବ୍ୟକ୍ତିଗତ ଡାଟା କାର୍ଯ୍ୟସ୍ଥଳୀ ଆପଗୁଡ଼ିକ ଠାରୁ ପୃଥକ୍ ଓ ଲୁକ୍କାୟିତ ଅଟେ"</string>
|
<string name="work_profile_edu_personal_apps" msgid="4155536355149317441">"ବ୍ୟକ୍ତିଗତ ଡାଟା କାର୍ଯ୍ୟସ୍ଥଳୀ ଆପଗୁଡ଼ିକ ଠାରୁ ପୃଥକ୍ ଓ ଲୁକ୍କାୟିତ ଅଟେ"</string>
|
||||||
<string name="work_profile_edu_work_apps" msgid="237051938268703058">"କାର୍ଯ୍ୟସ୍ଥଳୀ ଆପଗୁଡ଼ିକ ଓ ଡାଟା ଆପଣଙ୍କ IT ଆଡମିନଙ୍କୁ ଦେଖାଯାଏ"</string>
|
<string name="work_profile_edu_work_apps" msgid="237051938268703058">"କାର୍ଯ୍ୟସ୍ଥଳୀ ଆପଗୁଡ଼ିକ ଓ ଡାଟା ଆପଣଙ୍କ IT ଆଡମିନଙ୍କୁ ଦେଖାଯାଏ"</string>
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
<attr name="widgetsTheme" format="reference" />
|
<attr name="widgetsTheme" format="reference" />
|
||||||
<attr name="loadingIconColor" format="color" />
|
<attr name="loadingIconColor" format="color" />
|
||||||
<attr name="iconOnlyShortcutColor" format="color"/>
|
<attr name="iconOnlyShortcutColor" format="color"/>
|
||||||
|
<attr name="eduHalfSheetBGColor" format="color"/>
|
||||||
|
|
||||||
<attr name="folderDotColor" format="color" />
|
<attr name="folderDotColor" format="color" />
|
||||||
<attr name="folderFillColor" format="color" />
|
<attr name="folderFillColor" format="color" />
|
||||||
|
|||||||
@@ -103,9 +103,9 @@
|
|||||||
<!-- Label for install drop target. [CHAR_LIMIT=20] -->
|
<!-- Label for install drop target. [CHAR_LIMIT=20] -->
|
||||||
<string name="install_drop_target_label">Install</string>
|
<string name="install_drop_target_label">Install</string>
|
||||||
<!-- Label for install dismiss prediction. -->
|
<!-- Label for install dismiss prediction. -->
|
||||||
<string translatable="false" name="dismiss_prediction_label">Don\'t suggest app</string>
|
<string name="dismiss_prediction_label">Don\'t suggest app</string>
|
||||||
<!-- Label for pinning predicted app. -->
|
<!-- Label for pinning predicted app. -->
|
||||||
<string name="pin_prediction" translatable="false">Pin Prediction</string>
|
<string name="pin_prediction">Pin Prediction</string>
|
||||||
|
|
||||||
|
|
||||||
<!-- Permissions: -->
|
<!-- Permissions: -->
|
||||||
@@ -342,7 +342,7 @@
|
|||||||
<!--- heading shown when user opens work apps tab while work apps are paused -->
|
<!--- heading shown when user opens work apps tab while work apps are paused -->
|
||||||
<string name="work_apps_paused_title">Work profile is paused</string>
|
<string name="work_apps_paused_title">Work profile is paused</string>
|
||||||
<!--- body shown when user opens work apps tab while work apps are paused -->
|
<!--- body shown when user opens work apps tab while work apps are paused -->
|
||||||
<string name="work_apps_paused_body">Work apps can\’t send you notifications, use your battery, or access your location</string>
|
<string name="work_apps_paused_body">Work apps can\'t send you notifications, use your battery, or access your location</string>
|
||||||
<!-- content description for paused work apps list -->
|
<!-- content description for paused work apps list -->
|
||||||
<string name="work_apps_paused_content_description">Work profile is paused. Work apps can\’t send you notifications, use your battery, or access your location</string>
|
<string name="work_apps_paused_content_description">Work profile is paused. Work apps can\’t send you notifications, use your battery, or access your location</string>
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@
|
|||||||
<item name="loadingIconColor">#CCFFFFFF</item>
|
<item name="loadingIconColor">#CCFFFFFF</item>
|
||||||
<item name="iconOnlyShortcutColor">?android:attr/textColorSecondary</item>
|
<item name="iconOnlyShortcutColor">?android:attr/textColorSecondary</item>
|
||||||
<item name="workProfileOverlayTextColor">#FF212121</item>
|
<item name="workProfileOverlayTextColor">#FF212121</item>
|
||||||
|
<item name="eduHalfSheetBGColor">?android:attr/colorAccent</item>
|
||||||
|
|
||||||
<item name="android:windowTranslucentStatus">false</item>
|
<item name="android:windowTranslucentStatus">false</item>
|
||||||
<item name="android:windowTranslucentNavigation">false</item>
|
<item name="android:windowTranslucentNavigation">false</item>
|
||||||
@@ -90,7 +91,7 @@
|
|||||||
<item name="android:textColorHint">#A0FFFFFF</item>
|
<item name="android:textColorHint">#A0FFFFFF</item>
|
||||||
<item name="android:colorControlHighlight">#A0FFFFFF</item>
|
<item name="android:colorControlHighlight">#A0FFFFFF</item>
|
||||||
<item name="android:colorPrimary">#FF212121</item>
|
<item name="android:colorPrimary">#FF212121</item>
|
||||||
<item name="allAppsScrimColor">#FF212121</item>
|
<item name="allAppsScrimColor">#FF000000</item>
|
||||||
<item name="allAppsInterimScrimAlpha">102</item>
|
<item name="allAppsInterimScrimAlpha">102</item>
|
||||||
<item name="allAppsNavBarScrimColor">#80000000</item>
|
<item name="allAppsNavBarScrimColor">#80000000</item>
|
||||||
<item name="popupColorPrimary">#3C4043</item> <!-- Gray 800 -->
|
<item name="popupColorPrimary">#3C4043</item> <!-- Gray 800 -->
|
||||||
@@ -106,6 +107,7 @@
|
|||||||
<item name="loadingIconColor">#99FFFFFF</item>
|
<item name="loadingIconColor">#99FFFFFF</item>
|
||||||
<item name="iconOnlyShortcutColor">#B3FFFFFF</item>
|
<item name="iconOnlyShortcutColor">#B3FFFFFF</item>
|
||||||
<item name="workProfileOverlayTextColor">@android:color/white</item>
|
<item name="workProfileOverlayTextColor">@android:color/white</item>
|
||||||
|
<item name="eduHalfSheetBGColor">#DD000000</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="LauncherTheme.Dark.DarkMainColor" parent="@style/LauncherTheme.Dark">
|
<style name="LauncherTheme.Dark.DarkMainColor" parent="@style/LauncherTheme.Dark">
|
||||||
@@ -229,9 +231,7 @@
|
|||||||
|
|
||||||
<style name="TextHeadline" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle" />
|
<style name="TextHeadline" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle" />
|
||||||
<style name="PrimaryMediumText" parent="@android:style/TextAppearance.DeviceDefault.Medium"/>
|
<style name="PrimaryMediumText" parent="@android:style/TextAppearance.DeviceDefault.Medium"/>
|
||||||
<style name="PrimaryHeadline" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle">
|
<style name="PrimaryHeadline" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle"/>
|
||||||
<item name="android:textStyle">bold</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="TextTitle" parent="@android:style/TextAppearance.DeviceDefault" />
|
<style name="TextTitle" parent="@android:style/TextAppearance.DeviceDefault" />
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.android.launcher3;
|
package com.android.launcher3;
|
||||||
|
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.APP_LAUNCH_TAP;
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
|
||||||
import static com.android.launcher3.util.DefaultDisplay.CHANGE_ROTATION;
|
import static com.android.launcher3.util.DefaultDisplay.CHANGE_ROTATION;
|
||||||
|
|
||||||
import android.app.ActivityOptions;
|
import android.app.ActivityOptions;
|
||||||
@@ -183,8 +183,7 @@ public abstract class BaseDraggingActivity extends BaseActivity
|
|||||||
sourceContainer);
|
sourceContainer);
|
||||||
}
|
}
|
||||||
getUserEventDispatcher().logAppLaunch(v, intent, user);
|
getUserEventDispatcher().logAppLaunch(v, intent, user);
|
||||||
|
getStatsLogManager().log(LAUNCHER_APP_LAUNCH_TAP, item == null ? null
|
||||||
getStatsLogManager().log(APP_LAUNCH_TAP, item == null ? null
|
|
||||||
: item.buildProto(null));
|
: item.buildProto(null));
|
||||||
return true;
|
return true;
|
||||||
} catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
|
} catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ import com.android.launcher3.model.data.ItemInfoWithIcon;
|
|||||||
import com.android.launcher3.model.data.PackageItemInfo;
|
import com.android.launcher3.model.data.PackageItemInfo;
|
||||||
import com.android.launcher3.model.data.PromiseAppInfo;
|
import com.android.launcher3.model.data.PromiseAppInfo;
|
||||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||||
|
import com.android.launcher3.util.SafeCloseable;
|
||||||
import com.android.launcher3.views.ActivityContext;
|
import com.android.launcher3.views.ActivityContext;
|
||||||
import com.android.launcher3.views.IconLabelDotView;
|
import com.android.launcher3.views.IconLabelDotView;
|
||||||
|
|
||||||
@@ -722,17 +723,34 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getVisualDragBounds(Rect bounds) {
|
public void getWorkspaceVisualDragBounds(Rect bounds) {
|
||||||
DeviceProfile grid = mActivity.getDeviceProfile();
|
DeviceProfile grid = mActivity.getDeviceProfile();
|
||||||
BubbleTextView.getIconBounds(this, bounds, grid.iconSizePx);
|
BubbleTextView.getIconBounds(this, bounds, grid.iconSizePx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getIconSizeForDisplay(int display) {
|
||||||
|
DeviceProfile grid = mActivity.getDeviceProfile();
|
||||||
|
switch (display) {
|
||||||
|
case DISPLAY_ALL_APPS:
|
||||||
|
return grid.allAppsIconSizePx;
|
||||||
|
case DISPLAY_WORKSPACE:
|
||||||
|
case DISPLAY_FOLDER:
|
||||||
|
default:
|
||||||
|
return grid.iconSizePx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getSourceVisualDragBounds(Rect bounds) {
|
||||||
|
BubbleTextView.getIconBounds(this, bounds, getIconSizeForDisplay(mDisplay));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void prepareDrawDragView() {
|
public SafeCloseable prepareDrawDragView() {
|
||||||
if (getIcon() instanceof FastBitmapDrawable) {
|
if (getIcon() instanceof FastBitmapDrawable) {
|
||||||
FastBitmapDrawable icon = (FastBitmapDrawable) getIcon();
|
FastBitmapDrawable icon = (FastBitmapDrawable) getIcon();
|
||||||
icon.setScale(1f);
|
icon.setScale(1f);
|
||||||
}
|
}
|
||||||
setForceHideDot(true);
|
setForceHideDot(true);
|
||||||
|
return () -> { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.launcher3;
|
package com.android.launcher3;
|
||||||
|
|
||||||
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_CANCEL;
|
||||||
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_REMOVE;
|
||||||
import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
|
import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
|
||||||
import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.UNDO;
|
import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.UNDO;
|
||||||
|
|
||||||
@@ -27,6 +29,7 @@ import android.view.View;
|
|||||||
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
|
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
|
||||||
import com.android.launcher3.dragndrop.DragOptions;
|
import com.android.launcher3.dragndrop.DragOptions;
|
||||||
import com.android.launcher3.logging.LoggerUtils;
|
import com.android.launcher3.logging.LoggerUtils;
|
||||||
|
import com.android.launcher3.logging.StatsLogManager;
|
||||||
import com.android.launcher3.model.ModelWriter;
|
import com.android.launcher3.model.ModelWriter;
|
||||||
import com.android.launcher3.model.data.FolderInfo;
|
import com.android.launcher3.model.data.FolderInfo;
|
||||||
import com.android.launcher3.model.data.ItemInfo;
|
import com.android.launcher3.model.data.ItemInfo;
|
||||||
@@ -38,6 +41,8 @@ import com.android.launcher3.views.Snackbar;
|
|||||||
|
|
||||||
public class DeleteDropTarget extends ButtonDropTarget {
|
public class DeleteDropTarget extends ButtonDropTarget {
|
||||||
|
|
||||||
|
private final StatsLogManager mStatsLogManager;
|
||||||
|
|
||||||
private int mControlType = ControlType.DEFAULT_CONTROLTYPE;
|
private int mControlType = ControlType.DEFAULT_CONTROLTYPE;
|
||||||
|
|
||||||
public DeleteDropTarget(Context context, AttributeSet attrs) {
|
public DeleteDropTarget(Context context, AttributeSet attrs) {
|
||||||
@@ -46,6 +51,7 @@ public class DeleteDropTarget extends ButtonDropTarget {
|
|||||||
|
|
||||||
public DeleteDropTarget(Context context, AttributeSet attrs, int defStyle) {
|
public DeleteDropTarget(Context context, AttributeSet attrs, int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
|
this.mStatsLogManager = StatsLogManager.newInstance(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -120,6 +126,11 @@ public class DeleteDropTarget extends ButtonDropTarget {
|
|||||||
d.dragInfo.container = NO_ID;
|
d.dragInfo.container = NO_ID;
|
||||||
}
|
}
|
||||||
super.onDrop(d, options);
|
super.onDrop(d, options);
|
||||||
|
mStatsLogManager.log(
|
||||||
|
mControlType == ControlType.REMOVE_TARGET
|
||||||
|
? LAUNCHER_ITEM_DROPPED_ON_REMOVE
|
||||||
|
: LAUNCHER_ITEM_DROPPED_ON_CANCEL,
|
||||||
|
d.logInstanceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ public interface DropTarget {
|
|||||||
public DraggableView originalView = null;
|
public DraggableView originalView = null;
|
||||||
|
|
||||||
/** Used for matching DROP event with its corresponding DRAG event on the server side. */
|
/** Used for matching DROP event with its corresponding DRAG event on the server side. */
|
||||||
final InstanceId mLogInstanceId =
|
public final InstanceId logInstanceId =
|
||||||
new InstanceIdSequence(1 << 20 /*InstanceId.INSTANCE_ID_MAX*/)
|
new InstanceIdSequence(1 << 20 /*InstanceId.INSTANCE_ID_MAX*/)
|
||||||
.newInstanceId();
|
.newInstanceId();
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ import android.database.sqlite.SQLiteDatabase;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.CancellationSignal;
|
import android.os.CancellationSignal;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.StrictMode;
|
import android.os.StrictMode;
|
||||||
@@ -87,12 +86,12 @@ import android.view.accessibility.AccessibilityEvent;
|
|||||||
import android.view.animation.OvershootInterpolator;
|
import android.view.animation.OvershootInterpolator;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.CallSuper;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import com.android.launcher3.DropTarget.DragObject;
|
import com.android.launcher3.DropTarget.DragObject;
|
||||||
import com.android.launcher3.LauncherStateManager.StateHandler;
|
|
||||||
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
|
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
|
||||||
import com.android.launcher3.allapps.AllAppsContainerView;
|
import com.android.launcher3.allapps.AllAppsContainerView;
|
||||||
import com.android.launcher3.allapps.AllAppsStore;
|
import com.android.launcher3.allapps.AllAppsStore;
|
||||||
@@ -130,6 +129,10 @@ import com.android.launcher3.popup.PopupContainerWithArrow;
|
|||||||
import com.android.launcher3.popup.PopupDataProvider;
|
import com.android.launcher3.popup.PopupDataProvider;
|
||||||
import com.android.launcher3.popup.SystemShortcut;
|
import com.android.launcher3.popup.SystemShortcut;
|
||||||
import com.android.launcher3.qsb.QsbContainerView;
|
import com.android.launcher3.qsb.QsbContainerView;
|
||||||
|
import com.android.launcher3.statemanager.StateManager;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateHandler;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||||
|
import com.android.launcher3.statemanager.StatefulActivity;
|
||||||
import com.android.launcher3.states.RotationHelper;
|
import com.android.launcher3.states.RotationHelper;
|
||||||
import com.android.launcher3.testing.TestLogging;
|
import com.android.launcher3.testing.TestLogging;
|
||||||
import com.android.launcher3.testing.TestProtocol;
|
import com.android.launcher3.testing.TestProtocol;
|
||||||
@@ -193,7 +196,7 @@ import java.util.stream.Stream;
|
|||||||
/**
|
/**
|
||||||
* Default launcher application.
|
* Default launcher application.
|
||||||
*/
|
*/
|
||||||
public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
public class Launcher extends StatefulActivity<LauncherState> implements LauncherExterns,
|
||||||
Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin> {
|
Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin> {
|
||||||
public static final String TAG = "Launcher";
|
public static final String TAG = "Launcher";
|
||||||
|
|
||||||
@@ -240,7 +243,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
public static final String ON_RESUME_EVT = "Launcher.onResume";
|
public static final String ON_RESUME_EVT = "Launcher.onResume";
|
||||||
public static final String ON_NEW_INTENT_EVT = "Launcher.onNewIntent";
|
public static final String ON_NEW_INTENT_EVT = "Launcher.onNewIntent";
|
||||||
|
|
||||||
private LauncherStateManager mStateManager;
|
private StateManager<LauncherState> mStateManager;
|
||||||
|
|
||||||
private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;
|
private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;
|
||||||
|
|
||||||
@@ -324,10 +327,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
|
|
||||||
private RotationHelper mRotationHelper;
|
private RotationHelper mRotationHelper;
|
||||||
|
|
||||||
final Handler mHandler = new Handler();
|
|
||||||
private final Runnable mHandleDeferredResume = this::handleDeferredResume;
|
|
||||||
private boolean mDeferredResumePending;
|
|
||||||
|
|
||||||
private float mCurrentAssistantVisibility = 0f;
|
private float mCurrentAssistantVisibility = 0f;
|
||||||
|
|
||||||
protected LauncherOverlayManager mOverlayManager;
|
protected LauncherOverlayManager mOverlayManager;
|
||||||
@@ -374,9 +373,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
|
|
||||||
mDragController = new DragController(this);
|
mDragController = new DragController(this);
|
||||||
mAllAppsController = new AllAppsTransitionController(this);
|
mAllAppsController = new AllAppsTransitionController(this);
|
||||||
mStateManager = new LauncherStateManager(this);
|
mStateManager = new StateManager<>(this, NORMAL);
|
||||||
|
|
||||||
mOnboardingPrefs = createOnboardingPrefs(mSharedPrefs, mStateManager);
|
mOnboardingPrefs = createOnboardingPrefs(mSharedPrefs);
|
||||||
|
|
||||||
mAppWidgetManager = new WidgetManagerHelper(this);
|
mAppWidgetManager = new WidgetManagerHelper(this);
|
||||||
mAppWidgetHost = new LauncherAppWidgetHost(this,
|
mAppWidgetHost = new LauncherAppWidgetHost(this,
|
||||||
@@ -439,7 +438,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
|
|
||||||
mRotationHelper.initialize();
|
mRotationHelper.initialize();
|
||||||
|
|
||||||
mStateManager.addStateListener(new LauncherStateManager.StateListener() {
|
mStateManager.addStateListener(new StateListener<LauncherState>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStateTransitionComplete(LauncherState finalState) {
|
public void onStateTransitionComplete(LauncherState finalState) {
|
||||||
@@ -466,9 +465,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
return new LauncherOverlayManager() { };
|
return new LauncherOverlayManager() { };
|
||||||
}
|
}
|
||||||
|
|
||||||
protected OnboardingPrefs createOnboardingPrefs(SharedPreferences sharedPrefs,
|
protected OnboardingPrefs createOnboardingPrefs(SharedPreferences sharedPrefs) {
|
||||||
LauncherStateManager stateManager) {
|
return new OnboardingPrefs<>(this, sharedPrefs);
|
||||||
return new OnboardingPrefs<>(this, sharedPrefs, stateManager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public OnboardingPrefs getOnboardingPrefs() {
|
public OnboardingPrefs getOnboardingPrefs() {
|
||||||
@@ -522,13 +520,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reapplyUi() {
|
|
||||||
reapplyUi(true /* cancelCurrentAnimation */);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reapplyUi(boolean cancelCurrentAnimation) {
|
public void reapplyUi(boolean cancelCurrentAnimation) {
|
||||||
getRootView().dispatchInsets();
|
getRootView().dispatchInsets();
|
||||||
getStateManager().reapplyState(cancelCurrentAnimation);
|
super.reapplyUi(cancelCurrentAnimation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -582,7 +576,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
return mFocusHandler;
|
return mFocusHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LauncherStateManager getStateManager() {
|
@Override
|
||||||
|
public StateManager<LauncherState> getStateManager() {
|
||||||
return mStateManager;
|
return mStateManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -889,11 +884,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
final boolean wasActive = isUserActive();
|
|
||||||
final LauncherState origState = getStateManager().getState();
|
|
||||||
final int origDragLayerChildCount = mDragLayer.getChildCount();
|
|
||||||
super.onStop();
|
super.onStop();
|
||||||
|
|
||||||
if (mDeferOverlayCallbacks) {
|
if (mDeferOverlayCallbacks) {
|
||||||
checkIfOverlayStillDeferred();
|
checkIfOverlayStillDeferred();
|
||||||
} else {
|
} else {
|
||||||
@@ -901,28 +892,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
}
|
}
|
||||||
|
|
||||||
logStopAndResume(Action.Command.STOP);
|
logStopAndResume(Action.Command.STOP);
|
||||||
|
|
||||||
mAppWidgetHost.setListenIfResumed(false);
|
mAppWidgetHost.setListenIfResumed(false);
|
||||||
|
|
||||||
NotificationListener.removeNotificationsChangedListener();
|
NotificationListener.removeNotificationsChangedListener();
|
||||||
getStateManager().moveToRestState();
|
|
||||||
|
|
||||||
// Workaround for b/78520668, explicitly trim memory once UI is hidden
|
|
||||||
onTrimMemory(TRIM_MEMORY_UI_HIDDEN);
|
|
||||||
|
|
||||||
if (wasActive) {
|
|
||||||
// The expected condition is that this activity is stopped because the device goes to
|
|
||||||
// sleep and the UI may have noticeable changes.
|
|
||||||
mDragLayer.post(() -> {
|
|
||||||
if ((!getStateManager().isInStableState(origState)
|
|
||||||
// The drag layer may be animating (e.g. dismissing QSB).
|
|
||||||
|| mDragLayer.getAlpha() < 1
|
|
||||||
// Maybe an ArrowPopup is closed.
|
|
||||||
|| mDragLayer.getChildCount() != origDragLayerChildCount)) {
|
|
||||||
onUiChangedWhileSleeping();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -938,35 +909,27 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
TraceHelper.INSTANCE.endSection(traceToken);
|
TraceHelper.INSTANCE.endSection(traceToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleDeferredResume() {
|
@Override
|
||||||
if (hasBeenResumed() && !mStateManager.getState().hasFlag(FLAG_NON_INTERACTIVE)) {
|
@CallSuper
|
||||||
logStopAndResume(Action.Command.RESUME);
|
protected void onDeferredResumed() {
|
||||||
getUserEventDispatcher().startSession();
|
logStopAndResume(Action.Command.RESUME);
|
||||||
|
getUserEventDispatcher().startSession();
|
||||||
|
|
||||||
AppLaunchTracker.INSTANCE.get(this).onReturnedToHome();
|
AppLaunchTracker.INSTANCE.get(this).onReturnedToHome();
|
||||||
|
|
||||||
// Process any items that were added while Launcher was away.
|
// Process any items that were added while Launcher was away.
|
||||||
InstallShortcutReceiver.disableAndFlushInstallQueue(
|
InstallShortcutReceiver.disableAndFlushInstallQueue(
|
||||||
InstallShortcutReceiver.FLAG_ACTIVITY_PAUSED, this);
|
InstallShortcutReceiver.FLAG_ACTIVITY_PAUSED, this);
|
||||||
|
|
||||||
// Refresh shortcuts if the permission changed.
|
// Refresh shortcuts if the permission changed.
|
||||||
mModel.refreshShortcutsIfRequired();
|
mModel.refreshShortcutsIfRequired();
|
||||||
|
|
||||||
// Set the notification listener and fetch updated notifications when we resume
|
// Set the notification listener and fetch updated notifications when we resume
|
||||||
NotificationListener.setNotificationsChangedListener(mPopupDataProvider);
|
NotificationListener.setNotificationsChangedListener(mPopupDataProvider);
|
||||||
|
|
||||||
DiscoveryBounce.showForHomeIfNeeded(this);
|
DiscoveryBounce.showForHomeIfNeeded(this);
|
||||||
|
|
||||||
onDeferredResumed();
|
|
||||||
addActivityFlags(ACTIVITY_STATE_DEFERRED_RESUMED);
|
|
||||||
|
|
||||||
mDeferredResumePending = false;
|
|
||||||
} else {
|
|
||||||
mDeferredResumePending = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onDeferredResumed() { }
|
|
||||||
|
|
||||||
private void logStopAndResume(int command) {
|
private void logStopAndResume(int command) {
|
||||||
int containerType = mStateManager.getState().containerType;
|
int containerType = mStateManager.getState().containerType;
|
||||||
@@ -1015,10 +978,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
return mOverlayManager;
|
return mOverlayManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onStateSetStart(LauncherState state) {
|
public void onStateSetStart(LauncherState state) {
|
||||||
if (mDeferredResumePending) {
|
super.onStateSetStart(state);
|
||||||
handleDeferredResume();
|
|
||||||
}
|
|
||||||
if (mDeferOverlayCallbacks) {
|
if (mDeferOverlayCallbacks) {
|
||||||
scheduleDeferredCheck();
|
scheduleDeferredCheck();
|
||||||
}
|
}
|
||||||
@@ -1041,7 +1003,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
mWorkspace.getPageIndicator().setShouldAutoHide(!state.hasFlag(FLAG_MULTI_PAGE));
|
mWorkspace.getPageIndicator().setShouldAutoHide(!state.hasFlag(FLAG_MULTI_PAGE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onStateSetEnd(LauncherState state) {
|
public void onStateSetEnd(LauncherState state) {
|
||||||
|
super.onStateSetStart(state);
|
||||||
getAppWidgetHost().setResumed(state == LauncherState.NORMAL);
|
getAppWidgetHost().setResumed(state == LauncherState.NORMAL);
|
||||||
getWorkspace().setClipChildren(!state.hasFlag(FLAG_MULTI_PAGE));
|
getWorkspace().setClipChildren(!state.hasFlag(FLAG_MULTI_PAGE));
|
||||||
|
|
||||||
@@ -1067,9 +1031,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
TraceHelper.FLAG_UI_EVENT);
|
TraceHelper.FLAG_UI_EVENT);
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
mHandler.removeCallbacks(mHandleDeferredResume);
|
|
||||||
Utilities.postAsyncCallback(mHandler, mHandleDeferredResume);
|
|
||||||
|
|
||||||
if (!mOnResumeCallbacks.isEmpty()) {
|
if (!mOnResumeCallbacks.isEmpty()) {
|
||||||
final ArrayList<OnResumeCallback> resumeCallbacks = new ArrayList<>(mOnResumeCallbacks);
|
final ArrayList<OnResumeCallback> resumeCallbacks = new ArrayList<>(mOnResumeCallbacks);
|
||||||
mOnResumeCallbacks.clear();
|
mOnResumeCallbacks.clear();
|
||||||
@@ -1112,10 +1073,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInState(LauncherState state) {
|
|
||||||
return mStateManager.getState() == state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restores the previous state, if it exists.
|
* Restores the previous state, if it exists.
|
||||||
*
|
*
|
||||||
@@ -1354,8 +1311,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
protected void onUiChangedWhileSleeping() { }
|
|
||||||
|
|
||||||
private void updateNotificationDots(Predicate<PackageUserKey> updatedDots) {
|
private void updateNotificationDots(Predicate<PackageUserKey> updatedDots) {
|
||||||
mWorkspace.updateNotificationDots(updatedDots);
|
mWorkspace.updateNotificationDots(updatedDots);
|
||||||
mAppsView.getAppsStore().updateNotificationDots(updatedDots);
|
mAppsView.getAppsStore().updateNotificationDots(updatedDots);
|
||||||
@@ -2720,7 +2675,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||||||
return super.onKeyUp(keyCode, event);
|
return super.onKeyUp(keyCode, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected StateHandler[] createStateHandlers() {
|
protected StateHandler<LauncherState>[] createStateHandlers() {
|
||||||
return new StateHandler[] { getAllAppsController(), getWorkspace() };
|
return new StateHandler[] { getAllAppsController(), getWorkspace() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,8 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.launcher3;
|
package com.android.launcher3;
|
||||||
|
|
||||||
|
|
||||||
import android.animation.Animator;
|
|
||||||
import android.app.ActivityOptions;
|
import android.app.ActivityOptions;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
@@ -57,17 +54,6 @@ public class LauncherAppTransitionManager implements ResourceBasedOverride {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of animations which run on state properties.
|
|
||||||
*/
|
|
||||||
public int getStateElementAnimationsCount() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Animator createStateElementAnimation(int index, float... values) {
|
|
||||||
throw new RuntimeException("Unknown gesture animation " + index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers remote animations for certain system transitions.
|
* Registers remote animations for certain system transitions.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_A
|
|||||||
import static com.android.launcher3.provider.LauncherDbUtils.copyTable;
|
import static com.android.launcher3.provider.LauncherDbUtils.copyTable;
|
||||||
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
|
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
|
||||||
import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
|
import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
|
||||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.backup.BackupManager;
|
import android.app.backup.BackupManager;
|
||||||
@@ -48,7 +47,6 @@ import android.net.Uri;
|
|||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
@@ -85,6 +83,7 @@ import java.net.URISyntaxException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class LauncherProvider extends ContentProvider {
|
public class LauncherProvider extends ContentProvider {
|
||||||
@@ -92,8 +91,7 @@ public class LauncherProvider extends ContentProvider {
|
|||||||
private static final boolean LOGD = false;
|
private static final boolean LOGD = false;
|
||||||
|
|
||||||
private static final String DOWNGRADE_SCHEMA_FILE = "downgrade_schema.json";
|
private static final String DOWNGRADE_SCHEMA_FILE = "downgrade_schema.json";
|
||||||
private static final String TOKEN_RESTORE_BACKUP_TABLE = "restore_backup_table";
|
private static final long RESTORE_BACKUP_TABLE_DELAY = TimeUnit.SECONDS.toMillis(30);
|
||||||
private static final long RESTORE_BACKUP_TABLE_DELAY = 60000;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the schema of the database. Changes in scheme need not be backwards compatible.
|
* Represents the schema of the database. Changes in scheme need not be backwards compatible.
|
||||||
@@ -107,6 +105,8 @@ public class LauncherProvider extends ContentProvider {
|
|||||||
|
|
||||||
protected DatabaseHelper mOpenHelper;
|
protected DatabaseHelper mOpenHelper;
|
||||||
|
|
||||||
|
private long mLastRestoreTimestamp = 0L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $ adb shell dumpsys activity provider com.android.launcher3
|
* $ adb shell dumpsys activity provider com.android.launcher3
|
||||||
*/
|
*/
|
||||||
@@ -412,11 +412,12 @@ public class LauncherProvider extends ContentProvider {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
case LauncherSettings.Settings.METHOD_RESTORE_BACKUP_TABLE: {
|
case LauncherSettings.Settings.METHOD_RESTORE_BACKUP_TABLE: {
|
||||||
final Handler handler = MODEL_EXECUTOR.getHandler();
|
final long ts = System.currentTimeMillis();
|
||||||
handler.removeCallbacksAndMessages(TOKEN_RESTORE_BACKUP_TABLE);
|
if (ts - mLastRestoreTimestamp > RESTORE_BACKUP_TABLE_DELAY) {
|
||||||
handler.postDelayed(() -> RestoreDbTask.restoreIfPossible(
|
mLastRestoreTimestamp = ts;
|
||||||
getContext(), mOpenHelper, new BackupManager(getContext())),
|
RestoreDbTask.restoreIfPossible(
|
||||||
TOKEN_RESTORE_BACKUP_TABLE, RESTORE_BACKUP_TABLE_DELAY);
|
getContext(), mOpenHelper, new BackupManager(getContext()));
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
case LauncherSettings.Settings.METHOD_UPDATE_CURRENT_OPEN_HELPER: {
|
case LauncherSettings.Settings.METHOD_UPDATE_CURRENT_OPEN_HELPER: {
|
||||||
|
|||||||
@@ -15,19 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.launcher3;
|
package com.android.launcher3;
|
||||||
|
|
||||||
import static android.view.View.VISIBLE;
|
|
||||||
|
|
||||||
import static com.android.launcher3.anim.Interpolators.ACCEL;
|
|
||||||
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
|
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
|
||||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
|
||||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
|
|
||||||
import static com.android.launcher3.anim.Interpolators.clampToProgress;
|
|
||||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
|
|
||||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
|
|
||||||
import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL;
|
import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL;
|
||||||
import static com.android.launcher3.testing.TestProtocol.BACKGROUND_APP_STATE_ORDINAL;
|
import static com.android.launcher3.testing.TestProtocol.BACKGROUND_APP_STATE_ORDINAL;
|
||||||
import static com.android.launcher3.testing.TestProtocol.HINT_STATE_ORDINAL;
|
import static com.android.launcher3.testing.TestProtocol.HINT_STATE_ORDINAL;
|
||||||
@@ -39,24 +27,22 @@ import static com.android.launcher3.testing.TestProtocol.QUICK_SWITCH_STATE_ORDI
|
|||||||
import static com.android.launcher3.testing.TestProtocol.SPRING_LOADED_STATE_ORDINAL;
|
import static com.android.launcher3.testing.TestProtocol.SPRING_LOADED_STATE_ORDINAL;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.View;
|
|
||||||
import android.view.animation.Interpolator;
|
import android.view.animation.Interpolator;
|
||||||
|
|
||||||
import com.android.launcher3.allapps.AllAppsContainerView;
|
import com.android.launcher3.statemanager.BaseState;
|
||||||
|
import com.android.launcher3.statemanager.StateManager;
|
||||||
import com.android.launcher3.states.HintState;
|
import com.android.launcher3.states.HintState;
|
||||||
import com.android.launcher3.states.SpringLoadedState;
|
import com.android.launcher3.states.SpringLoadedState;
|
||||||
import com.android.launcher3.states.StateAnimationConfig;
|
|
||||||
import com.android.launcher3.uioverrides.states.AllAppsState;
|
import com.android.launcher3.uioverrides.states.AllAppsState;
|
||||||
import com.android.launcher3.uioverrides.states.OverviewState;
|
import com.android.launcher3.uioverrides.states.OverviewState;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base state for various states used for the Launcher
|
* Base state for various states used for the Launcher
|
||||||
*/
|
*/
|
||||||
public abstract class LauncherState {
|
public abstract class LauncherState implements BaseState<LauncherState> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of elements indicating various workspace elements which change visibility across states
|
* Set of elements indicating various workspace elements which change visibility across states
|
||||||
@@ -76,25 +62,22 @@ public abstract class LauncherState {
|
|||||||
HOTSEAT_SEARCH_BOX | ALL_APPS_HEADER | ALL_APPS_HEADER_EXTRA | ALL_APPS_CONTENT;
|
HOTSEAT_SEARCH_BOX | ALL_APPS_HEADER | ALL_APPS_HEADER_EXTRA | ALL_APPS_CONTENT;
|
||||||
|
|
||||||
// Flag indicating workspace has multiple pages visible.
|
// Flag indicating workspace has multiple pages visible.
|
||||||
public static final int FLAG_MULTI_PAGE = 1 << 0;
|
public static final int FLAG_MULTI_PAGE = BaseState.getFlag(0);
|
||||||
// Flag indicating that workspace and its contents are not accessible
|
// Flag indicating that workspace and its contents are not accessible
|
||||||
public static final int FLAG_WORKSPACE_INACCESSIBLE = 1 << 1;
|
public static final int FLAG_WORKSPACE_INACCESSIBLE = BaseState.getFlag(1);
|
||||||
|
|
||||||
public static final int FLAG_DISABLE_RESTORE = 1 << 2;
|
|
||||||
// Flag indicating the state allows workspace icons to be dragged.
|
// Flag indicating the state allows workspace icons to be dragged.
|
||||||
public static final int FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED = 1 << 3;
|
public static final int FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED = BaseState.getFlag(2);
|
||||||
// Flag to indicate that workspace should draw page background
|
// Flag to indicate that workspace should draw page background
|
||||||
public static final int FLAG_WORKSPACE_HAS_BACKGROUNDS = 1 << 4;
|
public static final int FLAG_WORKSPACE_HAS_BACKGROUNDS = BaseState.getFlag(3);
|
||||||
// Flag to indicate that Launcher is non-interactive in this state
|
|
||||||
public static final int FLAG_NON_INTERACTIVE = 1 << 5;
|
|
||||||
// True if the back button should be hidden when in this state (assuming no floating views are
|
// True if the back button should be hidden when in this state (assuming no floating views are
|
||||||
// open, launcher has window focus, etc).
|
// open, launcher has window focus, etc).
|
||||||
public static final int FLAG_HIDE_BACK_BUTTON = 1 << 6;
|
public static final int FLAG_HIDE_BACK_BUTTON = BaseState.getFlag(4);
|
||||||
// Flag to indicate if the state would have scrim over sysui region: statu sbar and nav bar
|
// Flag to indicate if the state would have scrim over sysui region: statu sbar and nav bar
|
||||||
public static final int FLAG_HAS_SYS_UI_SCRIM = 1 << 7;
|
public static final int FLAG_HAS_SYS_UI_SCRIM = BaseState.getFlag(5);
|
||||||
// Flag to inticate that all popups should be closed when this state is enabled.
|
// Flag to inticate that all popups should be closed when this state is enabled.
|
||||||
public static final int FLAG_CLOSE_POPUPS = 1 << 8;
|
public static final int FLAG_CLOSE_POPUPS = BaseState.getFlag(6);
|
||||||
public static final int FLAG_OVERVIEW_UI = 1 << 9;
|
public static final int FLAG_OVERVIEW_UI = BaseState.getFlag(7);
|
||||||
|
|
||||||
|
|
||||||
public static final float NO_OFFSET = 0;
|
public static final float NO_OFFSET = 0;
|
||||||
@@ -167,26 +150,15 @@ public abstract class LauncherState {
|
|||||||
/**
|
/**
|
||||||
* Returns if the state has the provided flag
|
* Returns if the state has the provided flag
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public final boolean hasFlag(int mask) {
|
public final boolean hasFlag(int mask) {
|
||||||
return (mFlags & mask) != 0;
|
return (mFlags & mask) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if the state can be persisted across activity restarts.
|
|
||||||
*/
|
|
||||||
public final boolean shouldDisableRestore() {
|
|
||||||
return hasFlag(FLAG_DISABLE_RESTORE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LauncherState[] values() {
|
public static LauncherState[] values() {
|
||||||
return Arrays.copyOf(sAllStates, sAllStates.length);
|
return Arrays.copyOf(sAllStates, sAllStates.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return How long the animation to this state should take (or from this state to NORMAL).
|
|
||||||
*/
|
|
||||||
public abstract int getTransitionDuration(Context context);
|
|
||||||
|
|
||||||
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
|
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
|
||||||
return new ScaleAndTranslation(NO_SCALE, NO_OFFSET, NO_OFFSET);
|
return new ScaleAndTranslation(NO_SCALE, NO_OFFSET, NO_OFFSET);
|
||||||
}
|
}
|
||||||
@@ -280,65 +252,22 @@ public abstract class LauncherState {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public LauncherState getHistoryForState(LauncherState previousState) {
|
public LauncherState getHistoryForState(LauncherState previousState) {
|
||||||
// No history is supported
|
// No history is supported
|
||||||
return NORMAL;
|
return NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onBackPressed(Launcher launcher) {
|
@Override
|
||||||
if (this != NORMAL) {
|
public String toString() {
|
||||||
LauncherStateManager lsm = launcher.getStateManager();
|
return "Ordinal-" + ordinal;
|
||||||
LauncherState lastState = lsm.getLastState();
|
|
||||||
lsm.goToState(lastState);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void onBackPressed(Launcher launcher) {
|
||||||
* Prepares for a non-user controlled animation from fromState to this state. Preparations
|
if (this != NORMAL) {
|
||||||
* include:
|
StateManager<LauncherState> lsm = launcher.getStateManager();
|
||||||
* - Setting interpolators for various animations included in the state transition.
|
LauncherState lastState = lsm.getLastState();
|
||||||
* - Setting some start values (e.g. scale) for views that are hidden but about to be shown.
|
lsm.goToState(lastState);
|
||||||
*/
|
|
||||||
public void prepareForAtomicAnimation(Launcher launcher, LauncherState fromState,
|
|
||||||
StateAnimationConfig config) {
|
|
||||||
if (this == NORMAL && fromState == OVERVIEW) {
|
|
||||||
config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
|
|
||||||
config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
|
|
||||||
config.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCEL, 0, 0.9f));
|
|
||||||
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL);
|
|
||||||
config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7);
|
|
||||||
Workspace workspace = launcher.getWorkspace();
|
|
||||||
|
|
||||||
// Start from a higher workspace scale, but only if we're invisible so we don't jump.
|
|
||||||
boolean isWorkspaceVisible = workspace.getVisibility() == VISIBLE;
|
|
||||||
if (isWorkspaceVisible) {
|
|
||||||
CellLayout currentChild = (CellLayout) workspace.getChildAt(
|
|
||||||
workspace.getCurrentPage());
|
|
||||||
isWorkspaceVisible = currentChild.getVisibility() == VISIBLE
|
|
||||||
&& currentChild.getShortcutsAndWidgets().getAlpha() > 0;
|
|
||||||
}
|
|
||||||
if (!isWorkspaceVisible) {
|
|
||||||
workspace.setScaleX(0.92f);
|
|
||||||
workspace.setScaleY(0.92f);
|
|
||||||
}
|
|
||||||
Hotseat hotseat = launcher.getHotseat();
|
|
||||||
boolean isHotseatVisible = hotseat.getVisibility() == VISIBLE && hotseat.getAlpha() > 0;
|
|
||||||
if (!isHotseatVisible) {
|
|
||||||
hotseat.setScaleX(0.92f);
|
|
||||||
hotseat.setScaleY(0.92f);
|
|
||||||
if (ENABLE_OVERVIEW_ACTIONS.get()) {
|
|
||||||
AllAppsContainerView qsbContainer = launcher.getAppsView();
|
|
||||||
View qsb = qsbContainer.getSearchView();
|
|
||||||
boolean qsbVisible = qsb.getVisibility() == VISIBLE && qsb.getAlpha() > 0;
|
|
||||||
if (!qsbVisible) {
|
|
||||||
qsbContainer.setScaleX(0.92f);
|
|
||||||
qsbContainer.setScaleY(0.92f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (this == NORMAL && fromState == OVERVIEW_PEEK) {
|
|
||||||
// Keep fully visible until the very end (when overview is offscreen) to make invisible.
|
|
||||||
config.setInterpolator(ANIM_OVERVIEW_FADE, t -> t < 1 ? 0 : 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP
|
|||||||
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.DISMISS_PREDICTION;
|
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.DISMISS_PREDICTION;
|
||||||
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.RECONFIGURE;
|
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.RECONFIGURE;
|
||||||
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.UNINSTALL;
|
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.UNINSTALL;
|
||||||
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_DONT_SUGGEST;
|
||||||
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_UNINSTALL;
|
||||||
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_UNINSTALL_CANCELLED;
|
||||||
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_UNINSTALL_COMPLETED;
|
||||||
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_SYSTEM_MASK;
|
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_SYSTEM_MASK;
|
||||||
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_SYSTEM_NO;
|
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_SYSTEM_NO;
|
||||||
|
|
||||||
@@ -34,6 +38,7 @@ import com.android.launcher3.config.FeatureFlags;
|
|||||||
import com.android.launcher3.dragndrop.DragOptions;
|
import com.android.launcher3.dragndrop.DragOptions;
|
||||||
import com.android.launcher3.logging.FileLog;
|
import com.android.launcher3.logging.FileLog;
|
||||||
import com.android.launcher3.logging.LoggerUtils;
|
import com.android.launcher3.logging.LoggerUtils;
|
||||||
|
import com.android.launcher3.logging.StatsLogManager;
|
||||||
import com.android.launcher3.model.AppLaunchTracker;
|
import com.android.launcher3.model.AppLaunchTracker;
|
||||||
import com.android.launcher3.model.data.ItemInfo;
|
import com.android.launcher3.model.data.ItemInfo;
|
||||||
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
||||||
@@ -58,7 +63,7 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
|
|||||||
|
|
||||||
private static final long CACHE_EXPIRE_TIMEOUT = 5000;
|
private static final long CACHE_EXPIRE_TIMEOUT = 5000;
|
||||||
private final ArrayMap<UserHandle, Boolean> mUninstallDisabledCache = new ArrayMap<>(1);
|
private final ArrayMap<UserHandle, Boolean> mUninstallDisabledCache = new ArrayMap<>(1);
|
||||||
|
private final StatsLogManager mStatsLogManager;
|
||||||
private final Alarm mCacheExpireAlarm;
|
private final Alarm mCacheExpireAlarm;
|
||||||
private boolean mHadPendingAlarm;
|
private boolean mHadPendingAlarm;
|
||||||
|
|
||||||
@@ -69,8 +74,8 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
|
|||||||
|
|
||||||
public SecondaryDropTarget(Context context, AttributeSet attrs, int defStyle) {
|
public SecondaryDropTarget(Context context, AttributeSet attrs, int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
|
|
||||||
mCacheExpireAlarm = new Alarm();
|
mCacheExpireAlarm = new Alarm();
|
||||||
|
mStatsLogManager = StatsLogManager.newInstance(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -214,6 +219,11 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
|
|||||||
// Defer onComplete
|
// Defer onComplete
|
||||||
d.dragSource = new DeferredOnComplete(d.dragSource, getContext());
|
d.dragSource = new DeferredOnComplete(d.dragSource, getContext());
|
||||||
super.onDrop(d, options);
|
super.onDrop(d, options);
|
||||||
|
if (mCurrentAccessibilityAction == UNINSTALL) {
|
||||||
|
mStatsLogManager.log(LAUNCHER_ITEM_DROPPED_ON_UNINSTALL, d.logInstanceId);
|
||||||
|
} else if (mCurrentAccessibilityAction == DISMISS_PREDICTION) {
|
||||||
|
mStatsLogManager.log(LAUNCHER_ITEM_DROPPED_ON_DONT_SUGGEST, d.logInstanceId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -338,8 +348,10 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
|
|||||||
mDragObject.dragInfo.user, PackageManager.MATCH_UNINSTALLED_PACKAGES) == null) {
|
mDragObject.dragInfo.user, PackageManager.MATCH_UNINSTALLED_PACKAGES) == null) {
|
||||||
mDragObject.dragSource = mOriginal;
|
mDragObject.dragSource = mOriginal;
|
||||||
mOriginal.onDropCompleted(SecondaryDropTarget.this, mDragObject, true);
|
mOriginal.onDropCompleted(SecondaryDropTarget.this, mDragObject, true);
|
||||||
|
mStatsLogManager.log(LAUNCHER_ITEM_UNINSTALL_COMPLETED, mDragObject.logInstanceId);
|
||||||
} else {
|
} else {
|
||||||
sendFailure();
|
sendFailure();
|
||||||
|
mStatsLogManager.log(LAUNCHER_ITEM_UNINSTALL_CANCELLED, mDragObject.logInstanceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ import com.android.launcher3.model.data.LauncherAppWidgetInfo;
|
|||||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||||
import com.android.launcher3.pageindicators.WorkspacePageIndicator;
|
import com.android.launcher3.pageindicators.WorkspacePageIndicator;
|
||||||
import com.android.launcher3.popup.PopupContainerWithArrow;
|
import com.android.launcher3.popup.PopupContainerWithArrow;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateHandler;
|
||||||
import com.android.launcher3.states.StateAnimationConfig;
|
import com.android.launcher3.states.StateAnimationConfig;
|
||||||
import com.android.launcher3.touch.WorkspaceTouchListener;
|
import com.android.launcher3.touch.WorkspaceTouchListener;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
|
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
|
||||||
@@ -119,7 +120,7 @@ import java.util.function.Predicate;
|
|||||||
*/
|
*/
|
||||||
public class Workspace extends PagedView<WorkspacePageIndicator>
|
public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||||
implements DropTarget, DragSource, View.OnTouchListener,
|
implements DropTarget, DragSource, View.OnTouchListener,
|
||||||
DragController.DragListener, Insettable, LauncherStateManager.StateHandler,
|
DragController.DragListener, Insettable, StateHandler<LauncherState>,
|
||||||
WorkspaceLayoutManager {
|
WorkspaceLayoutManager {
|
||||||
|
|
||||||
/** The value that {@link #mTransitionProgress} must be greater than for
|
/** The value that {@link #mTransitionProgress} must be greater than for
|
||||||
@@ -416,8 +417,12 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
|||||||
mLauncher.getStateManager().goToState(SPRING_LOADED);
|
mLauncher.getStateManager().goToState(SPRING_LOADED);
|
||||||
mStatsLogManager.log(
|
mStatsLogManager.log(
|
||||||
LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED,
|
LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED,
|
||||||
dragObject.mLogInstanceId,
|
dragObject.logInstanceId,
|
||||||
dragObject.originalDragInfo.buildProto(null));
|
dragObject.originalDragInfo.buildProto(
|
||||||
|
dragObject.dragSource instanceof Folder
|
||||||
|
? ((Folder) dragObject.dragSource).mInfo
|
||||||
|
: null)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deferRemoveExtraEmptyScreen() {
|
public void deferRemoveExtraEmptyScreen() {
|
||||||
@@ -1437,6 +1442,10 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
|||||||
|
|
||||||
mOutlineProvider = previewProvider;
|
mOutlineProvider = previewProvider;
|
||||||
|
|
||||||
|
if (draggableView == null && child instanceof DraggableView) {
|
||||||
|
draggableView = (DraggableView) child;
|
||||||
|
}
|
||||||
|
|
||||||
// The drag bitmap follows the touch point around on the screen
|
// The drag bitmap follows the touch point around on the screen
|
||||||
final Bitmap b = previewProvider.createDragBitmap();
|
final Bitmap b = previewProvider.createDragBitmap();
|
||||||
int halfPadding = previewProvider.previewPadding / 2;
|
int halfPadding = previewProvider.previewPadding / 2;
|
||||||
@@ -1447,12 +1456,8 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
|||||||
Point dragVisualizeOffset = null;
|
Point dragVisualizeOffset = null;
|
||||||
Rect dragRect = new Rect();
|
Rect dragRect = new Rect();
|
||||||
|
|
||||||
if (draggableView == null && child instanceof DraggableView) {
|
|
||||||
draggableView = (DraggableView) child;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (draggableView != null) {
|
if (draggableView != null) {
|
||||||
draggableView.getVisualDragBounds(dragRect);
|
draggableView.getSourceVisualDragBounds(dragRect);
|
||||||
dragLayerY += dragRect.top;
|
dragLayerY += dragRect.top;
|
||||||
dragVisualizeOffset = new Point(- halfPadding, halfPadding);
|
dragVisualizeOffset = new Point(- halfPadding, halfPadding);
|
||||||
}
|
}
|
||||||
@@ -1645,7 +1650,10 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
|||||||
Rect folderLocation = new Rect();
|
Rect folderLocation = new Rect();
|
||||||
float scale = mLauncher.getDragLayer().getDescendantRectRelativeToSelf(v, folderLocation);
|
float scale = mLauncher.getDragLayer().getDescendantRectRelativeToSelf(v, folderLocation);
|
||||||
target.removeView(v);
|
target.removeView(v);
|
||||||
|
mStatsLogManager.log(
|
||||||
|
LauncherEvent.LAUNCHER_ITEM_DROP_FOLDER_CREATED,
|
||||||
|
d.logInstanceId,
|
||||||
|
destInfo.buildProto(null));
|
||||||
FolderIcon fi = mLauncher.addFolder(target, container, screenId, targetCell[0],
|
FolderIcon fi = mLauncher.addFolder(target, container, screenId, targetCell[0],
|
||||||
targetCell[1]);
|
targetCell[1]);
|
||||||
destInfo.cellX = -1;
|
destInfo.cellX = -1;
|
||||||
@@ -1683,6 +1691,10 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
|||||||
if (dropOverView instanceof FolderIcon) {
|
if (dropOverView instanceof FolderIcon) {
|
||||||
FolderIcon fi = (FolderIcon) dropOverView;
|
FolderIcon fi = (FolderIcon) dropOverView;
|
||||||
if (fi.acceptDrop(d.dragInfo)) {
|
if (fi.acceptDrop(d.dragInfo)) {
|
||||||
|
mStatsLogManager.log(
|
||||||
|
LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
|
||||||
|
d.logInstanceId,
|
||||||
|
fi.mInfo.buildProto(null));
|
||||||
fi.onDrop(d, false /* itemReturnedOnFailedDrop */);
|
fi.onDrop(d, false /* itemReturnedOnFailedDrop */);
|
||||||
|
|
||||||
// if the drag started here, we need to remove it from the workspace
|
// if the drag started here, we need to remove it from the workspace
|
||||||
@@ -1885,15 +1897,15 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
|||||||
|
|
||||||
mLauncher.getStateManager().goToState(
|
mLauncher.getStateManager().goToState(
|
||||||
NORMAL, SPRING_LOADED_EXIT_DELAY, onCompleteRunnable);
|
NORMAL, SPRING_LOADED_EXIT_DELAY, onCompleteRunnable);
|
||||||
|
mStatsLogManager.log(
|
||||||
|
LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
|
||||||
|
d.logInstanceId,
|
||||||
|
d.dragInfo.buildProto(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d.stateAnnouncer != null && !droppedOnOriginalCell) {
|
if (d.stateAnnouncer != null && !droppedOnOriginalCell) {
|
||||||
d.stateAnnouncer.completeAction(R.string.item_moved);
|
d.stateAnnouncer.completeAction(R.string.item_moved);
|
||||||
}
|
}
|
||||||
mStatsLogManager.log(
|
|
||||||
LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
|
|
||||||
d.mLogInstanceId,
|
|
||||||
d.dragInfo.buildProto(null));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onNoCellFound(View dropTargetLayout) {
|
public void onNoCellFound(View dropTargetLayout) {
|
||||||
@@ -2515,6 +2527,10 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
|||||||
resetTransitionTransform();
|
resetTransitionTransform();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mStatsLogManager.log(
|
||||||
|
LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
|
||||||
|
d.logInstanceId,
|
||||||
|
d.dragInfo.buildProto(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bitmap createWidgetBitmap(ItemInfo widgetInfo, View layout) {
|
public Bitmap createWidgetBitmap(ItemInfo widgetInfo, View layout) {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public class WorkspaceStateTransitionAnimation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see com.android.launcher3.LauncherStateManager.StateHandler#setStateWithAnimation
|
* @see com.android.launcher3.statemanager.StateManager.StateHandler#setStateWithAnimation
|
||||||
*/
|
*/
|
||||||
public void setStateWithAnimation(
|
public void setStateWithAnimation(
|
||||||
LauncherState toState, StateAnimationConfig config, PendingAnimation animation) {
|
LauncherState toState, StateAnimationConfig config, PendingAnimation animation) {
|
||||||
|
|||||||
@@ -28,11 +28,11 @@ import com.android.launcher3.DeviceProfile;
|
|||||||
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
|
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.LauncherStateManager.StateHandler;
|
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||||
import com.android.launcher3.anim.PendingAnimation;
|
import com.android.launcher3.anim.PendingAnimation;
|
||||||
import com.android.launcher3.anim.PropertySetter;
|
import com.android.launcher3.anim.PropertySetter;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateHandler;
|
||||||
import com.android.launcher3.states.StateAnimationConfig;
|
import com.android.launcher3.states.StateAnimationConfig;
|
||||||
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
||||||
import com.android.launcher3.util.Themes;
|
import com.android.launcher3.util.Themes;
|
||||||
@@ -50,8 +50,8 @@ import com.android.systemui.plugins.PluginListener;
|
|||||||
* If release velocity < THRES1, snap according to either top or bottom depending on whether it's
|
* If release velocity < THRES1, snap according to either top or bottom depending on whether it's
|
||||||
* closer to top or closer to the page indicator.
|
* closer to top or closer to the page indicator.
|
||||||
*/
|
*/
|
||||||
public class AllAppsTransitionController implements StateHandler, OnDeviceProfileChangeListener,
|
public class AllAppsTransitionController implements StateHandler<LauncherState>,
|
||||||
PluginListener<AllAppsSearchPlugin> {
|
OnDeviceProfileChangeListener, PluginListener<AllAppsSearchPlugin> {
|
||||||
|
|
||||||
public static final FloatProperty<AllAppsTransitionController> ALL_APPS_PROGRESS =
|
public static final FloatProperty<AllAppsTransitionController> ALL_APPS_PROGRESS =
|
||||||
new FloatProperty<AllAppsTransitionController>("allAppsProgress") {
|
new FloatProperty<AllAppsTransitionController>("allAppsProgress") {
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ import android.view.MotionEvent;
|
|||||||
import com.android.launcher3.AbstractFloatingView;
|
import com.android.launcher3.AbstractFloatingView;
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.LauncherStateManager.StateListener;
|
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||||
import com.android.launcher3.util.OnboardingPrefs;
|
import com.android.launcher3.util.OnboardingPrefs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,7 +46,7 @@ public class DiscoveryBounce extends AbstractFloatingView {
|
|||||||
private final Launcher mLauncher;
|
private final Launcher mLauncher;
|
||||||
private final Animator mDiscoBounceAnimation;
|
private final Animator mDiscoBounceAnimation;
|
||||||
|
|
||||||
private final StateListener mStateListener = new StateListener() {
|
private final StateListener<LauncherState> mStateListener = new StateListener<LauncherState>() {
|
||||||
@Override
|
@Override
|
||||||
public void onStateTransitionStart(LauncherState toState) {
|
public void onStateTransitionStart(LauncherState toState) {
|
||||||
handleClose(false);
|
handleClose(false);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import android.view.MotionEvent;
|
|||||||
|
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.LauncherStateManager;
|
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||||
import com.android.launcher3.views.WorkEduView;
|
import com.android.launcher3.views.WorkEduView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,7 +32,7 @@ public class LauncherAllAppsContainerView extends AllAppsContainerView {
|
|||||||
|
|
||||||
private final Launcher mLauncher;
|
private final Launcher mLauncher;
|
||||||
|
|
||||||
private LauncherStateManager.StateListener mWorkTabListener;
|
private StateListener<LauncherState> mWorkTabListener;
|
||||||
|
|
||||||
public LauncherAllAppsContainerView(Context context) {
|
public LauncherAllAppsContainerView(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
|
|||||||
@@ -105,6 +105,13 @@ public class PendingAnimation implements PropertySetter {
|
|||||||
add(anim);
|
add(anim);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T> void addFloat(T target, FloatProperty<T> property, float from, float to,
|
||||||
|
TimeInterpolator interpolator) {
|
||||||
|
Animator anim = ObjectAnimator.ofFloat(target, property, from, to);
|
||||||
|
anim.setDuration(mDuration).setInterpolator(interpolator);
|
||||||
|
add(anim);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> void setInt(T target, IntProperty<T> property, int value,
|
public <T> void setInt(T target, IntProperty<T> property, int value,
|
||||||
TimeInterpolator interpolator) {
|
TimeInterpolator interpolator) {
|
||||||
|
|||||||
@@ -186,8 +186,7 @@ public class DragController implements DragDriver.EventListener, TouchController
|
|||||||
|
|
||||||
mDragObject.dragSource = source;
|
mDragObject.dragSource = source;
|
||||||
mDragObject.dragInfo = dragInfo;
|
mDragObject.dragInfo = dragInfo;
|
||||||
mDragObject.originalDragInfo = new ItemInfo();
|
mDragObject.originalDragInfo = mDragObject.dragInfo.makeShallowCopy();
|
||||||
mDragObject.originalDragInfo.copyFrom(dragInfo);
|
|
||||||
|
|
||||||
if (dragOffset != null) {
|
if (dragOffset != null) {
|
||||||
dragView.setDragVisualizeOffset(new Point(dragOffset));
|
dragView.setDragVisualizeOffset(new Point(dragOffset));
|
||||||
|
|||||||
@@ -274,19 +274,29 @@ public class DragLayer extends BaseDragLayer<Launcher> {
|
|||||||
scale *= childScale;
|
scale *= childScale;
|
||||||
int toX = Math.round(coord[0]);
|
int toX = Math.round(coord[0]);
|
||||||
int toY = Math.round(coord[1]);
|
int toY = Math.round(coord[1]);
|
||||||
|
|
||||||
float toScale = scale;
|
float toScale = scale;
|
||||||
|
|
||||||
if (child instanceof DraggableView) {
|
if (child instanceof DraggableView) {
|
||||||
|
// This code is fairly subtle. Please verify drag and drop is pixel-perfect in a number
|
||||||
|
// of scenarios before modifying (from all apps, from workspace, different grid-sizes,
|
||||||
|
// shortcuts from in and out of Launcher etc).
|
||||||
DraggableView d = (DraggableView) child;
|
DraggableView d = (DraggableView) child;
|
||||||
d.getVisualDragBounds(dragViewBounds);
|
Rect destRect = new Rect();
|
||||||
|
d.getWorkspaceVisualDragBounds(destRect);
|
||||||
|
|
||||||
|
// In most cases this additional scale factor should be a no-op (1). It mainly accounts
|
||||||
|
// for alternate grids where the source and destination icon sizes are different
|
||||||
|
toScale *= ((1f * destRect.width())
|
||||||
|
/ (dragView.getMeasuredWidth() - dragView.getBlurSizeOutline()));
|
||||||
|
|
||||||
// This accounts for the offset of the DragView created by scaling it about its
|
// This accounts for the offset of the DragView created by scaling it about its
|
||||||
// center as it animates into place.
|
// center as it animates into place.
|
||||||
float scaleShiftX = dragView.getMeasuredWidth() * (1 - scale) / 2;
|
float scaleShiftX = dragView.getMeasuredWidth() * (1 - toScale) / 2;
|
||||||
float scaleShiftY = dragView.getMeasuredHeight() * (1 - scale) / 2;
|
float scaleShiftY = dragView.getMeasuredHeight() * (1 - toScale) / 2;
|
||||||
|
|
||||||
toX += scale * (dragViewBounds.left - dragView.getBlurSizeOutline() / 2) - scaleShiftX;
|
toX += scale * destRect.left - toScale * dragView.getBlurSizeOutline() / 2 - scaleShiftX;
|
||||||
toY += scale * (dragViewBounds.top - dragView.getBlurSizeOutline() / 2) - scaleShiftY;
|
toY += scale * destRect.top - toScale * dragView.getBlurSizeOutline() / 2 - scaleShiftY;
|
||||||
}
|
}
|
||||||
|
|
||||||
child.setVisibility(INVISIBLE);
|
child.setVisibility(INVISIBLE);
|
||||||
|
|||||||
@@ -49,18 +49,18 @@ import com.android.launcher3.FirstFrameAnimatorHelper;
|
|||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.LauncherSettings;
|
import com.android.launcher3.LauncherSettings;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.LauncherStateManager;
|
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.anim.Interpolators;
|
import com.android.launcher3.anim.Interpolators;
|
||||||
import com.android.launcher3.icons.LauncherIcons;
|
import com.android.launcher3.icons.LauncherIcons;
|
||||||
import com.android.launcher3.model.data.ItemInfo;
|
import com.android.launcher3.model.data.ItemInfo;
|
||||||
|
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||||
import com.android.launcher3.util.Themes;
|
import com.android.launcher3.util.Themes;
|
||||||
import com.android.launcher3.util.Thunk;
|
import com.android.launcher3.util.Thunk;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class DragView extends View implements LauncherStateManager.StateListener {
|
public class DragView extends View implements StateListener<LauncherState> {
|
||||||
private static final ColorMatrix sTempMatrix1 = new ColorMatrix();
|
private static final ColorMatrix sTempMatrix1 = new ColorMatrix();
|
||||||
private static final ColorMatrix sTempMatrix2 = new ColorMatrix();
|
private static final ColorMatrix sTempMatrix2 = new ColorMatrix();
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ package com.android.launcher3.dragndrop;
|
|||||||
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.android.launcher3.util.SafeCloseable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface defining methods required for drawing and previewing DragViews, drag previews, and
|
* Interface defining methods required for drawing and previewing DragViews, drag previews, and
|
||||||
* related animations
|
* related animations
|
||||||
@@ -42,9 +46,12 @@ public interface DraggableView {
|
|||||||
int getViewType();
|
int getViewType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Before rendering as a DragView bitmap, some views need a preparation step.
|
* Before rendering as a DragView bitmap, some views need a preparation step. Returns a
|
||||||
|
* callback to clear any preparation work
|
||||||
*/
|
*/
|
||||||
default void prepareDrawDragView() { }
|
@NonNull default SafeCloseable prepareDrawDragView() {
|
||||||
|
return () -> { };
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If an actual View subclass, this method returns the rectangle (within the View's coordinates)
|
* If an actual View subclass, this method returns the rectangle (within the View's coordinates)
|
||||||
@@ -53,5 +60,14 @@ public interface DraggableView {
|
|||||||
*
|
*
|
||||||
* @param bounds Visual bounds in the views coordinates will be written here.
|
* @param bounds Visual bounds in the views coordinates will be written here.
|
||||||
*/
|
*/
|
||||||
default void getVisualDragBounds(Rect bounds) { }
|
default void getWorkspaceVisualDragBounds(Rect bounds) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as above, but accounts for differing icon sizes between source and destination
|
||||||
|
*
|
||||||
|
* @param bounds Visual bounds in the views coordinates will be written here.
|
||||||
|
*/
|
||||||
|
default void getSourceVisualDragBounds(Rect bounds) {
|
||||||
|
getWorkspaceVisualDragBounds(bounds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ import com.android.launcher3.dragndrop.DragController;
|
|||||||
import com.android.launcher3.dragndrop.DragController.DragListener;
|
import com.android.launcher3.dragndrop.DragController.DragListener;
|
||||||
import com.android.launcher3.dragndrop.DragLayer;
|
import com.android.launcher3.dragndrop.DragLayer;
|
||||||
import com.android.launcher3.dragndrop.DragOptions;
|
import com.android.launcher3.dragndrop.DragOptions;
|
||||||
|
import com.android.launcher3.logging.StatsLogManager;
|
||||||
import com.android.launcher3.model.data.AppInfo;
|
import com.android.launcher3.model.data.AppInfo;
|
||||||
import com.android.launcher3.model.data.FolderInfo;
|
import com.android.launcher3.model.data.FolderInfo;
|
||||||
import com.android.launcher3.model.data.FolderInfo.FolderListener;
|
import com.android.launcher3.model.data.FolderInfo.FolderListener;
|
||||||
@@ -1346,6 +1347,10 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
|||||||
if (d.stateAnnouncer != null) {
|
if (d.stateAnnouncer != null) {
|
||||||
d.stateAnnouncer.completeAction(R.string.item_moved);
|
d.stateAnnouncer.completeAction(R.string.item_moved);
|
||||||
}
|
}
|
||||||
|
StatsLogManager.newInstance(getContext())
|
||||||
|
.log(StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
|
||||||
|
d.logInstanceId,
|
||||||
|
d.dragInfo.buildProto(mInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is used so the item doesn't immediately appear in the folder when added. In one case
|
// This is used so the item doesn't immediately appear in the folder when added. In one case
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import com.android.launcher3.R;
|
|||||||
import com.android.launcher3.Reorderable;
|
import com.android.launcher3.Reorderable;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.Workspace;
|
import com.android.launcher3.Workspace;
|
||||||
|
import com.android.launcher3.allapps.AllAppsContainerView;
|
||||||
import com.android.launcher3.anim.Interpolators;
|
import com.android.launcher3.anim.Interpolators;
|
||||||
import com.android.launcher3.config.FeatureFlags;
|
import com.android.launcher3.config.FeatureFlags;
|
||||||
import com.android.launcher3.dot.FolderDotInfo;
|
import com.android.launcher3.dot.FolderDotInfo;
|
||||||
@@ -85,7 +86,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
|
|||||||
|
|
||||||
@Thunk ActivityContext mActivity;
|
@Thunk ActivityContext mActivity;
|
||||||
@Thunk Folder mFolder;
|
@Thunk Folder mFolder;
|
||||||
private FolderInfo mInfo;
|
public FolderInfo mInfo;
|
||||||
|
|
||||||
private CheckLongPressHelper mLongPressHelper;
|
private CheckLongPressHelper mLongPressHelper;
|
||||||
|
|
||||||
@@ -385,6 +386,14 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
|
|||||||
float finalAlpha = index < MAX_NUM_ITEMS_IN_PREVIEW ? 0.5f : 0f;
|
float finalAlpha = index < MAX_NUM_ITEMS_IN_PREVIEW ? 0.5f : 0f;
|
||||||
|
|
||||||
float finalScale = scale * scaleRelativeToDragLayer;
|
float finalScale = scale * scaleRelativeToDragLayer;
|
||||||
|
|
||||||
|
// Account for potentially different icon sizes with non-default grid settings
|
||||||
|
if (d.dragSource instanceof AllAppsContainerView) {
|
||||||
|
DeviceProfile grid = mActivity.getDeviceProfile();
|
||||||
|
float containerScale = (1f * grid.iconSizePx / grid.allAppsIconSizePx);
|
||||||
|
finalScale *= containerScale;
|
||||||
|
}
|
||||||
|
|
||||||
dragLayer.animateView(animateView, from, to, finalAlpha,
|
dragLayer.animateView(animateView, from, to, finalAlpha,
|
||||||
1, 1, finalScale, finalScale, DROP_IN_ANIMATION_DURATION,
|
1, 1, finalScale, finalScale, DROP_IN_ANIMATION_DURATION,
|
||||||
Interpolators.DEACCEL_2, Interpolators.ACCEL_2,
|
Interpolators.DEACCEL_2, Interpolators.ACCEL_2,
|
||||||
@@ -758,7 +767,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getVisualDragBounds(Rect bounds) {
|
public void getWorkspaceVisualDragBounds(Rect bounds) {
|
||||||
getPreviewBounds(bounds);
|
getPreviewBounds(bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user