Merge "Fix a couple of issues with quick switch from home to empty recents" into sc-dev
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index 842abc3..7ab09c5 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -103,16 +103,40 @@
android:clearTaskOnLaunch="true"
android:exported="false"/>
+ <!--
+ Activity for gesture nav onboarding.
+ It's protected by android.permission.REBOOT to ensure that only system apps can start it
+ (setup wizard already has this permission)
+ -->
<activity android:name="com.android.quickstep.interaction.GestureSandboxActivity"
- android:autoRemoveFromRecents="true"
- android:excludeFromRecents="true"
- android:screenOrientation="portrait"
- android:exported="true">
+ android:autoRemoveFromRecents="true"
+ android:excludeFromRecents="true"
+ android:screenOrientation="portrait"
+ android:permission="android.permission.REBOOT"
+ android:exported="true">
<intent-filter>
<action android:name="com.android.quickstep.action.GESTURE_SANDBOX"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
+
+ <!--
+ Activity following gesture nav onboarding.
+ It's protected by android.permission.REBOOT to ensure that only system apps can start it
+ (setup wizard already has this permission)
+ -->
+ <activity android:name="com.android.quickstep.interaction.AllSetActivity"
+ android:autoRemoveFromRecents="true"
+ android:excludeFromRecents="true"
+ android:screenOrientation="portrait"
+ android:permission="android.permission.REBOOT"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="com.android.quickstep.action.GESTURE_ONBOARDING_ALL_SET"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ </activity>
+
<activity
android:name=".hybridhotseat.HotseatEduActivity"
android:theme="@android:style/Theme.NoDisplay"
diff --git a/quickstep/res/drawable/ic_all_set.xml b/quickstep/res/drawable/ic_all_set.xml
new file mode 100644
index 0000000..a6852aa
--- /dev/null
+++ b/quickstep/res/drawable/ic_all_set.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2021 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="42dp"
+ android:height="40dp"
+ android:viewportWidth="42"
+ android:viewportHeight="40">
+ <path
+ android:pathData="M38,14H25.38L27.28,4.86L27.34,4.22C27.34,3.4 27,2.64 26.46,2.1L24.34,0C24.34,0 10.16,13.7 10,14H0V40H32C33.66,40 35.08,39 35.68,37.56L41.72,23.46C41.9,23 42,22.52 42,22V18C42,15.8 40.2,14 38,14ZM10,36H4V18H10V36ZM38,22L32,36H14V16L22.68,7.32L20,18H38V22Z"
+ android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/quickstep/res/layout/activity_allset.xml b/quickstep/res/layout/activity_allset.xml
new file mode 100644
index 0000000..a6a17e5
--- /dev/null
+++ b/quickstep/res/layout/activity_allset.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingStart="@dimen/allset_page_margin_horizontal"
+ android:paddingEnd="@dimen/allset_page_margin_horizontal"
+ android:layoutDirection="locale"
+ android:textDirection="locale"
+ android:background="?android:attr/colorBackground">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_gravity="start"
+ android:gravity="start"
+ android:orientation="vertical">
+
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/allset_title_icon_margin_top"
+ android:src="@drawable/ic_all_set"/>
+
+ <TextView
+ android:id="@+id/title"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/allset_title_margin_top"
+ android:gravity="start"
+ android:text="@string/allset_title"/>
+
+ <TextView
+ android:id="@+id/subtitle"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/allset_subtitle_margin_top"
+ android:gravity="start"
+ android:text="@string/allset_description"/>
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/navigation_settings"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
+ android:textSize="14sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_above="@+id/hint"
+ android:gravity="center_horizontal"
+ android:layout_marginBottom="72dp"/>
+
+ <TextView
+ android:id="@id/hint"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
+ android:textSize="14sp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/allset_hint_margin_bottom"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true"
+ android:text="@string/allset_hint"/>
+</RelativeLayout>
diff --git a/quickstep/res/values/attrs.xml b/quickstep/res/values/attrs.xml
new file mode 100644
index 0000000..336fb57
--- /dev/null
+++ b/quickstep/res/values/attrs.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 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.
+-->
+<resources>
+ <declare-styleable name="AllSetLinkSpan">
+ <attr name="android:textSize"/>
+ <attr name="android:fontFamily"/>
+ </declare-styleable>
+</resources>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 9c0a083..4f9b3eb 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -99,6 +99,13 @@
<dimen name="gesture_tutorial_feedback_margin_start_end">24dp</dimen>
<dimen name="gesture_tutorial_button_margin_start_end">18dp</dimen>
+ <!-- All Set page -->
+ <dimen name="allset_page_margin_horizontal">40dp</dimen>
+ <dimen name="allset_title_margin_top">28dp</dimen>
+ <dimen name="allset_title_icon_margin_top">80dp</dimen>
+ <dimen name="allset_hint_margin_bottom">52dp</dimen>
+ <dimen name="allset_subtitle_margin_top">24dp</dimen>
+
<!-- All Apps Education tutorial -->
<dimen name="swipe_edu_padding">8dp</dimen>
<dimen name="swipe_edu_circle_size">64dp</dimen>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index a0f1638..7ada496 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -177,6 +177,15 @@
<!-- Feedback subtext displaying the current step and the total number of steps for the tutorial. [CHAR LIMIT=30] -->
<string name="gesture_tutorial_step">Tutorial <xliff:g id="current">%1$d</xliff:g>/<xliff:g id="total">%2$d</xliff:g></string>
+ <!-- Title of "All Set" page [CHAR LIMIT=NONE] -->
+ <string name="allset_title">All set!</string>
+ <!-- Hint string at the bottom of "All Set" page [CHAR LIMIT=NONE] -->
+ <string name="allset_hint">Swipe up to go home</string>
+ <!-- Description of "All Set" page [CHAR LIMIT=NONE] -->
+ <string name="allset_description">You\u2019re ready to start using your phone</string>
+ <!-- String linking to navigation settings on "All Set" page [CHAR LIMIT=NONE] -->
+ <string name="allset_navigation_settings"><annotation id="link">Navigation settings for accessibility</annotation></string>
+
<!-- ******* Overview ******* -->
<!-- Label for a button that causes the current overview app to be shared. [CHAR_LIMIT=40] -->
<string name="action_share">Share</string>
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 7c7d20a..0a8ecb8 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -59,7 +59,7 @@
parent="TextAppearance.GestureTutorial">
<item name="android:gravity">start</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
- <item name="android:fontFamily">google-sans</item>
+ <item name="android:fontFamily">google-sans-text</item>
<item name="android:letterSpacing">0.03</item>
<item name="android:textSize">18sp</item>
<item name="android:lineHeight">24sp</item>
@@ -99,6 +99,11 @@
<item name="android:textColor">@color/gesture_tutorial_primary_color</item>
</style>
+ <style name="TextAppearance.GestureTutorial.LinkText"
+ parent="TextAppearance.GestureTutorial.Feedback.Subtitle">
+ <item name="android:textSize">14sp</item>
+ </style>
+
<!--
Can be applied to views to color things like ripples and list highlights the workspace text
color.
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index ecaac94..10384a8 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -47,7 +47,6 @@
import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
import static com.android.quickstep.util.SwipePipToHomeAnimator.FRACTION_END;
import static com.android.quickstep.util.SwipePipToHomeAnimator.FRACTION_START;
-import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
@@ -55,7 +54,6 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.ActivityManager;
@@ -464,8 +462,6 @@
mDeviceState.getRotationTouchHelper()
.onEndTargetCalculated(mGestureState.getEndTarget(),
mActivityInterface);
-
- mRecentsView.onGestureEndTargetCalculated(mGestureState.getEndTarget());
});
notifyGestureStartedAsync();
@@ -1133,6 +1129,10 @@
}
homeAnimFactory.playAtomicAnimation(velocityPxPerMs.y);
mLauncherTransitionController = null;
+
+ if (mRecentsView != null) {
+ mRecentsView.onPrepareGestureEndAnimation(null, mGestureState.getEndTarget());
+ }
} else {
AnimatorSet animatorSet = new AnimatorSet();
ValueAnimator windowAnim = mCurrentShift.animateToValue(start, end);
@@ -1171,9 +1171,9 @@
}
});
animatorSet.play(windowAnim);
- S state = mActivityInterface.stateFromGestureEndTarget(mGestureState.getEndTarget());
- if (mRecentsView != null && state.displayOverviewTasksAsGrid(mDp)) {
- animatorSet.play(ObjectAnimator.ofFloat(mRecentsView, RECENTS_GRID_PROGRESS, 1));
+ if (mRecentsView != null) {
+ mRecentsView.onPrepareGestureEndAnimation(
+ animatorSet, mGestureState.getEndTarget());
}
animatorSet.setDuration(duration).setInterpolator(interpolator);
animatorSet.start();
@@ -1701,7 +1701,7 @@
// No need to apply any transform if there is ongoing swipe-pip-to-home animator since
// that animator handles the leash solely.
if (mRecentsAnimationTargets != null && !mIsSwipingPipToHome) {
- if (mRecentsViewScrollLinked) {
+ if (mRecentsViewScrollLinked && mRecentsView != null) {
mTaskViewSimulator.setScroll(mRecentsView.getScrollOffset());
}
mTaskViewSimulator.apply(mTransformParams);
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 9fa65d9..3c81d1b 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -163,7 +163,9 @@
@Override
public boolean isInLiveTileMode() {
- return false;
+ RecentsActivity activity = getCreatedActivity();
+ return activity != null && activity.getStateManager().getState() == DEFAULT &&
+ activity.isStarted();
}
@Override
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index 9398277..46cd8a2 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -260,6 +260,7 @@
@Override
public void setAnimation(RectFSpringAnim anim) {
anim.addAnimatorListener(floatingWidgetView);
+ floatingWidgetView.setOnTargetChangeListener(anim::onTargetPositionChanged);
floatingWidgetView.setFastFinishRunnable(anim::end);
}
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 3b92779..0e9e3ad 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -22,10 +22,13 @@
import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_DURATION;
import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_PRE_DELAY;
import static com.android.launcher3.Utilities.createHomeIntent;
+import static com.android.launcher3.graphics.SysUiScrim.SYSUI_PROGRESS;
import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL;
import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
import static com.android.quickstep.TaskViewUtils.createRecentsWindowAnimator;
+import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -35,6 +38,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
+import android.view.SurfaceControl.Transaction;
import android.view.View;
import androidx.annotation.Nullable;
@@ -47,6 +51,7 @@
import com.android.launcher3.R;
import com.android.launcher3.WrappedAnimationRunnerImpl;
import com.android.launcher3.WrappedLauncherAnimationRunner;
+import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
@@ -69,6 +74,7 @@
import com.android.quickstep.util.RecentsAtomicAnimationFactory;
import com.android.quickstep.util.SplitSelectStateController;
import com.android.quickstep.views.OverviewActionsView;
+import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.SplitPlaceholderView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.ActivityOptionsCompat;
@@ -90,6 +96,8 @@
private Handler mUiHandler = new Handler(Looper.getMainLooper());
+ private static final long HOME_APPEAR_DURATION = 250;
+
private RecentsDragLayer mDragLayer;
private ScrimView mScrimView;
private FallbackRecentsView mFallbackRecentsView;
@@ -112,6 +120,7 @@
mScrimView = findViewById(R.id.scrim_view);
mFallbackRecentsView = findViewById(R.id.overview_panel);
mActionsView = findViewById(R.id.overview_actions_view);
+ SYSUI_PROGRESS.set(getRootView().getSysUiScrim(), 0f);
SplitPlaceholderView splitPlaceholderView = findViewById(R.id.split_placeholder);
splitPlaceholderView.init(
@@ -291,6 +300,16 @@
super.onConfigurationChanged(newConfig);
}
+ @Override
+ public void onStateSetEnd(RecentsState state) {
+ super.onStateSetEnd(state);
+
+ if (state == RecentsState.DEFAULT) {
+ AccessibilityManagerCompat.sendStateEventToTest(getBaseContext(),
+ OVERVIEW_STATE_ORDINAL);
+ }
+ }
+
/**
* Initialize/update the device profile.
*/
@@ -329,7 +348,42 @@
}
public void startHome() {
- startActivity(createHomeIntent());
+ if (LIVE_TILE.get()) {
+ RecentsView recentsView = getOverviewPanel();
+ recentsView.switchToScreenshot(() -> recentsView.finishRecentsAnimation(true,
+ this::startHomeInternal));
+ } else {
+ startHomeInternal();
+ }
+ }
+
+ private void startHomeInternal() {
+ WrappedLauncherAnimationRunner runner = new WrappedLauncherAnimationRunner(
+ getMainThreadHandler(), this::onCreateAnimationToHome, true);
+ RemoteAnimationAdapterCompat adapterCompat =
+ new RemoteAnimationAdapterCompat(runner, HOME_APPEAR_DURATION, 0);
+ startActivity(createHomeIntent(),
+ ActivityOptionsCompat.makeRemoteAnimation(adapterCompat).toBundle());
+ }
+
+ private void onCreateAnimationToHome(
+ int transit, RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets,
+ RemoteAnimationTargetCompat[] nonAppTargets, AnimationResult result) {
+ AnimatorPlaybackController controller = getStateManager()
+ .createAnimationToNewWorkspace(RecentsState.BG_LAUNCHER, HOME_APPEAR_DURATION);
+ controller.dispatchOnStart();
+
+ RemoteAnimationTargets targets = new RemoteAnimationTargets(
+ appTargets, wallpaperTargets, nonAppTargets, MODE_OPENING);
+ for (RemoteAnimationTargetCompat app : targets.apps) {
+ new Transaction().setAlpha(app.leash.getSurfaceControl(), 1).apply();
+ }
+ AnimatorSet anim = new AnimatorSet();
+ anim.play(controller.getAnimationPlayer());
+ anim.setDuration(HOME_APPEAR_DURATION);
+ result.setAnimation(anim, this,
+ () -> getStateManager().goToState(RecentsState.HOME, false));
}
@Override
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 4d4b6e1..1bb8e96 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -20,6 +20,7 @@
import static com.android.quickstep.fallback.RecentsState.HOME;
import static com.android.quickstep.fallback.RecentsState.MODAL_TASK;
+import android.animation.AnimatorSet;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
@@ -27,6 +28,9 @@
import android.util.AttributeSet;
import android.util.Log;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statemanager.StateManager.StateListener;
import com.android.launcher3.testing.TestProtocol;
@@ -67,7 +71,6 @@
@Override
public void startHome() {
mActivity.startHome();
- mActivity.getStateManager().goToState(RecentsState.HOME);
}
/**
@@ -86,14 +89,17 @@
* to the center.
*/
@Override
- public void onGestureEndTargetCalculated(GestureState.GestureEndTarget endTarget) {
- super.onGestureEndTargetCalculated(endTarget);
- if (mHomeTaskInfo != null && endTarget == RECENTS) {
+ public void onPrepareGestureEndAnimation(
+ @Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget) {
+ super.onPrepareGestureEndAnimation(animatorSet, endTarget);
+ if (mHomeTaskInfo != null && endTarget == RECENTS && animatorSet != null) {
TaskView tv = getTaskView(mHomeTaskInfo.taskId);
if (tv != null) {
PendingAnimation pa = createTaskDismissAnimation(tv, true, false, 150);
pa.addEndListener(e -> setCurrentTask(-1));
- runDismissAnimation(pa);
+ AnimatorPlaybackController controller = pa.createPlaybackController();
+ controller.dispatchOnStart();
+ animatorSet.play(controller.getAnimationPlayer());
}
}
}
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsState.java b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
index b3d6cfa..b6cfdce 100644
--- a/quickstep/src/com/android/quickstep/fallback/RecentsState.java
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
@@ -39,15 +39,18 @@
private static final int FLAG_OVERVIEW_ACTIONS = BaseState.getFlag(3);
private static final int FLAG_SHOW_AS_GRID = BaseState.getFlag(4);
private static final int FLAG_SCRIM = BaseState.getFlag(5);
+ private static final int FLAG_LIVE_TILE = BaseState.getFlag(6);
public static final RecentsState DEFAULT = new RecentsState(0,
- FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_SHOW_AS_GRID | FLAG_SCRIM);
+ FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_SHOW_AS_GRID | FLAG_SCRIM
+ | FLAG_LIVE_TILE);
public static final RecentsState MODAL_TASK = new ModalState(1,
FLAG_DISABLE_RESTORE | FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_MODAL
- | FLAG_SHOW_AS_GRID | FLAG_SCRIM);
+ | FLAG_SHOW_AS_GRID | FLAG_SCRIM | FLAG_LIVE_TILE);
public static final RecentsState BACKGROUND_APP = new BackgroundAppState(2,
FLAG_DISABLE_RESTORE | FLAG_NON_INTERACTIVE | FLAG_FULL_SCREEN);
public static final RecentsState HOME = new RecentsState(3, 0);
+ public static final RecentsState BG_LAUNCHER = new LauncherState(4, 0);
public final int ordinal;
private final int mFlags;
@@ -108,6 +111,13 @@
}
/**
+ * For this state, whether live tile should be shown.
+ */
+ public boolean hasLiveTile() {
+ return hasFlag(FLAG_LIVE_TILE);
+ }
+
+ /**
* For this state, what color scrim should be drawn behind overview.
*/
public int getScrimColor(RecentsActivity activity) {
@@ -152,4 +162,15 @@
return getOverviewScaleAndOffsetForBackgroundState(activity);
}
}
+
+ private static class LauncherState extends RecentsState {
+ LauncherState(int id, int flags) {
+ super(id, flags);
+ }
+
+ @Override
+ public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
+ return new float[] { NO_SCALE, 1 };
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java b/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java
index d7458d2..273d1f6 100644
--- a/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java
@@ -15,6 +15,8 @@
*/
package com.android.quickstep.fallback;
+import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
+
import com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController;
import com.android.quickstep.RecentsActivity;
@@ -26,7 +28,8 @@
@Override
protected boolean isRecentsInteractive() {
- return mActivity.hasWindowFocus();
+ return mActivity.hasWindowFocus() || (LIVE_TILE.get()
+ && mActivity.getStateManager().getState().hasLiveTile());
}
@Override
diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
new file mode 100644
index 0000000..76f43c9
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2021 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 android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.text.TextPaint;
+import android.text.method.LinkMovementMethod;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.R;
+
+import java.net.URISyntaxException;
+
+/**
+ * A page shows after SUW flow to hint users to swipe up from the bottom of the screen to go home
+ * for the gestural system navigation.
+ */
+public class AllSetActivity extends Activity {
+
+ private static final String LOG_TAG = "AllSetActivity";
+ private static final String URI_SYSTEM_NAVIGATION_SETTING =
+ "#Intent;action=com.android.settings.SEARCH_RESULT_TRAMPOLINE;S.:settings:fragment_args_key=gesture_system_navigation_input_summary;S.:settings:show_fragment=com.android.settings.gestures.SystemNavigationGestureSettings;end";
+ private static final String EXTRA_ACCENT_COLOR_DARK_MODE = "accent_color_dark_mode";
+ private static final String EXTRA_ACCENT_COLOR_LIGHT_MODE = "accent_color_light_mode";
+
+ private int mAccentColor;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_allset);
+ setTitle(R.string.allset_title);
+
+ final int mode =
+ getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
+ mAccentColor = getIntent().getIntExtra(
+ mode == Configuration.UI_MODE_NIGHT_YES
+ ? EXTRA_ACCENT_COLOR_DARK_MODE : EXTRA_ACCENT_COLOR_LIGHT_MODE,
+ /* defValue= */ Color.BLACK);
+
+ ((ImageView) findViewById(R.id.icon)).getDrawable().mutate().setTint(mAccentColor);
+
+ TextView navigationSettings = findViewById(R.id.navigation_settings);
+ navigationSettings.setMovementMethod(LinkMovementMethod.getInstance());
+ AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan.LinkInfo(
+ AnnotationSpan.LinkInfo.DEFAULT_ANNOTATION,
+ new AllSetLinkSpan(
+ /* context= */ this,
+ view -> {
+ try {
+ startActivityForResult(
+ Intent.parseUri(URI_SYSTEM_NAVIGATION_SETTING, 0), 0);
+ } catch (URISyntaxException e) {
+ Log.e(LOG_TAG, "Failed to parse system nav settings intent", e);
+ }
+ finish();
+ }));
+ navigationSettings.setText(
+ AnnotationSpan.linkify(getText(R.string.allset_navigation_settings), linkInfo));
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+ if (hasFocus) {
+ hideSystemUI();
+ }
+ }
+
+ private void hideSystemUI() {
+ getWindow().getDecorView().setSystemUiVisibility(
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_FULLSCREEN);
+ getWindow().setNavigationBarColor(Color.TRANSPARENT);
+ }
+
+ private final class AllSetLinkSpan extends AnnotationSpan {
+
+ private final String mFontFamily;
+ private final int mTextSize;
+
+ AllSetLinkSpan(Context context, View.OnClickListener listener) {
+ super(listener);
+ TypedArray typedArray =
+ context.obtainStyledAttributes(R.style.TextAppearance_GestureTutorial_LinkText,
+ R.styleable.AllSetLinkSpan);
+ mFontFamily = typedArray.getString(R.styleable.AllSetLinkSpan_android_fontFamily);
+ mTextSize =
+ typedArray.getDimensionPixelSize(
+ R.styleable.AllSetLinkSpan_android_textSize, /* defValue= */ -1);
+ typedArray.recycle();
+ }
+
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ super.updateDrawState(ds);
+ ds.setColor(mAccentColor);
+ ds.setTypeface(Typeface.create(mFontFamily, Typeface.NORMAL));
+ ds.setUnderlineText(false);
+ if (mTextSize != -1) {
+ ds.setTextSize(mTextSize);
+ }
+ }
+ }
+
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/AnnotationSpan.java b/quickstep/src/com/android/quickstep/interaction/AnnotationSpan.java
new file mode 100644
index 0000000..fea5078
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/AnnotationSpan.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2018 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 android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.text.Annotation;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
+import android.text.style.URLSpan;
+import android.util.Log;
+import android.view.View;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * This class is used to add {@link View.OnClickListener} for the text been wrapped by
+ * annotation.
+ *
+ * Copied from packages/apps/Settings/src/com/android/settings/utils/AnnotationSpan.java.
+ */
+public class AnnotationSpan extends URLSpan {
+
+ private final View.OnClickListener mClickListener;
+
+ AnnotationSpan(View.OnClickListener lsn) {
+ super((String) null);
+ mClickListener = lsn;
+ }
+
+ @Override
+ public void onClick(View widget) {
+ if (mClickListener != null) {
+ mClickListener.onClick(widget);
+ }
+ }
+
+ public static CharSequence linkify(CharSequence rawText, LinkInfo... linkInfos) {
+ SpannableString msg = new SpannableString(rawText);
+ Annotation[] spans = msg.getSpans(0, msg.length(), Annotation.class);
+ SpannableStringBuilder builder = new SpannableStringBuilder(msg);
+ for (Annotation annotation : spans) {
+ final String key = annotation.getValue();
+ int start = msg.getSpanStart(annotation);
+ int end = msg.getSpanEnd(annotation);
+ AnnotationSpan link = null;
+ for (LinkInfo linkInfo : linkInfos) {
+ if (linkInfo.mAnnotation.equals(key)) {
+ link = linkInfo.mCustomizedSpan != null ? linkInfo.mCustomizedSpan
+ : new AnnotationSpan(linkInfo.mClickListener);
+ break;
+ }
+ }
+ if (link != null) {
+ builder.setSpan(link, start, end, msg.getSpanFlags(link));
+ }
+ }
+ return builder;
+ }
+
+ /**
+ * get the text part without having text for link part
+ */
+ public static CharSequence textWithoutLink(CharSequence encodedText) {
+ SpannableString msg = new SpannableString(encodedText);
+ Annotation[] spans = msg.getSpans(0, msg.length(), Annotation.class);
+ if (spans == null) {
+ return encodedText;
+ }
+ Arrays.sort(spans, Comparator.comparingInt(span -> -msg.getSpanStart(span)));
+ StringBuilder msgWithoutLink = new StringBuilder(msg.toString());
+ for (Annotation span : spans) {
+ msgWithoutLink.delete(msg.getSpanStart(span), msg.getSpanEnd(span));
+ }
+ return msgWithoutLink.toString();
+ }
+
+ /** Data class to store the annotation and the click action. */
+ public static class LinkInfo {
+ public static final String DEFAULT_ANNOTATION = "link";
+ private static final String TAG = "AnnotationSpan.LinkInfo";
+ private final String mAnnotation;
+ private final Boolean mActionable;
+ private final View.OnClickListener mClickListener;
+ private final AnnotationSpan mCustomizedSpan;
+
+ public LinkInfo(String annotation, View.OnClickListener listener) {
+ mAnnotation = annotation;
+ mClickListener = listener;
+ mActionable = true; // assume actionable
+ mCustomizedSpan = null;
+ }
+
+ public LinkInfo(String annotation, AnnotationSpan customizedSpan) {
+ mAnnotation = annotation;
+ mClickListener = null;
+ mActionable = customizedSpan != null;
+ mCustomizedSpan = customizedSpan;
+ }
+
+ public LinkInfo(Context context, String annotation, Intent intent) {
+ mAnnotation = annotation;
+ mCustomizedSpan = null;
+ if (intent != null) {
+ mActionable = context.getPackageManager().resolveActivity(intent, 0) != null;
+ } else {
+ mActionable = false;
+ }
+ if (mActionable) {
+ mClickListener =
+ view -> {
+ try {
+ context.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, "Activity was not found for intent, " + intent);
+ }
+ };
+ } else {
+ mClickListener = null;
+ }
+ }
+
+ public boolean isActionable() {
+ return mActionable;
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java b/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java
index c527be3..60c7add 100644
--- a/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java
+++ b/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java
@@ -20,8 +20,6 @@
import android.content.Context;
-import com.android.quickstep.OverviewComponentObserver;
-import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.SysUINavigationMode;
import java.util.function.Predicate;
@@ -37,7 +35,6 @@
private final Supplier<Boolean> mBasePredicate;
private final Predicate<SysUINavigationMode.Mode> mModePredicate;
private boolean mSupported;
- private OverviewComponentObserver mObserver;
private NavigationModeFeatureFlag(Supplier<Boolean> basePredicate,
Predicate<SysUINavigationMode.Mode> modePredicate) {
@@ -46,17 +43,12 @@
}
public boolean get() {
- return mBasePredicate.get() && mSupported && mObserver != null
- && mObserver.isHomeAndOverviewSame();
+ return mBasePredicate.get() && mSupported;
}
public void initialize(Context context) {
onNavigationModeChanged(SysUINavigationMode.INSTANCE.get(context).getMode());
SysUINavigationMode.INSTANCE.get(context).addModeChangeListener(this);
-
- // Temporary solution to disable live tile for the fallback launcher
- RecentsAnimationDeviceState rads = new RecentsAnimationDeviceState(context);
- mObserver = new OverviewComponentObserver(context, rads);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index e63f8bb..f578ad1 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -36,6 +36,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.BaseActivityInterface;
import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper;
@@ -95,7 +96,9 @@
mContext = context;
mSizeStrategy = sizeStrategy;
- mOrientationState = new RecentsOrientedState(context, sizeStrategy, i -> { });
+ // TODO(b/187074722): Don't create this per-TaskViewSimulator
+ mOrientationState = TraceHelper.allowIpcs("",
+ () -> new RecentsOrientedState(context, sizeStrategy, i -> { }));
mOrientationState.setGestureActive(true);
mCurrentFullscreenParams = new FullscreenDrawParams(context);
mOrientationStateId = mOrientationState.getStateId();
diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
index f74aa55..9ea2369 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
@@ -100,8 +100,8 @@
/** Restores the drawables to the source view. */
void finish() {
if (isUninitialized()) return;
- mSourceView.setForeground(mOriginalForeground);
- mSourceView.setBackground(mOriginalBackground);
+ if (mOriginalForeground != null) mSourceView.setForeground(mOriginalForeground);
+ if (mOriginalBackground != null) mSourceView.setBackground(mOriginalBackground);
}
void recycle() {
diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
index 8499902..ed54f10 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
@@ -27,6 +27,7 @@
import android.view.GhostView;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.FrameLayout;
import com.android.launcher3.Launcher;
@@ -39,7 +40,8 @@
/** A view that mimics an App Widget through a launch animation. */
@TargetApi(Build.VERSION_CODES.S)
-public class FloatingWidgetView extends FrameLayout implements AnimatorListener {
+public class FloatingWidgetView extends FrameLayout implements AnimatorListener,
+ OnGlobalLayoutListener {
private static final Matrix sTmpMatrix = new Matrix();
private final Launcher mLauncher;
@@ -54,6 +56,7 @@
private Runnable mEndRunnable;
private Runnable mFastFinishRunnable;
+ private Runnable mOnTargetChangeRunnable;
public FloatingWidgetView(Context context) {
this(context, null);
@@ -93,6 +96,32 @@
public void onAnimationRepeat(Animator animator) {
}
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ getViewTreeObserver().addOnGlobalLayoutListener(this);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ super.onDetachedFromWindow();
+ }
+
+ @Override
+ public void onGlobalLayout() {
+ if (isUninitialized()) return;
+ positionViews();
+ if (mOnTargetChangeRunnable != null) {
+ mOnTargetChangeRunnable.run();
+ }
+ }
+
+ /** Sets a runnable that is called on global layout change. */
+ public void setOnTargetChangeListener(Runnable onTargetChangeListener) {
+ mOnTargetChangeRunnable = onTargetChangeListener;
+ }
+
/** Sets a runnable that is called after a call to {@link #fastFinish()}. */
public void setFastFinishRunnable(Runnable runnable) {
mFastFinishRunnable = runnable;
@@ -205,6 +234,7 @@
private void recycle() {
mEndRunnable = null;
mFastFinishRunnable = null;
+ mOnTargetChangeRunnable = null;
mBackgroundPosition = null;
mListenerView.setListener(null);
mAppWidgetView = null;
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index c9e7a73..9797afd 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1631,7 +1631,16 @@
/**
* Called when a gesture from an app has finished, and an end target has been determined.
*/
- public void onGestureEndTargetCalculated(GestureState.GestureEndTarget endTarget) {
+ public void onPrepareGestureEndAnimation(
+ @Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget) {
+ if (mSizeStrategy.stateFromGestureEndTarget(endTarget)
+ .displayOverviewTasksAsGrid(mActivity.getDeviceProfile())) {
+ if (animatorSet == null) {
+ setGridProgress(1);
+ } else {
+ animatorSet.play(ObjectAnimator.ofFloat(this, RECENTS_GRID_PROGRESS, 1));
+ }
+ }
mCurrentGestureEndTarget = endTarget;
if (endTarget == GestureState.GestureEndTarget.NEW_TASK
|| endTarget == GestureState.GestureEndTarget.LAST_TASK) {
@@ -2249,7 +2258,8 @@
mPendingAnimation.addEndListener(new Consumer<Boolean>() {
@Override
public void accept(Boolean success) {
- if (LIVE_TILE.get() && taskView.isRunningTask() && success) {
+ if (LIVE_TILE.get() && mEnableDrawingLiveTile && taskView.isRunningTask()
+ && success) {
finishRecentsAnimation(true /* toHome */, () -> onEnd(success));
} else {
onEnd(success);
@@ -2347,7 +2357,7 @@
return true;
}
- protected void runDismissAnimation(PendingAnimation pendingAnim) {
+ private void runDismissAnimation(PendingAnimation pendingAnim) {
AnimatorPlaybackController controller = pendingAnim.createPlaybackController();
controller.dispatchOnStart();
controller.getAnimationPlayer().setInterpolator(FAST_OUT_SLOW_IN);
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 08f5879..99a8049 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -553,6 +553,7 @@
@Override
public void onAnimationEnd(Animator animator) {
+ recentsView.getLiveTileTaskViewSimulator().setDrawsBelowRecents(true);
mIsClickableAsLiveTile = true;
}
});
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index 20b4631..c1f3ac5 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -57,6 +57,22 @@
private final View[] mDragHandles = new View[HANDLE_COUNT];
private final List<Rect> mSystemGestureExclusionRects = new ArrayList<>(HANDLE_COUNT);
+ private final OnAttachStateChangeListener mWidgetViewAttachStateChangeListener =
+ new OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View view) {
+ // Do nothing
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View view) {
+ // When the app widget view is detached, we should close the resize frame.
+ // An example is when the dragging starts, the widget view is detached from
+ // CellLayout and then reattached to DragLayout.
+ close(false);
+ }
+ };
+
private LauncherAppWidgetHostView mWidgetView;
private CellLayout mCellLayout;
@@ -177,7 +193,11 @@
private void setupForWidget(LauncherAppWidgetHostView widgetView, CellLayout cellLayout,
DragLayer dragLayer) {
mCellLayout = cellLayout;
+ if (mWidgetView != null) {
+ mWidgetView.removeOnAttachStateChangeListener(mWidgetViewAttachStateChangeListener);
+ }
mWidgetView = widgetView;
+ mWidgetView.addOnAttachStateChangeListener(mWidgetViewAttachStateChangeListener);
LauncherAppWidgetProviderInfo info = (LauncherAppWidgetProviderInfo)
widgetView.getAppWidgetInfo();
mResizeMode = info.resizeMode;
@@ -628,6 +648,9 @@
@Override
protected void handleClose(boolean animate) {
mDragLayer.removeView(this);
+ if (mWidgetView != null) {
+ mWidgetView.removeOnAttachStateChangeListener(mWidgetViewAttachStateChangeListener);
+ }
}
@Override
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index a5852ba..dbdfb2b 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -32,6 +32,7 @@
import com.android.launcher3.Workspace;
import com.android.launcher3.dragndrop.DragController.DragListener;
import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.keyboard.KeyboardDragAndDropView;
import com.android.launcher3.model.data.AppInfo;
@@ -290,7 +291,12 @@
return actions;
}
- CellLayout layout = (CellLayout) host.getParent().getParent();
+ CellLayout layout;
+ if (host.getParent() instanceof DragView) {
+ layout = (CellLayout) ((DragView) host.getParent()).getContentViewParent().getParent();
+ } else {
+ layout = (CellLayout) host.getParent().getParent();
+ }
if ((providerInfo.resizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0) {
if (layout.isRegionVacant(info.cellX + info.spanX, info.cellY, 1, info.spanY) ||
layout.isRegionVacant(info.cellX - 1, info.cellY, 1, info.spanY)) {
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 119a91f..b11b63e 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -75,7 +75,7 @@
public class AllAppsContainerView extends SpringRelativeLayout implements DragSource,
Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener {
- private static final float FLING_VELOCITY_MULTIPLIER = 1800f;
+ private static final float FLING_VELOCITY_MULTIPLIER = 1000f;
// Starts the springs after at least 25% of the animation has passed.
private static final float FLING_ANIMATION_THRESHOLD = 0.25f;
@@ -611,7 +611,7 @@
public void onAnimationUpdate(ValueAnimator valueAnimator) {
if (shouldSpring
&& valueAnimator.getAnimatedFraction() >= FLING_ANIMATION_THRESHOLD) {
- absorbSwipeUpVelocity(-Math.abs(
+ absorbSwipeUpVelocity(Math.abs(
Math.round(velocity * FLING_VELOCITY_MULTIPLIER)));
shouldSpring = false;
}
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index c61c0d6..c4c7891 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -15,13 +15,15 @@
*/
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.OVERVIEW;
-import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
+import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
+import static com.android.launcher3.anim.Interpolators.ACCEL_2;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import static com.android.launcher3.util.SystemUiController.UI_STATE_ALLAPPS;
@@ -154,9 +156,9 @@
return;
}
- Interpolator interpolator = config.userControlled ? LINEAR : toState == OVERVIEW
- ? config.getInterpolator(ANIM_OVERVIEW_SCALE, FAST_OUT_SLOW_IN)
- : FAST_OUT_SLOW_IN;
+ Interpolator interpolator = toState.equals(ALL_APPS)
+ ? (config.userControlled ? ACCEL_2 : ACCEL_0_75) :
+ (config.userControlled ? DEACCEL_2 : DEACCEL);
Animator anim = createSpringAnimation(mProgress, targetProgress);
anim.setInterpolator(config.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
diff --git a/src/com/android/launcher3/model/data/SearchActionItemInfo.java b/src/com/android/launcher3/model/data/SearchActionItemInfo.java
index b3057d5..0eea92c 100644
--- a/src/com/android/launcher3/model/data/SearchActionItemInfo.java
+++ b/src/com/android/launcher3/model/data/SearchActionItemInfo.java
@@ -94,6 +94,11 @@
"SearchActionItemInfo can only have either an Intent or a PendingIntent");
}
mIntent = intent;
+ // bandage fix for just one week
+ if (intent != null && "com.android.server.telecom".equals(intent.getPackage())) {
+ intent.setAction(Intent.ACTION_DIAL);
+ intent.setPackage(null);
+ }
}
public PendingIntent getPendingIntent() {
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index f6a6448..9358c49 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -277,7 +277,7 @@
} else {
// Phone Portrait, LargeScreen Landscape/Portrait
viewGroup.setOrientation(LinearLayout.HORIZONTAL);
- lp.width = LinearLayout.LayoutParams.WRAP_CONTENT;
+ lp.width = LinearLayout.LayoutParams.MATCH_PARENT;
}
lp.height = LinearLayout.LayoutParams.WRAP_CONTENT;