Merging ub-launcher3-qt-dev, build 5642962
Test: Manual Bug:122345781 P1 Inflation happens and a binder call during swipe up gesture, that may cause jank Bug:123900446 P1 App to home animation should zoom into the app icon Bug:132209249 P1 Gesture bar interferes with Messenger chat heads. Bug:132815672 P1 -1 to home swipe up gesture Bug:132886768 P1 Swipe home animation sometimes drops frames Bug:133009122 P2 Rare flake: dragged launchable to workspace, but the current state is not WORKSPACE; Can't find a launcher object; selector: BySelector [RES='\Qcom.google.android.apps.nexuslauncher:id/apps_view\E'] Bug:133226418 P1 [Gesture Nav] App launch animation has has incorrect origin when launched in Overview Bug:133508173 P1 App switching is very janky on QT Bug:133871965 P1 (V35 20190528.00_RC00):Unable to unlock/minimize phone app during ongoing call Bug:134095068 P1 Shouldn't use seamless rotation in another case Bug:134166337 P1 3P Launcher Breaks Overview (Standalone) Bug:134172603 P1 Tracing for lab-only flakes Bug:134517106 P1 Swipe up to home should fade out scrim Bug:134532571 P1 Launcher flake: java.lang.AssertionError: http://go/tapl : want to switch from background to overview, but the current state is not BASE_OVERVIEW; Can't find a launcher object; selector: BySelector [RES='\Qcom.google.android.apps.nexuslauncher:id/overview_panel\E'] Bug:134674880 P1 App group name in expanded view is invisible with white wallpaper Change-Id: I9bca7db0f03bd4c0581ce946646bf5209e8f6c79
This commit is contained in:
+5
-1
@@ -121,12 +121,16 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti
|
||||
alpha.setDuration(CONTENT_ALPHA_DURATION);
|
||||
alpha.setInterpolator(LINEAR);
|
||||
anim.play(alpha);
|
||||
overview.setFreezeViewVisibility(true);
|
||||
|
||||
ObjectAnimator transY = ObjectAnimator.ofFloat(overview, View.TRANSLATION_Y, trans);
|
||||
transY.setInterpolator(AGGRESSIVE_EASE);
|
||||
transY.setDuration(CONTENT_TRANSLATION_DURATION);
|
||||
anim.play(transY);
|
||||
|
||||
return mLauncher.getStateManager()::reapplyState;
|
||||
return () -> {
|
||||
overview.setFreezeViewVisibility(false);
|
||||
mLauncher.getStateManager().reapplyState();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
-9
@@ -204,15 +204,6 @@ public abstract class RecentsUiFactory {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean-up logic that occurs when recents is no longer in use/visible.
|
||||
*
|
||||
* @param launcher the launcher activity
|
||||
*/
|
||||
public static void resetOverview(Launcher launcher) {
|
||||
launcher.<RecentsView>getOverviewPanel().reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recents logic that triggers when launcher state changes or launcher activity stops/resumes.
|
||||
*
|
||||
|
||||
-18
@@ -32,7 +32,6 @@ import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.LauncherStateManager.AnimationConfig;
|
||||
import com.android.launcher3.anim.AnimatorSetBuilder;
|
||||
import com.android.launcher3.anim.PropertySetter;
|
||||
import com.android.quickstep.hints.ProactiveHintsContainer;
|
||||
import com.android.quickstep.views.ClearAllButton;
|
||||
import com.android.quickstep.views.LauncherRecentsView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
@@ -55,14 +54,6 @@ public final class RecentsViewStateController extends
|
||||
if (state.overviewUi) {
|
||||
mRecentsView.updateEmptyMessage();
|
||||
mRecentsView.resetTaskVisuals();
|
||||
mRecentsView.setHintVisibility(1f);
|
||||
} else {
|
||||
mRecentsView.setHintVisibility(0f);
|
||||
ProactiveHintsContainer
|
||||
proactiveHintsContainer = mRecentsView.getProactiveHintsContainer();
|
||||
if (proactiveHintsContainer != null) {
|
||||
proactiveHintsContainer.removeAllViews();
|
||||
}
|
||||
}
|
||||
setAlphas(PropertySetter.NO_ANIM_PROPERTY_SETTER, state.getVisibleElements(mLauncher));
|
||||
mRecentsView.setFullscreenProgress(state.getOverviewFullscreenProgress());
|
||||
@@ -75,14 +66,6 @@ public final class RecentsViewStateController extends
|
||||
|
||||
if (!toState.overviewUi) {
|
||||
builder.addOnFinishRunnable(mRecentsView::resetTaskVisuals);
|
||||
mRecentsView.setHintVisibility(0f);
|
||||
builder.addOnFinishRunnable(() -> {
|
||||
ProactiveHintsContainer
|
||||
proactiveHintsContainer = mRecentsView.getProactiveHintsContainer();
|
||||
if (proactiveHintsContainer != null) {
|
||||
proactiveHintsContainer.removeAllViews();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (toState.overviewUi) {
|
||||
@@ -94,7 +77,6 @@ public final class RecentsViewStateController extends
|
||||
updateAnim.setDuration(config.duration);
|
||||
builder.play(updateAnim);
|
||||
mRecentsView.updateEmptyMessage();
|
||||
builder.addOnFinishRunnable(() -> mRecentsView.setHintVisibility(1f));
|
||||
}
|
||||
|
||||
PropertySetter propertySetter = config.getPropertySetter(builder);
|
||||
|
||||
-3
@@ -21,7 +21,6 @@ import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.quickstep.util.ClipAnimationHelper;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
@@ -45,8 +44,6 @@ public class BackgroundAppState extends OverviewState {
|
||||
|
||||
@Override
|
||||
public void onStateEnabled(Launcher launcher) {
|
||||
RecentsView rv = launcher.getOverviewPanel();
|
||||
rv.setOverviewStateEnabled(true);
|
||||
AbstractFloatingView.closeAllOpenViews(launcher, false);
|
||||
}
|
||||
|
||||
|
||||
-8
@@ -86,17 +86,9 @@ public class OverviewState extends LauncherState {
|
||||
|
||||
@Override
|
||||
public void onStateEnabled(Launcher launcher) {
|
||||
RecentsView rv = launcher.getOverviewPanel();
|
||||
rv.setOverviewStateEnabled(true);
|
||||
AbstractFloatingView.closeAllOpenViews(launcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateDisabled(Launcher launcher) {
|
||||
RecentsView rv = launcher.getOverviewPanel();
|
||||
rv.setOverviewStateEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateTransitionEnd(Launcher launcher) {
|
||||
launcher.getRotationHelper().setCurrentStateRequest(REQUEST_ROTATE);
|
||||
|
||||
-3
@@ -98,9 +98,6 @@ public class NavBarToHomeTouchController implements TouchController, SwipeDetect
|
||||
if (mStartState == OVERVIEW || mStartState == ALL_APPS) {
|
||||
return true;
|
||||
}
|
||||
if (!mLauncher.hasWindowFocus()) {
|
||||
return true;
|
||||
}
|
||||
if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+24
-6
@@ -17,6 +17,7 @@ package com.android.quickstep;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
||||
import static com.android.quickstep.fallback.FallbackRecentsView.ZOOM_PROGRESS;
|
||||
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
|
||||
|
||||
import android.animation.Animator;
|
||||
@@ -33,6 +34,7 @@ import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.quickstep.fallback.FallbackRecentsView;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.util.RemoteAnimationTargetSet;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
@@ -120,11 +122,14 @@ public final class FallbackActivityControllerHelper implements
|
||||
return (transitionLength) -> { };
|
||||
}
|
||||
|
||||
RecentsView rv = activity.getOverviewPanel();
|
||||
FallbackRecentsView rv = activity.getOverviewPanel();
|
||||
rv.setContentAlpha(0);
|
||||
rv.getClearAllButton().setVisibilityAlpha(0);
|
||||
rv.setDisallowScrollToClearAll(true);
|
||||
|
||||
boolean fromState = !animateActivity;
|
||||
rv.setInOverviewState(fromState);
|
||||
|
||||
return new AnimationFactory() {
|
||||
|
||||
boolean isAnimatingToRecents = false;
|
||||
@@ -141,15 +146,28 @@ public final class FallbackActivityControllerHelper implements
|
||||
|
||||
@Override
|
||||
public void createActivityController(long transitionLength) {
|
||||
if (!isAnimatingToRecents) {
|
||||
return;
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
if (isAnimatingToRecents) {
|
||||
ObjectAnimator anim = ObjectAnimator.ofFloat(rv, CONTENT_ALPHA, 0, 1);
|
||||
anim.setDuration(transitionLength).setInterpolator(LINEAR);
|
||||
animatorSet.play(anim);
|
||||
}
|
||||
|
||||
ObjectAnimator anim = ObjectAnimator.ofFloat(rv, CONTENT_ALPHA, 0, 1);
|
||||
ObjectAnimator anim = ObjectAnimator.ofFloat(rv, ZOOM_PROGRESS, 1, 0);
|
||||
anim.setDuration(transitionLength).setInterpolator(LINEAR);
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
animatorSet.play(anim);
|
||||
callback.accept(AnimatorPlaybackController.wrap(animatorSet, transitionLength));
|
||||
|
||||
AnimatorPlaybackController controller =
|
||||
AnimatorPlaybackController.wrap(animatorSet, transitionLength);
|
||||
|
||||
// Since we are changing the start position of the UI, reapply the state, at the end
|
||||
controller.setEndAction(() -> {
|
||||
boolean endState = true;
|
||||
rv.setInOverviewState(controller.getInterpolatedProgress() > 0.5 ?
|
||||
endState : fromState);
|
||||
});
|
||||
|
||||
callback.accept(controller);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
+5
@@ -36,6 +36,7 @@ import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Region;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
@@ -53,6 +54,7 @@ import com.android.launcher3.allapps.DiscoveryBounce;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.SpringObjectAnimator;
|
||||
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.launcher3.views.FloatingIconView;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
@@ -174,6 +176,9 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
||||
@Override
|
||||
public AnimationFactory prepareRecentsUI(Launcher activity, boolean activityVisible,
|
||||
boolean animateActivity, Consumer<AnimatorPlaybackController> callback) {
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "prepareRecentsUI");
|
||||
}
|
||||
final LauncherState startState = activity.getStateManager().getState();
|
||||
|
||||
LauncherState resetState = startState;
|
||||
|
||||
@@ -125,7 +125,14 @@ public final class RecentsActivity extends BaseRecentsActivity {
|
||||
@Override
|
||||
public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats,
|
||||
AnimationResult result) {
|
||||
result.setAnimation(composeRecentsLaunchAnimator(taskView, targetCompats));
|
||||
AnimatorSet anim = composeRecentsLaunchAnimator(taskView, targetCompats);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mFallbackRecentsView.resetViewUI();
|
||||
}
|
||||
});
|
||||
result.setAnimation(anim);
|
||||
}
|
||||
};
|
||||
return ActivityOptionsCompat.makeRemoteAnimation(new RemoteAnimationAdapterCompat(
|
||||
|
||||
@@ -36,8 +36,6 @@ import java.util.List;
|
||||
*/
|
||||
public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
|
||||
public static final String AIAI_PACKAGE = "com.google.android.as";
|
||||
|
||||
/** Note that these will be shown in order from top to bottom, if available for the task. */
|
||||
private static final TaskSystemShortcut[] MENU_OPTIONS = new TaskSystemShortcut[]{
|
||||
new TaskSystemShortcut.AppInfo(),
|
||||
@@ -51,29 +49,33 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
new MainThreadInitializedObject<>(c -> Overrides.getObject(TaskOverlayFactory.class,
|
||||
c, R.string.task_overlay_factory_class));
|
||||
|
||||
public List<TaskSystemShortcut> getEnabledShortcuts(TaskView taskView) {
|
||||
final ArrayList<TaskSystemShortcut> shortcuts = new ArrayList<>();
|
||||
final BaseDraggingActivity activity = BaseActivity.fromContext(taskView.getContext());
|
||||
for (TaskSystemShortcut menuOption : MENU_OPTIONS) {
|
||||
View.OnClickListener onClickListener =
|
||||
menuOption.getOnClickListener(activity, taskView);
|
||||
if (onClickListener != null) {
|
||||
shortcuts.add(menuOption);
|
||||
}
|
||||
}
|
||||
return shortcuts;
|
||||
}
|
||||
|
||||
public TaskOverlay createOverlay(View thumbnailView) {
|
||||
return new TaskOverlay();
|
||||
}
|
||||
|
||||
public static class TaskOverlay {
|
||||
|
||||
public void setTaskInfo(Task task, ThumbnailData thumbnail, Matrix matrix) {
|
||||
}
|
||||
/**
|
||||
* Called when the current task is interactive for the user
|
||||
*/
|
||||
public void initOverlay(Task task, ThumbnailData thumbnail, Matrix matrix) { }
|
||||
|
||||
public void reset() {
|
||||
}
|
||||
|
||||
public List<TaskSystemShortcut> getEnabledShortcuts(TaskView taskView) {
|
||||
final ArrayList<TaskSystemShortcut> shortcuts = new ArrayList<>();
|
||||
final BaseDraggingActivity activity = BaseActivity.fromContext(taskView.getContext());
|
||||
for (TaskSystemShortcut menuOption : MENU_OPTIONS) {
|
||||
View.OnClickListener onClickListener =
|
||||
menuOption.getOnClickListener(activity, taskView);
|
||||
if (onClickListener != null) {
|
||||
shortcuts.add(menuOption);
|
||||
}
|
||||
}
|
||||
return shortcuts;
|
||||
}
|
||||
/**
|
||||
* Called when the overlay is no longer used.
|
||||
*/
|
||||
public void reset() { }
|
||||
}
|
||||
}
|
||||
|
||||
+37
-11
@@ -27,6 +27,8 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_N
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager;
|
||||
@@ -60,6 +62,7 @@ import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.BinderThread;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.MainThreadExecutor;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.ResourceUtils;
|
||||
@@ -77,6 +80,7 @@ import com.android.quickstep.inputconsumers.DeviceLockedInputConsumer;
|
||||
import com.android.quickstep.inputconsumers.InputConsumer;
|
||||
import com.android.quickstep.inputconsumers.OtherActivityInputConsumer;
|
||||
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
|
||||
import com.android.quickstep.inputconsumers.OverviewWithoutFocusInputConsumer;
|
||||
import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer;
|
||||
import com.android.systemui.shared.recents.IOverviewProxy;
|
||||
import com.android.systemui.shared.recents.ISystemUiProxy;
|
||||
@@ -543,9 +547,11 @@ public class TouchInteractionService extends Service implements
|
||||
if (!useSharedState) {
|
||||
mSwipeSharedState.clearAllState();
|
||||
}
|
||||
if (mKM.isDeviceLocked()) {
|
||||
if ((mSystemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0
|
||||
|| mKM.isDeviceLocked()) {
|
||||
// This handles apps launched in direct boot mode (e.g. dialer) as well as apps launched
|
||||
// while device is locked even after exiting direct boot mode (e.g. camera).
|
||||
// while device is locked after exiting direct boot mode (e.g. camera), or if the
|
||||
// app is showing over the lockscreen (even if not locked)
|
||||
return createDeviceLockedInputConsumer(runningTaskInfo);
|
||||
}
|
||||
|
||||
@@ -562,10 +568,9 @@ public class TouchInteractionService extends Service implements
|
||||
info.id = mSwipeSharedState.nextRunningTaskId;
|
||||
return createOtherActivityInputConsumer(event, info);
|
||||
} else if (mSwipeSharedState.goingToLauncher || activityControl.isResumed()) {
|
||||
return OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
|
||||
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
|
||||
activityControl.isInLiveTileMode()) {
|
||||
return OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
|
||||
return createOverviewInputConsumer(event);
|
||||
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityControl.isInLiveTileMode()) {
|
||||
return createOverviewInputConsumer(event);
|
||||
} else if (mGestureBlockingActivity != null && runningTaskInfo != null
|
||||
&& mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) {
|
||||
return InputConsumer.NO_OP;
|
||||
@@ -574,20 +579,24 @@ public class TouchInteractionService extends Service implements
|
||||
}
|
||||
}
|
||||
|
||||
private boolean disableHorizontalSwipe(MotionEvent event) {
|
||||
// mExclusionRegion can change on binder thread, use a local instance here.
|
||||
Region exclusionRegion = mExclusionRegion;
|
||||
return mMode == Mode.NO_BUTTON && exclusionRegion != null
|
||||
&& exclusionRegion.contains((int) event.getX(), (int) event.getY());
|
||||
}
|
||||
|
||||
private OtherActivityInputConsumer createOtherActivityInputConsumer(MotionEvent event,
|
||||
RunningTaskInfo runningTaskInfo) {
|
||||
final ActivityControlHelper activityControl =
|
||||
mOverviewComponentObserver.getActivityControlHelper();
|
||||
boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event);
|
||||
|
||||
// mExclusionRegion can change on binder thread, use a local instance here.
|
||||
Region exclusionRegion = mExclusionRegion;
|
||||
boolean disableHorizontalSwipe = mMode == Mode.NO_BUTTON && exclusionRegion != null
|
||||
&& exclusionRegion.contains((int) event.getX(), (int) event.getY());
|
||||
return new OtherActivityInputConsumer(this, runningTaskInfo, mRecentsModel,
|
||||
mOverviewComponentObserver.getOverviewIntent(), activityControl,
|
||||
shouldDefer, mOverviewCallbacks, mInputConsumer, this::onConsumerInactive,
|
||||
mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion, disableHorizontalSwipe);
|
||||
mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion,
|
||||
disableHorizontalSwipe(event));
|
||||
}
|
||||
|
||||
private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) {
|
||||
@@ -599,6 +608,23 @@ public class TouchInteractionService extends Service implements
|
||||
}
|
||||
}
|
||||
|
||||
public InputConsumer createOverviewInputConsumer(MotionEvent event) {
|
||||
final ActivityControlHelper activityControl =
|
||||
mOverviewComponentObserver.getActivityControlHelper();
|
||||
BaseDraggingActivity activity = activityControl.getCreatedActivity();
|
||||
if (activity == null) {
|
||||
return InputConsumer.NO_OP;
|
||||
}
|
||||
|
||||
if (activity.getRootView().hasWindowFocus()) {
|
||||
return new OverviewInputConsumer(activity, mInputMonitorCompat,
|
||||
false /* startingInActivityBounds */);
|
||||
} else {
|
||||
return new OverviewWithoutFocusInputConsumer(this, mInputMonitorCompat,
|
||||
disableHorizontalSwipe(event));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called by the consumer when it's no longer active.
|
||||
*/
|
||||
|
||||
+29
-3
@@ -59,6 +59,7 @@ import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@@ -83,6 +84,7 @@ import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.graphics.RotationMode;
|
||||
import com.android.launcher3.logging.UserEventDispatcher;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
||||
@@ -267,6 +269,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
private MultiStateCallback mStateCallback;
|
||||
// Used to control launcher components throughout the swipe gesture.
|
||||
private AnimatorPlaybackController mLauncherTransitionController;
|
||||
private boolean mHasLauncherTransitionControllerStarted;
|
||||
|
||||
private T mActivity;
|
||||
private RecentsView mRecentsView;
|
||||
@@ -457,17 +460,32 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
}
|
||||
|
||||
private void onLauncherStart(final T activity) {
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart");
|
||||
}
|
||||
if (mActivity != activity) {
|
||||
return;
|
||||
}
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 1");
|
||||
}
|
||||
if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
|
||||
return;
|
||||
}
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 2");
|
||||
}
|
||||
|
||||
// If we've already ended the gesture and are going home, don't prepare recents UI,
|
||||
// as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL.
|
||||
if (mGestureEndTarget != HOME) {
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 3");
|
||||
}
|
||||
Runnable initAnimFactory = () -> {
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 4");
|
||||
}
|
||||
mAnimationFactory = mActivityControlHelper.prepareRecentsUI(mActivity,
|
||||
mWasLauncherAlreadyVisible, true,
|
||||
this::onAnimatorPlaybackControllerCreated);
|
||||
@@ -477,8 +495,14 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
// Launcher is visible, but might be about to stop. Thus, if we prepare recents
|
||||
// now, it might get overridden by moveToRestState() in onStop(). To avoid this,
|
||||
// wait until the next gesture (and possibly launcher) starts.
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 5");
|
||||
}
|
||||
mStateCallback.addCallback(STATE_GESTURE_STARTED, initAnimFactory);
|
||||
} else {
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 6");
|
||||
}
|
||||
initAnimFactory.run();
|
||||
}
|
||||
}
|
||||
@@ -647,8 +671,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
}
|
||||
|
||||
private void buildAnimationController() {
|
||||
if (mGestureEndTarget == HOME || (mLauncherTransitionController != null
|
||||
&& mLauncherTransitionController.getAnimationPlayer().isStarted())) {
|
||||
if (mGestureEndTarget == HOME || mHasLauncherTransitionControllerStarted) {
|
||||
// We don't want a new mLauncherTransitionController if mGestureEndTarget == HOME (it
|
||||
// has its own animation) or if we're already animating the current controller.
|
||||
return;
|
||||
@@ -858,7 +881,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha);
|
||||
}
|
||||
|
||||
return OverviewInputConsumer.newInstance(mActivityControlHelper, null, true);
|
||||
BaseDraggingActivity activity = mActivityControlHelper.getCreatedActivity();
|
||||
return activity == null
|
||||
? InputConsumer.NO_OP : new OverviewInputConsumer(activity, null, true);
|
||||
}
|
||||
|
||||
private void endRunningWindowAnim() {
|
||||
@@ -1122,6 +1147,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
}
|
||||
mLauncherTransitionController.getAnimationPlayer().start();
|
||||
}
|
||||
mHasLauncherTransitionControllerStarted = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+69
@@ -15,19 +15,45 @@
|
||||
*/
|
||||
package com.android.quickstep.fallback;
|
||||
|
||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.FloatProperty;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.LauncherState.ScaleAndTranslation;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.quickstep.RecentsActivity;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
|
||||
public class FallbackRecentsView extends RecentsView<RecentsActivity> {
|
||||
|
||||
public static final FloatProperty<FallbackRecentsView> ZOOM_PROGRESS =
|
||||
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 float mZoomTranslationY = 0f;
|
||||
|
||||
public FallbackRecentsView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
@@ -35,6 +61,7 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
|
||||
public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setOverviewStateEnabled(true);
|
||||
setOverlayEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,4 +97,46 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
|
||||
// Just use the activity task size for multi-window as well.
|
||||
return false;
|
||||
}
|
||||
|
||||
public void resetViewUI() {
|
||||
setZoomProgress(0);
|
||||
resetTaskVisuals();
|
||||
}
|
||||
|
||||
public void setInOverviewState(boolean inOverviewState) {
|
||||
if (mInOverviewState != inOverviewState) {
|
||||
mInOverviewState = inOverviewState;
|
||||
if (mInOverviewState) {
|
||||
resetTaskVisuals();
|
||||
} else {
|
||||
setZoomProgress(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
|
||||
if (getTaskViewCount() == 0) {
|
||||
mZoomScale = 1f;
|
||||
mZoomTranslationY = 0f;
|
||||
} else {
|
||||
TaskView dummyTask = getTaskViewAt(0);
|
||||
ScaleAndTranslation sat = getTempClipAnimationHelper()
|
||||
.updateForFullscreenOverview(dummyTask)
|
||||
.getScaleAndTranslation();
|
||||
mZoomScale = sat.scale;
|
||||
mZoomTranslationY = sat.translationY;
|
||||
}
|
||||
|
||||
setZoomProgress(mZoomInProgress);
|
||||
}
|
||||
|
||||
public void setZoomProgress(float progress) {
|
||||
mZoomInProgress = progress;
|
||||
SCALE_PROPERTY.set(this, Utilities.mapRange(mZoomInProgress, 1, mZoomScale));
|
||||
TRANSLATION_Y.set(this, Utilities.mapRange(mZoomInProgress, 0, mZoomTranslationY));
|
||||
FULLSCREEN_PROGRESS.set(this, mZoomInProgress);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.quickstep.hints;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Bundle;
|
||||
|
||||
public final class HintUtil {
|
||||
|
||||
public static final String ID_KEY = "id";
|
||||
public static final String ICON_KEY = "icon";
|
||||
public static final String TEXT_KEY = "text";
|
||||
public static final String TAP_ACTION_KEY = "tap_action";
|
||||
|
||||
private HintUtil() {}
|
||||
|
||||
public static Bundle makeHint(String id, Icon icon, CharSequence text) {
|
||||
Bundle hint = new Bundle();
|
||||
hint.putString(ID_KEY, id);
|
||||
hint.putParcelable(ICON_KEY, icon);
|
||||
hint.putCharSequence(TEXT_KEY, text);
|
||||
return hint;
|
||||
}
|
||||
|
||||
public static Bundle makeHint(Icon icon, CharSequence text, PendingIntent tapAction) {
|
||||
Bundle hint = new Bundle();
|
||||
hint.putParcelable(ICON_KEY, icon);
|
||||
hint.putCharSequence(TEXT_KEY, text);
|
||||
hint.putParcelable(TAP_ACTION_KEY, tapAction);
|
||||
return hint;
|
||||
}
|
||||
|
||||
public static String getId(Bundle hint) {
|
||||
String id = hint.getString(ID_KEY);
|
||||
if (id == null) {
|
||||
throw new IllegalArgumentException("Hint does not contain an ID");
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public static Icon getIcon(Bundle hint) {
|
||||
Icon icon = hint.getParcelable(ICON_KEY);
|
||||
if (icon == null) {
|
||||
throw new IllegalArgumentException("Hint does not contain an icon");
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
public static CharSequence getText(Bundle hint) {
|
||||
CharSequence text = hint.getCharSequence(TEXT_KEY);
|
||||
if (text == null) {
|
||||
throw new IllegalArgumentException("Hint does not contain text");
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public static PendingIntent getTapAction(Bundle hint) {
|
||||
PendingIntent tapAction = hint.getParcelable(TAP_ACTION_KEY);
|
||||
if (tapAction == null) {
|
||||
throw new IllegalArgumentException("Hint does not contain a tap action");
|
||||
}
|
||||
return tapAction;
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.quickstep.hints;
|
||||
|
||||
import static com.android.quickstep.hints.HintUtil.getIcon;
|
||||
import static com.android.quickstep.hints.HintUtil.getText;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
|
||||
public class HintView extends LinearLayout {
|
||||
private ImageView mIconView;
|
||||
private TextView mLabelView;
|
||||
|
||||
public HintView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public HintView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public HintView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public HintView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
public void setHint(Bundle hint) {
|
||||
mLabelView.setText(getText(hint));
|
||||
|
||||
Icon icon = getIcon(hint);
|
||||
if (icon == null) {
|
||||
mIconView.setVisibility(GONE);
|
||||
} else {
|
||||
mIconView.setImageIcon(icon);
|
||||
mIconView.setVisibility(VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mIconView = findViewById(R.id.icon);
|
||||
mLabelView = findViewById(R.id.label);
|
||||
}
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
package com.android.quickstep.hints;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.FloatProperty;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
public class ProactiveHintsContainer extends FrameLayout {
|
||||
|
||||
public static final FloatProperty<ProactiveHintsContainer> HINT_VISIBILITY =
|
||||
new FloatProperty<ProactiveHintsContainer>("hint_visibility") {
|
||||
@Override
|
||||
public void setValue(ProactiveHintsContainer proactiveHintsContainer, float v) {
|
||||
proactiveHintsContainer.setHintVisibility(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(ProactiveHintsContainer proactiveHintsContainer) {
|
||||
return proactiveHintsContainer.mHintVisibility;
|
||||
}
|
||||
};
|
||||
|
||||
private float mHintVisibility;
|
||||
|
||||
public ProactiveHintsContainer(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ProactiveHintsContainer(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public ProactiveHintsContainer(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public ProactiveHintsContainer(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
public void setView(View v) {
|
||||
removeAllViews();
|
||||
addView(v);
|
||||
}
|
||||
|
||||
public void setHintVisibility(float v) {
|
||||
if (v == 1) {
|
||||
setVisibility(VISIBLE);
|
||||
} else {
|
||||
setVisibility(GONE);
|
||||
}
|
||||
mHintVisibility = v;
|
||||
}
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.quickstep.hints;
|
||||
|
||||
public final class UiHintListenerConstants {
|
||||
|
||||
private UiHintListenerConstants() {}
|
||||
|
||||
// Operations
|
||||
public static final int ON_HINTS_RETURNED_CODE = 5;
|
||||
|
||||
// Keys
|
||||
public static final String SESSION_ID_KEY = "session_id";
|
||||
public static final String HINTS_KEY = "hints";
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.quickstep.hints;
|
||||
|
||||
public final class UiInterfaceConstants {
|
||||
|
||||
private UiInterfaceConstants() {}
|
||||
|
||||
// Operations
|
||||
public static final int ON_HINT_TAP_CODE = 4;
|
||||
|
||||
public static final int REQUEST_HINTS_CODE = 7;
|
||||
|
||||
// Keys
|
||||
public static final String SESSION_ID_KEY = "session_id";
|
||||
public static final String HINT_ID_KEY = "hint_id";
|
||||
public static final String WIDTH_PX_KEY = "width_px";
|
||||
public static final String HEIGHT_PX_KEY = "height_px";
|
||||
public static final String HINT_SPACE_WIDTH_PX_KEY = "hint_space_width_px";
|
||||
public static final String HINT_SPACE_HEIGHT_PX_KEY = "hint_space_height_px";
|
||||
}
|
||||
+3
@@ -31,6 +31,7 @@ public interface InputConsumer {
|
||||
int TYPE_DEVICE_LOCKED = 1 << 4;
|
||||
int TYPE_ACCESSIBILITY = 1 << 5;
|
||||
int TYPE_SCREEN_PINNED = 1 << 6;
|
||||
int TYPE_OVERVIEW_WITHOUT_FOCUS = 1 << 7;
|
||||
|
||||
InputConsumer NO_OP = () -> TYPE_NO_OP;
|
||||
|
||||
@@ -78,6 +79,8 @@ public interface InputConsumer {
|
||||
return "ACCESSIBILITY";
|
||||
case TYPE_SCREEN_PINNED:
|
||||
return "SCREEN_PINNED";
|
||||
case TYPE_OVERVIEW_WITHOUT_FOCUS:
|
||||
return "TYPE_OVERVIEW_WITHOUT_FOCUS";
|
||||
default:
|
||||
return "NO_OP";
|
||||
}
|
||||
|
||||
+8
-20
@@ -28,7 +28,6 @@ import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_LANDSC
|
||||
import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_SEASCAPE;
|
||||
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
|
||||
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
|
||||
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
||||
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||
|
||||
@@ -43,10 +42,8 @@ import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
@@ -65,6 +62,7 @@ import com.android.quickstep.WindowTransformSwipeHandler;
|
||||
import com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget;
|
||||
import com.android.quickstep.util.CachedEventDispatcher;
|
||||
import com.android.quickstep.util.MotionPauseDetector;
|
||||
import com.android.quickstep.util.NavBarPosition;
|
||||
import com.android.quickstep.util.RecentsAnimationListenerSet;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.BackgroundExecutor;
|
||||
@@ -95,7 +93,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
private final SysUINavigationMode.Mode mMode;
|
||||
private final RectF mSwipeTouchRegion;
|
||||
|
||||
private final int mDisplayRotation;
|
||||
private final NavBarPosition mNavBarPosition;
|
||||
|
||||
private final Consumer<OtherActivityInputConsumer> mOnCompleteCallback;
|
||||
private final MotionPauseDetector mMotionPauseDetector;
|
||||
@@ -157,7 +155,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
mInputConsumer = inputConsumer;
|
||||
mSwipeSharedState = swipeSharedState;
|
||||
|
||||
mDisplayRotation = getSystemService(WindowManager.class).getDefaultDisplay().getRotation();
|
||||
mNavBarPosition = new NavBarPosition(base);
|
||||
mDragSlop = QuickStepContract.getQuickStepDragSlopPx();
|
||||
float slop = QuickStepContract.getQuickStepTouchSlopPx();
|
||||
mSquaredTouchSlop = slop * slop;
|
||||
@@ -188,9 +186,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
if (mPassedDragSlop && mInteractionHandler != null
|
||||
&& !mRecentsViewDispatcher.hasConsumer()) {
|
||||
mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher(
|
||||
isNavBarOnLeft()
|
||||
? ROTATION_SEASCAPE
|
||||
: (isNavBarOnRight() ? ROTATION_LANDSCAPE : RotationMode.NORMAL)));
|
||||
mNavBarPosition.getRotationMode()));
|
||||
}
|
||||
int edgeFlags = ev.getEdgeFlags();
|
||||
ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR);
|
||||
@@ -329,14 +325,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
mInteractionHandler.onGestureStarted();
|
||||
}
|
||||
|
||||
private boolean isNavBarOnRight() {
|
||||
return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_90;
|
||||
}
|
||||
|
||||
private boolean isNavBarOnLeft() {
|
||||
return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_270;
|
||||
}
|
||||
|
||||
private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
|
||||
TOUCH_INTERACTION_LOG.addLog("startRecentsAnimation");
|
||||
|
||||
@@ -382,8 +370,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
ViewConfiguration.get(this).getScaledMaximumFlingVelocity());
|
||||
float velocityX = mVelocityTracker.getXVelocity(mActivePointerId);
|
||||
float velocityY = mVelocityTracker.getYVelocity(mActivePointerId);
|
||||
float velocity = isNavBarOnRight() ? velocityX
|
||||
: isNavBarOnLeft() ? -velocityX
|
||||
float velocity = mNavBarPosition.isRightEdge() ? velocityX
|
||||
: mNavBarPosition.isLeftEdge() ? -velocityX
|
||||
: velocityY;
|
||||
|
||||
mInteractionHandler.updateDisplacement(getDisplacement(ev) - mStartDisplacement);
|
||||
@@ -444,9 +432,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
}
|
||||
|
||||
private float getDisplacement(MotionEvent ev) {
|
||||
if (isNavBarOnRight()) {
|
||||
if (mNavBarPosition.isRightEdge()) {
|
||||
return ev.getX() - mDownPos.x;
|
||||
} else if (isNavBarOnLeft()) {
|
||||
} else if (mNavBarPosition.isLeftEdge()) {
|
||||
return mDownPos.x - ev.getX();
|
||||
} else {
|
||||
return ev.getY() - mDownPos.y;
|
||||
|
||||
+4
-4
@@ -51,7 +51,7 @@ public class OverviewInputConsumer<T extends BaseDraggingActivity>
|
||||
private final boolean mStartingInActivityBounds;
|
||||
private boolean mTargetHandledTouch;
|
||||
|
||||
OverviewInputConsumer(T activity, @Nullable InputMonitorCompat inputMonitor,
|
||||
public OverviewInputConsumer(T activity, @Nullable InputMonitorCompat inputMonitor,
|
||||
boolean startingInActivityBounds) {
|
||||
mActivity = activity;
|
||||
mInputMonitor = inputMonitor;
|
||||
@@ -115,12 +115,12 @@ public class OverviewInputConsumer<T extends BaseDraggingActivity>
|
||||
}
|
||||
}
|
||||
|
||||
public static InputConsumer newInstance(ActivityControlHelper activityHelper,
|
||||
@Nullable InputMonitorCompat inputMonitor, boolean startingInActivityBounds) {
|
||||
public static InputConsumer newInstanceWithinActivityBounds(
|
||||
ActivityControlHelper activityHelper) {
|
||||
BaseDraggingActivity activity = activityHelper.getCreatedActivity();
|
||||
if (activity == null) {
|
||||
return InputConsumer.NO_OP;
|
||||
}
|
||||
return new OverviewInputConsumer(activity, inputMonitor, startingInActivityBounds);
|
||||
return new OverviewInputConsumer(activity, null, true);
|
||||
}
|
||||
}
|
||||
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.quickstep.inputconsumers;
|
||||
|
||||
import static android.view.MotionEvent.ACTION_CANCEL;
|
||||
import static android.view.MotionEvent.ACTION_DOWN;
|
||||
import static android.view.MotionEvent.ACTION_MOVE;
|
||||
import static android.view.MotionEvent.ACTION_UP;
|
||||
|
||||
import static com.android.launcher3.Utilities.squaredHypot;
|
||||
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PointF;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.quickstep.OverviewCallbacks;
|
||||
import com.android.quickstep.util.NavBarPosition;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.InputMonitorCompat;
|
||||
|
||||
public class OverviewWithoutFocusInputConsumer implements InputConsumer {
|
||||
|
||||
private final InputMonitorCompat mInputMonitor;
|
||||
private final boolean mDisableHorizontalSwipe;
|
||||
private final PointF mDownPos = new PointF();
|
||||
private final float mSquaredTouchSlop;
|
||||
private final Context mContext;
|
||||
private final NavBarPosition mNavBarPosition;
|
||||
|
||||
private boolean mInterceptedTouch;
|
||||
private VelocityTracker mVelocityTracker;
|
||||
|
||||
|
||||
public OverviewWithoutFocusInputConsumer(Context context, InputMonitorCompat inputMonitor,
|
||||
boolean disableHorizontalSwipe) {
|
||||
mInputMonitor = inputMonitor;
|
||||
mDisableHorizontalSwipe = disableHorizontalSwipe;
|
||||
mContext = context;
|
||||
mSquaredTouchSlop = Utilities.squaredTouchSlop(context);
|
||||
mNavBarPosition = new NavBarPosition(context);
|
||||
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return TYPE_OVERVIEW_WITHOUT_FOCUS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowInterceptByParent() {
|
||||
return !mInterceptedTouch;
|
||||
}
|
||||
|
||||
private void endTouchTracking() {
|
||||
if (mVelocityTracker != null) {
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMotionEvent(MotionEvent ev) {
|
||||
if (mVelocityTracker == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mVelocityTracker.addMovement(ev);
|
||||
switch (ev.getActionMasked()) {
|
||||
case ACTION_DOWN: {
|
||||
mDownPos.set(ev.getX(), ev.getY());
|
||||
break;
|
||||
}
|
||||
case ACTION_MOVE: {
|
||||
if (!mInterceptedTouch) {
|
||||
float displacementX = ev.getX() - mDownPos.x;
|
||||
float displacementY = ev.getY() - mDownPos.y;
|
||||
if (squaredHypot(displacementX, displacementY) >= mSquaredTouchSlop) {
|
||||
if (mDisableHorizontalSwipe
|
||||
&& Math.abs(displacementX) > Math.abs(displacementY)) {
|
||||
// Horizontal gesture is not allowed in this region
|
||||
endTouchTracking();
|
||||
break;
|
||||
}
|
||||
|
||||
mInterceptedTouch = true;
|
||||
|
||||
if (mInputMonitor != null) {
|
||||
mInputMonitor.pilferPointers();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ACTION_CANCEL:
|
||||
endTouchTracking();
|
||||
break;
|
||||
|
||||
case ACTION_UP: {
|
||||
finishTouchTracking(ev);
|
||||
endTouchTracking();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void finishTouchTracking(MotionEvent ev) {
|
||||
mVelocityTracker.computeCurrentVelocity(100);
|
||||
float velocityX = mVelocityTracker.getXVelocity();
|
||||
float velocityY = mVelocityTracker.getYVelocity();
|
||||
float velocity = mNavBarPosition.isRightEdge()
|
||||
? -velocityX : (mNavBarPosition.isLeftEdge() ? velocityX : -velocityY);
|
||||
|
||||
final boolean triggerQuickstep;
|
||||
if (Math.abs(velocity) >= ViewConfiguration.get(mContext).getScaledMinimumFlingVelocity()) {
|
||||
triggerQuickstep = velocity > 0;
|
||||
} else {
|
||||
float displacementX = mDisableHorizontalSwipe ? 0 : (ev.getX() - mDownPos.x);
|
||||
float displacementY = ev.getY() - mDownPos.y;
|
||||
triggerQuickstep = squaredHypot(displacementX, displacementY) >= mSquaredTouchSlop;
|
||||
}
|
||||
|
||||
if (triggerQuickstep) {
|
||||
OverviewCallbacks.get(mContext).closeAllWindows();
|
||||
ActivityManagerWrapper.getInstance()
|
||||
.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
|
||||
TOUCH_INTERACTION_LOG.addLog("startQuickstep");
|
||||
} else {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_LANDSCAPE;
|
||||
import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_SEASCAPE;
|
||||
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.Surface;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.launcher3.graphics.RotationMode;
|
||||
import com.android.quickstep.SysUINavigationMode;
|
||||
|
||||
/**
|
||||
* Utility class to check nav bar position
|
||||
*/
|
||||
public class NavBarPosition {
|
||||
|
||||
private final SysUINavigationMode.Mode mMode;
|
||||
private final int mDisplayRotation;
|
||||
|
||||
public NavBarPosition(Context context) {
|
||||
mMode = SysUINavigationMode.getMode(context);
|
||||
mDisplayRotation = context.getSystemService(WindowManager.class)
|
||||
.getDefaultDisplay().getRotation();
|
||||
}
|
||||
|
||||
public boolean isRightEdge() {
|
||||
return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_90;
|
||||
}
|
||||
|
||||
public boolean isLeftEdge() {
|
||||
return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_270;
|
||||
}
|
||||
|
||||
public RotationMode getRotationMode() {
|
||||
return isLeftEdge() ? ROTATION_SEASCAPE
|
||||
: (isRightEdge() ? ROTATION_LANDSCAPE : RotationMode.NORMAL);
|
||||
}
|
||||
}
|
||||
+21
-1
@@ -28,13 +28,20 @@ import com.android.launcher3.CellLayout;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAnimUtils.ViewProgressProperty;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.LauncherStateManager;
|
||||
import com.android.launcher3.LauncherStateManager.AnimationConfig;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.ShortcutAndWidgetContainer;
|
||||
import com.android.launcher3.anim.AnimatorSetBuilder;
|
||||
import com.android.launcher3.anim.PropertySetter;
|
||||
import com.android.launcher3.anim.SpringObjectAnimator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
|
||||
/**
|
||||
@@ -56,7 +63,7 @@ public class StaggeredWorkspaceAnim {
|
||||
private final float mSpringTransY;
|
||||
private final View mViewToIgnore;
|
||||
|
||||
private final List<ValueAnimator> mAnimators = new ArrayList<>();
|
||||
private final List<Animator> mAnimators = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* @param floatingViewOriginalView The FloatingIconView's original view.
|
||||
@@ -104,6 +111,9 @@ public class StaggeredWorkspaceAnim {
|
||||
View qsb = launcher.findViewById(R.id.search_container_all_apps);
|
||||
addStaggeredAnimationForView(qsb, grid.inv.numRows + 2, totalRows);
|
||||
}
|
||||
|
||||
addWorkspaceScrimAnimationForState(launcher, BACKGROUND_APP, 0);
|
||||
addWorkspaceScrimAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,4 +160,14 @@ public class StaggeredWorkspaceAnim {
|
||||
alpha.setStartDelay(startDelay);
|
||||
mAnimators.add(alpha);
|
||||
}
|
||||
|
||||
private void addWorkspaceScrimAnimationForState(Launcher launcher, LauncherState state,
|
||||
long duration) {
|
||||
AnimatorSetBuilder scrimAnimBuilder = new AnimatorSetBuilder();
|
||||
AnimationConfig scrimAnimConfig = new AnimationConfig();
|
||||
scrimAnimConfig.duration = duration;
|
||||
PropertySetter scrimPropertySetter = scrimAnimConfig.getPropertySetter(scrimAnimBuilder);
|
||||
launcher.getWorkspace().getStateTransitionAnimation().setScrim(scrimPropertySetter, state);
|
||||
mAnimators.add(scrimAnimBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
+20
-66
@@ -20,6 +20,7 @@ import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.LauncherState.RECENTS_CLEAR_ALL_BUTTON;
|
||||
import static com.android.launcher3.LauncherState.SPRING_LOADED;
|
||||
import static com.android.launcher3.QuickstepAppTransitionManagerImpl.ALL_APPS_PROGRESS_OFF_SCREEN;
|
||||
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
@@ -30,25 +31,20 @@ import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.LauncherStateManager.StateListener;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.appprediction.PredictionUiStateManager;
|
||||
import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
|
||||
import com.android.launcher3.util.PendingAnimation;
|
||||
import com.android.launcher3.views.BaseDragLayer;
|
||||
import com.android.launcher3.views.ScrimView;
|
||||
import com.android.quickstep.SysUINavigationMode;
|
||||
import com.android.quickstep.hints.ProactiveHintsContainer;
|
||||
import com.android.quickstep.util.ClipAnimationHelper;
|
||||
import com.android.quickstep.util.ClipAnimationHelper.TransformParams;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
@@ -57,11 +53,9 @@ import com.android.quickstep.util.LayoutUtils;
|
||||
* {@link RecentsView} used in Launcher activity
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
public class LauncherRecentsView extends RecentsView<Launcher> {
|
||||
public class LauncherRecentsView extends RecentsView<Launcher> implements StateListener {
|
||||
|
||||
private final TransformParams mTransformParams = new TransformParams();
|
||||
private final int mChipOverhang;
|
||||
@Nullable private ProactiveHintsContainer mProactiveHintsContainer;
|
||||
|
||||
public LauncherRecentsView(Context context) {
|
||||
this(context, null);
|
||||
@@ -74,16 +68,7 @@ public class LauncherRecentsView extends RecentsView<Launcher> {
|
||||
public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setContentAlpha(0);
|
||||
mChipOverhang = (int) context.getResources().getDimension(R.dimen.chip_hint_overhang);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
View hintContainer = mActivity.findViewById(R.id.hints);
|
||||
mProactiveHintsContainer =
|
||||
hintContainer instanceof ProactiveHintsContainer
|
||||
? (ProactiveHintsContainer) hintContainer : null;
|
||||
mActivity.getStateManager().addStateListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,11 +87,6 @@ public class LauncherRecentsView extends RecentsView<Launcher> {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ProactiveHintsContainer getProactiveHintsContainer() {
|
||||
return mProactiveHintsContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
maybeDrawEmptyMessage(canvas);
|
||||
@@ -160,23 +140,6 @@ public class LauncherRecentsView extends RecentsView<Launcher> {
|
||||
@Override
|
||||
protected void getTaskSize(DeviceProfile dp, Rect outRect) {
|
||||
LayoutUtils.calculateLauncherTaskSize(getContext(), dp, outRect);
|
||||
if (mProactiveHintsContainer != null) {
|
||||
BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) mProactiveHintsContainer.getLayoutParams();
|
||||
params.bottomMargin = getHeight() - outRect.bottom - mChipOverhang;
|
||||
params.width = outRect.width();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingAnimation createTaskLauncherAnimation(TaskView tv, long duration) {
|
||||
PendingAnimation anim = super.createTaskLauncherAnimation(tv, duration);
|
||||
|
||||
if (mProactiveHintsContainer != null) {
|
||||
anim.anim.play(ObjectAnimator.ofFloat(
|
||||
mProactiveHintsContainer, ProactiveHintsContainer.HINT_VISIBILITY, 0));
|
||||
}
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -194,31 +157,6 @@ public class LauncherRecentsView extends RecentsView<Launcher> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingAnimation createTaskDismissAnimation(TaskView taskView, boolean animateTaskView,
|
||||
boolean shouldRemoveTask, long duration) {
|
||||
PendingAnimation anim = super.createTaskDismissAnimation(taskView, animateTaskView,
|
||||
shouldRemoveTask, duration);
|
||||
|
||||
if (mProactiveHintsContainer != null) {
|
||||
anim.anim.play(ObjectAnimator.ofFloat(
|
||||
mProactiveHintsContainer, ProactiveHintsContainer.HINT_VISIBILITY, 0));
|
||||
anim.addEndListener(onEndListener -> {
|
||||
if (!onEndListener.isSuccess) {
|
||||
mProactiveHintsContainer.setHintVisibility(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
||||
public void setHintVisibility(float v) {
|
||||
if (mProactiveHintsContainer != null) {
|
||||
mProactiveHintsContainer.setHintVisibility(v);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTaskLaunched(boolean success) {
|
||||
if (success) {
|
||||
@@ -286,6 +224,22 @@ public class LauncherRecentsView extends RecentsView<Launcher> {
|
||||
PredictionUiStateManager.INSTANCE.get(getContext()).switchClient(Client.HOME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateTransitionStart(LauncherState toState) {
|
||||
setOverviewStateEnabled(toState.overviewUi);
|
||||
setFreezeViewVisibility(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateTransitionComplete(LauncherState finalState) {
|
||||
if (finalState == NORMAL || finalState == SPRING_LOADED) {
|
||||
// Clean-up logic that occurs when recents is no longer in use/visible.
|
||||
reset();
|
||||
}
|
||||
setOverlayEnabled(finalState == OVERVIEW);
|
||||
setFreezeViewVisibility(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOverviewStateEnabled(boolean enabled) {
|
||||
super.setOverviewStateEnabled(enabled);
|
||||
|
||||
@@ -72,6 +72,9 @@ import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.widget.ListView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.dynamicanimation.animation.SpringForce;
|
||||
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Insettable;
|
||||
@@ -111,9 +114,6 @@ import com.android.systemui.shared.system.TaskStackChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.dynamicanimation.animation.SpringForce;
|
||||
|
||||
/**
|
||||
* A list of recent tasks.
|
||||
*/
|
||||
@@ -168,8 +168,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
// The threshold at which we update the SystemUI flags when animating from the task into the app
|
||||
public static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.85f;
|
||||
|
||||
private static final float[] sTempFloatArray = new float[3];
|
||||
|
||||
protected final T mActivity;
|
||||
private final float mFastFlingVelocity;
|
||||
private final RecentsModel mModel;
|
||||
@@ -189,6 +187,8 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
|
||||
private boolean mDwbToastShown;
|
||||
private boolean mDisallowScrollToClearAll;
|
||||
private boolean mOverlayEnabled;
|
||||
private boolean mFreezeViewVisibility;
|
||||
|
||||
/**
|
||||
* TODO: Call reloadIdNeeded in onTaskStackChanged.
|
||||
@@ -428,11 +428,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
// Clear the task data for the removed child if it was visible
|
||||
if (child != mClearAllButton) {
|
||||
TaskView taskView = (TaskView) child;
|
||||
Task task = taskView.getTask();
|
||||
if (mHasVisibleTaskData.get(task.key.id)) {
|
||||
mHasVisibleTaskData.delete(task.key.id);
|
||||
taskView.onTaskListVisibilityChanged(false /* visible */);
|
||||
}
|
||||
mHasVisibleTaskData.delete(taskView.getTask().key.id);
|
||||
mTaskViewPool.recycle(taskView);
|
||||
}
|
||||
}
|
||||
@@ -455,7 +451,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
public void setOverviewStateEnabled(boolean enabled) {
|
||||
mOverviewStateEnabled = enabled;
|
||||
updateTaskStackListenerState();
|
||||
if (!enabled) mDwbToastShown = false;
|
||||
}
|
||||
|
||||
public void onDigitalWellbeingToastShown() {
|
||||
@@ -582,6 +577,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
}
|
||||
resetTaskVisuals();
|
||||
onTaskStackUpdated();
|
||||
updateEnabledOverlays();
|
||||
}
|
||||
|
||||
public int getTaskViewCount() {
|
||||
@@ -780,6 +776,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
|
||||
unloadVisibleTaskData();
|
||||
setCurrentPage(0);
|
||||
mDwbToastShown = false;
|
||||
}
|
||||
|
||||
public @Nullable TaskView getRunningTaskView() {
|
||||
@@ -1306,7 +1303,25 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
mEmptyMessagePaint.setAlpha(alphaInt);
|
||||
mEmptyIcon.setAlpha(alphaInt);
|
||||
|
||||
setVisibility(alpha > 0 ? VISIBLE : GONE);
|
||||
if (alpha > 0) {
|
||||
setVisibility(VISIBLE);
|
||||
} else if (!mFreezeViewVisibility) {
|
||||
setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Freezes the view visibility change. When frozen, the view will not change its visibility
|
||||
* to gone due to alpha changes.
|
||||
*/
|
||||
public void setFreezeViewVisibility(boolean freezeViewVisibility) {
|
||||
if (mFreezeViewVisibility != freezeViewVisibility) {
|
||||
mFreezeViewVisibility = freezeViewVisibility;
|
||||
|
||||
if (!mFreezeViewVisibility) {
|
||||
setVisibility(mContentAlpha > 0 ? VISIBLE : GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1545,6 +1560,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
protected void notifyPageSwitchListener(int prevPage) {
|
||||
super.notifyPageSwitchListener(prevPage);
|
||||
loadVisibleTaskData();
|
||||
updateEnabledOverlays();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1685,4 +1701,19 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
public ClipAnimationHelper getTempClipAnimationHelper() {
|
||||
return mTempClipAnimationHelper;
|
||||
}
|
||||
|
||||
private void updateEnabledOverlays() {
|
||||
int overlayEnabledPage = mOverlayEnabled ? getNextPage() : -1;
|
||||
int taskCount = getTaskViewCount();
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
((TaskView) getChildAt(i)).setOverlayEnabled(i == overlayEnabledPage);
|
||||
}
|
||||
}
|
||||
|
||||
public void setOverlayEnabled(boolean overlayEnabled) {
|
||||
if (mOverlayEnabled != overlayEnabled) {
|
||||
mOverlayEnabled = overlayEnabled;
|
||||
updateEnabledOverlays();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.views.BaseDragLayer;
|
||||
import com.android.quickstep.TaskOverlayFactory;
|
||||
import com.android.quickstep.TaskSystemShortcut;
|
||||
import com.android.quickstep.TaskUtils;
|
||||
import com.android.quickstep.views.IconView.OnScaleUpdateListener;
|
||||
@@ -196,7 +197,7 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
|
||||
final BaseDraggingActivity activity = BaseDraggingActivity.fromContext(getContext());
|
||||
final List<TaskSystemShortcut> shortcuts =
|
||||
taskView.getTaskOverlay().getEnabledShortcuts(taskView);
|
||||
TaskOverlayFactory.INSTANCE.get(getContext()).getEnabledShortcuts(taskView);
|
||||
final int count = shortcuts.size();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final TaskSystemShortcut menuOption = shortcuts.get(i);
|
||||
|
||||
+21
-10
@@ -98,6 +98,9 @@ public class TaskThumbnailView extends View {
|
||||
private float mDimAlphaMultiplier = 1f;
|
||||
private float mSaturation = 1f;
|
||||
|
||||
private boolean mOverlayEnabled;
|
||||
private boolean mRotated;
|
||||
|
||||
public TaskThumbnailView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -192,10 +195,6 @@ public class TaskThumbnailView extends View {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public TaskOverlay getTaskOverlay() {
|
||||
return mOverlay;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
RectF currentDrawnInsets = mFullscreenParams.mCurrentDrawnInsets;
|
||||
@@ -257,6 +256,22 @@ public class TaskThumbnailView extends View {
|
||||
return (TaskView) getParent();
|
||||
}
|
||||
|
||||
public void setOverlayEnabled(boolean overlayEnabled) {
|
||||
if (mOverlayEnabled != overlayEnabled) {
|
||||
mOverlayEnabled = overlayEnabled;
|
||||
updateOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateOverlay() {
|
||||
// The overlay doesn't really work when the screenshot is rotated, so don't add it.
|
||||
if (mOverlayEnabled && !mRotated && mBitmapShader != null && mThumbnailData != null) {
|
||||
mOverlay.initOverlay(mTask, mThumbnailData, mMatrix);
|
||||
} else {
|
||||
mOverlay.reset();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateThumbnailPaintFilter() {
|
||||
int mul = (int) ((1 - mDimAlpha * mDimAlphaMultiplier) * 255);
|
||||
ColorFilter filter = getColorFilter(mul, mIsDarkTextTheme, mSaturation);
|
||||
@@ -351,12 +366,8 @@ public class TaskThumbnailView extends View {
|
||||
mPaint.setShader(mBitmapShader);
|
||||
}
|
||||
|
||||
if (isRotated) {
|
||||
// The overlay doesn't really work when the screenshot is rotated, so don't add it.
|
||||
mOverlay.reset();
|
||||
} else {
|
||||
mOverlay.setTaskInfo(mTask, mThumbnailData, mMatrix);
|
||||
}
|
||||
mRotated = isRotated;
|
||||
updateOverlay();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@ import android.os.Handler;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.FloatProperty;
|
||||
import android.util.Log;
|
||||
import android.util.Property;
|
||||
import android.view.View;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
@@ -253,10 +252,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
return mIconView;
|
||||
}
|
||||
|
||||
public TaskOverlayFactory.TaskOverlay getTaskOverlay() {
|
||||
return mSnapshotView.getTaskOverlay();
|
||||
}
|
||||
|
||||
public AnimatorPlaybackController createLaunchAnimationForRunningTask() {
|
||||
final PendingAnimation pendingAnimation =
|
||||
getRecentsView().createTaskLauncherAnimation(this, RECENTS_LAUNCH_DURATION);
|
||||
@@ -488,6 +483,8 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
// Clear any references to the thumbnail (it will be re-read either from the cache or the
|
||||
// system on next bind)
|
||||
mSnapshotView.setThumbnail(mTask, null);
|
||||
setOverlayEnabled(false);
|
||||
onTaskListVisibilityChanged(false);
|
||||
if (mTask != null) {
|
||||
mTask.thumbnail = null;
|
||||
}
|
||||
@@ -608,7 +605,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
|
||||
final Context context = getContext();
|
||||
final List<TaskSystemShortcut> shortcuts =
|
||||
mSnapshotView.getTaskOverlay().getEnabledShortcuts(this);
|
||||
TaskOverlayFactory.INSTANCE.get(getContext()).getEnabledShortcuts(this);
|
||||
final int count = shortcuts.size();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final TaskSystemShortcut menuOption = shortcuts.get(i);
|
||||
@@ -647,7 +644,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
}
|
||||
|
||||
final List<TaskSystemShortcut> shortcuts =
|
||||
mSnapshotView.getTaskOverlay().getEnabledShortcuts(this);
|
||||
TaskOverlayFactory.INSTANCE.get(getContext()).getEnabledShortcuts(this);
|
||||
final int count = shortcuts.size();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final TaskSystemShortcut menuOption = shortcuts.get(i);
|
||||
@@ -733,6 +730,10 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
return mShowScreenshot;
|
||||
}
|
||||
|
||||
public void setOverlayEnabled(boolean overlayEnabled) {
|
||||
mSnapshotView.setOverlayEnabled(overlayEnabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* We update and subsequently draw these in {@link #setFullscreenProgress(float)}.
|
||||
*/
|
||||
|
||||
@@ -108,7 +108,7 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
|
||||
// Use a shorter duration for x or y translation to create a curve effect
|
||||
private static final long APP_LAUNCH_CURVED_DURATION = 250;
|
||||
private static final long APP_LAUNCH_ALPHA_DURATION = 50;
|
||||
private static final long APP_LAUNCH_ALPHA_START_DELAY = 50;
|
||||
private static final long APP_LAUNCH_ALPHA_START_DELAY = 25;
|
||||
|
||||
// We scale the durations for the downward app launch animations (minus the scale animation).
|
||||
private static final float APP_LAUNCH_DOWN_DUR_SCALE_FACTOR = 0.8f;
|
||||
|
||||
@@ -47,7 +47,6 @@ import com.android.launcher3.LauncherStateManager;
|
||||
import com.android.launcher3.LauncherStateManager.StateHandler;
|
||||
import com.android.launcher3.QuickstepAppTransitionManagerImpl;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.dragndrop.DragLayer;
|
||||
import com.android.launcher3.proxy.ProxyActivityStarter;
|
||||
import com.android.launcher3.proxy.StartActivityParams;
|
||||
import com.android.quickstep.OverviewInteractionState;
|
||||
@@ -64,10 +63,14 @@ import java.util.zip.Deflater;
|
||||
|
||||
public class UiFactory extends RecentsUiFactory {
|
||||
|
||||
public static Runnable enableLiveTouchControllerChanges(DragLayer dl) {
|
||||
NavigationModeChangeListener listener = m -> dl.recreateControllers();
|
||||
SysUINavigationMode mode = SysUINavigationMode.INSTANCE.get(dl.getContext());
|
||||
mode.addModeChangeListener(listener);
|
||||
public static Runnable enableLiveUIChanges(Launcher launcher) {
|
||||
NavigationModeChangeListener listener = m -> {
|
||||
launcher.getDragLayer().recreateControllers();
|
||||
launcher.getRotationHelper().setRotationHadDifferentUI(m != Mode.NO_BUTTON);
|
||||
};
|
||||
SysUINavigationMode mode = SysUINavigationMode.INSTANCE.get(launcher);
|
||||
SysUINavigationMode.Mode m = mode.addModeChangeListener(listener);
|
||||
launcher.getRotationHelper().setRotationHadDifferentUI(m != Mode.NO_BUTTON);
|
||||
return () -> mode.removeModeChangeListener(listener);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,14 +18,17 @@ package com.android.quickstep;
|
||||
|
||||
import com.android.launcher3.ui.AbstractLauncherUiTest;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.RuleChain;
|
||||
import org.junit.rules.TestRule;
|
||||
|
||||
/**
|
||||
* Base class for all instrumentation tests that deal with Quickstep.
|
||||
*/
|
||||
public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest {
|
||||
@Rule
|
||||
public TestRule mQuickstepOnOffExecutor =
|
||||
new NavigationModeSwitchRule(mLauncher);
|
||||
@Override
|
||||
protected TestRule getRulesInsideActivityMonitor() {
|
||||
return RuleChain.
|
||||
outerRule(new NavigationModeSwitchRule(mLauncher)).
|
||||
around(super.getRulesInsideActivityMonitor());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,11 +48,6 @@
|
||||
layout="@layout/overview_panel"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
android:id="@+id/hints"
|
||||
layout="@layout/proactive_hints_container"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<!-- Keep these behind the workspace so that they are not visible when
|
||||
we go into AllApps -->
|
||||
<com.android.launcher3.pageindicators.WorkspacePageIndicator
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2016 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.
|
||||
-->
|
||||
<Space
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp" />
|
||||
@@ -56,9 +56,9 @@
|
||||
android:paddingBottom="@dimen/folder_label_padding_bottom"
|
||||
android:paddingTop="@dimen/folder_label_padding_top"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:attr/textColorTertiary"
|
||||
android:textColor="?attr/folderTextColor"
|
||||
android:textColorHighlight="?android:attr/colorControlHighlight"
|
||||
android:textColorHint="?android:attr/textColorHint"
|
||||
android:textColorHint="?attr/folderTextColor"
|
||||
android:textSize="@dimen/folder_label_text_size" />
|
||||
|
||||
<com.android.launcher3.pageindicators.PageIndicatorDots
|
||||
|
||||
@@ -232,11 +232,6 @@
|
||||
<dimen name="snackbar_min_text_size">12sp</dimen>
|
||||
<dimen name="snackbar_max_text_size">14sp</dimen>
|
||||
|
||||
<!-- Hints -->
|
||||
<dimen name="chip_hint_height">26dp</dimen>
|
||||
<dimen name="chip_hint_bottom_margin">194dp</dimen>
|
||||
<dimen name="chip_hint_overhang">15dp</dimen>
|
||||
|
||||
<!-- Theming related -->
|
||||
<dimen name="default_dialog_corner_radius">8dp</dimen>
|
||||
|
||||
|
||||
@@ -99,10 +99,6 @@ public class DeviceProfile {
|
||||
public int folderChildTextSizePx;
|
||||
public int folderChildDrawablePaddingPx;
|
||||
|
||||
// Hints
|
||||
public int chipHintHeightPx;
|
||||
public int chipHintBottomMarginPx;
|
||||
|
||||
// Hotseat
|
||||
public int hotseatCellHeightPx;
|
||||
// In portrait: size = height, in landscape: size = width
|
||||
@@ -200,9 +196,6 @@ public class DeviceProfile {
|
||||
|
||||
workspaceCellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x);
|
||||
|
||||
chipHintHeightPx = res.getDimensionPixelSize(R.dimen.chip_hint_height);
|
||||
chipHintBottomMarginPx = res.getDimensionPixelSize(R.dimen.chip_hint_bottom_margin);
|
||||
|
||||
hotseatBarTopPaddingPx =
|
||||
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding);
|
||||
hotseatBarBottomPaddingPx = (isTallDevice ? 0
|
||||
|
||||
@@ -879,6 +879,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "Launcher.onStart");
|
||||
}
|
||||
RaceConditionTracker.onEvent(ON_START_EVT, ENTER);
|
||||
super.onStart();
|
||||
if (mLauncherCallbacks != null) {
|
||||
@@ -1063,7 +1066,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
|
||||
// Setup the drag layer
|
||||
mDragLayer.setup(mDragController, mWorkspace);
|
||||
mCancelTouchController = UiFactory.enableLiveTouchControllerChanges(mDragLayer);
|
||||
mCancelTouchController = UiFactory.enableLiveUIChanges(this);
|
||||
|
||||
mWorkspace.setup(mDragController);
|
||||
// Until the workspace is bound, ensure that we keep the wallpaper offset locked to the
|
||||
|
||||
@@ -258,9 +258,6 @@ public class LauncherState {
|
||||
* Called when the start transition ends and the user settles on this particular state.
|
||||
*/
|
||||
public void onStateTransitionEnd(Launcher launcher) {
|
||||
if (this == NORMAL || this == SPRING_LOADED) {
|
||||
UiFactory.resetOverview(launcher);
|
||||
}
|
||||
if (this == NORMAL) {
|
||||
// Clear any rotation locks when going to normal state
|
||||
launcher.getRotationHelper().setCurrentStateRequest(REQUEST_NONE);
|
||||
|
||||
@@ -1394,6 +1394,10 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
builder.play(stepAnimator);
|
||||
}
|
||||
|
||||
public WorkspaceStateTransitionAnimation getStateTransitionAnimation() {
|
||||
return mStateTransitionAnimation;
|
||||
}
|
||||
|
||||
public void updateAccessibilityFlags() {
|
||||
// TODO: Update the accessibility flags appropriately when dragging.
|
||||
int accessibilityFlag = mLauncher.getStateManager().getState().workspaceAccessibilityFlag;
|
||||
|
||||
@@ -130,7 +130,10 @@ public class WorkspaceStateTransitionAnimation {
|
||||
propertySetter.setFloat(mWorkspace.getPageIndicator(), View.TRANSLATION_Y,
|
||||
hotseatScaleAndTranslation.translationY, translationInterpolator);
|
||||
|
||||
// Set scrim
|
||||
setScrim(propertySetter, state);
|
||||
}
|
||||
|
||||
public void setScrim(PropertySetter propertySetter, LauncherState state) {
|
||||
WorkspaceAndHotseatScrim scrim = mLauncher.getDragLayer().getScrim();
|
||||
propertySetter.setFloat(scrim, SCRIM_PROGRESS, state.getWorkspaceScrimAlpha(mLauncher),
|
||||
LINEAR);
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.graphics.Bitmap;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
import android.view.DragEvent;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.KeyEvent;
|
||||
@@ -491,6 +492,16 @@ public class DragController implements DragDriver.EventListener, TouchController
|
||||
mLastTouch[0] = x;
|
||||
mLastTouch[1] = y;
|
||||
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.NO_DRAG_TAG,
|
||||
"handleMoveEvent Conditions " +
|
||||
mIsInPreDrag + ", " +
|
||||
(mIsInPreDrag && mOptions.preDragCondition != null) + ", " +
|
||||
(mIsInPreDrag && mOptions.preDragCondition != null
|
||||
&& mOptions.preDragCondition.shouldStartDrag(
|
||||
mDistanceSinceScroll)));
|
||||
}
|
||||
|
||||
if (mIsInPreDrag && mOptions.preDragCondition != null
|
||||
&& mOptions.preDragCondition.shouldStartDrag(mDistanceSinceScroll)) {
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
|
||||
@@ -73,7 +73,8 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
|
||||
|
||||
// This is used to defer setting rotation flags until the activity is being created
|
||||
private boolean mInitialized;
|
||||
public boolean mDestroyed;
|
||||
private boolean mDestroyed;
|
||||
private boolean mRotationHasDifferentUI;
|
||||
|
||||
private int mLastActivityFlags = -1;
|
||||
|
||||
@@ -92,8 +93,12 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
|
||||
}
|
||||
}
|
||||
|
||||
public void setRotationHadDifferentUI(boolean rotationHasDifferentUI) {
|
||||
mRotationHasDifferentUI = rotationHasDifferentUI;
|
||||
}
|
||||
|
||||
public boolean homeScreenCanRotate() {
|
||||
return mIgnoreAutoRotateSettings || mAutoRotateEnabled
|
||||
return mRotationHasDifferentUI || mIgnoreAutoRotateSettings || mAutoRotateEnabled
|
||||
|| mStateHandlerRequest != REQUEST_NONE
|
||||
|| mLauncher.getDeviceProfile().isMultiWindowMode;
|
||||
}
|
||||
|
||||
@@ -72,4 +72,5 @@ public final class TestProtocol {
|
||||
public static final String NO_DRAG_TAG = "b/133009122";
|
||||
public static final String NO_START_TAG = "b/132900132";
|
||||
public static final String NO_START_TASK_TAG = "b/133765434";
|
||||
public static final String NO_OVERVIEW_EVENT_TAG = "b/134532571";
|
||||
}
|
||||
|
||||
@@ -27,16 +27,17 @@ import android.util.MutableLong;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
|
||||
/**
|
||||
* A wrapper around {@link Trace} to allow easier proguarding for production builds.
|
||||
* A wrapper around {@link Trace} with some utility information.
|
||||
*
|
||||
* To enable any tracing log, execute the following command:
|
||||
* $ adb shell setprop log.tag.LAUNCHER_TRACE VERBOSE
|
||||
* $ adb shell setprop log.tag.TAGNAME VERBOSE
|
||||
*/
|
||||
public class TraceHelper {
|
||||
|
||||
private static final boolean ENABLED = FeatureFlags.IS_DOGFOOD_BUILD;
|
||||
private static final boolean ENABLED = isLoggable("LAUNCHER_TRACE", VERBOSE);
|
||||
|
||||
private static final boolean SYSTEM_TRACE = false;
|
||||
private static final boolean SYSTEM_TRACE = ENABLED;
|
||||
private static final ArrayMap<String, MutableLong> sUpTimes = ENABLED ? new ArrayMap<>() : null;
|
||||
|
||||
public static void beginSection(String sectionName) {
|
||||
|
||||
@@ -124,6 +124,7 @@ public class FloatingIconView extends View implements
|
||||
|
||||
private boolean mIsVerticalBarLayout = false;
|
||||
private boolean mIsAdaptiveIcon = false;
|
||||
private boolean mIsOpening;
|
||||
|
||||
private @Nullable Drawable mBadge;
|
||||
private @Nullable Drawable mForeground;
|
||||
@@ -178,8 +179,10 @@ public class FloatingIconView extends View implements
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
getViewTreeObserver().addOnGlobalLayoutListener(this);
|
||||
mLauncher.getRotationHelper().setCurrentTransitionRequest(REQUEST_LOCK);
|
||||
if (!mIsOpening) {
|
||||
getViewTreeObserver().addOnGlobalLayoutListener(this);
|
||||
mLauncher.getRotationHelper().setCurrentTransitionRequest(REQUEST_LOCK);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -326,7 +329,7 @@ public class FloatingIconView extends View implements
|
||||
* - For BubbleTextView, we return the icon bounds.
|
||||
*/
|
||||
private float getLocationBoundsForView(View v, RectF outRect) {
|
||||
boolean ignoreTransform = true;
|
||||
boolean ignoreTransform = !mIsOpening;
|
||||
if (v instanceof DeepShortcutView) {
|
||||
v = ((DeepShortcutView) v).getBubbleText();
|
||||
ignoreTransform = false;
|
||||
@@ -627,6 +630,7 @@ public class FloatingIconView extends View implements
|
||||
view.recycle();
|
||||
|
||||
view.mIsVerticalBarLayout = launcher.getDeviceProfile().isVerticalBarLayout();
|
||||
view.mIsOpening = isOpening;
|
||||
|
||||
view.mOriginalIcon = originalView;
|
||||
view.mPositionOut = positionOut;
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState.ScaleAndTranslation;
|
||||
import com.android.launcher3.LauncherStateManager.StateHandler;
|
||||
import com.android.launcher3.dragndrop.DragLayer;
|
||||
import com.android.launcher3.graphics.RotationMode;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
|
||||
@@ -40,7 +39,7 @@ public class UiFactory {
|
||||
launcher.getDragController(), new AllAppsSwipeController(launcher)};
|
||||
}
|
||||
|
||||
public static Runnable enableLiveTouchControllerChanges(DragLayer dl) {
|
||||
public static Runnable enableLiveUIChanges(Launcher l) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,19 +58,17 @@ import com.android.launcher3.model.AppLaunchTracker;
|
||||
import com.android.launcher3.tapl.LauncherInstrumentation;
|
||||
import com.android.launcher3.tapl.TestHelpers;
|
||||
import com.android.launcher3.util.Wait;
|
||||
import com.android.launcher3.util.rule.FailureWatcher;
|
||||
import com.android.launcher3.util.rule.LauncherActivityRule;
|
||||
import com.android.launcher3.util.rule.ShellCommandRule;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.RuleChain;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.rules.TestWatcher;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -93,11 +91,11 @@ public abstract class AbstractLauncherUiTest {
|
||||
public static final long SHORT_UI_TIMEOUT = 300;
|
||||
public static final long DEFAULT_UI_TIMEOUT = 10000;
|
||||
private static final String TAG = "AbstractLauncherUiTest";
|
||||
private static int sScreenshotCount = 0;
|
||||
|
||||
protected MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
|
||||
protected final UiDevice mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
protected final LauncherInstrumentation mLauncher;
|
||||
protected final LauncherInstrumentation mLauncher =
|
||||
new LauncherInstrumentation(getInstrumentation());
|
||||
protected Context mTargetContext;
|
||||
protected String mTargetPackage;
|
||||
|
||||
@@ -108,11 +106,9 @@ public abstract class AbstractLauncherUiTest {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (TestHelpers.isInLauncherProcess()) Utilities.enableRunningInTestHarnessForTests();
|
||||
mLauncher = new LauncherInstrumentation(getInstrumentation());
|
||||
}
|
||||
|
||||
@Rule
|
||||
public LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
|
||||
protected final LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
|
||||
|
||||
@Rule
|
||||
public ShellCommandRule mDefaultLauncherRule =
|
||||
@@ -166,43 +162,18 @@ public abstract class AbstractLauncherUiTest {
|
||||
}
|
||||
} : base;
|
||||
|
||||
protected TestRule getRulesInsideActivityMonitor() {
|
||||
return new FailureWatcher(this);
|
||||
}
|
||||
|
||||
@Rule
|
||||
public TestWatcher mFailureWatcher = new TestWatcher() {
|
||||
private void dumpViewHierarchy() {
|
||||
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
try {
|
||||
mDevice.dumpWindowHierarchy(stream);
|
||||
stream.flush();
|
||||
stream.close();
|
||||
for (String line : stream.toString().split("\\r?\\n")) {
|
||||
Log.e(TAG, line.trim());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "error dumping XML to logcat", e);
|
||||
}
|
||||
}
|
||||
public TestRule mOrderSensitiveRules = RuleChain.
|
||||
outerRule(mActivityMonitor).
|
||||
around(getRulesInsideActivityMonitor());
|
||||
|
||||
@Override
|
||||
protected void failed(Throwable e, Description description) {
|
||||
if (mDevice == null) return;
|
||||
final String pathname = getInstrumentation().getTargetContext().
|
||||
getFilesDir().getPath() + "/TaplTestScreenshot" + sScreenshotCount++ + ".png";
|
||||
Log.e(TAG, "Failed test " + description.getMethodName() +
|
||||
", screenshot will be saved to " + pathname +
|
||||
", track trace is below, UI object dump is further below:\n" +
|
||||
Log.getStackTraceString(e));
|
||||
dumpViewHierarchy();
|
||||
|
||||
try {
|
||||
final String dumpsysResult = mDevice.executeShellCommand(
|
||||
"dumpsys activity service TouchInteractionService");
|
||||
Log.d(TAG, "TouchInteractionService: " + dumpsysResult);
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
|
||||
mDevice.takeScreenshot(new File(pathname));
|
||||
}
|
||||
};
|
||||
public UiDevice getDevice() {
|
||||
return mDevice;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.android.launcher3.util.rule;
|
||||
|
||||
import static androidx.test.InstrumentationRegistry.getInstrumentation;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.launcher3.ui.AbstractLauncherUiTest;
|
||||
|
||||
import org.junit.rules.TestWatcher;
|
||||
import org.junit.runner.Description;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class FailureWatcher extends TestWatcher {
|
||||
private static final String TAG = "FailureWatcher";
|
||||
private static int sScreenshotCount = 0;
|
||||
private AbstractLauncherUiTest mAbstractLauncherUiTest;
|
||||
|
||||
public FailureWatcher(AbstractLauncherUiTest abstractLauncherUiTest) {
|
||||
mAbstractLauncherUiTest = abstractLauncherUiTest;
|
||||
}
|
||||
|
||||
private void dumpViewHierarchy() {
|
||||
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
try {
|
||||
mAbstractLauncherUiTest.getDevice().dumpWindowHierarchy(stream);
|
||||
stream.flush();
|
||||
stream.close();
|
||||
for (String line : stream.toString().split("\\r?\\n")) {
|
||||
Log.e(TAG, line.trim());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "error dumping XML to logcat", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void failed(Throwable e, Description description) {
|
||||
if (mAbstractLauncherUiTest.getDevice() == null) return;
|
||||
final String pathname = getInstrumentation().getTargetContext().
|
||||
getFilesDir().getPath() + "/TaplTestScreenshot" + sScreenshotCount++ + ".png";
|
||||
Log.e(TAG, "Failed test " + description.getMethodName() +
|
||||
", screenshot will be saved to " + pathname +
|
||||
", track trace is below, UI object dump is further below:\n" +
|
||||
Log.getStackTraceString(e));
|
||||
dumpViewHierarchy();
|
||||
|
||||
try {
|
||||
final String dumpsysResult = mAbstractLauncherUiTest.getDevice().executeShellCommand(
|
||||
"dumpsys activity service TouchInteractionService");
|
||||
Log.d(TAG, "TouchInteractionService: " + dumpsysResult);
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
|
||||
mAbstractLauncherUiTest.getDevice().takeScreenshot(new File(pathname));
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,7 @@ public class Background extends LauncherInstrumentation.VisibleContainer {
|
||||
}
|
||||
|
||||
protected void goToOverviewUnchecked(int expectedState) {
|
||||
mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING);
|
||||
switch (mLauncher.getNavigationModel()) {
|
||||
case ZERO_BUTTON: {
|
||||
final int centerX = mLauncher.getDevice().getDisplayWidth() / 2;
|
||||
@@ -103,6 +104,7 @@ public class Background extends LauncherInstrumentation.VisibleContainer {
|
||||
mLauncher.waitForSystemUiObject("recent_apps").click();
|
||||
break;
|
||||
}
|
||||
mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING);
|
||||
}
|
||||
|
||||
protected String getSwipeHeightRequestName() {
|
||||
|
||||
Reference in New Issue
Block a user