Merge "add FeatureFlag type to the dump / also sort them" into ub-launcher3-rvc-dev
diff --git a/quickstep/recents_ui_overrides/res/layout/overview_panel.xml b/quickstep/recents_ui_overrides/res/layout/overview_panel.xml
index eac0bfa..fe57e9b 100644
--- a/quickstep/recents_ui_overrides/res/layout/overview_panel.xml
+++ b/quickstep/recents_ui_overrides/res/layout/overview_panel.xml
@@ -13,12 +13,20 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.quickstep.views.LauncherRecentsView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:accessibilityPaneTitle="@string/accessibility_recent_apps"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:theme="@style/HomeScreenElementTheme"
- android:visibility="invisible" />
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <com.android.quickstep.views.LauncherRecentsView
+ android:id="@+id/overview_panel"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:accessibilityPaneTitle="@string/accessibility_recent_apps"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:theme="@style/HomeScreenElementTheme"
+ android:visibility="invisible" />
+
+ <include
+ android:id="@+id/overview_actions_view"
+ layout="@layout/overview_actions_container" />
+
+</merge>
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 3d6e519..2f55fda 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -15,19 +15,14 @@
*/
package com.android.launcher3.uioverrides;
-import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
import static com.android.launcher3.LauncherState.OVERVIEW_BUTTONS;
-import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
import android.annotation.TargetApi;
import android.os.Build;
import android.util.FloatProperty;
-import android.view.View;
-import android.view.animation.Interpolator;
import androidx.annotation.NonNull;
@@ -37,6 +32,7 @@
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.util.MultiValueAlpha;
import com.android.quickstep.views.ClearAllButton;
import com.android.quickstep.views.LauncherRecentsView;
import com.android.quickstep.views.RecentsView;
@@ -60,7 +56,7 @@
mRecentsView.updateEmptyMessage();
mRecentsView.resetTaskVisuals();
}
- setAlphas(PropertySetter.NO_ANIM_PROPERTY_SETTER, state, LINEAR);
+ setAlphas(PropertySetter.NO_ANIM_PROPERTY_SETTER, state);
mRecentsView.setFullscreenProgress(state.getOverviewFullscreenProgress());
}
@@ -78,22 +74,17 @@
AnimationSuccessListener.forRunnable(mRecentsView::resetTaskVisuals));
}
- setAlphas(builder, toState,
- config.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
+ setAlphas(builder, toState);
builder.setFloat(mRecentsView, FULLSCREEN_PROGRESS,
toState.getOverviewFullscreenProgress(), LINEAR);
}
- private void setAlphas(PropertySetter propertySetter, LauncherState state,
- Interpolator actionInterpolator) {
+ private void setAlphas(PropertySetter propertySetter, LauncherState state) {
float buttonAlpha = (state.getVisibleElements(mLauncher) & OVERVIEW_BUTTONS) != 0 ? 1 : 0;
propertySetter.setFloat(mRecentsView.getClearAllButton(), ClearAllButton.VISIBILITY_ALPHA,
buttonAlpha, LINEAR);
-
- View actionsView = mLauncher.getActionsView();
- if (actionsView != null) {
- propertySetter.setFloat(actionsView, VIEW_ALPHA, buttonAlpha, actionInterpolator);
- }
+ propertySetter.setFloat(mLauncher.getActionsView().getVisibilityAlpha(),
+ MultiValueAlpha.VALUE, buttonAlpha, LINEAR);
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
index bcfb11c..fc28da3 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -144,7 +144,6 @@
@Override
public void onStateTransitionEnd(Launcher launcher) {
- launcher.getRotationHelper().setCurrentStateRequest(REQUEST_ROTATE);
DiscoveryBounce.showForOverviewIfNeeded(launcher);
RecentsView recentsView = launcher.getOverviewPanel();
AccessibilityManagerCompat.sendCustomAccessibilityEvent(
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
index 1b3610a..f6f892b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
@@ -24,6 +24,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.view.MotionEvent;
+import android.view.View;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
@@ -209,9 +210,11 @@
mPendingAnimation = mRecentsView.createTaskLaunchAnimation(
mTaskBeingDragged, maxDuration, Interpolators.ZOOM_IN);
- mTempCords[1] = mTaskBeingDragged.getHeight();
- dl.getDescendantCoordRelativeToSelf(mTaskBeingDragged, mTempCords);
- mEndDisplacement = dl.getHeight() - mTempCords[1];
+ // Since the thumbnail is what is filling the screen, based the end displacement on it.
+ View thumbnailView = mTaskBeingDragged.getThumbnail();
+ mTempCords[1] = orientationHandler.getSecondaryDimension(thumbnailView);
+ dl.getDescendantCoordRelativeToSelf(thumbnailView, mTempCords);
+ mEndDisplacement = secondaryLayerDimension - mTempCords[1];
}
mEndDisplacement *= verticalFactor;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index fadde37..3513ad5 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -31,7 +31,6 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
-import android.util.Log;
import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
@@ -46,7 +45,6 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.VibratorWrapper;
import com.android.launcher3.views.FloatingIconView;
@@ -133,8 +131,7 @@
mDeviceState = deviceState;
mGestureState = gestureState;
mActivityInterface = gestureState.getActivityInterface();
- mActivityInitListener =
- mActivityInterface.createActivityInitListener(this::onActivityInit);
+ mActivityInitListener = mActivityInterface.createActivityInitListener(this::onActivityInit);
mInputConsumer = inputConsumer;
mAppWindowAnimationHelper = new AppWindowAnimationHelper(context);
mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
@@ -325,13 +322,14 @@
mAppWindowAnimationHelper.updateHomeBounds(getStackBounds(dp));
}
int displayRotation = 0;
- if (mOrientedState != null) {
+ if (mOrientedState != null && !mOrientedState.areMultipleLayoutOrientationsDisabled()) {
// TODO(b/150300347): The first recents animation after launcher is started with the
// foreground app not in landscape will look funky until that bug is fixed
displayRotation = mOrientedState.getDisplayRotation();
RectF tempRectF = new RectF(TEMP_RECT);
- mOrientedState.mapRectFromNormalOrientation(tempRectF, dp.widthPx, dp.heightPx);
+ mOrientedState.mapRectFromRotation(displayRotation,
+ tempRectF, dp.widthPx, dp.heightPx);
tempRectF.roundOut(TEMP_RECT);
}
mAppWindowAnimationHelper.updateTargetRect(TEMP_RECT);
@@ -395,11 +393,15 @@
public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { }
- public void initWhenReady() {
+ /**
+ * Registers a callback to run when the activity is ready.
+ * @param intent The intent that will be used to start the activity if it doesn't exist already.
+ */
+ public void initWhenReady(Intent intent) {
// Preload the plan
RecentsModel.INSTANCE.get(mContext).getTasks(null);
- mActivityInitListener.register();
+ mActivityInitListener.register(intent);
}
/**
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java
index 46b026e..b4492d8 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -188,10 +188,10 @@
}
@Override
- public void initWhenReady() {
+ public void initWhenReady(Intent intent) {
if (mInQuickSwitchMode) {
// Only init if we are in quickswitch mode
- super.initWhenReady();
+ super.initWhenReady(intent);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/ImageActionsApi.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/ImageActionsApi.java
index 33fe5a9..fd17551 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/ImageActionsApi.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/ImageActionsApi.java
@@ -42,9 +42,10 @@
public class ImageActionsApi {
private static final String TAG = BuildConfig.APPLICATION_ID + "ImageActionsApi";
- private final Context mContext;
- private final Supplier<Bitmap> mBitmapSupplier;
- private final SystemUiProxy mSystemUiProxy;
+
+ protected final Context mContext;
+ protected final Supplier<Bitmap> mBitmapSupplier;
+ protected final SystemUiProxy mSystemUiProxy;
public ImageActionsApi(Context context, Supplier<Bitmap> bitmapSupplier) {
mContext = context;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
index 42d944f..52a2558 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
@@ -71,6 +71,7 @@
mRecentsRootView = findViewById(R.id.drag_layer);
mFallbackRecentsView = findViewById(R.id.overview_panel);
mRecentsRootView.recreateControllers();
+ mFallbackRecentsView.init(findViewById(R.id.overview_actions_view));
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
index fbf29af..147f933 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
@@ -16,7 +16,6 @@
package com.android.quickstep;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
import android.content.Context;
@@ -84,47 +83,47 @@
/**
* Overlay on each task handling Overview Action Buttons.
*/
- public static class TaskOverlay {
+ public static class TaskOverlay<T extends OverviewActionsView> {
private final Context mApplicationContext;
- private OverviewActionsView mActionsView;
- private final TaskThumbnailView mThumbnailView;
+ protected final TaskThumbnailView mThumbnailView;
+ private T mActionsView;
protected TaskOverlay(TaskThumbnailView taskThumbnailView) {
mApplicationContext = taskThumbnailView.getContext().getApplicationContext();
mThumbnailView = taskThumbnailView;
}
+ protected T getActionsView() {
+ if (mActionsView == null) {
+ mActionsView = BaseActivity.fromContext(mThumbnailView.getContext()).findViewById(
+ R.id.overview_actions_view);
+ }
+ return mActionsView;
+ }
+
/**
* Called when the current task is interactive for the user
*/
public void initOverlay(Task task, ThumbnailData thumbnail, Matrix matrix) {
ImageActionsApi imageApi = new ImageActionsApi(
mApplicationContext, mThumbnailView::getThumbnail);
+ getActionsView().setCallbacks(new OverlayUICallbacks() {
+ @Override
+ public void onShare() {
+ imageApi.startShareActivity();
+ }
- if (mActionsView == null && ENABLE_OVERVIEW_ACTIONS.get()
- && SysUINavigationMode.removeShelfFromOverview(mApplicationContext)) {
- mActionsView = BaseActivity.fromContext(mThumbnailView.getContext()).findViewById(
- R.id.overview_actions_view);
- }
- if (mActionsView != null) {
- mActionsView.setListener(new OverviewActionsView.Listener() {
- @Override
- public void onShare() {
- imageApi.startShareActivity();
- }
-
- @Override
- public void onScreenshot() {
- imageApi.saveScreenshot(mThumbnailView.getThumbnail(),
- getTaskSnapshotBounds(), getTaskSnapshotInsets(), task.key.id);
- }
- });
- }
-
+ @Override
+ public void onScreenshot() {
+ imageApi.saveScreenshot(mThumbnailView.getThumbnail(),
+ getTaskSnapshotBounds(), getTaskSnapshotInsets(), task.key.id);
+ }
+ });
}
+
/**
* Called when the overlay is no longer used.
*/
@@ -161,4 +160,16 @@
return Insets.of(0, 0, 0, 0);
}
}
+
+ /**
+ * Callbacks the Ui can generate. This is the only way for a Ui to call methods on the
+ * controller.
+ */
+ public interface OverlayUICallbacks {
+ /** User has indicated they want to share the current task. */
+ void onShare();
+
+ /** User has indicated they want to screenshot the current task. */
+ void onScreenshot();
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index 0fb51f3..0b5221e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -90,7 +90,6 @@
import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.InputMonitorCompat;
-import com.android.systemui.shared.system.RecentsAnimationListener;
import com.android.systemui.shared.tracing.ProtoTraceable;
import java.io.FileDescriptor;
@@ -739,12 +738,14 @@
final BaseActivityInterface<BaseDraggingActivity> activityInterface =
mOverviewComponentObserver.getActivityInterface();
+ final Intent overviewIntent = new Intent(
+ mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState());
if (activityInterface.getCreatedActivity() == null) {
// Make sure that UI states will be initialized.
activityInterface.createActivityInitListener((wasVisible) -> {
AppLaunchTracker.INSTANCE.get(TouchInteractionService.this);
return false;
- }).register();
+ }).register(overviewIntent);
} else if (fromInit) {
// The activity has been created before the initialization of overview service. It is
// usually happens when booting or launcher is the top activity, so we should already
@@ -752,8 +753,7 @@
return;
}
- mTaskAnimationManager.preloadRecentsAnimation(
- mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState());
+ mTaskAnimationManager.preloadRecentsAnimation(overviewIntent);
}
@Override
@@ -832,7 +832,7 @@
private BaseSwipeUpHandler createLauncherSwipeHandler(GestureState gestureState,
long touchTimeMs, boolean continuingLastGesture, boolean isLikelyToStartNewTask) {
- return new LauncherSwipeHandler(this, mDeviceState, mTaskAnimationManager,
+ return new LauncherSwipeHandler(this, mDeviceState, mTaskAnimationManager,
gestureState, touchTimeMs, continuingLastGesture, mInputConsumer);
}
@@ -858,11 +858,6 @@
}
}
- public static void startRecentsActivityAsync(Intent intent, RecentsAnimationListener listener) {
- UI_HELPER_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance()
- .startRecentsActivity(intent, null, listener, null, null));
- }
-
@Override
public void onPluginConnected(OverscrollPlugin overscrollPlugin, Context context) {
mOverscrollPlugin = overscrollPlugin;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
index dc0c194..6d1bf11 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -30,6 +30,7 @@
import com.android.launcher3.Utilities;
import com.android.quickstep.RecentsActivity;
import com.android.quickstep.util.LayoutUtils;
+import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task;
@@ -67,6 +68,11 @@
public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ public void init(OverviewActionsView actionsView) {
+ super.init(actionsView);
setOverviewStateEnabled(true);
setOverlayEnabled(true);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index fe9ef2b..1f6c506 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -333,7 +333,8 @@
mTaskAnimationManager.isRecentsAnimationRunning(), isLikelyToStartNewTask);
mInteractionHandler.setGestureEndCallback(this::onInteractionGestureFinished);
mMotionPauseDetector.setOnMotionPauseListener(mInteractionHandler::onMotionPauseChanged);
- mInteractionHandler.initWhenReady();
+ Intent intent = new Intent(mInteractionHandler.getLaunchIntent());
+ mInteractionHandler.initWhenReady(intent);
if (mTaskAnimationManager.isRecentsAnimationRunning()) {
mActiveCallbacks = mTaskAnimationManager.continueRecentsAnimation(mGestureState);
@@ -341,7 +342,6 @@
mTaskAnimationManager.notifyRecentsAnimationState(mInteractionHandler);
notifyGestureStarted();
} else {
- Intent intent = mInteractionHandler.getLaunchIntent();
intent.putExtra(INTENT_EXTRA_LOG_TRACE_ID, mGestureState.getGestureId());
mActiveCallbacks = mTaskAnimationManager.startRecentsAnimation(mGestureState, intent,
mInteractionHandler);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java
index 0a21413..c49b8f2 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java
@@ -36,17 +36,14 @@
import com.android.launcher3.R;
import com.android.quickstep.GestureState;
import com.android.quickstep.InputConsumer;
-import com.android.quickstep.views.LauncherRecentsView;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.plugins.OverscrollPlugin;
import com.android.systemui.shared.system.InputMonitorCompat;
/**
* Input consumer for handling events to pass to an {@code OverscrollPlugin}.
- *
- * @param <T> Draggable activity subclass used by RecentsView
*/
-public class OverscrollInputConsumer<T extends BaseDraggingActivity> extends DelegateInputConsumer {
+public class OverscrollInputConsumer extends DelegateInputConsumer {
private static final String TAG = "OverscrollInputConsumer";
@@ -61,12 +58,12 @@
private final float mSquaredSlop;
- private final Context mContext;
private final GestureState mGestureState;
@Nullable
private final OverscrollPlugin mPlugin;
private final GestureDetector mGestureDetector;
+ @Nullable
private RecentsView mRecentsView;
public OverscrollInputConsumer(Context context, GestureState gestureState,
@@ -77,7 +74,6 @@
.getInteger(R.integer.assistant_gesture_corner_deg_threshold);
mFlingThresholdPx = context.getResources()
.getDimension(R.dimen.gestures_overscroll_fling_threshold);
- mContext = context;
mGestureState = gestureState;
mPlugin = plugin;
@@ -85,9 +81,6 @@
mSquaredSlop = slop * slop;
mGestureDetector = new GestureDetector(context, new FlingGestureListener());
-
- gestureState.getActivityInterface().createActivityInitListener(this::onActivityInit)
- .register();
}
@Override
@@ -95,12 +88,6 @@
return TYPE_OVERSCROLL | mDelegate.getType();
}
- private boolean onActivityInit(Boolean alreadyOnHome) {
- mRecentsView = mGestureState.getActivityInterface().getCreatedActivity().getOverviewPanel();
-
- return true;
- }
-
@Override
public void onMotionEvent(MotionEvent ev) {
switch (ev.getActionMasked()) {
@@ -191,10 +178,17 @@
}
private boolean isOverscrolled() {
+ if (mRecentsView == null) {
+ BaseDraggingActivity activity = mGestureState.getActivityInterface()
+ .getCreatedActivity();
+ if (activity != null) {
+ mRecentsView = activity.getOverviewPanel();
+ }
+ }
+
// Make sure there isn't an app to quick switch to on our right
int maxIndex = 0;
- if ((mRecentsView instanceof LauncherRecentsView)
- && ((LauncherRecentsView) mRecentsView).hasRecentsExtraCard()) {
+ if (mRecentsView != null && mRecentsView.hasRecentsExtraCard()) {
maxIndex = 1;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
index 75a5976..b739838 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
@@ -160,9 +160,9 @@
}
private float getSrcToTargetScale() {
- if (mOrientedState == null ||
- (mOrientedState.getDisplayRotation() == Surface.ROTATION_0
- || mOrientedState.getDisplayRotation() == Surface.ROTATION_180)) {
+ if (mOrientedState == null
+ || mOrientedState.isHomeRotationAllowed()
+ || mOrientedState.isDisplayPhoneNatural()) {
return mSourceRect.width() / mTargetRect.width();
} else {
return mSourceRect.height() / mTargetRect.height();
@@ -277,8 +277,9 @@
mCurrentRect.offset(params.mOffset, 0);
} else {
int displayRotation = mOrientedState.getDisplayRotation();
+ int launcherRotation = mOrientedState.getLauncherRotation();
mOrientedState.getOrientationHandler().offsetTaskRect(mCurrentRect,
- params.mOffset, displayRotation);
+ params.mOffset, displayRotation, launcherRotation);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
index 9cf45b3..bde6f9a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_COMPONENTS;
+import static com.android.launcher3.states.StateAnimationConfig.SKIP_DEPTH_CONTROLLER;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
import android.animation.Animator;
@@ -146,7 +147,7 @@
*/
private void prepareToAnimate(Launcher launcher) {
StateAnimationConfig config = new StateAnimationConfig();
- config.animFlags = ANIM_ALL_COMPONENTS | SKIP_OVERVIEW;
+ config.animFlags = ANIM_ALL_COMPONENTS | SKIP_OVERVIEW | SKIP_DEPTH_CONTROLLER;
config.duration = 0;
// setRecentsAttachedToAppWindow() will animate recents out.
launcher.getStateManager().createAtomicAnimation(BACKGROUND_APP, NORMAL, config).start();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index 98eb29a..78d75c5 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -47,7 +47,6 @@
import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statehandlers.DepthController;
-import com.android.launcher3.states.RotationHelper;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.views.ScrimView;
@@ -88,10 +87,6 @@
}
};
- private RotationHelper.ForcedRotationChangedListener mForcedRotationChangedListener =
- isForcedRotation -> LauncherRecentsView.this
- .disableMultipleLayoutRotations(!isForcedRotation);
-
public LauncherRecentsView(Context context) {
this(context, null);
}
@@ -102,11 +97,16 @@
public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- setContentAlpha(0);
mActivity.getStateManager().addStateListener(this);
}
@Override
+ public void init(OverviewActionsView actionsView) {
+ super.init(actionsView);
+ setContentAlpha(0);
+ }
+
+ @Override
public void startHome() {
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
switchToScreenshot(null,
@@ -344,7 +344,6 @@
super.onAttachedToWindow();
PluginManagerWrapper.INSTANCE.get(getContext()).addPluginListener(
mRecentsExtraCardPluginListener, RecentsExtraCard.class);
- mActivity.getRotationHelper().addForcedRotationCallback(mForcedRotationChangedListener);
}
@Override
@@ -352,7 +351,6 @@
super.onDetachedFromWindow();
PluginManagerWrapper.INSTANCE.get(getContext()).removePluginListener(
mRecentsExtraCardPluginListener);
- mActivity.getRotationHelper().removeForcedRotationCallback(mForcedRotationChangedListener);
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java
index 6a37e2b..93e68c0 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java
@@ -16,34 +16,59 @@
package com.android.quickstep.views;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
+import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
+
import android.content.Context;
import android.util.AttributeSet;
-import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
import android.widget.FrameLayout;
+import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import com.android.launcher3.R;
+import com.android.launcher3.util.MultiValueAlpha;
+import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
+import com.android.quickstep.TaskOverlayFactory.OverlayUICallbacks;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/**
* View for showing action buttons in Overview
*/
-public class OverviewActionsView extends FrameLayout {
+public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayout
+ implements OnClickListener {
- private final View mScreenshotButton;
- private final View mShareButton;
+ @IntDef(flag = true, value = {
+ HIDDEN_UNSUPPORTED_NAVIGATION,
+ HIDDEN_DISABLED_FEATURE,
+ HIDDEN_NON_ZERO_ROTATION,
+ HIDDEN_NO_TASKS,
+ HIDDEN_GESTURE_RUNNING,
+ HIDDEN_NO_RECENTS})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ActionsHiddenFlags { }
- /**
- * Listener for taps on the various actions.
- */
- public interface Listener {
- /** User has initiated the share actions. */
- void onShare();
+ public static final int HIDDEN_UNSUPPORTED_NAVIGATION = 1 << 0;
+ public static final int HIDDEN_DISABLED_FEATURE = 1 << 1;
+ public static final int HIDDEN_NON_ZERO_ROTATION = 1 << 2;
+ public static final int HIDDEN_NO_TASKS = 1 << 3;
+ public static final int HIDDEN_GESTURE_RUNNING = 1 << 4;
+ public static final int HIDDEN_NO_RECENTS = 1 << 5;
- /** User has initiated the screenshot action. */
- void onScreenshot();
- }
+ private static final int INDEX_CONTENT_ALPHA = 0;
+ private static final int INDEX_VISIBILITY_ALPHA = 1;
+ private static final int INDEX_HIDDEN_FLAGS_ALPHA = 2;
+
+ private final MultiValueAlpha mMultiValueAlpha;
+
+ @ActionsHiddenFlags
+ private int mHiddenFlags;
+
+ protected T mCallbacks;
public OverviewActionsView(Context context) {
this(context, null);
@@ -54,26 +79,62 @@
}
public OverviewActionsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
+ super(context, attrs, defStyleAttr, 0);
+ mMultiValueAlpha = new MultiValueAlpha(this, 3);
}
- public OverviewActionsView(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- LayoutInflater.from(context).inflate(R.layout.overview_actions, this, true);
- mShareButton = findViewById(R.id.action_share);
- mScreenshotButton = findViewById(R.id.action_screenshot);
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ findViewById(R.id.action_share).setOnClickListener(this);
+ findViewById(R.id.action_screenshot).setOnClickListener(this);
}
/**
* Set listener for callbacks on action button taps.
*
- * @param listener for callbacks, or {@code null} to clear the listener.
+ * @param callbacks for callbacks, or {@code null} to clear the listener.
*/
- public void setListener(@Nullable OverviewActionsView.Listener listener) {
- mShareButton.setOnClickListener(
- listener == null ? null : view -> listener.onShare());
- mScreenshotButton.setOnClickListener(
- listener == null ? null : view -> listener.onScreenshot());
+ public void setCallbacks(T callbacks) {
+ mCallbacks = callbacks;
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (mCallbacks == null) {
+ return;
+ }
+ int id = view.getId();
+ if (id == R.id.action_share) {
+ mCallbacks.onShare();
+ } else if (id == R.id.action_screenshot) {
+ mCallbacks.onScreenshot();
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ updateHiddenFlags(HIDDEN_DISABLED_FEATURE, !ENABLE_OVERVIEW_ACTIONS.get());
+ updateHiddenFlags(HIDDEN_UNSUPPORTED_NAVIGATION, !removeShelfFromOverview(getContext()));
+ }
+
+ public void updateHiddenFlags(@ActionsHiddenFlags int visibilityFlags, boolean enable) {
+ if (enable) {
+ mHiddenFlags |= visibilityFlags;
+ } else {
+ mHiddenFlags &= ~visibilityFlags;
+ }
+ boolean isHidden = mHiddenFlags != 0;
+ mMultiValueAlpha.getProperty(INDEX_HIDDEN_FLAGS_ALPHA).setValue(isHidden ? 0 : 1);
+ setVisibility(isHidden ? INVISIBLE : VISIBLE);
+ }
+
+ public AlphaProperty getContentAlpha() {
+ return mMultiValueAlpha.getProperty(INDEX_CONTENT_ALPHA);
+ }
+
+ public AlphaProperty getVisibilityAlpha() {
+ return mMultiValueAlpha.getProperty(INDEX_VISIBILITY_ALPHA);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index a18f7ba..24eae18 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -28,7 +28,6 @@
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.TASK_DISMISS_SWIPE_UP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.TASK_LAUNCH_SWIPE_DOWN;
@@ -39,6 +38,10 @@
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
+import static com.android.quickstep.views.OverviewActionsView.HIDDEN_GESTURE_RUNNING;
+import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION;
+import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS;
+import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
import android.animation.AnimatorSet;
import android.animation.LayoutTransition;
@@ -50,6 +53,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
@@ -66,12 +70,12 @@
import android.util.FloatProperty;
import android.util.Property;
import android.util.SparseBooleanArray;
-import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.OrientationEventListener;
+import android.view.Surface;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
@@ -85,7 +89,6 @@
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
-import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherState;
import com.android.launcher3.PagedView;
@@ -115,7 +118,6 @@
import com.android.quickstep.RecentsAnimationTargets;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.RecentsModel.TaskVisualsChangeListener;
-import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskThumbnailCache;
import com.android.quickstep.TaskUtils;
@@ -128,6 +130,7 @@
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.ConfigurationCompat;
import com.android.systemui.shared.system.LauncherEventUtil;
import com.android.systemui.shared.system.PackageManagerWrapper;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
@@ -172,7 +175,7 @@
}
};
- protected final RecentsOrientedState mOrientationState = new RecentsOrientedState();
+ protected RecentsOrientedState mOrientationState;
private OrientationEventListener mOrientationListener;
private int mPreviousRotation;
@@ -328,8 +331,7 @@
// Keeps track of the index where the first TaskView should be
private int mTaskViewStartIndex = 0;
- private View mActionsView;
- private boolean mGestureRunning = false;
+ private OverviewActionsView mActionsView;
private BaseActivity.MultiWindowModeChangedListener mMultiWindowModeChangedListener =
(inMultiWindowMode) -> {
@@ -343,6 +345,7 @@
super(context, attrs, defStyleAttr);
setPageSpacing(getResources().getDimensionPixelSize(R.dimen.recents_page_spacing));
setEnableFreeScroll(true);
+ mOrientationState = new RecentsOrientedState(context);
mFastFlingVelocity = getResources()
.getDimensionPixelSize(R.dimen.recents_fast_fling_velocity);
@@ -389,11 +392,6 @@
int rotation = RecentsOrientedState.getRotationForUserDegreesRotated(i);
if (mPreviousRotation != rotation) {
animateRecentsRotationInPlace(rotation);
- if (rotation == 0) {
- showActionsView();
- } else {
- hideActionsView();
- }
mPreviousRotation = rotation;
}
}
@@ -468,6 +466,10 @@
reset();
}
+ public void init(OverviewActionsView actionsView) {
+ mActionsView = actionsView;
+ }
+
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@@ -481,7 +483,7 @@
mIPinnedStackAnimationListener.setActivity(mActivity);
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(
mIPinnedStackAnimationListener);
- setActionsView();
+ mOrientationState.init();
}
@Override
@@ -496,6 +498,7 @@
mIdp.removeOnChangeListener(this);
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null);
mIPinnedStackAnimationListener.setActivity(null);
+ mOrientationState.destroy();
}
@Override
@@ -507,6 +510,7 @@
TaskView taskView = (TaskView) child;
mHasVisibleTaskData.delete(taskView.getTask().key.id);
mTaskViewPool.recycle(taskView);
+ mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, getTaskViewCount() == 0);
}
updateTaskStartIndex(child);
}
@@ -519,6 +523,7 @@
// child direction back to match system settings.
child.setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_LTR : View.LAYOUT_DIRECTION_RTL);
updateTaskStartIndex(child);
+ mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, false);
}
private void updateTaskStartIndex(View affectingView) {
@@ -549,9 +554,7 @@
}
public void setOverviewStateEnabled(boolean enabled) {
- if (supportsVerticalLandscape()
- && !TestProtocol.sDisableSensorRotation // Ignore hardware dependency for tests
- && mOrientationListener.canDetectOrientation()) {
+ if (canEnableOverviewRotationAnimation()) {
if (enabled) {
mOrientationListener.enable();
} else {
@@ -567,6 +570,13 @@
}
}
+ private boolean canEnableOverviewRotationAnimation() {
+ return supportsVerticalLandscape() // not 3P launcher
+ && !TestProtocol.sDisableSensorRotation // Ignore hardware dependency for tests..
+ && mOrientationListener.canDetectOrientation() // ..but does the hardware even work?
+ && !mOrientationState.canLauncherAutoRotate(); // launcher is going to rotate itself
+ }
+
public void onDigitalWellbeingToastShown() {
if (!mDwbToastShown) {
mDwbToastShown = true;
@@ -585,6 +595,15 @@
}
@Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ int windowConfigurationRotation = ConfigurationCompat
+ .getWindowConfigurationRotation(getResources().getConfiguration());
+ setLayoutInternal(mOrientationState.getTouchRotation(),
+ mOrientationState.getDisplayRotation(), windowConfigurationRotation);
+ }
+
+ @Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
final int x = (int) ev.getX();
@@ -668,7 +687,6 @@
if (getTaskViewCount() != requiredTaskCount) {
if (indexOfChild(mClearAllButton) != -1) {
removeView(mClearAllButton);
- hideActionsView();
}
for (int i = getTaskViewCount(); i < requiredTaskCount; i++) {
addView(mTaskViewPool.getView());
@@ -678,7 +696,6 @@
}
if (requiredTaskCount > 0) {
addView(mClearAllButton);
- showActionsView();
}
}
@@ -718,7 +735,6 @@
if (indexOfChild(mClearAllButton) != -1) {
removeView(mClearAllButton);
}
- hideActionsView();
}
public int getTaskViewCount() {
@@ -778,7 +794,7 @@
for (int i = 0; i < taskCount; i++) {
getTaskViewAt(i).setFullscreenProgress(mFullscreenProgress);
}
- if (mActionsView != null) {
+ if (mActionsView != null && mOrientationState.getLauncherRotation() == Surface.ROTATION_0) {
mActionsView.setVisibility(fullscreenProgress == 0 ? VISIBLE : INVISIBLE);
}
}
@@ -980,7 +996,7 @@
setEnableDrawingLiveTile(false);
setRunningTaskHidden(true);
setRunningTaskIconScaledDown(true);
- mGestureRunning = true;
+ mActionsView.updateHiddenFlags(HIDDEN_GESTURE_RUNNING, true);
}
/**
@@ -1046,7 +1062,7 @@
}
setRunningTaskHidden(false);
animateUpRunningTaskIconScale();
- mGestureRunning = false;
+ mActionsView.updateHiddenFlags(HIDDEN_GESTURE_RUNNING, false);
}
/**
@@ -1063,7 +1079,6 @@
addView(taskView, mTaskViewStartIndex);
if (wasEmpty) {
addView(mClearAllButton);
- showActionsView();
}
// The temporary running task is only used for the duration between the start of the
// gesture and the task list is loaded and applied
@@ -1387,7 +1402,6 @@
if (getTaskViewCount() == 0) {
removeViewInLayout(mClearAllButton);
- hideActionsView();
startHome();
} else {
snapToPageImmediately(pageToSnapTo);
@@ -1530,14 +1544,12 @@
int alphaInt = Math.round(alpha * 255);
mEmptyMessagePaint.setAlpha(alphaInt);
mEmptyIcon.setAlpha(alphaInt);
+ mActionsView.getContentAlpha().setValue(mContentAlpha);
+
if (alpha > 0) {
setVisibility(VISIBLE);
- if (!mGestureRunning) {
- showActionsView();
- }
} else if (!mFreezeViewVisibility) {
setVisibility(GONE);
- hideActionsView();
}
}
@@ -1548,24 +1560,33 @@
public void setFreezeViewVisibility(boolean freezeViewVisibility) {
if (mFreezeViewVisibility != freezeViewVisibility) {
mFreezeViewVisibility = freezeViewVisibility;
-
if (!mFreezeViewVisibility) {
setVisibility(mContentAlpha > 0 ? VISIBLE : GONE);
- if (mContentAlpha > 0) {
- showActionsView();
- } else {
- hideActionsView();
- }
}
}
}
+ @Override
+ public void setVisibility(int visibility) {
+ super.setVisibility(visibility);
+ if (mActionsView != null) {
+ mActionsView.updateHiddenFlags(HIDDEN_NO_RECENTS, visibility != VISIBLE);
+ }
+ }
+
public void setLayoutRotation(int touchRotation, int displayRotation) {
- if (mOrientationState.update(touchRotation, displayRotation)) {
+ int launcherRotation = mOrientationState.getLauncherRotation();
+ setLayoutInternal(touchRotation, displayRotation, launcherRotation);
+ }
+
+ private void setLayoutInternal(int touchRotation, int displayRotation, int launcherRotation) {
+ if (mOrientationState.update(touchRotation, displayRotation, launcherRotation)) {
mOrientationHandler = mOrientationState.getOrientationHandler();
mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources());
setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
mClearAllButton.setRotation(mOrientationHandler.getDegreesRotated());
+ mActivity.getDragLayer().recreateControllers();
+ mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION, touchRotation != 0);
requestLayout();
}
}
@@ -2022,7 +2043,8 @@
public Consumer<MotionEvent> getEventDispatcher(float navbarRotation) {
float degreesRotated;
if (navbarRotation == 0) {
- degreesRotated = mOrientationState.getTouchRotationDegrees();
+ degreesRotated = mOrientationState.areMultipleLayoutOrientationsDisabled() ? 0 :
+ mOrientationHandler.getDegreesRotated();
} else {
degreesRotated = -navbarRotation;
}
@@ -2035,7 +2057,8 @@
// PagedOrientationHandler
return e -> {
if (navbarRotation != 0
- && !mOrientationState.areMultipleLayoutOrientationsDisabled()) {
+ && !mOrientationState.areMultipleLayoutOrientationsDisabled()
+ && !mOrientationState.getOrientationHandler().isLayoutNaturalToLauncher()) {
mOrientationState.flipVertical(e);
super.onTouchEvent(e);
mOrientationState.flipVertical(e);
@@ -2122,36 +2145,4 @@
mActivity.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
}
}
-
- private void showActionsView() {
- if (mActionsView != null && getTaskViewCount() > 0) {
- mActionsView.setVisibility(VISIBLE);
- }
- }
-
- private void hideActionsView() {
- if (mActionsView != null) {
- mActionsView.setVisibility(GONE);
- }
- }
-
- private void setActionsView() {
- if (mActionsView == null && ENABLE_OVERVIEW_ACTIONS.get()
- && SysUINavigationMode.removeShelfFromOverview(mActivity)) {
- mActionsView = ((ViewGroup) getParent()).findViewById(R.id.overview_actions_view);
- if (mActionsView != null) {
- InsettableFrameLayout.LayoutParams layoutParams =
- new InsettableFrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
- getResources().getDimensionPixelSize(
- R.dimen.overview_actions_height));
- layoutParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
- int margin = getResources().getDimensionPixelSize(
- R.dimen.overview_actions_horizontal_margin);
- layoutParams.setMarginStart(margin);
- layoutParams.setMarginEnd(margin);
- mActionsView.setLayoutParams(layoutParams);
- showActionsView();
- }
- }
- }
}
diff --git a/quickstep/res/drawable/home_gesture.xml b/quickstep/res/drawable/home_gesture.xml
new file mode 100644
index 0000000..c253b7e
--- /dev/null
+++ b/quickstep/res/drawable/home_gesture.xml
@@ -0,0 +1,46 @@
+<!--
+ Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- Dummy translating rectangle until we have a proper animation. -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt" >
+ <aapt:attr name="android:drawable">
+ <vector
+ android:height="64dp"
+ android:width="64dp"
+ android:viewportHeight="600"
+ android:viewportWidth="600" >
+ <group
+ android:name="translationGroup"
+ android:pivotX="300.0"
+ android:pivotY="300.0"
+ android:rotation="180.0" >
+ <path
+ android:fillColor="#eeeeee"
+ android:pathData="M300,70 l 0,-70 70,0 0,140 -70,0 z" />
+ </group>
+ </vector>
+ </aapt:attr>
+
+ <target android:name="translationGroup">
+ <aapt:attr name="android:animation">
+ <objectAnimator
+ android:duration="3000"
+ android:propertyName="translateY"
+ android:valueFrom="0"
+ android:valueTo="-100" />
+ </aapt:attr>
+ </target>
+</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_fragment.xml b/quickstep/res/layout/gesture_tutorial_fragment.xml
index 0bc062a..69481ad 100644
--- a/quickstep/res/layout/gesture_tutorial_fragment.xml
+++ b/quickstep/res/layout/gesture_tutorial_fragment.xml
@@ -39,79 +39,58 @@
android:src="@drawable/gesture_tutorial_close_button"/>
<LinearLayout
+ android:id="@+id/gesture_tutorial_fragment_titles_container"
android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:layout_marginTop="70dp"
+ android:layout_alignParentTop="true"
+ android:focusable="true"
+ android:gravity="center_horizontal"
android:orientation="vertical">
- <LinearLayout
- android:id="@+id/gesture_tutorial_fragment_titles_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:focusable="true">
-
- <TextView
- android:id="@+id/gesture_tutorial_fragment_title_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginStart="@dimen/gesture_tutorial_title_margin_start_end"
- android:layout_marginEnd="@dimen/gesture_tutorial_title_margin_start_end"
- style="@style/TextAppearance.BackGestureTutorial.Title"/>
-
- <TextView
- android:id="@+id/gesture_tutorial_fragment_subtitle_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="10dp"
- android:layout_marginStart="@dimen/gesture_tutorial_subtitle_margin_start_end"
- android:layout_marginEnd="@dimen/gesture_tutorial_subtitle_margin_start_end"
- style="@style/TextAppearance.BackGestureTutorial.Subtitle"/>
-
- </LinearLayout>
-
- <Space
+ <TextView
+ android:id="@+id/gesture_tutorial_fragment_title_view"
android:layout_width="wrap_content"
- android:layout_weight="1"
- android:layout_height="0dp"
- android:layout_marginTop="48dp"
- android:layout_gravity="center_horizontal"
- android:gravity="center_horizontal"
- android:orientation="vertical"/>
-
- <!-- android:stateListAnimator="@null" removes shadow and normal on click behavior (increase
- of elevation and shadow) which is replaced by ripple effect in android:foreground -->
- <RelativeLayout
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="46dp"
- android:layout_marginBottom="48dp"
- android:layout_gravity="center_horizontal">
+ android:layout_marginStart="@dimen/gesture_tutorial_title_margin_start_end"
+ android:layout_marginEnd="@dimen/gesture_tutorial_title_margin_start_end"
+ style="@style/TextAppearance.GestureTutorial.Title"/>
- <Button
- android:id="@+id/gesture_tutorial_fragment_action_button"
- android:layout_width="142dp"
- android:layout_height="49dp"
- android:layout_marginEnd="@dimen/gesture_tutorial_button_margin_start_end"
- android:layout_alignParentEnd="true"
- android:stateListAnimator="@null"
- android:background="@drawable/gesture_tutorial_action_button_background"
- android:foreground="?android:attr/selectableItemBackgroundBorderless"
- style="@style/TextAppearance.BackGestureTutorial.ButtonLabel"/>
-
- <Button
- android:id="@+id/gesture_tutorial_fragment_action_text_button"
- android:layout_width="142dp"
- android:layout_height="49dp"
- android:layout_marginStart="@dimen/gesture_tutorial_button_margin_start_end"
- android:layout_alignParentStart="true"
- android:stateListAnimator="@null"
- android:background="@null"
- android:foreground="?android:attr/selectableItemBackgroundBorderless"
- style="@style/TextAppearance.BackGestureTutorial.TextButtonLabel"/>
-
- </RelativeLayout>
+ <TextView
+ android:id="@+id/gesture_tutorial_fragment_subtitle_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
+ android:layout_marginStart="@dimen/gesture_tutorial_subtitle_margin_start_end"
+ android:layout_marginEnd="@dimen/gesture_tutorial_subtitle_margin_start_end"
+ style="@style/TextAppearance.GestureTutorial.Subtitle"/>
</LinearLayout>
+
+ <!-- android:stateListAnimator="@null" removes shadow and normal on click behavior (increase
+ of elevation and shadow) which is replaced by ripple effect in android:foreground -->
+ <Button
+ android:id="@+id/gesture_tutorial_fragment_action_button"
+ android:layout_width="142dp"
+ android:layout_height="49dp"
+ android:layout_marginEnd="@dimen/gesture_tutorial_button_margin_start_end"
+ android:layout_marginBottom="48dp"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentBottom="true"
+ android:stateListAnimator="@null"
+ android:background="@drawable/gesture_tutorial_action_button_background"
+ android:foreground="?android:attr/selectableItemBackgroundBorderless"
+ style="@style/TextAppearance.GestureTutorial.ButtonLabel"/>
+
+ <Button
+ android:id="@+id/gesture_tutorial_fragment_action_text_button"
+ android:layout_width="142dp"
+ android:layout_height="49dp"
+ android:layout_marginStart="@dimen/gesture_tutorial_button_margin_start_end"
+ android:layout_marginBottom="48dp"
+ android:layout_alignParentStart="true"
+ android:layout_alignParentBottom="true"
+ android:stateListAnimator="@null"
+ android:background="@null"
+ android:foreground="?android:attr/selectableItemBackgroundBorderless"
+ style="@style/TextAppearance.GestureTutorial.TextButtonLabel"/>
</RelativeLayout>
\ No newline at end of file
diff --git a/quickstep/res/layout/overview_actions.xml b/quickstep/res/layout/overview_actions.xml
deleted file mode 100644
index ad5efb6..0000000
--- a/quickstep/res/layout/overview_actions.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <LinearLayout
- android:id="@+id/action_buttons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:orientation="horizontal">
- <Space
- android:layout_width="0dp"
- android:layout_height="1dp"
- android:layout_weight="1" >
- </Space>
- <Button
- android:id="@+id/action_screenshot"
- style="@style/OverviewActionButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableTop="@drawable/ic_screenshot"
- android:text="@string/action_screenshot" />
- <Space
- android:layout_width="0dp"
- android:layout_height="1dp"
- android:layout_weight="1" >
- </Space>
-
- <Button
- android:id="@+id/action_share"
- style="@style/OverviewActionButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableTop="@drawable/ic_share"
- android:text="@string/action_share" />
- <Space
- android:layout_width="0dp"
- android:layout_height="1dp"
- android:layout_weight="1" >
- </Space>
- </LinearLayout>
-
-</merge>
diff --git a/quickstep/res/layout/overview_actions_container.xml b/quickstep/res/layout/overview_actions_container.xml
index 328c20b..e163991 100644
--- a/quickstep/res/layout/overview_actions_container.xml
+++ b/quickstep/res/layout/overview_actions_container.xml
@@ -16,8 +16,48 @@
-->
<com.android.quickstep.views.OverviewActionsView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:visibility="gone">
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/overview_actions_height"
+ android:layout_gravity="center_horizontal|bottom"
+ android:layout_marginLeft="@dimen/overview_actions_horizontal_margin"
+ android:layout_marginRight="@dimen/overview_actions_horizontal_margin" >
+
+ <LinearLayout
+ android:id="@+id/action_buttons"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="horizontal">
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="1dp"
+ android:layout_weight="1" >
+ </Space>
+ <Button
+ android:id="@+id/action_screenshot"
+ style="@style/OverviewActionButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:drawableTop="@drawable/ic_screenshot"
+ android:text="@string/action_screenshot" />
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="1dp"
+ android:layout_weight="1" >
+ </Space>
+
+ <Button
+ android:id="@+id/action_share"
+ style="@style/OverviewActionButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:drawableTop="@drawable/ic_share"
+ android:text="@string/action_share" />
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="1dp"
+ android:layout_weight="1" >
+ </Space>
+ </LinearLayout>
</com.android.quickstep.views.OverviewActionsView>
\ No newline at end of file
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index d7c976d..61690ae 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -104,11 +104,17 @@
<!-- Subtitle shown during interactive parts of Back gesture tutorial for left edge. [CHAR LIMIT=60] -->
<string name="back_gesture_tutorial_engaged_subtitle_swipe_inward_left_edge" translatable="false">That\'s it! Now try swiping from the left edge.</string>
- <!-- Title shown on the confirmation screen after successful gesture. [CHAR LIMIT=30] -->
- <string name="back_gesture_tutorial_confirm_title" translatable="false">All set</string>
<!-- Subtitle shown on the confirmation screen after successful gesture. [CHAR LIMIT=60] -->
<string name="back_gesture_tutorial_confirm_subtitle" translatable="false">To change the sensitivity of the back gesture, go to Settings</string>
+
+ <!-- Title shown during interactive part of Home gesture tutorial. [CHAR LIMIT=30] -->
+ <string name="home_gesture_tutorial_playground_title" translatable="false">Tutorial: Go Home</string>
+ <!-- Subtitle shown during interactive parts of Home gesture tutorial. [CHAR LIMIT=60] -->
+ <string name="home_gesture_tutorial_playground_subtitle" translatable="false">Try swiping upward from the bottom edge of the screen</string>
+
+ <!-- Title shown on the confirmation screen after successful gesture. [CHAR LIMIT=30] -->
+ <string name="gesture_tutorial_confirm_title" translatable="false">All set</string>
<!-- Button text shown on a button on the confirm screen. [CHAR LIMIT=14] -->
<string name="gesture_tutorial_action_button_label" translatable="false">Done</string>
<!-- Button text shown on a text button on the confirm screen. [CHAR LIMIT=14] -->
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 14e054e..4915f5f 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -26,29 +26,29 @@
<item name="android:layout_height">wrap_content</item>
</style>
- <style name="TextAppearance.BackGestureTutorial"
+ <style name="TextAppearance.GestureTutorial"
parent="android:TextAppearance.Material.Body1" />
- <style name="TextAppearance.BackGestureTutorial.CallToAction"
+ <style name="TextAppearance.GestureTutorial.CallToAction"
parent="android:TextAppearance.Material.Body2" />
- <style name="TextAppearance.BackGestureTutorial.Title"
- parent="TextAppearance.BackGestureTutorial">
+ <style name="TextAppearance.GestureTutorial.Title"
+ parent="TextAppearance.GestureTutorial">
<item name="android:gravity">center</item>
<item name="android:textColor">@color/gesture_tutorial_title_color</item>
<item name="android:textSize">28sp</item>
</style>
- <style name="TextAppearance.BackGestureTutorial.Subtitle"
- parent="TextAppearance.BackGestureTutorial">
+ <style name="TextAppearance.GestureTutorial.Subtitle"
+ parent="TextAppearance.GestureTutorial">
<item name="android:gravity">center</item>
<item name="android:textColor">@color/gesture_tutorial_subtitle_color</item>
<item name="android:letterSpacing">0.03</item>
<item name="android:textSize">21sp</item>
</style>
- <style name="TextAppearance.BackGestureTutorial.ButtonLabel"
- parent="TextAppearance.BackGestureTutorial.CallToAction">
+ <style name="TextAppearance.GestureTutorial.ButtonLabel"
+ parent="TextAppearance.GestureTutorial.CallToAction">
<item name="android:gravity">center</item>
<item name="android:textColor">@color/gesture_tutorial_action_button_label_color</item>
<item name="android:letterSpacing">0.02</item>
@@ -56,8 +56,8 @@
<item name="android:textAllCaps">false</item>
</style>
- <style name="TextAppearance.BackGestureTutorial.TextButtonLabel"
- parent="TextAppearance.BackGestureTutorial.ButtonLabel">
+ <style name="TextAppearance.GestureTutorial.TextButtonLabel"
+ parent="TextAppearance.GestureTutorial.ButtonLabel">
<item name="android:textColor">@color/gesture_tutorial_primary_color</item>
</style>
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 48e25bd..b7abd61 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -28,7 +28,6 @@
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.CancellationSignal;
-import android.view.View;
import com.android.launcher3.LauncherState.ScaleAndTranslation;
import com.android.launcher3.LauncherStateManager.StateHandler;
@@ -52,6 +51,7 @@
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.util.RemoteFadeOutAnimationListener;
import com.android.quickstep.util.ShelfPeekAnim;
+import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -75,7 +75,7 @@
private final ShelfPeekAnim mShelfPeekAnim = new ShelfPeekAnim(this);
- private View mActionsView;
+ private OverviewActionsView mActionsView;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -164,19 +164,17 @@
protected void setupViews() {
super.setupViews();
mActionsView = findViewById(R.id.overview_actions_view);
-
+ ((RecentsView) getOverviewPanel()).init(mActionsView);
if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(this)) {
// Overview is above all other launcher elements, including qsb, so move it to the top.
getOverviewPanel().bringToFront();
- if (mActionsView != null) {
- mActionsView.bringToFront();
- }
+ mActionsView.bringToFront();
}
}
- public View getActionsView() {
- return mActionsView;
+ public <T extends OverviewActionsView> T getActionsView() {
+ return (T) mActionsView;
}
@Override
diff --git a/quickstep/src/com/android/launcher3/LauncherInitListener.java b/quickstep/src/com/android/launcher3/LauncherInitListener.java
index fbd7a8a..7fb0d43 100644
--- a/quickstep/src/com/android/launcher3/LauncherInitListener.java
+++ b/quickstep/src/com/android/launcher3/LauncherInitListener.java
@@ -23,7 +23,6 @@
import android.os.CancellationSignal;
import android.os.Handler;
-import com.android.launcher3.util.ActivityTracker;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -45,7 +44,7 @@
}
@Override
- public boolean init(Launcher launcher, boolean alreadyOnHome) {
+ public boolean handleInit(Launcher launcher, boolean alreadyOnHome) {
if (mRemoteAnimationProvider != null) {
QuickstepAppTransitionManagerImpl appTransitionManager =
(QuickstepAppTransitionManagerImpl) launcher.getAppTransitionManager();
@@ -71,7 +70,7 @@
}, cancellationSignal);
}
launcher.deferOverlayCallbacksUntilNextResumeOrStop();
- return super.init(launcher, alreadyOnHome);
+ return super.handleInit(launcher, alreadyOnHome);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index a30e102..70cbd82 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -291,6 +291,15 @@
launcherContentAnimator.second.run();
}
});
+ } else {
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mLauncher.addOnResumeCallback(() ->
+ ObjectAnimator.ofFloat(mLauncher.getDepthController(), DEPTH,
+ mLauncher.getStateManager().getState().getDepth(mLauncher)).start());
+ }
+ });
}
}
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index 24ba89a..f83737e 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -17,6 +17,7 @@
package com.android.launcher3.statehandlers;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.states.StateAnimationConfig.SKIP_DEPTH_CONTROLLER;
import android.os.IBinder;
import android.util.FloatProperty;
@@ -163,7 +164,9 @@
@Override
public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
PendingAnimation animation) {
- if (mSurface == null || config.onlyPlayAtomicComponent()) {
+ if (mSurface == null
+ || config.onlyPlayAtomicComponent()
+ || config.hasAnimationFlag(SKIP_DEPTH_CONTROLLER)) {
return;
}
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index 495c092..2e99500 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -22,6 +22,7 @@
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_UP;
+import static com.android.launcher3.states.RotationHelper.deltaRotation;
import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
import android.content.res.Resources;
@@ -138,7 +139,8 @@
* @param info The current displayInfo
*/
void enableMultipleRegions(boolean enableMultipleRegions, DefaultDisplay.Info info) {
- mEnableMultipleRegions = enableMultipleRegions;
+ mEnableMultipleRegions = enableMultipleRegions &&
+ mMode != SysUINavigationMode.Mode.TWO_BUTTONS;
if (!enableMultipleRegions) {
mQuickStepStartingRotation = -1;
resetSwipeRegions(info);
@@ -364,16 +366,4 @@
return false;
}
}
-
- /**
- * @return how many factors {@param newRotation} is rotated 90 degrees clockwise.
- * E.g. 1->Rotated by 90 degrees clockwise, 2->Rotated 180 clockwise...
- * A value of 0 means no rotation has been applied
- */
- @SurfaceRotation
- private static int deltaRotation(int oldRotation, int newRotation) {
- int delta = newRotation - oldRotation;
- if (delta < 0) delta += 4;
- return delta;
- }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index 640ae76..d58ab5d 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -46,7 +46,7 @@
case LEFT_EDGE_BACK_NAVIGATION:
return R.string.back_gesture_tutorial_playground_title_swipe_inward_left_edge;
case BACK_NAVIGATION_COMPLETE:
- return R.string.back_gesture_tutorial_confirm_title;
+ return R.string.gesture_tutorial_confirm_title;
}
return null;
}
@@ -82,10 +82,12 @@
@Override
void onActionButtonClicked(View button) {
- hideHandCoachingAnimation();
- if (button == mActionTextButton) {
- mTutorialFragment.startSystemNavigationSetting();
- }
+ mTutorialFragment.closeTutorial();
+ }
+
+ @Override
+ void onActionTextButtonClicked(View button) {
+ mTutorialFragment.startSystemNavigationSetting();
mTutorialFragment.closeTutorial();
}
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
index ddf1cda..59067c1 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
@@ -15,29 +15,11 @@
*/
package com.android.quickstep.interaction;
-import android.os.Bundle;
-
import com.android.launcher3.R;
-import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback;
-import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
import com.android.quickstep.interaction.TutorialController.TutorialType;
/** Shows the Back gesture interactive tutorial. */
-public class BackGestureTutorialFragment extends TutorialFragment
- implements BackGestureAttemptCallback {
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mEdgeBackGestureHandler.registerBackGestureAttemptCallback(this);
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mEdgeBackGestureHandler.unregisterBackGestureAttemptCallback();
- }
-
+public class BackGestureTutorialFragment extends TutorialFragment {
@Override
int getHandAnimationResId() {
return R.drawable.back_gesture;
@@ -47,11 +29,4 @@
TutorialController createController(TutorialType type) {
return new BackGestureTutorialController(this, type);
}
-
- @Override
- public void onBackGestureAttempted(BackGestureResult result) {
- if (mTutorialController != null) {
- mTutorialController.onBackGestureAttempted(result);
- }
- }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
index 414ddfa..f8d9d8d 100644
--- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
@@ -15,11 +15,12 @@
*/
package com.android.quickstep.interaction;
+import static com.android.quickstep.interaction.TutorialFragment.KEY_TUTORIAL_TYPE;
+
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.Window;
@@ -44,13 +45,7 @@
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.gesture_tutorial_activity);
- try {
- mFragment = TutorialFragment.newInstance(BackGestureTutorialFragment.class,
- TutorialType.RIGHT_EDGE_BACK_NAVIGATION);
- } catch (InstantiationException | IllegalAccessException e) {
- Log.wtf(LOG_TAG, "Failed to create tutorial fragment!", e);
- mFragment = new BackGestureTutorialFragment();
- }
+ mFragment = TutorialFragment.newInstance(getTutorialType(getIntent().getExtras()));
getSupportFragmentManager().beginTransaction()
.add(R.id.gesture_tutorial_fragment_container, mFragment)
.commit();
@@ -77,6 +72,19 @@
}
}
+ private TutorialType getTutorialType(Bundle extras) {
+ TutorialType defaultType = TutorialType.RIGHT_EDGE_BACK_NAVIGATION;
+
+ if (extras == null || !extras.containsKey(KEY_TUTORIAL_TYPE)) {
+ return defaultType;
+ }
+ try {
+ return TutorialType.valueOf(extras.getString(KEY_TUTORIAL_TYPE, ""));
+ } catch (IllegalArgumentException e) {
+ return defaultType;
+ }
+ }
+
private void hideSystemUI() {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
new file mode 100644
index 0000000..0bf996d
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.interaction;
+
+import static com.android.quickstep.interaction.TutorialController.TutorialType.HOME_NAVIGATION_COMPLETE;
+
+import android.view.View;
+
+import com.android.launcher3.R;
+import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
+
+/** A {@link TutorialController} for the Home tutorial. */
+final class HomeGestureTutorialController extends TutorialController {
+
+ HomeGestureTutorialController(HomeGestureTutorialFragment fragment, TutorialType tutorialType) {
+ super(fragment, tutorialType);
+ }
+
+ @Override
+ void transitToController() {
+ super.transitToController();
+ if (mTutorialType != HOME_NAVIGATION_COMPLETE) {
+ mHandCoachingAnimation.startLoopedAnimation(mTutorialType);
+ }
+ }
+
+ @Override
+ Integer getTitleStringId() {
+ switch (mTutorialType) {
+ case HOME_NAVIGATION:
+ return R.string.home_gesture_tutorial_playground_title;
+ case HOME_NAVIGATION_COMPLETE:
+ return R.string.gesture_tutorial_confirm_title;
+ }
+ return null;
+ }
+
+ @Override
+ Integer getSubtitleStringId() {
+ if (mTutorialType == TutorialType.HOME_NAVIGATION) {
+ return R.string.home_gesture_tutorial_playground_subtitle;
+ }
+ return null;
+ }
+
+ @Override
+ Integer getActionButtonStringId() {
+ if (mTutorialType == HOME_NAVIGATION_COMPLETE) {
+ return R.string.gesture_tutorial_action_button_label;
+ }
+ return null;
+ }
+
+ @Override
+ void onActionButtonClicked(View button) {
+ mTutorialFragment.closeTutorial();
+ }
+
+ @Override
+ public void onBackGestureAttempted(BackGestureResult result) {
+ switch (mTutorialType) {
+ case HOME_NAVIGATION:
+ break;
+ case HOME_NAVIGATION_COMPLETE:
+ if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
+ || result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
+ mTutorialFragment.closeTutorial();
+ }
+ break;
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
new file mode 100644
index 0000000..613f188
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.interaction;
+
+import com.android.launcher3.R;
+import com.android.quickstep.interaction.TutorialController.TutorialType;
+
+/** Shows the Home gesture interactive tutorial. */
+public class HomeGestureTutorialFragment extends TutorialFragment {
+ @Override
+ int getHandAnimationResId() {
+ return R.drawable.home_gesture;
+ }
+
+ @Override
+ TutorialController createController(TutorialType type) {
+ return new HomeGestureTutorialController(this, type);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index cd4d0d8..f0cb567 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -82,6 +82,8 @@
void onActionButtonClicked(View button) {}
+ void onActionTextButtonClicked(View button) {}
+
void hideHandCoachingAnimation() {
mHandCoachingAnimation.stop();
}
@@ -94,9 +96,9 @@
private void updateTitles() {
updateTitleView(mTitleTextView, getTitleStringId(),
- R.style.TextAppearance_BackGestureTutorial_Title);
+ R.style.TextAppearance_GestureTutorial_Title);
updateTitleView(mSubtitleTextView, getSubtitleStringId(),
- R.style.TextAppearance_BackGestureTutorial_Subtitle);
+ R.style.TextAppearance_GestureTutorial_Subtitle);
}
private void updateTitleView(TextView textView, @Nullable Integer stringId, int styleId) {
@@ -112,7 +114,8 @@
private void updateActionButtons() {
updateButton(mActionButton, getActionButtonStringId(), this::onActionButtonClicked);
- updateButton(mActionTextButton, getActionTextButtonStringId(), this::onActionButtonClicked);
+ updateButton(
+ mActionTextButton, getActionTextButtonStringId(), this::onActionTextButtonClicked);
}
private void updateButton(Button button, @Nullable Integer stringId, OnClickListener listener) {
@@ -131,5 +134,7 @@
RIGHT_EDGE_BACK_NAVIGATION,
LEFT_EDGE_BACK_NAVIGATION,
BACK_NAVIGATION_COMPLETE,
+ HOME_NAVIGATION,
+ HOME_NAVIGATION_COMPLETE
}
}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 09ea8d6..6346a9b 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -31,11 +31,13 @@
import androidx.fragment.app.FragmentActivity;
import com.android.launcher3.R;
+import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback;
+import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
import com.android.quickstep.interaction.TutorialController.TutorialType;
import java.net.URISyntaxException;
-abstract class TutorialFragment extends Fragment {
+abstract class TutorialFragment extends Fragment implements BackGestureAttemptCallback {
private static final String LOG_TAG = "TutorialFragment";
private static final String SYSTEM_NAVIGATION_SETTING_INTENT =
@@ -43,7 +45,7 @@
+ ".:settings:fragment_args_key=gesture_system_navigation_input_summary;S"
+ ".:settings:show_fragment=com.android.settings.gestures"
+ ".SystemNavigationGestureSettings;end";
- private static final String KEY_TUTORIAL_TYPE = "tutorialType";
+ static final String KEY_TUTORIAL_TYPE = "tutorial_type";
TutorialType mTutorialType;
@Nullable TutorialController mTutorialController = null;
@@ -51,16 +53,34 @@
TutorialHandAnimation mHandCoachingAnimation;
EdgeBackGestureHandler mEdgeBackGestureHandler;
- public static TutorialFragment newInstance(
- Class<? extends TutorialFragment> fragmentClass, TutorialType tutorialType)
- throws java.lang.InstantiationException, IllegalAccessException {
- TutorialFragment fragment = fragmentClass.newInstance();
+ public static TutorialFragment newInstance(TutorialType tutorialType) {
+ TutorialFragment fragment = getFragmentForTutorialType(tutorialType);
+ if (fragment == null) {
+ fragment = new BackGestureTutorialFragment();
+ tutorialType = TutorialType.RIGHT_EDGE_BACK_NAVIGATION;
+ }
Bundle args = new Bundle();
args.putSerializable(KEY_TUTORIAL_TYPE, tutorialType);
fragment.setArguments(args);
return fragment;
}
+ @Nullable
+ private static TutorialFragment getFragmentForTutorialType(TutorialType tutorialType) {
+ switch (tutorialType) {
+ case RIGHT_EDGE_BACK_NAVIGATION:
+ case LEFT_EDGE_BACK_NAVIGATION:
+ case BACK_NAVIGATION_COMPLETE:
+ return new BackGestureTutorialFragment();
+ case HOME_NAVIGATION:
+ case HOME_NAVIGATION_COMPLETE:
+ return new HomeGestureTutorialFragment();
+ default:
+ Log.e(LOG_TAG, "Failed to find an appropriate fragment for " + tutorialType.name());
+ }
+ return null;
+ }
+
abstract int getHandAnimationResId();
abstract TutorialController createController(TutorialType type);
@@ -71,6 +91,13 @@
Bundle args = savedInstanceState != null ? savedInstanceState : getArguments();
mTutorialType = (TutorialType) args.getSerializable(KEY_TUTORIAL_TYPE);
mEdgeBackGestureHandler = new EdgeBackGestureHandler(getContext());
+ mEdgeBackGestureHandler.registerBackGestureAttemptCallback(this);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mEdgeBackGestureHandler.unregisterBackGestureAttemptCallback();
}
@Override
@@ -78,8 +105,7 @@
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
- mRootView = inflater.inflate(R.layout.gesture_tutorial_fragment,
- container, /* attachToRoot= */ false);
+ mRootView = inflater.inflate(R.layout.gesture_tutorial_fragment, container, false);
mRootView.setOnApplyWindowInsetsListener((view, insets) -> {
Insets systemInsets = insets.getInsets(WindowInsets.Type.systemBars());
mEdgeBackGestureHandler.setInsets(systemInsets.left, systemInsets.right);
@@ -131,6 +157,13 @@
return mHandCoachingAnimation;
}
+ @Override
+ public void onBackGestureAttempted(BackGestureResult result) {
+ if (mTutorialController != null) {
+ mTutorialController.onBackGestureAttempted(result);
+ }
+ }
+
void closeTutorial() {
FragmentActivity activity = getActivity();
if (activity != null) {
@@ -149,5 +182,4 @@
Log.e(LOG_TAG, "The launch Activity not found: " + e);
}
}
-
}
diff --git a/quickstep/src/com/android/quickstep/util/ActivityInitListener.java b/quickstep/src/com/android/quickstep/util/ActivityInitListener.java
index b1c72ce..2a0fe32 100644
--- a/quickstep/src/com/android/quickstep/util/ActivityInitListener.java
+++ b/quickstep/src/com/android/quickstep/util/ActivityInitListener.java
@@ -31,6 +31,8 @@
private final BiPredicate<T, Boolean> mOnInitListener;
private final ActivityTracker<T> mActivityTracker;
+ private boolean mIsRegistered = false;
+
/**
* @param onInitListener a callback made when the activity is initialized. The callback should
* return true to continue receiving callbacks (ie. for if the activity is
@@ -43,27 +45,45 @@
}
@Override
- public boolean init(T activity, boolean alreadyOnHome) {
+ public final boolean init(T activity, boolean alreadyOnHome) {
+ if (!mIsRegistered) {
+ return false;
+ }
+ return handleInit(activity, alreadyOnHome);
+ }
+
+ protected boolean handleInit(T activity, boolean alreadyOnHome) {
return mOnInitListener.test(activity, alreadyOnHome);
}
/**
* Registers the activity-created listener. If the activity is already created, then the
* callback provided in the constructor will be called synchronously.
+ * @param intent The intent that will be used to initialize the activity, if the activity
+ * doesn't already exist. We add the callback as an extra on this intent.
*/
- public void register() {
- mActivityTracker.schedule(this);
+ public void register(Intent intent) {
+ mIsRegistered = true;
+ mActivityTracker.runCallbackWhenActivityExists(this, intent);
}
+ /**
+ * After calling this, we won't {@link #init} even when the activity is ready.
+ */
public void unregister() {
- mActivityTracker.clearReference(this);
+ mIsRegistered = false;
}
+ /**
+ * Starts the given intent with the provided animation. Unlike {@link #register(Intent)}, this
+ * method will not call {@link #init} if the activity already exists, it will only call it when
+ * we get handleIntent() for the provided intent that we're starting.
+ */
public void registerAndStartActivity(Intent intent, RemoteAnimationProvider animProvider,
Context context, Handler handler, long duration) {
- register();
+ mIsRegistered = true;
Bundle options = animProvider.toActivityOptions(handler, duration, context).toBundle();
- context.startActivity(addToIntent(new Intent((intent))), options);
+ context.startActivity(addToIntent(new Intent(intent)), options);
}
}
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index f72e458..eefe8ac 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -16,20 +16,36 @@
package com.android.quickstep.util;
+import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.hardware.camera2.params.OutputConfiguration.ROTATION_180;
+import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
+import static com.android.launcher3.config.FeatureFlags.FLAG_ENABLE_FIXED_ROTATION_TRANSFORM;
+import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
+import static com.android.launcher3.states.RotationHelper.FIXED_ROTATION_TRANSFORM_SETTING_NAME;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static java.lang.annotation.RetentionPolicy.SOURCE;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.database.ContentObserver;
import android.graphics.Matrix;
import android.graphics.RectF;
+import android.os.Handler;
+import android.provider.Settings;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.Surface;
import androidx.annotation.IntDef;
+import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.touch.PortraitPagedViewHandler;
@@ -44,8 +60,17 @@
* This class has initial default state assuming the device and foreground app have
* no ({@link Surface#ROTATION_0} rotation.
*/
-public final class RecentsOrientedState {
+public final class RecentsOrientedState implements SharedPreferences.OnSharedPreferenceChangeListener {
+ private static final String TAG = "RecentsOrientedState";
+ private static final boolean DEBUG = false;
+
+ private ContentObserver mSystemAutoRotateObserver = new ContentObserver(new Handler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateAutoRotateSetting();
+ }
+ };
@Retention(SOURCE)
@IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
public @interface SurfaceRotation {}
@@ -54,15 +79,45 @@
private @SurfaceRotation int mTouchRotation = ROTATION_0;
private @SurfaceRotation int mDisplayRotation = ROTATION_0;
+ private @SurfaceRotation int mLauncherRotation = Surface.ROTATION_0;
+
/**
* If {@code true} we default to {@link PortraitPagedViewHandler} and don't support any fake
* launcher orientations.
*/
private boolean mDisableMultipleOrientations;
+ private boolean mIsHomeRotationAllowed;
+ private boolean mIsSystemRotationAllowed;
+
+ private final ContentResolver mContentResolver;
+ private final SharedPreferences mSharedPrefs;
+ private final boolean mAllowConfigurationDefaultValue;
+
private final Matrix mTmpMatrix = new Matrix();
private final Matrix mTmpInverseMatrix = new Matrix();
+ public RecentsOrientedState(Context context) {
+ mContentResolver = context.getContentResolver();
+ mSharedPrefs = Utilities.getPrefs(context);
+
+ Resources res = context.getResources();
+ int originalSmallestWidth = res.getConfiguration().smallestScreenWidthDp
+ * res.getDisplayMetrics().densityDpi / DENSITY_DEVICE_STABLE;
+ mAllowConfigurationDefaultValue = originalSmallestWidth >= 600;
+
+ boolean isForcedRotation = Utilities.getFeatureFlagsPrefs(context)
+ .getBoolean(FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, true)
+ && !mAllowConfigurationDefaultValue;
+ UI_HELPER_EXECUTOR.execute(() -> {
+ if (context.checkSelfPermission(WRITE_SECURE_SETTINGS) == PERMISSION_GRANTED) {
+ Settings.Global.putInt(mContentResolver, FIXED_ROTATION_TRANSFORM_SETTING_NAME,
+ isForcedRotation ? 1 : 0);
+ }
+ });
+ disableMultipleOrientations(!isForcedRotation);
+ }
+
/**
* Sets the appropriate {@link PagedOrientationHandler} for {@link #mOrientationHandler}
* @param touchRotation The rotation the nav bar region that is touched is in
@@ -72,19 +127,33 @@
* false otherwise
*/
public boolean update(
- @SurfaceRotation int touchRotation, @SurfaceRotation int displayRotation) {
+ @SurfaceRotation int touchRotation, @SurfaceRotation int displayRotation,
+ int launcherRotation) {
if (!FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get()) {
return false;
}
if (mDisableMultipleOrientations) {
return false;
}
- if (mDisplayRotation == displayRotation && mTouchRotation == touchRotation) {
+ if (mDisplayRotation == displayRotation && mTouchRotation == touchRotation
+ && launcherRotation == mLauncherRotation) {
return false;
}
+ mLauncherRotation = launcherRotation;
mDisplayRotation = displayRotation;
mTouchRotation = touchRotation;
+
+ if ((mIsHomeRotationAllowed && mIsSystemRotationAllowed) ||
+ mLauncherRotation == mTouchRotation) {
+ // TODO(b/153476489) Need to determine when launcher is rotated
+ mOrientationHandler = PagedOrientationHandler.HOME_ROTATED;
+ if (DEBUG) {
+ Log.d(TAG, "Set Orientation Handler: " + mOrientationHandler);
+ }
+ return true;
+ }
+
if (mTouchRotation == ROTATION_90) {
mOrientationHandler = PagedOrientationHandler.LANDSCAPE;
} else if (mTouchRotation == ROTATION_270) {
@@ -92,6 +161,9 @@
} else {
mOrientationHandler = PagedOrientationHandler.PORTRAIT;
}
+ if (DEBUG) {
+ Log.d(TAG, "Set Orientation Handler: " + mOrientationHandler);
+ }
return true;
}
@@ -99,8 +171,12 @@
return mDisableMultipleOrientations;
}
+ public boolean canLauncherAutoRotate() {
+ return mIsHomeRotationAllowed && mIsSystemRotationAllowed;
+ }
+
/**
- * Setting this preference will render future calls to {@link #update(int, int)} as a no-op.
+ * Setting this preference renders future calls to {@link #update(int, int, int)} as a no-op.
*/
public void disableMultipleOrientations(boolean disable) {
mDisableMultipleOrientations = disable;
@@ -110,6 +186,39 @@
}
}
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
+ updateHomeRotationSetting();
+ }
+
+ private void updateAutoRotateSetting() {
+ try {
+ mIsSystemRotationAllowed = Settings.System.getInt(mContentResolver,
+ Settings.System.ACCELEROMETER_ROTATION) == 1;
+ } catch (Settings.SettingNotFoundException e) {
+ Log.e(TAG, "autorotate setting not found", e);
+ }
+ }
+
+ private void updateHomeRotationSetting() {
+ mIsHomeRotationAllowed = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
+ mAllowConfigurationDefaultValue);
+ }
+
+ public void init() {
+ mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
+ mContentResolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION),
+ false, mSystemAutoRotateObserver);
+ updateAutoRotateSetting();
+ updateHomeRotationSetting();
+ }
+
+ public void destroy() {
+ mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
+ mContentResolver.unregisterContentObserver(mSystemAutoRotateObserver);
+ }
+
@SurfaceRotation
public int getDisplayRotation() {
return mDisplayRotation;
@@ -120,6 +229,14 @@
return mTouchRotation;
}
+ public boolean isHomeRotationAllowed() {
+ return mIsHomeRotationAllowed;
+ }
+
+ public int getLauncherRotation() {
+ return mLauncherRotation;
+ }
+
public int getTouchRotationDegrees() {
switch (mTouchRotation) {
case ROTATION_90:
@@ -166,8 +283,12 @@
}
public void mapRectFromNormalOrientation(RectF src, int screenWidth, int screenHeight) {
+ mapRectFromRotation(mDisplayRotation, src, screenWidth, screenHeight);
+ }
+
+ public void mapRectFromRotation(int rotation, RectF src, int screenWidth, int screenHeight) {
mTmpMatrix.reset();
- postDisplayRotation(mDisplayRotation, screenWidth, screenHeight, mTmpMatrix);
+ postDisplayRotation(rotation, screenWidth, screenHeight, mTmpMatrix);
mTmpMatrix.mapRect(src);
}
@@ -192,6 +313,10 @@
}
}
+ public boolean isDisplayPhoneNatural() {
+ return mDisplayRotation == Surface.ROTATION_0 || mDisplayRotation == Surface.ROTATION_180;
+ }
+
/**
* Posts the transformation on the matrix representing the provided display rotation
*/
diff --git a/res/layout/all_apps_content_layout.xml b/res/layout/all_apps_content_layout.xml
new file mode 100644
index 0000000..5698977
--- /dev/null
+++ b/res/layout/all_apps_content_layout.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/apps_list_view_override"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_below="@id/search_container_all_apps"
+ android:clipToPadding="false"
+ android:descendantFocusability="afterDescendants"
+ android:focusable="true"
+ android:layout_marginTop="@dimen/all_apps_header_top_padding"
+ android:orientation="vertical">
+</LinearLayout>
diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml
index de13277..a137908 100644
--- a/res/layout/launcher.xml
+++ b/res/layout/launcher.xml
@@ -45,12 +45,8 @@
<include
android:id="@+id/overview_panel"
- layout="@layout/overview_panel"
- android:visibility="gone" />
+ layout="@layout/overview_panel" />
- <include
- android:id="@+id/overview_actions_view"
- layout="@layout/overview_actions_container" />
<!-- Keep these behind the workspace so that they are not visible when
we go into AllApps -->
diff --git a/res/layout/overview_panel.xml b/res/layout/overview_panel.xml
index 2637f03..f513688 100644
--- a/res/layout/overview_panel.xml
+++ b/res/layout/overview_panel.xml
@@ -17,4 +17,5 @@
<Space
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dp"
- android:layout_height="0dp" />
\ No newline at end of file
+ android:layout_height="0dp"
+ android:visibility="gone" />
\ No newline at end of file
diff --git a/res/values-v26/styles.xml b/res/values-v26/styles.xml
index 8fb408b..d2f0802 100644
--- a/res/values-v26/styles.xml
+++ b/res/values-v26/styles.xml
@@ -20,6 +20,7 @@
<!-- Theme for the widget container. -->
<style name="WidgetContainerTheme" parent="@android:style/Theme.DeviceDefault.Settings">
<item name="android:colorPrimaryDark">#E8EAED</item>
+ <item name="android:textColorSecondary">?android:attr/textColorPrimary</item>
<item name="android:colorEdgeEffect">?android:attr/textColorSecondary</item>
</style>
<style name="WidgetContainerTheme.Dark" parent="AppTheme.Dark">
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 814b728..7de44a3 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -40,8 +40,6 @@
import com.android.launcher3.logging.StatsLogUtils;
import com.android.launcher3.logging.StatsLogUtils.LogStateProvider;
import com.android.launcher3.logging.UserEventDispatcher;
-import com.android.launcher3.testing.TestLogging;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.ViewCache;
@@ -332,7 +330,6 @@
return;
}
try {
- TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "start: shortcut", packageName);
getSystemService(LauncherApps.class).startShortcut(packageName, id, sourceBounds,
startActivityOptions, user);
} catch (SecurityException | IllegalStateException e) {
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 2dc7836..f69c8ed 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -41,8 +41,6 @@
import com.android.launcher3.model.AppLaunchTracker;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.testing.TestLogging;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.uioverrides.WallpaperColorInfo;
import com.android.launcher3.util.DefaultDisplay;
@@ -173,7 +171,6 @@
startShortcutIntentSafely(intent, optsBundle, item, sourceContainer);
} else if (user == null || user.equals(Process.myUserHandle())) {
// Could be launching some bookkeeping activity
- TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "start: activity", intent);
startActivity(intent, optsBundle);
AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(),
Process.myUserHandle(), sourceContainer);
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index 41eeb78..8eceec0 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -183,10 +183,6 @@
public void onScrollStateChanged(int state) {
super.onScrollStateChanged(state);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "onScrollStateChanged: " + state);
- }
-
if (state == SCROLL_STATE_IDLE) {
AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext());
}
@@ -196,10 +192,6 @@
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
if (isLayoutSuppressed()) info.setScrollable(false);
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- Log.d(TestProtocol.NO_SCROLL_END_WIDGETS,
- "onInitializeAccessibilityNodeInfo, scrollable: " + info.isScrollable());
- }
}
@Override
@@ -207,12 +199,8 @@
final boolean changing = frozen != isLayoutSuppressed();
super.setLayoutFrozen(frozen);
if (changing) {
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "setLayoutFrozen " + frozen
- + " @ " + Log.getStackTraceString(new Throwable()));
- ActivityContext.lookupContext(getContext()).getDragLayer()
- .sendAccessibilityEvent(TYPE_WINDOW_CONTENT_CHANGED);
- }
+ ActivityContext.lookupContext(getContext()).getDragLayer()
+ .sendAccessibilityEvent(TYPE_WINDOW_CONTENT_CHANGED);
}
}
}
\ No newline at end of file
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 93247ab..e8e88c4 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -29,6 +29,7 @@
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@@ -70,7 +71,7 @@
* too aggressive.
*/
public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, OnResumeCallback,
- IconLabelDotView, DraggableView {
+ IconLabelDotView, DraggableView, Reorderable {
private static final int DISPLAY_WORKSPACE = 0;
private static final int DISPLAY_ALL_APPS = 1;
@@ -78,6 +79,8 @@
private static final int[] STATE_PRESSED = new int[] {android.R.attr.state_pressed};
+ private final PointF mTranslationForReorder = new PointF(0, 0);
+ private float mScaleForReorder = 1f;
private static final Property<BubbleTextView, Float> DOT_SCALE_PROPERTY
= new Property<BubbleTextView, Float>(Float.TYPE, "dotScale") {
@@ -672,6 +675,30 @@
return mIconSize;
}
+ public void setReorderOffset(float x, float y) {
+ mTranslationForReorder.set(x, y);
+ super.setTranslationX(x);
+ super.setTranslationY(y);
+ }
+
+ public void getReorderOffset(PointF offset) {
+ offset.set(mTranslationForReorder);
+ }
+
+ public void setReorderScale(float scale) {
+ mScaleForReorder = scale;
+ super.setScaleX(scale);
+ super.setScaleY(scale);
+ }
+
+ public float getReorderScale() {
+ return mScaleForReorder;
+ }
+
+ public View getView() {
+ return this;
+ }
+
@Override
public int getViewType() {
return DRAGGABLE_ICON;
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 99416c4..71a787f 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -33,6 +33,7 @@
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@@ -54,7 +55,6 @@
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.accessibility.DragAndDropAccessibilityDelegate;
import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.anim.PropertyListBuilder;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.folder.PreviewBackground;
@@ -66,7 +66,6 @@
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.widget.LauncherAppWidgetHostView;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -99,6 +98,7 @@
// return an (x, y) value from helper functions. Do NOT use them to maintain other state.
@Thunk final int[] mTmpPoint = new int[2];
@Thunk final int[] mTempLocation = new int[2];
+ final PointF mTmpPointF = new PointF();
// Used to visualize / debug the Grid of the CellLayout
private static final boolean VISUALIZE_GRID = false;
@@ -136,7 +136,7 @@
private final Paint mDragOutlinePaint = new Paint();
@Thunk final ArrayMap<LayoutParams, Animator> mReorderAnimators = new ArrayMap<>();
- @Thunk final ArrayMap<View, ReorderPreviewAnimation> mShakeAnimators = new ArrayMap<>();
+ @Thunk final ArrayMap<Reorderable, ReorderPreviewAnimation> mShakeAnimators = new ArrayMap<>();
private boolean mItemPlacementDirty = false;
@@ -1868,10 +1868,11 @@
boolean skip = mode == ReorderPreviewAnimation.MODE_HINT && solution.intersectingViews
!= null && !solution.intersectingViews.contains(child);
+
LayoutParams lp = (LayoutParams) child.getLayoutParams();
- if (c != null && !skip) {
- ReorderPreviewAnimation rha = new ReorderPreviewAnimation(child, mode, lp.cellX,
- lp.cellY, c.cellX, c.cellY, c.spanX, c.spanY);
+ if (c != null && !skip && (child instanceof Reorderable)) {
+ ReorderPreviewAnimation rha = new ReorderPreviewAnimation((Reorderable) child,
+ mode, lp.cellX, lp.cellY, c.cellX, c.cellY, c.spanX, c.spanY);
rha.animate();
}
}
@@ -1893,7 +1894,7 @@
// Class which represents the reorder preview animations. These animations show that an item is
// in a temporary state, and hint at where the item will return to.
class ReorderPreviewAnimation {
- final View child;
+ final Reorderable child;
float finalDeltaX;
float finalDeltaY;
float initDeltaX;
@@ -1913,8 +1914,8 @@
float animationProgress = 0;
ValueAnimator a;
- public ReorderPreviewAnimation(View child, int mode, int cellX0, int cellY0, int cellX1,
- int cellY1, int spanX, int spanY) {
+ public ReorderPreviewAnimation(Reorderable child, int mode, int cellX0, int cellY0,
+ int cellX1, int cellY1, int spanX, int spanY) {
regionToCenterPoint(cellX0, cellY0, spanX, spanY, mTmpPoint);
final int x0 = mTmpPoint[0];
final int y0 = mTmpPoint[1];
@@ -1926,63 +1927,60 @@
this.child = child;
this.mode = mode;
+ finalDeltaX = 0;
+ finalDeltaY = 0;
- // TODO issue!
- setInitialAnimationValues(false);
- finalScale = (mChildScale - (CHILD_DIVIDEND / child.getWidth())) * initScale;
- finalDeltaX = initDeltaX;
- finalDeltaY = initDeltaY;
+ child.getReorderOffset(mTmpPointF);
+ initDeltaX = mTmpPointF.x;
+ initDeltaY = mTmpPointF.y;
+ initScale = child.getReorderScale();
+ finalScale = mChildScale - (CHILD_DIVIDEND / child.getView().getWidth()) * initScale;
+
int dir = mode == MODE_HINT ? -1 : 1;
if (dX == dY && dX == 0) {
} else {
if (dY == 0) {
- finalDeltaX += - dir * Math.signum(dX) * mReorderPreviewAnimationMagnitude;
+ finalDeltaX = -dir * Math.signum(dX) * mReorderPreviewAnimationMagnitude;
} else if (dX == 0) {
- finalDeltaY += - dir * Math.signum(dY) * mReorderPreviewAnimationMagnitude;
+ finalDeltaY = -dir * Math.signum(dY) * mReorderPreviewAnimationMagnitude;
} else {
double angle = Math.atan( (float) (dY) / dX);
- finalDeltaX += (int) (- dir * Math.signum(dX) *
- Math.abs(Math.cos(angle) * mReorderPreviewAnimationMagnitude));
- finalDeltaY += (int) (- dir * Math.signum(dY) *
- Math.abs(Math.sin(angle) * mReorderPreviewAnimationMagnitude));
+ finalDeltaX = (int) (-dir * Math.signum(dX)
+ * Math.abs(Math.cos(angle) * mReorderPreviewAnimationMagnitude));
+ finalDeltaY = (int) (-dir * Math.signum(dY)
+ * Math.abs(Math.sin(angle) * mReorderPreviewAnimationMagnitude));
}
}
}
- void setInitialAnimationValues(boolean restoreOriginalValues) {
- if (restoreOriginalValues) {
- if (child instanceof LauncherAppWidgetHostView) {
- LauncherAppWidgetHostView lahv = (LauncherAppWidgetHostView) child;
- initScale = lahv.getScaleToFit();
- initDeltaX = lahv.getTranslationForCentering().x;
- initDeltaY = lahv.getTranslationForCentering().y;
- } else {
- initScale = mChildScale;
- initDeltaX = 0;
- initDeltaY = 0;
- }
- } else {
- initScale = child.getScaleX();
- initDeltaX = child.getTranslationX();
- initDeltaY = child.getTranslationY();
- }
+ void setInitialAnimationValuesToBaseline() {
+ initScale = mChildScale;
+ initDeltaX = 0;
+ initDeltaY = 0;
}
void animate() {
- boolean noMovement = (finalDeltaX == initDeltaX) && (finalDeltaY == initDeltaY);
+ boolean noMovement = (finalDeltaX == 0) && (finalDeltaY == 0);
if (mShakeAnimators.containsKey(child)) {
ReorderPreviewAnimation oldAnimation = mShakeAnimators.get(child);
- oldAnimation.cancel();
mShakeAnimators.remove(child);
+
if (noMovement) {
- completeAnimationImmediately();
+ // A previous animation for this item exists, and no new animation will exist.
+ // Finish the old animation smoothly.
+ oldAnimation.finishAnimation();
return;
+ } else {
+ // A previous animation for this item exists, and a new one will exist. Stop
+ // the old animation in its tracks, and proceed with the new one.
+ oldAnimation.cancel();
}
}
if (noMovement) {
return;
}
+
ValueAnimator va = ObjectAnimator.ofFloat(this, ANIMATION_PROGRESS, 0, 1);
a = va;
@@ -1999,7 +1997,7 @@
va.addListener(new AnimatorListenerAdapter() {
public void onAnimationRepeat(Animator animation) {
// We make sure to end only after a full period
- setInitialAnimationValues(true);
+ setInitialAnimationValuesToBaseline();
repeating = true;
}
});
@@ -2012,11 +2010,9 @@
float r1 = (mode == MODE_HINT && repeating) ? 1.0f : animationProgress;
float x = r1 * finalDeltaX + (1 - r1) * initDeltaX;
float y = r1 * finalDeltaY + (1 - r1) * initDeltaY;
- child.setTranslationX(x);
- child.setTranslationY(y);
+ child.setReorderOffset(x, y);
float s = animationProgress * finalScale + (1 - animationProgress) * initScale;
- child.setScaleX(s);
- child.setScaleY(s);
+ child.setReorderScale(s);
}
private void cancel() {
@@ -2025,27 +2021,27 @@
}
}
- @Thunk void completeAnimationImmediately() {
+ /**
+ * Smoothly returns the item to its baseline position / scale
+ */
+ @Thunk void finishAnimation() {
if (a != null) {
a.cancel();
}
- setInitialAnimationValues(true);
- a = new PropertyListBuilder()
- .scale(initScale)
- .translationX(initDeltaX)
- .translationY(initDeltaY)
- .build(child)
- .setDuration(REORDER_ANIMATION_DURATION);
- Launcher.cast(mActivity).getDragController().addFirstFrameAnimationHelper(a);
+ setInitialAnimationValuesToBaseline();
+ ValueAnimator va = ObjectAnimator.ofFloat(this, ANIMATION_PROGRESS,
+ animationProgress, 0);
+ a = va;
a.setInterpolator(DEACCEL_1_5);
+ a.setDuration(REORDER_ANIMATION_DURATION);
a.start();
}
}
private void completeAndClearReorderPreviewAnimations() {
for (ReorderPreviewAnimation a: mShakeAnimators.values()) {
- a.completeAnimationImmediately();
+ a.finishAnimation();
}
mShakeAnimators.clear();
}
diff --git a/src/com/android/launcher3/CheckLongPressHelper.java b/src/com/android/launcher3/CheckLongPressHelper.java
index ef353f9..ff405ec 100644
--- a/src/com/android/launcher3/CheckLongPressHelper.java
+++ b/src/com/android/launcher3/CheckLongPressHelper.java
@@ -113,7 +113,10 @@
}
private void triggerLongPress() {
- if ((mView.getParent() != null) && mView.hasWindowFocus() && !mHasPerformedLongPress) {
+ if ((mView.getParent() != null)
+ && mView.hasWindowFocus()
+ && (!mView.isPressed() || mListener == null)
+ && !mHasPerformedLongPress) {
boolean handled;
if (mListener != null) {
handled = mListener.onLongClick(mView);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index f69940b..bf05a24 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1547,6 +1547,7 @@
mOverlayManager.onActivityDestroyed(this);
mAppTransitionManager.unregisterRemoteAnimations();
mUserChangedCallbackCloseable.close();
+ mAllAppsController.onActivityDestroyed();
}
public LauncherAccessibilityDelegate getAccessibilityDelegate() {
@@ -1674,6 +1675,7 @@
private void processShortcutFromDrop(PendingAddShortcutInfo info) {
Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setComponent(info.componentName);
setWaitingForResult(PendingRequestArgs.forIntent(REQUEST_CREATE_SHORTCUT, intent, info));
+ TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "start: processShortcutFromDrop");
if (!info.activityInfo.startConfigActivity(this, REQUEST_CREATE_SHORTCUT)) {
handleActivityResult(REQUEST_CREATE_SHORTCUT, RESULT_CANCELED, null);
}
diff --git a/src/com/android/launcher3/LauncherAppWidgetHost.java b/src/com/android/launcher3/LauncherAppWidgetHost.java
index 9921f76..7ea6851 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHost.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHost.java
@@ -30,6 +30,8 @@
import android.widget.Toast;
import com.android.launcher3.model.WidgetsModel;
+import com.android.launcher3.testing.TestLogging;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.widget.DeferredAppWidgetHostView;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.PendingAppWidgetHostView;
@@ -298,6 +300,7 @@
}
try {
+ TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "start: startConfigActivity");
startAppWidgetConfigureActivityForResult(activity, widgetId, 0, requestCode, null);
} catch (ActivityNotFoundException | SecurityException e) {
Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
diff --git a/src/com/android/launcher3/Reorderable.java b/src/com/android/launcher3/Reorderable.java
new file mode 100644
index 0000000..5112eaf
--- /dev/null
+++ b/src/com/android/launcher3/Reorderable.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+import android.graphics.PointF;
+import android.view.View;
+
+public interface Reorderable {
+
+ /**
+ * Set the offset related to reorder hint and "bounce" animations
+ */
+ void setReorderOffset(float x, float y);
+
+ void getReorderOffset(PointF offset);
+
+ /**
+ * Set the scale related to reorder hint and "bounce" animations
+ */
+ void setReorderScale(float scale);
+ float getReorderScale();
+
+ /**
+ * Get the com.android.view related to this object
+ */
+ View getView();
+}
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 68b0706..071c03d 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -1,5 +1,6 @@
package com.android.launcher3.allapps;
+import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT;
import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA;
import static com.android.launcher3.LauncherState.APPS_VIEW_ITEM_MASK;
@@ -17,7 +18,10 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
+import android.content.Context;
import android.util.FloatProperty;
+import android.view.View;
+import android.view.ViewGroup;
import android.view.animation.Interpolator;
import com.android.launcher3.DeviceProfile;
@@ -30,8 +34,11 @@
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ScrimView;
+import com.android.systemui.plugins.AllAppsSearchPlugin;
+import com.android.systemui.plugins.PluginListener;
/**
* Handles AllApps view transition.
@@ -43,7 +50,8 @@
* If release velocity < THRES1, snap according to either top or bottom depending on whether it's
* closer to top or closer to the page indicator.
*/
-public class AllAppsTransitionController implements StateHandler, OnDeviceProfileChangeListener {
+public class AllAppsTransitionController implements StateHandler, OnDeviceProfileChangeListener,
+ PluginListener<AllAppsSearchPlugin> {
public static final FloatProperty<AllAppsTransitionController> ALL_APPS_PROGRESS =
new FloatProperty<AllAppsTransitionController>("allAppsProgress") {
@@ -79,6 +87,9 @@
private float mScrollRangeDelta = 0;
+ private AllAppsSearchPlugin mPlugin;
+ private View mPluginContent;
+
public AllAppsTransitionController(Launcher l) {
mLauncher = l;
mShiftRange = mLauncher.getDeviceProfile().heightPx;
@@ -145,6 +156,7 @@
setProgress(state.getVerticalProgress(mLauncher));
setAlphas(state, new StateAnimationConfig(), NO_ANIM_PROPERTY_SETTER);
onProgressAnimationEnd();
+ updatePlugin(state);
}
/**
@@ -178,6 +190,20 @@
builder.add(anim);
setAlphas(toState, config, builder);
+
+ updatePlugin(toState);
+ }
+
+ private void updatePlugin(LauncherState toState) {
+ if (mPlugin == null) return;
+ if (toState == ALL_APPS) {
+ // TODO: change this from toggle event to continuous transition event.
+ mPlugin.setEditText(mAppsView.getSearchUiManager().setTextSearchEnabled(true));
+ } else {
+ mAppsView.getSearchUiManager().setTextSearchEnabled(false);
+ mPlugin.setEditText(null);
+ }
+
}
public Animator createSpringAnimation(float... progressValues) {
@@ -196,10 +222,15 @@
Interpolator allAppsFade = config.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR);
Interpolator headerFade = config.getInterpolator(ANIM_ALL_APPS_HEADER_FADE, allAppsFade);
- setter.setViewAlpha(mAppsView.getContentView(), hasAllAppsContent ? 1 : 0, allAppsFade);
- setter.setViewAlpha(mAppsView.getScrollBar(), hasAllAppsContent ? 1 : 0, allAppsFade);
- mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra, hasAllAppsContent,
- setter, headerFade, allAppsFade);
+
+ if (mPlugin == null) {
+ setter.setViewAlpha(mAppsView.getContentView(), hasAllAppsContent ? 1 : 0, allAppsFade);
+ setter.setViewAlpha(mAppsView.getScrollBar(), hasAllAppsContent ? 1 : 0, allAppsFade);
+ mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra,
+ hasAllAppsContent, setter, headerFade, allAppsFade);
+ } else {
+ setter.setViewAlpha(mPluginContent, hasAllAppsContent ? 1 : 0, allAppsFade);
+ }
mAppsView.getSearchUiManager().setContentVisibility(visibleElements, setter, allAppsFade);
setter.setInt(mScrimView, ScrimView.DRAG_HANDLE_ALPHA,
@@ -215,6 +246,8 @@
public void setupViews(AllAppsContainerView appsView, ScrimView scrimView) {
mAppsView = appsView;
mScrimView = scrimView;
+ PluginManagerWrapper.INSTANCE.get(mLauncher)
+ .addPluginListener(this, AllAppsSearchPlugin.class, false);
}
/**
@@ -238,4 +271,24 @@
mAppsView.reset(false /* animate */);
}
}
+
+ @Override
+ public void onPluginConnected(AllAppsSearchPlugin plugin, Context context) {
+ mPlugin = plugin;
+ mPluginContent = mLauncher.getLayoutInflater().inflate(
+ R.layout.all_apps_content_layout, mAppsView, false);
+ mAppsView.addView(mPluginContent);
+ mPluginContent.setAlpha(0f);
+ mPlugin.setup((ViewGroup) mPluginContent);
+ }
+
+ @Override
+ public void onPluginDisconnected(AllAppsSearchPlugin plugin) {
+ mPlugin = null;
+ mAppsView.removeView(mPluginContent);
+ }
+
+ public void onActivityDestroyed() {
+ PluginManagerWrapper.INSTANCE.get(mLauncher).removePluginListener(this);
+ }
}
diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java
index fc29a30..0648682 100644
--- a/src/com/android/launcher3/allapps/DiscoveryBounce.java
+++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java
@@ -172,8 +172,7 @@
if (withDelay) {
new Handler().postDelayed(() -> showForOverviewIfNeeded(launcher, false), DELAY_MS);
return;
- } else if (Launcher.ACTIVITY_TRACKER.hasPending()
- || AbstractFloatingView.getTopOpenView(launcher) != null) {
+ } else if (AbstractFloatingView.getTopOpenView(launcher) != null) {
// TODO: Move these checks to the top and call this method after invalidate handler.
return;
}
diff --git a/src/com/android/launcher3/allapps/SearchUiManager.java b/src/com/android/launcher3/allapps/SearchUiManager.java
index cf9a088..34bf636 100644
--- a/src/com/android/launcher3/allapps/SearchUiManager.java
+++ b/src/com/android/launcher3/allapps/SearchUiManager.java
@@ -18,6 +18,9 @@
import android.graphics.Rect;
import android.view.KeyEvent;
import android.view.animation.Interpolator;
+import android.widget.EditText;
+
+import androidx.annotation.Nullable;
import com.android.launcher3.anim.PropertySetter;
@@ -52,4 +55,14 @@
*/
void setContentVisibility(int visibleElements, PropertySetter setter,
Interpolator interpolator);
+
+ /**
+ * Called to control how the search UI result should be handled.
+ *
+ * @param isEnabled when {@code true}, the search is all handled inside AOSP
+ * and is not overlayable.
+ * @return the searchbox edit text object
+ */
+ @Nullable
+ EditText setTextSearchEnabled(boolean isEnabled);
}
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index 9e3a862..e72e1a8 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -33,6 +33,7 @@
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.animation.Interpolator;
+import android.widget.EditText;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
@@ -214,4 +215,9 @@
Interpolator interpolator) {
setter.setViewAlpha(this, (visibleElements & ALL_APPS_HEADER) != 0 ? 1 : 0, interpolator);
}
+
+ @Override
+ public EditText setTextSearchEnabled(boolean isEnabled) {
+ return this;
+ }
}
diff --git a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
index 737c97b..1d32d1d 100644
--- a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
+++ b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
@@ -75,9 +75,6 @@
}
public static void sendScrollFinishedEventToTest(Context context) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "sendScrollFinishedEventToTest");
- }
final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
if (accessibilityManager == null) return;
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 6c40b8a..0df6713 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -170,16 +170,14 @@
}
}, null, View.DRAG_FLAG_GLOBAL);
-
- Intent homeIntent = listener.addToIntent(
- new Intent(Intent.ACTION_MAIN)
+ Intent homeIntent = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME)
.setPackage(getPackageName())
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
-
- Launcher.ACTIVITY_TRACKER.schedule(listener);
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ Launcher.ACTIVITY_TRACKER.runCallbackWhenActivityExists(listener, homeIntent);
startActivity(homeIntent,
- ActivityOptions.makeCustomAnimation(this, 0, android.R.anim.fade_out).toBundle());
+ ActivityOptions.makeCustomAnimation(this, 0, android.R.anim.fade_out)
+ .toBundle());
mFinishOnPause = true;
return false;
}
diff --git a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
index e47a16f..707fd06 100644
--- a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
@@ -161,7 +161,6 @@
}
protected void postCleanup() {
- Launcher.ACTIVITY_TRACKER.clearReference(this);
if (mLauncher != null) {
// Remove any drag params from the launcher intent since the drag operation is complete.
Intent newIntent = new Intent(mLauncher.getIntent());
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 4fe1d1a..12d88df 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -164,6 +164,7 @@
@Thunk final ArrayList<View> mItemsInReadingOrder = new ArrayList<View>();
private AnimatorSet mCurrentAnimator;
+ private boolean mIsAnimatingClosed = false;
protected final Launcher mLauncher;
protected DragController mDragController;
@@ -729,15 +730,24 @@
}
private void animateClosed() {
+ if (mIsAnimatingClosed) {
+ return;
+ }
if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
mCurrentAnimator.cancel();
}
AnimatorSet a = new FolderAnimationManager(this, false /* isOpening */).getAnimator();
a.addListener(new AnimatorListenerAdapter() {
@Override
+ public void onAnimationStart(Animator animation) {
+ mIsAnimatingClosed = true;
+ }
+
+ @Override
public void onAnimationEnd(Animator animation) {
closeComplete(true);
announceAccessibilityChanges();
+ mIsAnimatingClosed = false;
}
});
startAnimation(a);
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index e29971e..96bdc2a 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -26,6 +26,7 @@
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
@@ -49,6 +50,7 @@
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.OnAlarmListener;
import com.android.launcher3.R;
+import com.android.launcher3.Reorderable;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
import com.android.launcher3.anim.Interpolators;
@@ -79,7 +81,7 @@
* An icon that can appear on in the workspace representing an {@link Folder}.
*/
public class FolderIcon extends FrameLayout implements FolderListener, IconLabelDotView,
- DraggableView {
+ DraggableView, Reorderable {
@Thunk ActivityContext mActivity;
@Thunk Folder mFolder;
@@ -119,6 +121,9 @@
private float mDotScale;
private Animator mDotScaleAnim;
+ private final PointF mTranslationForReorder = new PointF(0, 0);
+ private float mScaleForReorder = 1f;
+
private static final Property<FolderIcon, Float> DOT_SCALE_PROPERTY
= new Property<FolderIcon, Float>(Float.TYPE, "dotScale") {
@Override
@@ -226,16 +231,6 @@
mBackground.getBounds(outBounds);
}
- @Override
- public int getViewType() {
- return DRAGGABLE_ICON;
- }
-
- @Override
- public void getVisualDragBounds(Rect bounds) {
- getPreviewBounds(bounds);
- }
-
public float getBackgroundStrokeWidth() {
return mBackground.getStrokeWidth();
}
@@ -716,4 +711,39 @@
public void onFolderClose(int currentPage) {
mPreviewItemManager.onFolderClose(currentPage);
}
+
+
+ public void setReorderOffset(float x, float y) {
+ mTranslationForReorder.set(x, y);
+ super.setTranslationX(x);
+ super.setTranslationY(y);
+ }
+
+ public void getReorderOffset(PointF offset) {
+ offset.set(mTranslationForReorder);
+ }
+
+ public void setReorderScale(float scale) {
+ mScaleForReorder = scale;
+ super.setScaleX(scale);
+ super.setScaleY(scale);
+ }
+
+ public float getReorderScale() {
+ return mScaleForReorder;
+ }
+
+ public View getView() {
+ return this;
+ }
+
+ @Override
+ public int getViewType() {
+ return DRAGGABLE_ICON;
+ }
+
+ @Override
+ public void getVisualDragBounds(Rect bounds) {
+ getPreviewBounds(bounds);
+ }
}
diff --git a/src/com/android/launcher3/folder/FolderNameInfo.java b/src/com/android/launcher3/folder/FolderNameInfo.java
index 1287219..1841cd9 100644
--- a/src/com/android/launcher3/folder/FolderNameInfo.java
+++ b/src/com/android/launcher3/folder/FolderNameInfo.java
@@ -50,6 +50,10 @@
return mLabel;
}
+ public double getScore() {
+ return mScore;
+ }
+
/**
* Used to package this object into a {@link Parcel}.
*
diff --git a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
index 8dc2e61..5bf9173 100644
--- a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
+++ b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
@@ -216,17 +216,27 @@
if (launchSandboxIntent.resolveActivity(context.getPackageManager()) == null) {
return;
}
- PreferenceCategory sandboxCategory = newCategory("Sandbox");
- Preference launchSandboxPreference = new Preference(context);
- launchSandboxPreference.setKey("launchSandbox");
- launchSandboxPreference.setTitle("Launch Gesture Navigation Sandbox");
- launchSandboxPreference.setSummary(
- "This provides tutorials and a place to practice navigation gestures.");
- launchSandboxPreference.setOnPreferenceClickListener(preference -> {
- startActivity(launchSandboxIntent);
+ PreferenceCategory sandboxCategory = newCategory("Gesture Navigation Sandbox");
+ sandboxCategory.setSummary("Learn and practice navigation gestures");
+ Preference launchBackTutorialPreference = new Preference(context);
+ launchBackTutorialPreference.setKey("launchBackTutorial");
+ launchBackTutorialPreference.setTitle("Launch Back Tutorial");
+ launchBackTutorialPreference.setSummary("Learn how to use the Back gesture");
+ launchBackTutorialPreference.setOnPreferenceClickListener(preference -> {
+ startActivity(launchSandboxIntent.putExtra(
+ "tutorial_type", "RIGHT_EDGE_BACK_NAVIGATION"));
return true;
});
- sandboxCategory.addPreference(launchSandboxPreference);
+ sandboxCategory.addPreference(launchBackTutorialPreference);
+ Preference launchHomeTutorialPreference = new Preference(context);
+ launchHomeTutorialPreference.setKey("launchHomeTutorial");
+ launchHomeTutorialPreference.setTitle("Launch Home Tutorial");
+ launchHomeTutorialPreference.setSummary("Learn how to use the Home gesture");
+ launchHomeTutorialPreference.setOnPreferenceClickListener(preference -> {
+ startActivity(launchSandboxIntent.putExtra("tutorial_type", "HOME_NAVIGATION"));
+ return true;
+ });
+ sandboxCategory.addPreference(launchHomeTutorialPreference);
}
private String toName(String action) {
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index 2e0521f..3640d8b 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -15,47 +15,44 @@
*/
package com.android.launcher3.states;
-import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
-import static com.android.launcher3.config.FeatureFlags.FLAG_ENABLE_FIXED_ROTATION_TRANSFORM;
-import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-
import android.app.Activity;
import android.content.ContentResolver;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.os.Handler;
import android.provider.Settings;
+import android.util.Log;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.UiThreadHelper;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Utility class to manage launcher rotation
*/
public class RotationHelper implements OnSharedPreferenceChangeListener {
+ private static final String TAG = "RotationHelper";
+
public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation";
public static final String FIXED_ROTATION_TRANSFORM_SETTING_NAME = "fixed_rotation_transform";
private final ContentResolver mContentResolver;
+ private boolean mSystemAutoRotateEnabled;
- /**
- * Listener to receive changes when {@link #FIXED_ROTATION_TRANSFORM_SETTING_NAME} flag changes.
- */
- public interface ForcedRotationChangedListener {
- void onForcedRotationChanged(boolean isForcedRotation);
- }
+ private ContentObserver mSystemAutoRotateObserver = new ContentObserver(new Handler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateAutoRotateSetting();
+ }
+ };
public static boolean getAllowRotationDefaultValue() {
// If the device's pixel density was scaled (usually via settings for A11y), use the
@@ -72,12 +69,9 @@
private final Activity mActivity;
private final SharedPreferences mSharedPrefs;
- private final SharedPreferences mFeatureFlagsPrefs;
private boolean mIgnoreAutoRotateSettings;
- private boolean mAutoRotateEnabled;
- private boolean mForcedRotation;
- private List<ForcedRotationChangedListener> mForcedRotationChangedListeners = new ArrayList<>();
+ private boolean mHomeRotationEnabled;
/**
* Rotation request made by
@@ -108,67 +102,35 @@
if (!mIgnoreAutoRotateSettings) {
mSharedPrefs = Utilities.getPrefs(mActivity);
mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
- mAutoRotateEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
+ mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
getAllowRotationDefaultValue());
} else {
mSharedPrefs = null;
}
mContentResolver = activity.getContentResolver();
- mFeatureFlagsPrefs = Utilities.getFeatureFlagsPrefs(mActivity);
- mFeatureFlagsPrefs.registerOnSharedPreferenceChangeListener(this);
- updateForcedRotation(true);
}
- /**
- * @param setValueFromPrefs If true, then {@link #mForcedRotation} will get set to the value
- * from the home developer settings. Otherwise it will not.
- * This is primarily to allow tests to set their own conditions.
- */
- private void updateForcedRotation(boolean setValueFromPrefs) {
- boolean isForcedRotation = mFeatureFlagsPrefs
- .getBoolean(FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, true)
- && !getAllowRotationDefaultValue();
- if (mForcedRotation == isForcedRotation) {
- return;
+ private void updateAutoRotateSetting() {
+ int autoRotateEnabled = 0;
+ try {
+ autoRotateEnabled = Settings.System.getInt(mContentResolver,
+ Settings.System.ACCELEROMETER_ROTATION);
+ } catch (Settings.SettingNotFoundException e) {
+ Log.e(TAG, "autorotate setting not found", e);
}
- if (setValueFromPrefs) {
- mForcedRotation = isForcedRotation;
- }
- UI_HELPER_EXECUTOR.execute(() -> {
- if (mActivity.checkSelfPermission(WRITE_SECURE_SETTINGS) == PERMISSION_GRANTED) {
- Settings.Global.putInt(mContentResolver, FIXED_ROTATION_TRANSFORM_SETTING_NAME,
- mForcedRotation ? 1 : 0);
- }
- });
- for (ForcedRotationChangedListener listener : mForcedRotationChangedListeners) {
- listener.onForcedRotationChanged(mForcedRotation);
- }
- }
- /**
- * will not be called when first registering the listener.
- */
- public void addForcedRotationCallback(ForcedRotationChangedListener listener) {
- mForcedRotationChangedListeners.add(listener);
- }
-
- public void removeForcedRotationCallback(ForcedRotationChangedListener listener) {
- mForcedRotationChangedListeners.remove(listener);
+ mSystemAutoRotateEnabled = autoRotateEnabled == 1;
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
- if (FLAG_ENABLE_FIXED_ROTATION_TRANSFORM.equals(s)) {
- updateForcedRotation(true);
- return;
- }
-
- boolean wasRotationEnabled = mAutoRotateEnabled;
- mAutoRotateEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
+ boolean wasRotationEnabled = mHomeRotationEnabled;
+ mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
getAllowRotationDefaultValue());
- if (mAutoRotateEnabled != wasRotationEnabled) {
+ if (mHomeRotationEnabled != wasRotationEnabled) {
notifyChange();
+ updateAutoRotateSetting();
}
}
@@ -197,10 +159,6 @@
public void forceAllowRotationForTesting(boolean allowRotation) {
mIgnoreAutoRotateSettings =
allowRotation || mActivity.getResources().getBoolean(R.bool.allow_rotation);
- // TODO(b/150214193) Tests currently expect launcher to be able to be rotated
- // Modify tests for this new behavior
- mForcedRotation = !allowRotation;
- updateForcedRotation(false);
notifyChange();
}
@@ -208,6 +166,11 @@
if (!mInitialized) {
mInitialized = true;
notifyChange();
+
+ mContentResolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION),
+ false, mSystemAutoRotateObserver);
+ updateAutoRotateSetting();
}
}
@@ -217,8 +180,7 @@
if (mSharedPrefs != null) {
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
}
- mForcedRotationChangedListeners.clear();
- mFeatureFlagsPrefs.unregisterOnSharedPreferenceChangeListener(this);
+ mContentResolver.unregisterContentObserver(mSystemAutoRotateObserver);
}
}
@@ -228,10 +190,7 @@
}
final int activityFlags;
- if (mForcedRotation) {
- // TODO(b/150214193) Properly address this
- activityFlags = SCREEN_ORIENTATION_PORTRAIT;
- } else if (mStateHandlerRequest != REQUEST_NONE) {
+ if (mStateHandlerRequest != REQUEST_NONE) {
activityFlags = mStateHandlerRequest == REQUEST_LOCK ?
SCREEN_ORIENTATION_LOCKED : SCREEN_ORIENTATION_UNSPECIFIED;
} else if (mCurrentTransitionRequest != REQUEST_NONE) {
@@ -240,7 +199,7 @@
} else if (mCurrentStateRequest == REQUEST_LOCK) {
activityFlags = SCREEN_ORIENTATION_LOCKED;
} else if (mIgnoreAutoRotateSettings || mCurrentStateRequest == REQUEST_ROTATE
- || mAutoRotateEnabled) {
+ || mHomeRotationEnabled) {
activityFlags = SCREEN_ORIENTATION_UNSPECIFIED;
} else {
// If auto rotation is off, allow rotation on the activity, in case the user is using
@@ -253,11 +212,23 @@
}
}
+ /**
+ * @return how many factors {@param newRotation} is rotated 90 degrees clockwise.
+ * E.g. 1->Rotated by 90 degrees clockwise, 2->Rotated 180 clockwise...
+ * A value of 0 means no rotation has been applied
+ */
+ public static int deltaRotation(int oldRotation, int newRotation) {
+ int delta = newRotation - oldRotation;
+ if (delta < 0) delta += 4;
+ return delta;
+ }
+
@Override
public String toString() {
return String.format("[mStateHandlerRequest=%d, mCurrentStateRequest=%d,"
- + " mLastActivityFlags=%d, mIgnoreAutoRotateSettings=%b, mAutoRotateEnabled=%b]",
+ + " mLastActivityFlags=%d, mIgnoreAutoRotateSettings=%b, mHomeRotationEnabled=%b,"
+ + " mSystemAutoRotateEnabled=%b]",
mStateHandlerRequest, mCurrentStateRequest, mLastActivityFlags,
- mIgnoreAutoRotateSettings, mAutoRotateEnabled);
+ mIgnoreAutoRotateSettings, mHomeRotationEnabled, mSystemAutoRotateEnabled);
}
}
diff --git a/src/com/android/launcher3/states/StateAnimationConfig.java b/src/com/android/launcher3/states/StateAnimationConfig.java
index 82cde64..8dccbd3 100644
--- a/src/com/android/launcher3/states/StateAnimationConfig.java
+++ b/src/com/android/launcher3/states/StateAnimationConfig.java
@@ -37,6 +37,7 @@
PLAY_ATOMIC_OVERVIEW_SCALE,
PLAY_ATOMIC_OVERVIEW_PEEK,
SKIP_OVERVIEW,
+ SKIP_DEPTH_CONTROLLER
})
@Retention(RetentionPolicy.SOURCE)
public @interface AnimationFlags {}
@@ -44,6 +45,7 @@
public static final int PLAY_ATOMIC_OVERVIEW_SCALE = 1 << 1;
public static final int PLAY_ATOMIC_OVERVIEW_PEEK = 1 << 2;
public static final int SKIP_OVERVIEW = 1 << 3;
+ public static final int SKIP_DEPTH_CONTROLLER = 1 << 4;
public long duration;
public boolean userControlled;
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index e7449bb..82f2eb4 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -98,5 +98,4 @@
public static final String PERMANENT_DIAG_TAG = "TaplTarget";
public static final String APP_NOT_DISABLED = "b/139891609";
- public static final String NO_SCROLL_END_WIDGETS = "b/152354290";
}
diff --git a/src/com/android/launcher3/touch/HomeRotatedPageHandler.java b/src/com/android/launcher3/touch/HomeRotatedPageHandler.java
new file mode 100644
index 0000000..710b676
--- /dev/null
+++ b/src/com/android/launcher3/touch/HomeRotatedPageHandler.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.touch;
+
+import android.graphics.RectF;
+import android.view.Surface;
+
+public class HomeRotatedPageHandler extends PortraitPagedViewHandler {
+ @Override
+ public void offsetTaskRect(RectF rect, float value, int displayRotation, int launcherRotation) {
+ if (launcherRotation == Surface.ROTATION_0) {
+ super.offsetTaskRect(rect, value, displayRotation, launcherRotation);
+ } else if (launcherRotation == Surface.ROTATION_90) {
+ if (displayRotation == Surface.ROTATION_0) {
+ rect.offset(0, value);
+ } else if (displayRotation == Surface.ROTATION_90) {
+ rect.offset(value, 0);
+ } else if (displayRotation == Surface.ROTATION_180) {
+ rect.offset(-value, 0);
+ } else {
+ rect.offset(-value, 0);
+ }
+ } else if (launcherRotation == Surface.ROTATION_270) {
+ if (displayRotation == Surface.ROTATION_0) {
+ rect.offset(0, -value);
+ } else if (displayRotation == Surface.ROTATION_90) {
+ rect.offset(value, 0);
+ } else if (displayRotation == Surface.ROTATION_180) {
+ rect.offset(0, -value);
+ } else {
+ rect.offset(value, 0);
+ }
+ } // TODO (b/149609488) handle 180 case as well
+ }
+}
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index f7091fc..6abca76 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -52,6 +52,8 @@
import com.android.launcher3.model.data.PromiseAppInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
+import com.android.launcher3.testing.TestLogging;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.views.FloatingIconView;
import com.android.launcher3.widget.PendingAppWidgetHostView;
@@ -240,6 +242,8 @@
private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher,
@Nullable String sourceContainer) {
+ TestLogging.recordEvent(
+ TestProtocol.SEQUENCE_MAIN, "start: startAppShortcutOrInfoActivity");
Intent intent;
if (item instanceof PromiseAppInfo) {
PromiseAppInfo promiseAppInfo = (PromiseAppInfo) item;
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index bab5747..f9f3bf4 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -78,6 +78,11 @@
}
@Override
+ public boolean isLayoutNaturalToLauncher() {
+ return false;
+ }
+
+ @Override
public void adjustFloatingIconStartVelocity(PointF velocity) {
float oldX = velocity.x;
float oldY = velocity.y;
@@ -182,7 +187,7 @@
}
@Override
- public void offsetTaskRect(RectF rect, float value, int displayRotation) {
+ public void offsetTaskRect(RectF rect, float value, int displayRotation, int launcherRotation) {
if (displayRotation == Surface.ROTATION_0) {
rect.offset(0, value);
} else if (displayRotation == Surface.ROTATION_90) {
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index 50606ec..ba4c064 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -42,6 +42,7 @@
PagedOrientationHandler PORTRAIT = new PortraitPagedViewHandler();
PagedOrientationHandler LANDSCAPE = new LandscapePagedViewHandler();
PagedOrientationHandler SEASCAPE = new SeascapePagedViewHandler();
+ PagedOrientationHandler HOME_ROTATED = new HomeRotatedPageHandler();
interface Int2DAction<T> {
void call(T target, int x, int y);
@@ -79,7 +80,7 @@
void setMaxScroll(AccessibilityEvent event, int maxScroll);
boolean getRecentsRtlSetting(Resources resources);
float getDegreesRotated();
- void offsetTaskRect(RectF rect, float value, int delta);
+ void offsetTaskRect(RectF rect, float value, int delta, int launcherRotation);
int getPrimaryValue(int x, int y);
int getSecondaryValue(int x, int y);
void delegateScrollTo(PagedView pagedView, int secondaryScroll, int primaryScroll);
@@ -89,6 +90,7 @@
void scrollerStartScroll(OverScroller scroller, int newPosition);
void getCurveProperties(PagedView view, Rect insets, CurveProperties out);
boolean isGoingUp(float displacement);
+ boolean isLayoutNaturalToLauncher();
/**
* Maps the velocity from the coordinate plane of the foreground app to that
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 245138f..7c44eba 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -78,6 +78,11 @@
}
@Override
+ public boolean isLayoutNaturalToLauncher() {
+ return true;
+ }
+
+ @Override
public void adjustFloatingIconStartVelocity(PointF velocity) {
//no-op
}
@@ -180,7 +185,7 @@
}
@Override
- public void offsetTaskRect(RectF rect, float value, int displayRotation) {
+ public void offsetTaskRect(RectF rect, float value, int displayRotation, int launcherRotation) {
if (displayRotation == Surface.ROTATION_0) {
rect.offset(value, 0);
} else if (displayRotation == Surface.ROTATION_90) {
diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
index eebd87f..5ce8a57 100644
--- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
@@ -36,7 +36,7 @@
}
@Override
- public void offsetTaskRect(RectF rect, float value, int displayRotation) {
+ public void offsetTaskRect(RectF rect, float value, int displayRotation, int launcherRotation) {
if (displayRotation == Surface.ROTATION_0) {
rect.offset(0, value);
} else if (displayRotation == Surface.ROTATION_90) {
diff --git a/src/com/android/launcher3/util/ActivityTracker.java b/src/com/android/launcher3/util/ActivityTracker.java
index 499f655..59266b4 100644
--- a/src/com/android/launcher3/util/ActivityTracker.java
+++ b/src/com/android/launcher3/util/ActivityTracker.java
@@ -15,27 +15,23 @@
*/
package com.android.launcher3.util;
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
-import android.util.Log;
import androidx.annotation.Nullable;
import com.android.launcher3.BaseActivity;
-import com.android.launcher3.testing.TestProtocol;
import java.lang.ref.WeakReference;
/**
* Helper class to statically track activity creation
+ * @param <T> The activity type to track
*/
-public final class ActivityTracker<T extends BaseActivity> implements Runnable {
+public final class ActivityTracker<T extends BaseActivity> {
private WeakReference<T> mCurrentActivity = new WeakReference<>(null);
- private WeakReference<SchedulerCallback<T>> mPendingCallback = new WeakReference<>(null);
private static final String EXTRA_SCHEDULER_CALLBACK = "launcher.scheduler_callback";
@@ -51,76 +47,32 @@
}
/**
- * Schedules the callback to be notified when the activity is created.
- * @return true if the activity is already created, false otherwise
+ * Call {@link SchedulerCallback#init(BaseActivity, boolean)} when the activity is ready.
+ * If the activity is already created, this is called immediately, otherwise we add the
+ * callback as an extra on the intent, and will call init() when we get handleIntent().
+ * @param callback The callback to call init() on when the activity is ready.
+ * @param intent The intent that will be used to initialize the activity, if the activity
+ * doesn't already exist. We add the callback as an extra on this intent.
*/
- public boolean schedule(SchedulerCallback<? extends T> callback) {
- synchronized (this) {
- mPendingCallback = new WeakReference<>((SchedulerCallback<T>) callback);
- }
- if (!notifyInitIfPending()) {
- // If the activity doesn't already exist, then post and wait for the activity to start
- MAIN_EXECUTOR.execute(this);
- return false;
- }
- return true;
- }
-
- @Override
- public void run() {
- notifyInitIfPending();
- }
-
- /**
- * Notifies the pending callback if the activity is now created.
- * @return true if the activity is now created.
- */
- private boolean notifyInitIfPending() {
+ public void runCallbackWhenActivityExists(SchedulerCallback<T> callback, Intent intent) {
T activity = mCurrentActivity.get();
if (activity != null) {
- notifyInitIfPending(activity, activity.isStarted());
- return true;
+ callback.init(activity, activity.isStarted());
+ } else {
+ callback.addToIntent(intent);
}
- return false;
- }
-
- public boolean notifyInitIfPending(T activity, boolean alreadyOnHome) {
- SchedulerCallback<T> pendingCallback = mPendingCallback.get();
- if (pendingCallback != null) {
- if (!pendingCallback.init(activity, alreadyOnHome)) {
- clearReference(pendingCallback);
- }
- return true;
- }
- return false;
- }
-
- public boolean clearReference(SchedulerCallback<? extends T> handler) {
- synchronized (this) {
- if (mPendingCallback.get() == handler) {
- mPendingCallback.clear();
- return true;
- }
- return false;
- }
- }
-
- public boolean hasPending() {
- return mPendingCallback.get() != null;
}
public boolean handleCreate(T activity) {
mCurrentActivity = new WeakReference<>(activity);
- return handleIntent(activity, activity.getIntent(), false, false);
+ return handleIntent(activity, activity.getIntent(), false);
}
public boolean handleNewIntent(T activity, Intent intent) {
- return handleIntent(activity, intent, activity.isStarted(), true);
+ return handleIntent(activity, intent, activity.isStarted());
}
- private boolean handleIntent(
- T activity, Intent intent, boolean alreadyOnHome, boolean explicitIntent) {
- boolean result = false;
+ private boolean handleIntent(T activity, Intent intent, boolean alreadyOnHome) {
if (intent != null && intent.getExtras() != null) {
IBinder stateBinder = intent.getExtras().getBinder(EXTRA_SCHEDULER_CALLBACK);
if (stateBinder instanceof ObjectWrapper) {
@@ -129,19 +81,26 @@
if (!handler.init(activity, alreadyOnHome)) {
intent.getExtras().remove(EXTRA_SCHEDULER_CALLBACK);
}
- result = true;
+ return true;
}
}
- if (!result && !explicitIntent) {
- result = notifyInitIfPending(activity, alreadyOnHome);
- }
- return result;
+ return false;
}
public interface SchedulerCallback<T extends BaseActivity> {
+ /**
+ * Called when the activity is ready.
+ * @param alreadyOnHome Whether the activity is already started.
+ * @return Whether to continue receiving callbacks (i.e. if the activity is recreated).
+ */
boolean init(T activity, boolean alreadyOnHome);
+ /**
+ * Adds this callback as an extra on the intent, so we can retrieve it in handleIntent() and
+ * call {@link #init}. The intent should be used to start the activity after calling this
+ * method in order for us to get handleIntent().
+ */
default Intent addToIntent(Intent intent) {
Bundle extras = new Bundle();
extras.putBinder(EXTRA_SCHEDULER_CALLBACK, ObjectWrapper.wrap(this));
diff --git a/src/com/android/launcher3/util/MultiValueAlpha.java b/src/com/android/launcher3/util/MultiValueAlpha.java
index 07f835d..a8642b0 100644
--- a/src/com/android/launcher3/util/MultiValueAlpha.java
+++ b/src/com/android/launcher3/util/MultiValueAlpha.java
@@ -16,7 +16,7 @@
package com.android.launcher3.util;
-import android.util.Property;
+import android.util.FloatProperty;
import android.view.View;
import java.util.Arrays;
@@ -26,8 +26,8 @@
*/
public class MultiValueAlpha {
- public static final Property<AlphaProperty, Float> VALUE =
- new Property<AlphaProperty, Float>(Float.TYPE, "value") {
+ public static final FloatProperty<AlphaProperty> VALUE =
+ new FloatProperty<AlphaProperty>("value") {
@Override
public Float get(AlphaProperty alphaProperty) {
@@ -35,7 +35,7 @@
}
@Override
- public void set(AlphaProperty object, Float value) {
+ public void setValue(AlphaProperty object, float value) {
object.setValue(value);
}
};
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 2fc3eaf..6915953 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -275,9 +275,6 @@
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "BaseDragLayer: " + ev);
- }
switch (ev.getAction()) {
case ACTION_DOWN: {
mTouchDispatchState |= TOUCH_DISPATCHING_VIEW;
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index e114cf8..5b3840f 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -124,7 +124,6 @@
super.onAttachedToWindow();
if (!mIsOpening) {
getViewTreeObserver().addOnGlobalLayoutListener(this);
- mLauncher.getRotationHelper().setCurrentTransitionRequest(REQUEST_LOCK);
}
}
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index 880f123..d5c3c1d 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -40,6 +40,8 @@
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.popup.ArrowPopup;
import com.android.launcher3.shortcuts.DeepShortcutView;
+import com.android.launcher3.testing.TestLogging;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
import com.android.launcher3.widget.WidgetsFullSheet;
@@ -184,6 +186,7 @@
}
public static boolean startSettings(View view) {
+ TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "start: startSettings");
Launcher launcher = Launcher.getLauncher(view.getContext());
launcher.startActivity(new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
.setPackage(launcher.getPackageName())
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 5d33f13..6f2e179 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -19,8 +19,6 @@
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
import android.content.res.Configuration;
-import android.graphics.PointF;
-import android.graphics.Rect;
import android.os.Handler;
import android.os.SystemClock;
import android.util.SparseBooleanArray;
@@ -40,7 +38,6 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.dragndrop.DragLayer;
-import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.util.Executors;
@@ -51,7 +48,7 @@
* {@inheritDoc}
*/
public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView
- implements TouchCompleteListener, View.OnLongClickListener, DraggableView {
+ implements TouchCompleteListener, View.OnLongClickListener {
// Related to the auto-advancing of widgets
private static final long ADVANCE_INTERVAL = 20000;
@@ -73,15 +70,7 @@
private boolean mIsAutoAdvanceRegistered;
private Runnable mAutoAdvanceRunnable;
- /**
- * The scaleX and scaleY value such that the widget fits within its cellspans, scaleX = scaleY.
- */
- private float mScaleToFit = 1f;
- /**
- * The translation values to center the widget within its cellspans.
- */
- private final PointF mTranslationForCentering = new PointF(0, 0);
public LauncherAppWidgetHostView(Context context) {
super(context);
@@ -307,26 +296,6 @@
scheduleNextAdvance();
}
- public void setScaleToFit(float scale) {
- mScaleToFit = scale;
- setScaleX(scale);
- setScaleY(scale);
- }
-
- public float getScaleToFit() {
- return mScaleToFit;
- }
-
- public void setTranslationForCentering(float x, float y) {
- mTranslationForCentering.set(x, y);
- setTranslationX(x);
- setTranslationY(y);
- }
-
- public PointF getTranslationForCentering() {
- return mTranslationForCentering;
- }
-
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
@@ -357,17 +326,4 @@
}
return false;
}
-
- @Override
- public int getViewType() {
- return DRAGGABLE_WIDGET;
- }
-
- @Override
- public void getVisualDragBounds(Rect bounds) {
- int width = (int) (getMeasuredWidth() * mScaleToFit);
- int height = (int) (getMeasuredHeight() * mScaleToFit);
-
- bounds.set(0, 0 , width, height);
- }
}
diff --git a/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java b/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java
index 104ad77..5ea01d9 100644
--- a/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java
@@ -18,12 +18,14 @@
import android.appwidget.AppWidgetHostView;
import android.content.Context;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
+import com.android.launcher3.Reorderable;
import com.android.launcher3.dragndrop.DraggableView;
import java.util.ArrayList;
@@ -32,7 +34,20 @@
* Extension of AppWidgetHostView with support for controlled keyboard navigation.
*/
public abstract class NavigableAppWidgetHostView extends AppWidgetHostView
- implements DraggableView {
+ implements DraggableView, Reorderable {
+
+ /**
+ * The scaleX and scaleY value such that the widget fits within its cellspans, scaleX = scaleY.
+ */
+ private float mScaleToFit = 1f;
+
+ /**
+ * The translation values to center the widget within its cellspans.
+ */
+ private final PointF mTranslationForCentering = new PointF(0, 0);
+
+ private final PointF mTranslationForReorder = new PointF(0, 0);
+ private float mScaleForReorder = 1f;
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mChildrenFocused;
@@ -137,6 +152,47 @@
setSelected(childIsFocused);
}
+ public void setScaleToFit(float scale) {
+ mScaleToFit = scale;
+ super.setScaleX(scale * mScaleForReorder);
+ super.setScaleY(scale * mScaleForReorder);
+ }
+
+ public float getScaleToFit() {
+ return mScaleToFit;
+ }
+
+ public View getView() {
+ return this;
+ }
+
+
+ public void setTranslationForCentering(float x, float y) {
+ mTranslationForCentering.set(x, y);
+ super.setTranslationX(x + mTranslationForReorder.x);
+ super.setTranslationY(y + mTranslationForReorder.y);
+ }
+
+ public void setReorderOffset(float x, float y) {
+ mTranslationForReorder.set(x, y);
+ super.setTranslationX(mTranslationForCentering.x + x);
+ super.setTranslationY(mTranslationForCentering.y + y);
+ }
+
+ public void getReorderOffset(PointF offset) {
+ offset.set(mTranslationForReorder);
+ }
+
+ public void setReorderScale(float scale) {
+ mScaleForReorder = scale;
+ super.setScaleX(mScaleToFit * scale);
+ super.setScaleY(mScaleToFit * scale);
+ }
+
+ public float getReorderScale() {
+ return mScaleForReorder;
+ }
+
@Override
public int getViewType() {
return DRAGGABLE_WIDGET;
@@ -144,6 +200,9 @@
@Override
public void getVisualDragBounds(Rect bounds) {
- bounds.set(0, 0 , getMeasuredWidth(), getMeasuredHeight());
+ int width = (int) (getMeasuredWidth() * mScaleToFit);
+ int height = (int) (getMeasuredHeight() * mScaleToFit);
+
+ bounds.set(0, 0 , width, height);
}
}
diff --git a/src/com/android/launcher3/widget/WidgetsFullSheet.java b/src/com/android/launcher3/widget/WidgetsFullSheet.java
index 37a30af..536b766 100644
--- a/src/com/android/launcher3/widget/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsFullSheet.java
@@ -71,14 +71,6 @@
}
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "WidgetsFullSheet: " + ev);
- }
- return super.dispatchTouchEvent(ev);
- }
-
public WidgetsFullSheet(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
diff --git a/src/com/android/launcher3/widget/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
index 17baa27..82d4110 100644
--- a/src/com/android/launcher3/widget/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
@@ -158,23 +158,13 @@
mScrollbar.isHitInParent(e.getX(), e.getY(), mFastScrollerOffset);
}
if (mTouchDownOnScroller) {
- final boolean result = mScrollbar.handleTouchEvent(e, mFastScrollerOffset);
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "onInterceptTouchEvent 1 " + result);
- }
- return result;
- }
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "onInterceptTouchEvent 2 false");
+ return mScrollbar.handleTouchEvent(e, mFastScrollerOffset);
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "WidgetsRecyclerView.onTouchEvent");
- }
if (mTouchDownOnScroller) {
mScrollbar.handleTouchEvent(e, mFastScrollerOffset);
}
@@ -182,31 +172,5 @@
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "onRequestDisallowInterceptTouchEvent "
- + disallowIntercept);
- }
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- final boolean result = super.dispatchTouchEvent(ev);
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "WidgetsRecyclerView: state: "
- + getScrollState()
- + " can scroll: " + getLayoutManager().canScrollVertically()
- + " result: " + result
- + " layout suppressed: " + isLayoutSuppressed()
- + " event: " + ev);
- }
- return result;
- }
-
- @Override
- public void stopNestedScroll() {
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "stopNestedScroll");
- }
- super.stopNestedScroll();
}
}
\ No newline at end of file
diff --git a/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java b/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java
new file mode 100644
index 0000000..b865a20
--- /dev/null
+++ b/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.plugins;
+
+import android.view.ViewGroup;
+import android.widget.EditText;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Implement this plugin interface to add a row of views to the top of the all apps drawer.
+ */
+@ProvidesInterface(action = AllAppsSearchPlugin.ACTION, version = AllAppsSearchPlugin.VERSION)
+public interface AllAppsSearchPlugin extends Plugin {
+ String ACTION = "com.android.systemui.action.PLUGIN_ALL_APPS_SEARCH_ACTIONS";
+ int VERSION = 1;
+
+ void setup(ViewGroup parent);
+ void setEditText(EditText editText);
+}
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index a7089fe..86faddb 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -162,7 +162,6 @@
mLauncher.enableDebugTracing();
// Avoid double-reporting of Launcher crashes.
mLauncher.setOnLauncherCrashed(() -> mLauncherPid = 0);
- mLauncher.disableSensorRotation();
}
protected final LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
@@ -278,7 +277,6 @@
clearPackageData(mDevice.getLauncherPackageName());
mLauncher.enableDebugTracing();
mLauncherPid = mLauncher.getPid();
- mLauncher.disableSensorRotation();
}
}
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index de1ada4..57000a0 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -314,7 +314,7 @@
switchToAllApps();
allApps.freeze();
try {
- allApps.getAppIcon(APP_NAME).dragToWorkspace(false);
+ allApps.getAppIcon(APP_NAME).dragToWorkspace(false, false);
mLauncher.getWorkspace().getWorkspaceAppIcon(APP_NAME).launch(getAppPackageName());
} finally {
allApps.unfreeze();
@@ -342,7 +342,7 @@
getMenuItem(0);
final String shortcutName = menuItem.getText();
- menuItem.dragToWorkspace(false);
+ menuItem.dragToWorkspace(false, false);
mLauncher.getWorkspace().getWorkspaceAppIcon(shortcutName).launch(getAppPackageName());
} finally {
allApps.unfreeze();
diff --git a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
index 0a6579a..9d4ccff 100644
--- a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
@@ -94,7 +94,7 @@
WidgetConfigStartupMonitor monitor = new WidgetConfigStartupMonitor();
widgets.
getWidget(mWidgetInfo.getLabel(mTargetContext.getPackageManager())).
- dragToWorkspace(true);
+ dragToWorkspace(true, false);
// Widget id for which the config activity was opened
mWidgetId = monitor.getWidgetId();
diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
index 5e26aa6..f146db5 100644
--- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
@@ -57,7 +57,7 @@
getWorkspace().
openAllWidgets().
getWidget(widgetInfo.getLabel(mTargetContext.getPackageManager())).
- dragToWorkspace(false);
+ dragToWorkspace(false, false);
assertTrue(mActivityMonitor.itemExists(
(info, view) -> info instanceof LauncherAppWidgetInfo &&
@@ -83,7 +83,7 @@
mDevice.pressHome();
mLauncher.getWorkspace().openAllWidgets()
.getWidget("com.android.launcher3.testcomponent.CustomShortcutConfigActivity")
- .dragToWorkspace(false);
+ .dragToWorkspace(false, true);
mLauncher.getWorkspace().getWorkspaceAppIcon("Shortcut")
.launch(getAppPackageName());
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIcon.java b/tests/tapl/com/android/launcher3/tapl/AppIcon.java
index bdfd563..5de5b4a 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIcon.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIcon.java
@@ -31,7 +31,6 @@
*/
public final class AppIcon extends Launchable {
- private static final Pattern START_EVENT = Pattern.compile("start:");
private static final Pattern LONG_CLICK_EVENT = Pattern.compile("onAllAppsItemLongClick");
AppIcon(LauncherInstrumentation launcher, UiObject2 icon) {
@@ -64,6 +63,6 @@
@Override
protected void expectActivityStartEvents() {
- mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, START_EVENT);
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_START);
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java
index 37a7b91..a40919b 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java
@@ -27,8 +27,6 @@
*/
public class AppIconMenuItem extends Launchable {
- private static final Pattern START_SHORTCUT_EVENT = Pattern.compile("start: shortcut:");
-
AppIconMenuItem(LauncherInstrumentation launcher, UiObject2 shortcut) {
super(launcher, shortcut);
}
@@ -51,6 +49,6 @@
@Override
protected void expectActivityStartEvents() {
- mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, START_SHORTCUT_EVENT);
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_START);
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index 2922acf..df7436c 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -77,8 +77,9 @@
/**
* Drags an object to the center of homescreen.
* @param startsActivity whether it's expected to start an activity.
+ * @param isWidgetShortcut whether we drag a widget shortcut
*/
- public void dragToWorkspace(boolean startsActivity) {
+ public void dragToWorkspace(boolean startsActivity, boolean isWidgetShortcut) {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
final Point launchableCenter = getObject().getVisibleCenter();
final Point displaySize = mLauncher.getRealDisplaySize();
@@ -93,6 +94,7 @@
displaySize.y / 2),
getLongPressIndicator(),
startsActivity,
+ isWidgetShortcut,
() -> addExpectedEventsForLongClick());
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 84eae2d..debc736 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -99,6 +99,7 @@
private static final Pattern EVENT_PILFER_POINTERS = Pattern.compile("pilferPointers");
static final Pattern EVENT_START_ACTIVITY = Pattern.compile("Activity\\.onStart");
static final Pattern EVENT_STOP_ACTIVITY = Pattern.compile("Activity\\.onStop");
+ static final Pattern EVENT_START = Pattern.compile("start:");
static final Pattern EVENT_TOUCH_DOWN_TIS = getTouchEventPatternTIS("ACTION_DOWN");
static final Pattern EVENT_TOUCH_UP_TIS = getTouchEventPatternTIS("ACTION_UP");
@@ -247,8 +248,6 @@
}
}
}
-
- disableSensorRotation();
}
public void enableCheckEventsForSuccessfulGestures() {
@@ -1265,7 +1264,7 @@
TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
- public void disableSensorRotation() {
+ private void disableSensorRotation() {
getTestInfo(TestProtocol.REQUEST_MOCK_SENSOR_ROTATION);
}
@@ -1306,6 +1305,7 @@
public Closable eventsCheck() {
Assert.assertTrue("Nested event checking", !sCheckingEvents);
+ disableSensorRotation();
sCheckingEvents = true;
mExpectedPid = getPid();
if (sEventChecker == null) sEventChecker = new LogEventChecker();
diff --git a/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java b/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java
index 63a97f4..d1268cc 100644
--- a/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java
+++ b/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java
@@ -43,6 +43,7 @@
LauncherInstrumentation.log("OptionsPopupMenuItem before click "
+ mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
mLauncher.clickLauncherObject(mObject);
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_START);
if (!Build.MODEL.contains("Cuttlefish") ||
Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q &&
!"R".equals(Build.VERSION.CODENAME)) {
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index b3b5e32..0d91dc2 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -180,6 +180,7 @@
mLauncher.getVisibleBounds(workspace).centerY()),
"deep_shortcuts_container",
false,
+ false,
() -> mLauncher.expectEvent(
TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT));
verifyActiveContainer();
@@ -202,7 +203,8 @@
static void dragIconToWorkspace(
LauncherInstrumentation launcher, Launchable launchable, Point dest,
- String longPressIndicator, boolean startsActivity, Runnable expectLongClickEvents) {
+ String longPressIndicator, boolean startsActivity, boolean isWidgetShortcut,
+ Runnable expectLongClickEvents) {
LauncherInstrumentation.log("dragIconToWorkspace: begin");
final Point launchableCenter = launchable.getObject().getVisibleCenter();
final long downTime = SystemClock.uptimeMillis();
@@ -224,6 +226,9 @@
downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, dest,
LauncherInstrumentation.GestureScope.INSIDE),
NORMAL_STATE_ORDINAL);
+ if (startsActivity || isWidgetShortcut) {
+ launcher.expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_START);
+ }
if (startsActivity) {
launcher.expectEvent(
TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_STOP_ACTIVITY);